gtk-wave-cleaner-0.22-04/0000777000175000017500000000000013455327363016221 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/COPYING0000777000175000017500000003005013120075106017235 0ustar00alisteralister00000000000000 GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS gtk-wave-cleaner-0.22-04/Changelog0000666000175000017500000004657013455322225020037 0ustar00alisteralister00000000000000GWC Changelog KNOWN ISSUE: GWC fails to open wav files with metadata; refer to the README for details. 0.22-04 April 16, 2019 This release is mostly fixes and improvements for osx packaging. Note that the version number has jumped to -04 because I had several attempts at creating an osx package, using up some numbers, and I don't want to create confusion between them and newer releases. (I figured it was a good idea to use the same three numbers in CFBundleVersion, but actually it doesn't support 0 as the first number. So in future I should instead append something like "+build1".) BUGFIX: playback mono files at correct speed with pulseaudio backend. NEW: warn the user if the current working directory is not writable, as that causes big problems. CODE: allow building with pulseaudio backend on osx, as the coreaudio backend is broken (playback does not work in the previous OSX packages). CHANGED BEHAVIOUR: on osx write files to sensible locations. DOC: document optional dependencies (LAME and vorbis-tools). 0.22-01 August 04, 2017 Minor build/packaging type fixes. 0.22 July 18, 2017 This release is by Alister Hood. Jeff Welty has advised via email that he has not used GWC for several years and does not have time currently to look at any issues with it. This release is a port from the old GNOME libraries to plain GTK2 and does not include major changes in functionality. There is plenty of bugfixing and cleanup of how things work, but much of it will only be apparent in less typical "corner cases". A more detailed summary of the changes is below. For full details refer to the git commit log at https://github.com/AlisterH/gwc Patches or pull requests are of course encouraged! BUGFIX: apply Debian patch to prevent crash on x86_64. BUGFIX: apply Debian patch to build successfully if using clang. BUGFIX: solve various problems with ogg and mp3 encoding. BUGFIX: don't freeze when stopping alsa playback (please report if you do still experience and freezes). NEW: on Mac OSX integrate with the system "application menu", dock and basic keyboard shortcuts. NEW: support for gtk-can-change-accels = 1 (in ~/.gtkrc-2.0). CODE: reimplemented the gui to use plain gtk2, removing the dependencies on obsolete Gnome libraries. This also fixes a number of minor gui bugs and modernises things like file choosers. CODE: various other gui bugfixes and improvements. CODE: follow more standards for where we install files. CODE: various fixes to the build system, including actually installing to --prefix. CODE: general cleanup including removing duplicated or unnecessary files, fixing typos etc. DOC: remove the old help manual in favour of the quickstart guide, and show the help without requiring a GNOME environment. CHANGED CONFIG FILE: the location has changed - typically it was ~/.gnome2/gnome_wave_cleaner and is now ~/.config/gtk-wave-cleaner/gwc.conf The format has not changed so it is possible for you to move an old file to the new location. CHANGED BEHAVIOUR: Undo files and clipboard data are now saved in $XDG_CACHE_HOME if possible (rather than the current working directory). Undo files are saved in unique subdirectories so multiple instances of gwc won't interfere with each other. The clipboard is shared between all gwc instances unless you override $XDG_CACHE_HOME (or it does not exist). CHANGED NAME: GWC no longer depends on the deprecated GNOME libs, does not depend on GTK3, and is not very "Gnomish". Including Gnome in the name is therefore misleading, so the full name has been changed to "Gtk Wave Cleaner". RENAMED EXECUTABLE: there is at least one other project named gwc, so to avoid packaging clashes the executable is renamed to gtk-wave-cleaner. Symlink or alias it as gwc if the long name bothers you ;) 0.21-19 Feb 2, 2013 BUGFIX: warning on opening audio device incorrectly displayed pulse audio message when neither alsa or pulse audio was being used BUGFIX: Encoding to ogg or mp3 has always been broken, can only encode to once during GWC session. Fixed by using named pipe NEW: A simple front end for encoding to MP3s. Only a -V xx encoding option, but can have default artist and album tags now, and enter trackname when encoding the selection. Kind of klunky user interface, but it works. 0.21-18 Feb 1, 2013 BUGFIX: pulse audio using pulse_simple_new was incorrectly checking error return Apr 10, 2012 BUGFIX: length of tracks on cdrdao toc file was too short by 1 sample 0.21-17 Apr 8, 2012 CODE: Remove executable permissions from undo and .gwc files, thanks quadrispro BUGFIX: Alsa device was not opened correctly with interleaved samples BUGFIX: Create cdrdao toc file not using marker pairs was badly broken. 0.21-16 Mar 17, 2011 CODE: Better implementation of ALSA driver for detecting number of processed frames 0.21-15 Mar 17, 2011 BUGFIX: Configure script was not working for ALSA CODE: Small upgrade for alsa driver, should attach even when other apps have alsa open 0.21-14 Mar 16, 2011 BUGFIX: Configure script was out of date with regards to alsa, pulseaudio. Fixed COPYRIGHT: Some important copyright notices from the cephes library now included in i0.c i1.c and chbevl.c CODE: added shortcut keys '3' which moves view forward by 1 revolution of 33 1/3 rpm, '2' moves view back 0.21-13 CODE: Better information feedback when libsndfile fails to open file BUGFIX: pulse audio playback does not register completion BUGFIX: Makefile.in did not have dependency for audio_pa.c 0.21-12 NEW: Alpha code -- pulse audio audio driver by default 0.21-11 BUGFIX: Amplify had a bug when only amplifying a single channel. NEW: Alpha code -- trying to read MP3's and OGG file types. NEW: Experimental -- defining click detector in terms of decibels rather than the previous unintuitive values NEW: Ifdefs for DENOISE_TRY_ONE_SAMPLE. Generally a horrendously bad idea to denoise using a window width of 1. EXPERIMENTAL: Started playing around with code to restore harmonic content on very old recordings (aka harmonic exciters...) *Many* improvements from Michael Gruhn follow: --- BUGFIX: disallow closing while file is being processed (preventing segfault) BUGFIX: long filenames handled better BUGFIX: removed some buffer overruns in sprintfs and probably avoided some more BUGFIX: disallow closing while processing in batch mode (preventing segfault) BUGFIX: return EXIT_SUCCESS on success instead of 1 for better batch integration NEW: allow selection of hpf declick for batch processing NEW: end keyword to set stop_position to end of file for batch processing NEW: usage message explaining batch mode for batch processing 0.21-10 Mar 22, 2009 CODE: leave click marks option in declicking BUGFIX: biquad fixed -- BUGFIX: cdrdao output was unnecessarily constrained by blocksizes 0.21-09 Dec 19, 2008 CODE: undo needed to use off_t in lseek calls (Thanks Dave Hill, from Feb 2007) BUGFIX: alsa playback would at times crash, fixed 0.21-08 Feb 23, 2007 CODE: Add info for setting device in settings->miscellaneous Feb 21, 2007 BUGFIX: Big endian machines had playback problem, using patch from Paul Brossier fixes the problem Jan 12, 2007 BUGFIX: Paul Sanders found declick bug in get_hpf(), which is probably why some clicks were not getting repaired. CODE: Paul Sanders sent a speed improvement which makes declick run about 80 percent faster 0.21-07 Oct 20, 2006 BUGFIX: Ok. I messed up. The save changes stuff on exit was broken. Hopefully fixed now :-) 0.21-06 Feb 8, 2006 BUGFIX: In biquad.c the filter parameters could be incorrectly displayed with the defaults rather than as saved in preferences (Thanks Simon Lavender-Jones) BUGFIX: In declick.c, stderr variable changed to std_err to avoid conflicts with stderr file pointer. BUGFIX: In audio_util.c, make sure n_samples is > 1 when on audio file open. BUGFIX: Make install was not installing the help files in the proper place CODE: Manual declick shortcut changed from CTRL-A to ALT-A (to avoid conflict with select all) CODE: When exiting, or closing audio file, user can committed changes, undo changes or cancel. CODE: shortcut "a" now appends to cdrdao toc file only the selected region, not everything between all markers. NEW: Incorporated tap_reverb algorithm, uses internally stored settings if external ~/.reverbed is not found NEW: Added many functions to batch capability 0.21-05 Jan 20, 2006 CODE: zooming in on a selection of only 1 sample gives a 2 second zoom (thanks David Gesswein) BUGFIX: opening a new audio file would corrupt the previously opened audio file's *.gwc (thanks David Gesswein) BUGFIX: CDTEXT output for cdrdao improved (thanks David Gesswein) BUGFIX: The Lorber-Hoeldrich algorithms had a big bug, fixed. CODE: new expand selection to markers feature (thanks David Gesswein for the idea) CODE: using rectangular window on all pre-sampling. CODE: configure script suggests installation of libsnd-devel package. 0.21-04 Nov 10, 2005 BUGFIX: In function declick_with_sensitivity in gwc.c repair_clicks variable needed to be set before start_save_undo. (Thanks Simon Lavender-Jones) BUGFIX: In audio_alsa, the snd_pcm_delay call could return an underrun code (-EPIPE) which means the handle needs reset. BUGFIX: In denoise.c, the blackman windowing algorithm implementation was incorrect. CODE: In audio_alsa.c, make minimum size audio device buffer 4096, as a multiple of the reported frame size. CODE: Started experimenting with Wolfe & Godsill noise removal process. Not well understood yet... 0.21-03 July 15, 2005 DOC: Error in documentation for FFT Strong Declick Sensitivity fixed BUGFIX: Failure to open an audio file would create near infinite looping of warning messages BUGFIX: set_playback_cursor_position now uses audio_state == AUDIO_IS_PLAYBACK to determine if the audio is playing. 0.21-02 Feb 3, 2005 CODE: second attempt at merging in Rob's OSX stuff CODE: getting the meschach headers copied up (properly!) to the gwc source directory 0.21-01 Feb 2, 2005 CODE: First attempt at merging in Rob's OSX stuff 0.20-10b April 27, 2005 BUGFIX: Fixed left,right variable references in declick.c when using the old FFTW libs(lines 575 ...) 0.20-10a April 13, 2005 BUGFIX: Fixed p variable in declick.c when using the old FFTW libs(lines 470, 490) BUGFIX: Biquad.c needed a prototype 0.20-10 Feb 1, 2005 CODE: IIR high/low/band/notch filtering, with known public domain source code CODE: FFT click detection CODE: Can limit frequency range applied in denoising (experimental) 0.20-09 Dec 28, 2004 BUGFIX: Markers could be drawn at inappropriate places BUGFIX: Selection in areas with 2 markers w/in 10 pixels would jump to first marker. BUGFIX: Playing audio could freeze with change make in 0.20-08 BUGFIX: Makefile didn't recognize --prefix as passed to configure script. Thanks to Thiemo Gehrke CODE: Thiemo Ghehrke did nice cleanup on config.in and Makefile.in CODE: Can generate pink/white noise (useful if you don't have a good noise sample for denoising) CODE: Adding IIR lowpass filtering CODE: Adding left/right mixing functions to amplify CODE: Expanding the main window vertically now only expands the audio view, not the text at the bottom. -- thanks to joseph daly 0.20-08 Dec 14, 2004 BUGFIX: Increased stack limit to 6 megabytes, some denoising ops needed this or they would segfault BUGFIX: Undo skip,save,cancel dialog window was not destroyed properly BUGFIX: Declick would try to declick outside the current selection window CODE: Using an updated meschach library from http://www.math.uiowa.edu/~dstewart/meschach/ CODE: Attempting to stop playback without generating artificial "clicks" by gracefully closing audio device. CODE: Estimate large gap actually works now :-) CODE: Insert silence asks for confirmation 0.20-07 August 2, 2004 BUGFIX: Declicking errors via meschach singular matrices could generate too many errors, now fixed. (stat.c) BUGFIX: Warning message about fftw libs not found clarified to indicate fftw 3.x libs not found 0.20-06 August 2, 2004 BUGFIX: Fixed configure.in to work properly with gnome2 development libs (removed old GNOME_INIT stuff). CODE: Fixed warning messages in default typecast in markers.c 0.20-05 July 29, 2004 BUGFIX: Uhhhh, errrr, Really fixed configure error complaining about needing libsndfile 2.x 0.20-04 May 21, 2004 BUGFIX: Fixed configure error complaining about needing libsndfile 2.x April 1, 2004 BUGFIX: audio_alsa.c, audio_device_open did not open user defined device. 0.20-03 April 8, 2004 BUGFIX: Hanning-overlap-add method would alter channel not selected for denoising. April 1, 2004 BUGFIX: audio_alsa.c, audio_device_open did not open user defined device. 0.20-02 March 5, 2004 CODE:Frank Freudenberg supplied cut & paste code for audio CODE:Rob Fair adding option for selecting audio device CODE:Jeff Welty Gnome-2.x -ified GWC CODE:Lindsay Harris tracked down segfault issue with denoise 0.19-10 September 26, 2003 CODE:Frank Freudenberg supplied audio device abstraction, so we now have alsa and oss drivers CODE:Bill Jetzer supplied the means for setting up GWC in batch mode. 0.19-9 September 6, 2003 BUGFIX: windowed and out arrays needed inside fft_remove_noise regardless of HAVE_FFTW3 0.19-8 CODE: Thanks to Frank Freudenberg, we now can compile with FFTW 3.x libs CODE: Worked on the online help system, not complete but getting there. BUGFIX: Hopefully nailed the "declick until end of file" crash bug. 0.19-5 ----- August 21, 2003 CODE: Streamlined encoding_selection code in gwc.c CODE: Added progress meter in the encoding process 0.19-4 ----- Added interface (frontend) to lame/oggenc for MP3 and Ogg encodings of selected waveform portions. Fixed issue with warnings if closing pop up windows via X in corner. Fixed issues with performing tasks with no file opened causing segfault. Fixed issue of trying to play when sonogram is being built. Fixed issue of trying to display sonogram(or do anything) while file is being played. Added some fixes to improve speed of display/amplify and some other functions. (do not cast if not needed and when you must cast do it wisely. See http://www.mega-nerd.com/FPcast/ by Eric De Castro Lopo Author of libsndfile API). 0.19-3 ------ April 7, 2003 CODE: Lame libs incorporated, to save selection as MP3 (Thanks Charles!) BUGFIX: The Lorber-Hoeldrich and Ephram denoise algorithms had a small bug, fixed. 0.19-2 ------ Mar 1, 2003 CODE: Determined cause of some libsndfile config checks failing, added notice about /etc/ld.so.conf Feb 17, 2003 CODE: Fixed netbsd bug, and a configuration bug (now copying machine.h from meschach after meschach build). 0.19-1 ------ Feb 16, 2003 CODE: Faster audio redraws, added song markers (thanks to David Gesswein). Also started netbsd-izing 0.18 ------ November, 2002 CODE: Made the markers persistent, and can now have up to 200 markers 0.17-6 ------ October 29, 2002 BUGFIX: Detect only checkbox now doesn't toggle on/off when pressing spacebar after it has focus CODE: Improved click detection speed. 0.17-5 ------ September 29, 2002 BUGFIX: Check for FFT_SIZE < n_noise_samples. BUGFIX: Sonogram could crash in some cases. CODE: Pop a dialogue warning if failed reading audio data. NEW: 'a' key creates, or appends cdrdao.toc, with info about the audio between the 2 markers. Can be used with cdrdao. 0.17-4 ------ September 24, 2002 BUGFIX: fixed is_valid_audio function, sndfile point was not being set... 0.17-3 ------ September 21, 2002 NEW: Hanning Window with overlap-add implemented. Much, much faster... BUGFIX: Denoise window and suppression method are no longer mishandled by the preferences dialogue. BUGFIX: Audio files no longer need to end in .wav extension, must only be recognized by libsndfile 0.17-2 ------ September 15, 2002 BUGFIX: The Lorber - Hoeldrich denoise algorithm had a bug, fixed. Results will be greatly improved. CODE: Now integrated with libsndfile CODE: Left and right channels now display unique levels at all zoom levels (previously the average was displayed when the compressed audio image was used CODE: Amplify can now feather in the amplification amount, this prevents creating discontinuities in signal values at the start or end of the amplification region. 0.16-5 ------ September 7, 2002 BUGFIX: Changed AC_INIT in configure.in from "gwc" to "gwc.c", so configure script would work properly 0.16-4 ------ August 24, 2002 BUGFIX: Undo improperly assumed a region was highlighted, resulting in mysterious undo results. 0.16-3 ------ July 31, 2002 BUGFIX: Playback was hosed on some audio cards. This hopefully will fix it... CODE: Icons now appear on menus (though they need spacing...) 0.16-2 (not released) ------ DOC: How to clear markers CODE: Warn before saving selection over existing file DOC: Better description of manual click repair versus click detection and repair CODE: Declicking information now appears in status bar instead of popup CODE: Select between markers (with keypress 'm') -- still needs a button CODE: 's' key selection time is configurable with prefs->misc CODE: 'z' key zooms in on selection 0.16-1 (not released) ------ CODE: Added undo button to toolbar 0.15 ---- June 17, 2002 CODE: Fixed annoyance -- selection didn't select enough samples on the right side of selection CODE: Now using 2 toolbars, with no text GRAPHICS: Cool icons from Ian Leonard EXPERIMENTAL: Can declick in "batch" mode. 0.14 ---- May 14, 2002 CODE: Massive speedup of "Save selection as" 0.13 ---- April 27, 2002 CODE: Cleaned up all of the warning messages generated during the compile, almost all were unused variables... CODE: Improved buffering of audio during playback, finer resolution also achieved on playback. 0.12 ---- April 21, 2002 BUGFIX: Lorber denoise method was always used, regardless of parameter settings. This bug was introduced in 0.06-4 CODE: Denoise preferences moved to Settings menu, Dialogue box for denoise made more meaningful 0.11 ---- April 18, 2002 BUGFIX: Memory leak in the delicking algorithm, it was partly in the meschach package... NEW: The memory mapped mode of accessing audio files is deprecated, file size is no longer a limitation, swap space usage is way down... 0.10 ---- April 15, 2002 KNOWN PROBLEM: Still a memory leak somewhere in the delicking algorithm, it may be in the meschach package... NEW: Declick sensitivity setting available from Settings drop-down menu NEW: Iterate in declick -- will iterate in delick until no more repairs are made in a delick window CODE: Some dialog widget functions are now in dialog.c, 0.09 ---- April 13, 2002 BUGFIX: Memory leak in declicking algorithm, could eat up a few hundred megabytes declicking a 15 minute track BUGFIX: The idle function was consuming large amounts of CPU, this is completely reworked. BUGFIX: Markers were previously reset to -1, selecting near the start of song would snap to -1, now set to large negative 0.08 ---- April 10, 2002 BUGFIX: Save selection to same file as current file would core dump, this is now disallowed. BUGFIX: The Lorber-Hoeldrich noise reduction method had an error, fixed. No perceptible difference in sound output. NEW: Ephraim and Malah's noise suppression method (1984) was added. NEW: configure now works with fft libs for Suse-linux 0.07 ---- April 1, 2002 NEW: Created gwc.spec file for generation of binary rpm BUGFIX: Fixed bug in declick, unrepaired clicks now appear highlighted in red 0.06-2 ------ BUGFIX: Fixed buffering problem with audio on playback systems with heavy loads. 0.06-1 ------ NEW: Can now have the declicking algorithm only identify clicks, not repair them NEW: Hitting the "s" key, stops playback, and highlights the last 1/2 second of audio played NEW: GWC remembers the last directory where a wavfile was opened from. gtk-wave-cleaner-0.22-04/INSTALL0000777000175000017500000000354013122047722017244 0ustar00alisteralister00000000000000--- Installation is via the classic `./configure; make; make install`. Refer to the README for further information. This file documents specific installation problems which may be encountered. --- Problems with linking: You don't have libsndfile in a standard place, like /usr/lib, but /usr/local/lib -- make sure /usr/local/lib is in your /etc/ld.so.conf file, and reload the runtime loader (man ldconf) -- you will need to add /usr/local/lib/pkgconfig to your PKG_CONFIG_PATH environment variable, like so: export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig --- Problems with autotools versions: e.g. building on OSX "Snow Leopard" (10.6) I had problems like this: configure.in:3: require Automake 1.12, but have 1.10 I was using homebrew, so I had to install newer versions e.g. `brew install automake`, then do this to use these versions rather than the system ones: export PATH="/usr/local/opt/automake/bin:/usr/local/opt/autoconf/bin:$PATH" --- Problems with pkgconfig: e.g. building on OSX leopard I had problems like this: checking for gtk+-2.0... no configure: error: Package requirements (gtk+-2.0) were not met: Package 'libpng', required by 'cairo', not found Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To solve it I had to do this: export PKG_CONFIG_PATH=$(find /usr/local/Cellar -name 'pkgconfig' -type d | grep lib/pkgconfig | tr '\n' ':' | sed s/.$//) --- I think this is probably fixed, but it was previously reported that `make install` did not work due to datadir not being defined. This was fixed by configuring with `--datadir=$pkgdir/usr/share`. $pkgdir related to the distribution's packaging system. gtk-wave-cleaner-0.22-04/Makefile.am0000666000175000017500000002205413455327235020256 0ustar00alisteralister00000000000000# Alister: there are issues with the way this is all set up. # 1. It is too complicated - we aren't letting autotools do enough for us. # 2. Make does not recognise if header files have changed and rebuild the necessary objects. # 3. We haven't properly integrated meschach. Make here doesn't recognise if any of meschach's header or source files have changed, and autoconf or autoreconf here doesn't touch it. (also see note in meschach/configure - neither autoconf nor building in meschach actually works in our version). # 4. `make dist` needs to be told to include all of the header and source files, as we haven't specified them as gwc_SOURCES. # 5. `make clean` errors trying to clean the meschach directory if `make` has not been run :) # 6. `make install-strip` doesn't strip # etc # Note if we contemplate updating meschach or using an external meschach library we need to check what Jeff did to our version: # - Jeff said he fixed a bad memory leak (I *think* this is also fixed in the debian version). # - Jeff made a change to err.c, which I have commented # - Anything else? prefix = @prefix@ exec_prefix = @exec_prefix@ if DEBUG AM_CFLAGS = -g3 -O0 AM_CXXFLAGS = -g3 -O0 else AM_CFLAGS = -O2 AM_CXXFLAGS = -O2 endif # Alister: OSX potential issues # On an old test system I initially couldn't use -lgtkmacintegration as it wasn't building # properly, so I had to link to the object files. #OSX_OBJS = /Users/alister/gtk-mac-integration-2.0.8/src/.libs/*.o # Note depending on your build environment you might need something like -lgtkmacintegration.2 # This is now taken care of by configure.in #OSX_LIBS = -framework CoreAudio -lgtkmacintegration-gtk2 # Don't need coreaudio if using pulseaudio #OSX_LIBS = -lgtkmacintegration-gtk2 BINDIR = @bindir@ DATADIR = @datadir@ # is this one used for anything?: DATAROOTDIR = @datarootdir@ LIBDIR = @libdir@ SYSCONFDIR = @sysconfdir@ APPNAME = gtk-wave-cleaner DOCDIR = $(DATADIR)/doc # Alister: if you set HELPDIR different to DOCDIR, you will need to add it to the uninstall routine below HELPDIR = $(DOCDIR) # use this for SuSE and maybe other distros #DOCDIR = /usr/share/doc/packages/gtk-wave-cleaner #HELPDIR = $(DOCDIR) DEFS = -DDATADIR=\"$(DATADIR)\" -DHELPDIR=\"$(HELPDIR)\" -DLIBDIR=\"$(LIBDIR)\" -DAPPNAME=\"$(APPNAME)\" @OSXDEF@ @ALSADEF@ @PAHDR@ @FFTWHDR@ @FFTWPREC@ @OGGHDR@ @MP3HDR@ CFLAGS = -D_FILE_OFFSET_BITS=64 -Wall @CFLAGS@ @GTK_CFLAGS@ @SNDFILE_CFLAGS@ LIBS= meschach.a @GTK_LIBS@ @SNDFILE_LIBS@ @ALSALIB@ @PALIB@ @FFTWLIB@ @OGGLIB@ @MP3LIB@ @OSXLIBS@ -lm SRC = tap_reverb_file_io.c tap_reverb.c reverb.c dialog.c gwc.c audio_device.c audio_edit.c audio_util.c gtkled.c gtkledbar.c preferences.c drawing.c amplify.c denoise.c undo.c declick.c sample_block.c decrackle.c stat.c dethunk.c i0.c i1.c chbevl.c markers.c encode.c soundfile.c pinknoise.c biquad.c OBJS = $(SRC:.c=.o) # Alister: We should be able to avoid most of this - see item 3 and 4 in the comment at the top # Alister: leave out meschach/configure.in, as it makes a broken configure, and someone may try to use it! EXTRA_DIST = $(SRC) icons data osx_packaging Changelog doc ar.c audio_osx.c audio_pa.c audio_oss.c audio_alsa.c \ ar.h audio_device.h audio_edit.h biquad.h encoding.h fmtheaders.h gtkled.h gtkledbar.h gwc.h mconf.h mp3.h mp3-duration.h reverb_settings.h soundfile.h stat.h tap_reverb.h tap_reverb_common.h tap_reverb_file_io.h \ meschach/DOC meschach/MACHINES meschach/arnoldi.c meschach/bdfactor.c meschach/bkpfacto.c meschach/chfactor.c meschach/configure meschach/conjgrad.c meschach/copy.c meschach/copyright meschach/dmacheps.c meschach/err.c meschach/err.h \ meschach/extras.c meschach/fft.c meschach/FILELIST meschach/fmacheps.c meschach/givens.c meschach/hessen.c meschach/hsehldr.c meschach/init.c meschach/iotort.c meschach/iter.h meschach/iter0.c meschach/iternsym.c meschach/itersym.c meschach/itertort.c meschach/ivecop.c meschach/lanczos.c \ meschach/ls.dat meschach/lufactor.c meschach/machine.c meschach/machine.h.in meschach/makefile.in meschach/matlab.c meschach/matlab.h meschach/matop.c meschach/matrix.h meschach/matrix2.h meschach/matrixio.c meschach/maxint.c meschach/meminfo.c meschach/meminfo.h meschach/memory.c meschach/memstat.c \ meschach/memtort.c meschach/mfunc.c meschach/mfuntort.c meschach/norm.c meschach/oldnames.h meschach/otherio.c meschach/pxop.c meschach/qrfactor.c meschach/README meschach/rk4.dat meschach/schur.c meschach/solve.c meschach/sparse.c meschach/sparse.h meschach/sparse2.h meschach/sparseio.c \ meschach/spbkp.c meschach/spchfctr.c meschach/splufctr.c meschach/sprow.c meschach/spswap.c meschach/sptort.c meschach/submat.c meschach/svd.c meschach/symmeig.c meschach/tags meschach/torture.c meschach/tutadv.c meschach/tutorial.c meschach/update.c meschach/vecop.c meschach/version.c \ meschach/zcopy.c meschach/zfunc.c meschach/zgivens.c meschach/zhessen.c meschach/zhsehldr.c meschach/zlufctr.c meschach/zmachine.c meschach/zmatio.c meschach/zmatlab.c meschach/zmatop.c meschach/zmatrix.h meschach/zmatrix2.h meschach/zmemory.c meschach/znorm.c meschach/zqrfctr.c meschach/zschur.c \ meschach/zsolve.c meschach/ztorture.c meschach/zvecop.c BINFILES = $(APPNAME) # Alister: normally this should automatically cause `make [un]install` to install/uninstall it, but in our case we are doing it manually below dist_bin_SCRIPTS = gwcbatch # Confusingly we don't have the DOCFILES in the doc directory, only the HELPFILES DOCFILES = README INSTALL TODO COPYING Changelog HELPFILES = $(APPNAME).html gtkrc-example.txt HELPFILESSRCD = doc DATADIRS = \ icons/hicolor/16x16/apps \ icons/hicolor/22x22/apps \ icons/hicolor/24x24/apps \ icons/hicolor/32x32/apps \ icons/hicolor/64x64/apps \ icons/hicolor/128x128/apps \ icons/hicolor/256x256/apps \ icons/hicolor/scalable/apps\ applications ### CC = @CC@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) #Alister: I don't think we ever needed OSX_CFLAGS #COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(OSX_CFLAGS) ### handy to have around for checking buffer overruns #EFENCE = -lefence EFENCE = all : gwc gwc : meschach.a $(OBJS) $(CC) $(OBJS) $(EFENCE) $(LDFLAGS) $(LIBS) -o $(APPNAME) # Alister: If you have trouble building on a Mac # set OSX_OBJS and OSX_LIBS above and use this: #$(CC) $(OSX_LIBS) $(OBJS) $(OSX_OBJS) $(EFENCE) $(LDFLAGS) $(LIBS) -o $(APPNAME) audio_device.o : audio_device.c audio_alsa.c audio_oss.c audio_osx.c audio_pa.c Makefile $(COMPILE) -c audio_device.c audio_util.o : audio_util.c Makefile $(COMPILE) -c audio_util.c .c.o : $(COMPILE) -c $< # Alister: note that we can mostly install to the OSX appdir using something like this: # make DESTDIR=/tmp/gwc/osx_packaging/Gtk\ Wave\ Cleaner.app/Contents/Resources install # but the binary won't be in the ...Contents/MacOS directory # so do this: # mv /osx_packaging/Gtk\ Wave\ Cleaner.app/Contents/Resources/bin/gtk-wave-cleaner /osx_packaging/Gtk\ Wave\ Cleaner.app/Contents/MacOS/gtk-wave-cleaner.bin # The .desktop and icon files aren't used, anyway, but at least it installs the docs! # How do we get it to load the logo in the about dialog from either the icon files or the .icns? install : gwc install -d "$(DESTDIR)"$(BINDIR) install -d "$(DESTDIR)"$(DOCDIR)/$(APPNAME) install -d "$(DESTDIR)"$(HELPDIR)/$(APPNAME) install -p $(BINFILES) $(dist_bin_SCRIPTS) "$(DESTDIR)"$(BINDIR) install -p -m 0644 $(DOCFILES) "$(DESTDIR)"$(DOCDIR)/$(APPNAME) for hf in $(HELPFILES) ; do install -p -m 0644 $(HELPFILESSRCD)/$$hf "$(DESTDIR)"$(HELPDIR)/$(APPNAME) ; done for hf in $(DATADIRS) ; do install -d "$(DESTDIR)"$(DATADIR)/$$hf && install -p -m 0644 data/$$hf/$(APPNAME).* "$(DESTDIR)"$(DATADIR)/$$hf ; done # if we are using DESTDIR this is pointless, so should we skip it?: gtk-update-icon-cache -f -t "$(DESTDIR)"$(DATADIR)/icons/hicolor uninstall : ( cd "$(DESTDIR)"$(BINDIR) && rm -f $(BINFILES) $(dist_bin_SCRIPTS) ) ( cd "$(DESTDIR)"$(DOCDIR)/$(APPNAME) && rm -f $(DOCFILES) ) ( cd "$(DESTDIR)"$(HELPDIR)/$(APPNAME) && rm -f $(HELPFILES) ) # Alister: note osx errors on --ignore-fail-on-non-empty # But we wouldn't normally run `make uninstall` on osx # If we need to we can install gnu coreutils and use its rmdir ( rmdir --ignore-fail-on-non-empty "$(DESTDIR)"$(DOCDIR)/$(APPNAME) $(DOCDIR) ) ( for hf in $(DATADIRS) ; do rm "$(DESTDIR)"$(DATADIR)/$$hf/$(APPNAME).* && rmdir -p --ignore-fail-on-non-empty "$(DESTDIR)"$(DATADIR)/$$hf; done ) # Alister: why does this test not work? # ( if [$(DOCDIR) != $(HELPDIR)]; then rmdir --ignore-fail-on-non-empty "$(DESTDIR)"$(HELPDIR)/$(APPNAME) "$(DESTDIR)"$(HELPDIR); fi) # should we be running this on uninstall?: # gtk-update-icon-cache -f -t "$(DESTDIR)"$(DATADIR)/icons/hicolor meschach.a : meschach/meschach.a cp meschach/meschach.a . meschach/meschach.a : # Alister: a very old message on the mailing list seemed to imply that --with-sparse is necessary to build successfully, # but this doesn't actually seem to be the case now (cd meschach ; ./configure --with-sparse ; make part1 ; make part2 ; make part3 ; cp machine.h ..) clean : rm -f $(APPNAME) *.o core meschach.a meschach/meschach.a machine.h (cd meschach ; make realclean) gtk-wave-cleaner-0.22-04/Makefile.in0000644000175000017500000007174213455327346020276 0ustar00alisteralister00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Alister: there are issues with the way this is all set up. # 1. It is too complicated - we aren't letting autotools do enough for us. # 2. Make does not recognise if header files have changed and rebuild the necessary objects. # 3. We haven't properly integrated meschach. Make here doesn't recognise if any of meschach's header or source files have changed, and autoconf or autoreconf here doesn't touch it. (also see note in meschach/configure - neither autoconf nor building in meschach actually works in our version). # 4. `make dist` needs to be told to include all of the header and source files, as we haven't specified them as gwc_SOURCES. # 5. `make clean` errors trying to clean the meschach directory if `make` has not been run :) # 6. `make install-strip` doesn't strip # etc # Note if we contemplate updating meschach or using an external meschach library we need to check what Jeff did to our version: # - Jeff said he fixed a bad memory leak (I *think* this is also fixed in the debian version). # - Jeff made a change to err.c, which I have commented # - Anything else? VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(dist_bin_SCRIPTS) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__installdirs = "$(DESTDIR)$(bindir)" SCRIPTS = $(dist_bin_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in COPYING INSTALL README TODO \ compile install-sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ ALSACFLAGS = @ALSACFLAGS@ ALSADEF = @ALSADEF@ ALSALIB = @ALSALIB@ ALSA_CFLAGS = @ALSA_CFLAGS@ ALSA_LIBS = @ALSA_LIBS@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ ### CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = -D_FILE_OFFSET_BITS=64 -Wall @CFLAGS@ @GTK_CFLAGS@ @SNDFILE_CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ # use this for SuSE and maybe other distros #DOCDIR = /usr/share/doc/packages/gtk-wave-cleaner #HELPDIR = $(DOCDIR) DEFS = -DDATADIR=\"$(DATADIR)\" -DHELPDIR=\"$(HELPDIR)\" -DLIBDIR=\"$(LIBDIR)\" -DAPPNAME=\"$(APPNAME)\" @OSXDEF@ @ALSADEF@ @PAHDR@ @FFTWHDR@ @FFTWPREC@ @OGGHDR@ @MP3HDR@ DEPDIR = @DEPDIR@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FFTWHDR = @FFTWHDR@ FFTWLIB = @FFTWLIB@ FFTWPREC = @FFTWPREC@ GREP = @GREP@ GTK_CFLAGS = @GTK_CFLAGS@ GTK_LIBS = @GTK_LIBS@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = meschach.a @GTK_LIBS@ @SNDFILE_LIBS@ @ALSALIB@ @PALIB@ @FFTWLIB@ @OGGLIB@ @MP3LIB@ @OSXLIBS@ -lm LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MP3HDR = @MP3HDR@ MP3LIB = @MP3LIB@ OBJEXT = @OBJEXT@ OGGHDR = @OGGHDR@ OGGLIB = @OGGLIB@ OSXDEF = @OSXDEF@ OSXLIBS = @OSXLIBS@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PAHDR = @PAHDR@ PALIB = @PALIB@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ PULSEAUDIO_CFLAGS = @PULSEAUDIO_CFLAGS@ PULSEAUDIO_LIBS = @PULSEAUDIO_LIBS@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SNDFILE_CFLAGS = @SNDFILE_CFLAGS@ SNDFILE_LIBS = @SNDFILE_LIBS@ STRIP = @STRIP@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @DEBUG_FALSE@AM_CFLAGS = -O2 @DEBUG_TRUE@AM_CFLAGS = -g3 -O0 @DEBUG_FALSE@AM_CXXFLAGS = -O2 @DEBUG_TRUE@AM_CXXFLAGS = -g3 -O0 # Alister: OSX potential issues # On an old test system I initially couldn't use -lgtkmacintegration as it wasn't building # properly, so I had to link to the object files. #OSX_OBJS = /Users/alister/gtk-mac-integration-2.0.8/src/.libs/*.o # Note depending on your build environment you might need something like -lgtkmacintegration.2 # This is now taken care of by configure.in #OSX_LIBS = -framework CoreAudio -lgtkmacintegration-gtk2 # Don't need coreaudio if using pulseaudio #OSX_LIBS = -lgtkmacintegration-gtk2 BINDIR = @bindir@ DATADIR = @datadir@ # is this one used for anything?: DATAROOTDIR = @datarootdir@ LIBDIR = @libdir@ SYSCONFDIR = @sysconfdir@ APPNAME = gtk-wave-cleaner DOCDIR = $(DATADIR)/doc # Alister: if you set HELPDIR different to DOCDIR, you will need to add it to the uninstall routine below HELPDIR = $(DOCDIR) SRC = tap_reverb_file_io.c tap_reverb.c reverb.c dialog.c gwc.c audio_device.c audio_edit.c audio_util.c gtkled.c gtkledbar.c preferences.c drawing.c amplify.c denoise.c undo.c declick.c sample_block.c decrackle.c stat.c dethunk.c i0.c i1.c chbevl.c markers.c encode.c soundfile.c pinknoise.c biquad.c OBJS = $(SRC:.c=.o) # Alister: We should be able to avoid most of this - see item 3 and 4 in the comment at the top # Alister: leave out meschach/configure.in, as it makes a broken configure, and someone may try to use it! EXTRA_DIST = $(SRC) icons data osx_packaging Changelog doc ar.c audio_osx.c audio_pa.c audio_oss.c audio_alsa.c \ ar.h audio_device.h audio_edit.h biquad.h encoding.h fmtheaders.h gtkled.h gtkledbar.h gwc.h mconf.h mp3.h mp3-duration.h reverb_settings.h soundfile.h stat.h tap_reverb.h tap_reverb_common.h tap_reverb_file_io.h \ meschach/DOC meschach/MACHINES meschach/arnoldi.c meschach/bdfactor.c meschach/bkpfacto.c meschach/chfactor.c meschach/configure meschach/conjgrad.c meschach/copy.c meschach/copyright meschach/dmacheps.c meschach/err.c meschach/err.h \ meschach/extras.c meschach/fft.c meschach/FILELIST meschach/fmacheps.c meschach/givens.c meschach/hessen.c meschach/hsehldr.c meschach/init.c meschach/iotort.c meschach/iter.h meschach/iter0.c meschach/iternsym.c meschach/itersym.c meschach/itertort.c meschach/ivecop.c meschach/lanczos.c \ meschach/ls.dat meschach/lufactor.c meschach/machine.c meschach/machine.h.in meschach/makefile.in meschach/matlab.c meschach/matlab.h meschach/matop.c meschach/matrix.h meschach/matrix2.h meschach/matrixio.c meschach/maxint.c meschach/meminfo.c meschach/meminfo.h meschach/memory.c meschach/memstat.c \ meschach/memtort.c meschach/mfunc.c meschach/mfuntort.c meschach/norm.c meschach/oldnames.h meschach/otherio.c meschach/pxop.c meschach/qrfactor.c meschach/README meschach/rk4.dat meschach/schur.c meschach/solve.c meschach/sparse.c meschach/sparse.h meschach/sparse2.h meschach/sparseio.c \ meschach/spbkp.c meschach/spchfctr.c meschach/splufctr.c meschach/sprow.c meschach/spswap.c meschach/sptort.c meschach/submat.c meschach/svd.c meschach/symmeig.c meschach/tags meschach/torture.c meschach/tutadv.c meschach/tutorial.c meschach/update.c meschach/vecop.c meschach/version.c \ meschach/zcopy.c meschach/zfunc.c meschach/zgivens.c meschach/zhessen.c meschach/zhsehldr.c meschach/zlufctr.c meschach/zmachine.c meschach/zmatio.c meschach/zmatlab.c meschach/zmatop.c meschach/zmatrix.h meschach/zmatrix2.h meschach/zmemory.c meschach/znorm.c meschach/zqrfctr.c meschach/zschur.c \ meschach/zsolve.c meschach/ztorture.c meschach/zvecop.c BINFILES = $(APPNAME) # Alister: normally this should automatically cause `make [un]install` to install/uninstall it, but in our case we are doing it manually below dist_bin_SCRIPTS = gwcbatch # Confusingly we don't have the DOCFILES in the doc directory, only the HELPFILES DOCFILES = README INSTALL TODO COPYING Changelog HELPFILES = $(APPNAME).html gtkrc-example.txt HELPFILESSRCD = doc DATADIRS = \ icons/hicolor/16x16/apps \ icons/hicolor/22x22/apps \ icons/hicolor/24x24/apps \ icons/hicolor/32x32/apps \ icons/hicolor/64x64/apps \ icons/hicolor/128x128/apps \ icons/hicolor/256x256/apps \ icons/hicolor/scalable/apps\ applications COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) #Alister: I don't think we ever needed OSX_CFLAGS #COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(OSX_CFLAGS) ### handy to have around for checking buffer overruns #EFENCE = -lefence EFENCE = all: all-am .SUFFIXES: .SUFFIXES: .c .o am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): install-dist_binSCRIPTS: $(dist_bin_SCRIPTS) @$(NORMAL_INSTALL) @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-dist_binSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) tags TAGS: ctags CTAGS: cscope cscopelist: distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-am all-am: Makefile $(SCRIPTS) installdirs: for dir in "$(DESTDIR)$(bindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install-exec: install-exec-am install-data: install-data-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-dist_binSCRIPTS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-dist_binSCRIPTS .MAKE: install-am install-strip .PHONY: all all-am am--refresh check check-am clean clean-generic \ cscopelist-am ctags-am dist dist-all dist-bzip2 dist-gzip \ dist-lzip dist-shar dist-tarZ dist-xz dist-zip distcheck \ distclean distclean-generic distcleancheck distdir \ distuninstallcheck dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am \ install-dist_binSCRIPTS install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags-am uninstall uninstall-am \ uninstall-dist_binSCRIPTS .PRECIOUS: Makefile all : gwc gwc : meschach.a $(OBJS) $(CC) $(OBJS) $(EFENCE) $(LDFLAGS) $(LIBS) -o $(APPNAME) # Alister: If you have trouble building on a Mac # set OSX_OBJS and OSX_LIBS above and use this: #$(CC) $(OSX_LIBS) $(OBJS) $(OSX_OBJS) $(EFENCE) $(LDFLAGS) $(LIBS) -o $(APPNAME) audio_device.o : audio_device.c audio_alsa.c audio_oss.c audio_osx.c audio_pa.c Makefile $(COMPILE) -c audio_device.c audio_util.o : audio_util.c Makefile $(COMPILE) -c audio_util.c .c.o : $(COMPILE) -c $< # Alister: note that we can mostly install to the OSX appdir using something like this: # make DESTDIR=/tmp/gwc/osx_packaging/Gtk\ Wave\ Cleaner.app/Contents/Resources install # but the binary won't be in the ...Contents/MacOS directory # so do this: # mv /osx_packaging/Gtk\ Wave\ Cleaner.app/Contents/Resources/bin/gtk-wave-cleaner /osx_packaging/Gtk\ Wave\ Cleaner.app/Contents/MacOS/gtk-wave-cleaner.bin # The .desktop and icon files aren't used, anyway, but at least it installs the docs! # How do we get it to load the logo in the about dialog from either the icon files or the .icns? install : gwc install -d "$(DESTDIR)"$(BINDIR) install -d "$(DESTDIR)"$(DOCDIR)/$(APPNAME) install -d "$(DESTDIR)"$(HELPDIR)/$(APPNAME) install -p $(BINFILES) $(dist_bin_SCRIPTS) "$(DESTDIR)"$(BINDIR) install -p -m 0644 $(DOCFILES) "$(DESTDIR)"$(DOCDIR)/$(APPNAME) for hf in $(HELPFILES) ; do install -p -m 0644 $(HELPFILESSRCD)/$$hf "$(DESTDIR)"$(HELPDIR)/$(APPNAME) ; done for hf in $(DATADIRS) ; do install -d "$(DESTDIR)"$(DATADIR)/$$hf && install -p -m 0644 data/$$hf/$(APPNAME).* "$(DESTDIR)"$(DATADIR)/$$hf ; done # if we are using DESTDIR this is pointless, so should we skip it?: gtk-update-icon-cache -f -t "$(DESTDIR)"$(DATADIR)/icons/hicolor uninstall : ( cd "$(DESTDIR)"$(BINDIR) && rm -f $(BINFILES) $(dist_bin_SCRIPTS) ) ( cd "$(DESTDIR)"$(DOCDIR)/$(APPNAME) && rm -f $(DOCFILES) ) ( cd "$(DESTDIR)"$(HELPDIR)/$(APPNAME) && rm -f $(HELPFILES) ) # Alister: note osx errors on --ignore-fail-on-non-empty # But we wouldn't normally run `make uninstall` on osx # If we need to we can install gnu coreutils and use its rmdir ( rmdir --ignore-fail-on-non-empty "$(DESTDIR)"$(DOCDIR)/$(APPNAME) $(DOCDIR) ) ( for hf in $(DATADIRS) ; do rm "$(DESTDIR)"$(DATADIR)/$$hf/$(APPNAME).* && rmdir -p --ignore-fail-on-non-empty "$(DESTDIR)"$(DATADIR)/$$hf; done ) # Alister: why does this test not work? # ( if [$(DOCDIR) != $(HELPDIR)]; then rmdir --ignore-fail-on-non-empty "$(DESTDIR)"$(HELPDIR)/$(APPNAME) "$(DESTDIR)"$(HELPDIR); fi) # should we be running this on uninstall?: # gtk-update-icon-cache -f -t "$(DESTDIR)"$(DATADIR)/icons/hicolor meschach.a : meschach/meschach.a cp meschach/meschach.a . meschach/meschach.a : # Alister: a very old message on the mailing list seemed to imply that --with-sparse is necessary to build successfully, # but this doesn't actually seem to be the case now (cd meschach ; ./configure --with-sparse ; make part1 ; make part2 ; make part3 ; cp machine.h ..) clean : rm -f $(APPNAME) *.o core meschach.a meschach/meschach.a machine.h (cd meschach ; make realclean) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: gtk-wave-cleaner-0.22-04/README0000666000175000017500000000671313455322257017105 0ustar00alisteralister00000000000000GWC 0.22 -------------- This is the README for Gtk Wave Cleaner, a gui application to remove noise (hiss, pops and clicks) from audio files in WAV and similar formats. Requirements ------------ - a *nix based operating system i.e. linux, bsd, osx etc. GWC can be run on Windows either in a Linux virtual machine or in "windows subsystem for linux" on 64bit Windows 10 using pulseaudio and X11 servers for windows. - gtk2 (www.gtk.org); included in common Linux distributions. - libsndfile (www.mega-nerd.com/libsndfile/); there are packages available for common Linux distributions. - either the OSS, ALSA or Pulse Audio sound drivers, or Mac OSX. - fftw libs (www.fftw.org); there are packages available for common Linux distributions. - [optional] perl to use gwcbatch helper script. Not required for normal gui use. - [optional] perldoc to view gwcbatch usage instructions (or just open it in a text editor). - [optional] xdg-open from xdg-utils (https://www.freedesktop.org/wiki/Software/xdg-utils/) to open the manual file from the help menu. Not required on OSX. - [optional] vorbis-tools and lame for ogg and mp3 export. License ------------ The source code and all associated files are freely available under the GNU General Public License (GPL) agreement. Installation ------------ If you are using a release source tarball, extract it (tar -xvzf <...>). Enter the directory created. Run "./configure". Run "make". Run "make install". "gtk-wave-cleaner" is the program file. All you have to do is run it, or click on the menu entry. In case you are building the source from git you will first need to run "autoreconf -i" Additional options ------------------ Run "./configure --help" for additional compile options. By default the GWC binary is installed in /usr/local/bin/ and document files are installed in /usr/local/share/doc/gtk-wave-cleaner. Override this with "./configure --prefix=/usr" or similar. If you have playback problems try disabling alsa (--disable-alsa) to use oss. In an alsa environment you can use it with aoss if necessary. Distributions may want to enable pulseaudio (--enable-pa). Note that mp3 and ogg reading support are currently still broken, so ignore those options. If you have problems installing check whether they are documented in the INSTALL file. Instructions for use: --------------------- Check out the help documentation included in this distribution and available from the help menu in GWC. Known Issues: ------------- GWC fails to open wav files with metadata, such as those created by recent versions of ffmpeg. GWC will produce an error like this: "Failed to open /root/whistle.wav, 'Error : Cannot open file in read/write mode due to string data in header.'". Libsndfile does not support RDWR mode for these files. If you are creating them using ffmpeg try adding "-flags bitexact" into your command line (although this will reduce ffmpeg's performance), or writing to a different libsndfile supported format such as .au or .aiff. A workaround for existing files is to open and save the file in mhwaveedit, but since you should keep your original recording as a backup anyway, I suggest either converting to a different format using sndfile-convert or ffmpeg, or using `SimplifyWave` from waveutils or `shntool strip` to make a copy of the file with a clean header. Background: ----------- For links and a brief presentation describing the technical aspects of the audio restoration methods used in GWC visit http://gwc.sourceforge.net/ jeff@redhawk.org gtk-wave-cleaner-0.22-04/TODO0000777000175000017500000000237213120075107016701 0ustar00alisteralister00000000000000 The Gnome Wave Cleaner Project BUG/TODO List (In order of importance) 7/13/2002 - Jeff Welty, Redhawk Technologies KNOWN BUGS: ----------- ANNOYANCES: ----------- Document declick settings. Not clear what effect the settings have. Eg Strong Declick sensitivity. What's effect does an increase have? What's the upper limit? Help does not really explain that GWC commits all changes to the original file instantly, and undo saves the deltas needed to get back, so on exit all your changes are saved. (Perhaps all that is really required is a "Save changes" on exit, and then if the answer is no execute all the undos). "Save Selection As" does not save the current view, it requires a selection... FEATURE SUGGESTIONS (in order of implementation) : -------------------------------------------------- Method to play from a arbitrary point - i.e. play from current marker FEATURES THAT WOULD BE HARDER TO IMPLEMENT( but still good ideas :-) -------------------------------------------------------------------- Scroll when selecting Remember the last 3 files edited, and show them in the file drop-down menu for easier opening Put de-click iterator on main screen? LADSPA-ize the filters. (Not possible) Save as mp3, ogg (run though 'lame'?) (Done) gtk-wave-cleaner-0.22-04/aclocal.m40000666000175000017500000014624713455314764020100 0ustar00alisteralister00000000000000# generated automatically by aclocal 1.15 -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- dnl serial 11 (pkg-config-0.29.1) dnl dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, but dnl WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU dnl General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA dnl 02111-1307, USA. dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a dnl configuration script generated by Autoconf, you may include it under dnl the same distribution terms that you use for the rest of that dnl program. dnl PKG_PREREQ(MIN-VERSION) dnl ----------------------- dnl Since: 0.29 dnl dnl Verify that the version of the pkg-config macros are at least dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's dnl installed version of pkg-config, this checks the developer's version dnl of pkg.m4 when generating configure. dnl dnl To ensure that this macro is defined, also add: dnl m4_ifndef([PKG_PREREQ], dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], [m4_define([PKG_MACROS_VERSION], [0.29.1]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) dnl ---------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to dnl first found in the path. Checks that the version of pkg-config found dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])dnl PKG_PROG_PKG_CONFIG dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------------------------------- dnl Since: 0.18 dnl dnl Check to see whether a particular set of modules exists. Similar to dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) dnl only at the first occurence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) dnl --------------------------------------------- dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting dnl pkg_failed based on the result. m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])dnl _PKG_CONFIG dnl _PKG_SHORT_ERRORS_SUPPORTED dnl --------------------------- dnl Internal check to see if pkg-config supports short errors. AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])dnl _PKG_SHORT_ERRORS_SUPPORTED dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl -------------------------------------------------------------- dnl Since: 0.4.0 dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES might not happen, you should be sure to include an dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])dnl PKG_CHECK_MODULES dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], dnl [ACTION-IF-NOT-FOUND]) dnl --------------------------------------------------------------------- dnl Since: 0.29 dnl dnl Checks for existence of MODULES and gathers its build flags with dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags dnl and VARIABLE-PREFIX_LIBS from --libs. dnl dnl Note that if there is a possibility the first call to dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to dnl include an explicit call to PKG_PROG_PKG_CONFIG in your dnl configure.ac. AC_DEFUN([PKG_CHECK_MODULES_STATIC], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl _save_PKG_CONFIG=$PKG_CONFIG PKG_CONFIG="$PKG_CONFIG --static" PKG_CHECK_MODULES($@) PKG_CONFIG=$_save_PKG_CONFIG[]dnl ])dnl PKG_CHECK_MODULES_STATIC dnl PKG_INSTALLDIR([DIRECTORY]) dnl ------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable pkgconfigdir as the location where a module dnl should install pkg-config .pc files. By default the directory is dnl $libdir/pkgconfig, but the default can be changed by passing dnl DIRECTORY. The user can override through the --with-pkgconfigdir dnl parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_INSTALLDIR dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) dnl -------------------------------- dnl Since: 0.27 dnl dnl Substitutes the variable noarch_pkgconfigdir as the location where a dnl module should install arch-independent pkg-config .pc files. By dnl default the directory is $datadir/pkgconfig, but the default can be dnl changed by passing DIRECTORY. The user can override through the dnl --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ])dnl PKG_NOARCH_INSTALLDIR dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) dnl ------------------------------------------- dnl Since: 0.28 dnl dnl Retrieves the value of the pkg-config variable for the given module. AC_DEFUN([PKG_CHECK_VAR], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl _PKG_CONFIG([$1], [variable="][$3]["], [$2]) AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])dnl PKG_CHECK_VAR # Copyright (C) 2002-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.15' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.15], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.15])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2014 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR gtk-wave-cleaner-0.22-04/amplify.c0000666000175000017500000002366113450764342020033 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* amplify.c */ #include #include "gwc.h" #define BUFSIZE 10000 static gfloat amount_first[2] = {1.0,1.0} ; static gfloat amount_last[2] = {1.0,1.0} ; static gfloat amount_first_l[2] = {1.0,0.0} ; static gfloat amount_last_l[2] = {1.0,0.0} ; static gfloat amount_first_r[2] = {0.0,1.0} ; static gfloat amount_last_r[2] = {0.0,1.0} ; static int feather_width = 20 ; void simple_amplify_audio(struct sound_prefs *p, long first, long last, int channel_mask, double amount) { long left[BUFSIZE], right[BUFSIZE] ; long current, i ; int loops = 0 ; current = first ; push_status_text("Amplifying audio") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; { while(current <= last) { long n = MIN(last - current + 1, BUFSIZE) ; long tmplast = current + n - 1 ; gfloat p = (gfloat)(current-first)/(last-first+1) ; n = read_wavefile_data(left, right, current, tmplast) ; update_progress_bar(p,PROGRESS_UPDATE_INTERVAL,FALSE) ; for(i = 0 ; i < n ; i++) { if(channel_mask & 0x01) { left[i] = lrint(amount*left[i]) ; } if(channel_mask & 0x02) { right[i] = lrint(amount*right[i]) ; } } write_wavefile_data(left, right, current, tmplast) ; current += n ; if(last - current < 10) loops++ ; if(loops > 5) { warning("infinite loop in amplify_audio, programming error\n") ; } } resample_audio_data(p, first, last) ; save_sample_block_data(p) ; } update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; main_redraw(FALSE, TRUE) ; } void amplify_audio(struct sound_prefs *p, long first, long last, int channel_mask) { long left[BUFSIZE], right[BUFSIZE] ; long current, i ; int loops = 0 ; current = first ; push_status_text("Amplifying audio") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; { while(current <= last) { long n = MIN(last - current + 1, BUFSIZE) ; long tmplast = current + n - 1 ; gfloat p = (gfloat)(current-first)/(last-first+1) ; n = read_wavefile_data(left, right, current, tmplast) ; update_progress_bar(p,PROGRESS_UPDATE_INTERVAL,FALSE) ; for(i = 0 ; i < n ; i++) { long icurrent = current + i ; double p_last = (double)(icurrent-first+1)/(double)(last-first+1) ; double p_first = 1.0 - p_last ; double feather_p = 1.0 ; double wet_left, wet_right ; if(icurrent - first < feather_width) feather_p = (double)(icurrent-first)/(double)(feather_width) ; if(last - icurrent < feather_width) feather_p = (double)(last - icurrent)/(double)(feather_width) ; if(channel_mask & 0x01) { wet_left = ((double)left[i]*(amount_first_l[0]*p_first+amount_last_l[0]*p_last)) ; wet_left += ((double)right[i]*(amount_first_r[0]*p_first+amount_last_r[0]*p_last)) ; } if(channel_mask & 0x02) { wet_right = ((double)left[i]*(amount_first_l[1]*p_first+amount_last_l[1]*p_last)) ; wet_right += ((double)right[i]*(amount_first_r[1]*p_first+amount_last_r[1]*p_last)) ; } if(channel_mask & 0x01) { left[i] = lrint((double)left[i]*(1.0-feather_p) + wet_left*feather_p) ; } if(channel_mask & 0x02) { right[i] = lrint((double)right[i]*(1.0-feather_p) + wet_right*feather_p) ; } } write_wavefile_data(left, right, current, tmplast) ; current += n ; if(last - current < 10) loops++ ; if(loops > 5) { warning("infinite loop in amplify_audio, programming error\n") ; } } resample_audio_data(p, first, last) ; save_sample_block_data(p) ; } update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; main_redraw(FALSE, TRUE) ; } int amplify_dialog(struct sound_prefs current, struct view *v) { GtkWidget *dlg, *maxtext, *dialog_table, *leftframe, *rightframe, *l_tbl, *r_tbl ; GtkWidget *amount_first_entry_l[2] ; GtkWidget *amount_last_entry_l[2] ; GtkWidget *amount_first_entry_r[2] ; GtkWidget *amount_last_entry_r[2] ; GtkWidget *feather_width_entry ; int dclose = 0 ; int row = 0 ; int dres ; char buf[200] ; /* Alister: everything using gtkcurve has been commented out since gwc-0.20-09 and it appears prior to that */ /* the implementation was never actually completed i.e. the widget worked, but it didn't do anything except */ /* print values to stdout. */ /* GtkWidget *curve ; */ /* gfloat curve_data[20] ; */ dialog_table = gtk_table_new(3,1,0) ; l_tbl = gtk_table_new(5,2,0) ; r_tbl = gtk_table_new(5,2,0) ; gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 12) ; gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6) ; gtk_widget_show (dialog_table); gtk_table_set_row_spacings(GTK_TABLE(l_tbl), 4) ; gtk_table_set_col_spacings(GTK_TABLE(l_tbl), 6) ; gtk_container_set_border_width(GTK_CONTAINER(l_tbl), 5) ; gtk_widget_show (l_tbl); gtk_table_set_row_spacings(GTK_TABLE(r_tbl), 4) ; gtk_table_set_col_spacings(GTK_TABLE(r_tbl), 6) ; gtk_container_set_border_width(GTK_CONTAINER(r_tbl), 5) ; gtk_widget_show (r_tbl); dlg = gtk_dialog_new_with_buttons("Amplify", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); sprintf(buf, "Maximum amplification without clipping is %6.2f.\n", (double)1.0/(double)current.max_value) ; maxtext = gtk_label_new (buf); gtk_widget_show (maxtext); gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), maxtext, TRUE, TRUE, 0); /* curve = gtk_curve_new (); */ /* gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), curve, TRUE, TRUE, row++); */ /* gtk_widget_show (curve); */ /* //gtk_curve_set_curve_type(GTK_CURVE(curve),GTK_CURVE_TYPE_LINEAR) ; */ /* gtk_curve_set_range(GTK_CURVE(curve),0.0,100.0,0.0,100.0) ; */ /* gtk_curve_reset(GTK_CURVE(curve)) ; */ /* //gtk_curve_set_vector(GTK_CURVE(curve),2,curve_data) ; */ leftframe = gtk_frame_new ("Left channel source"); gtk_container_add(GTK_CONTAINER(leftframe), l_tbl) ; gtk_widget_show (leftframe); gtk_table_attach_defaults(GTK_TABLE(dialog_table), leftframe, 0, 2, row, row+1) ; row++ ; amount_first_entry_l[0] = add_number_entry_with_label_double(amount_first_l[0], "Left Channel beginning:", l_tbl, 0) ; amount_last_entry_l[0] = add_number_entry_with_label_double(amount_last_l[0], "Left Channel end:", l_tbl, 1) ; amount_first_entry_r[0] = add_number_entry_with_label_double(amount_first_r[0], "Right Channel beginning:", l_tbl, 2) ; amount_last_entry_r[0] = add_number_entry_with_label_double(amount_last_r[0], "Right Channel end:", l_tbl, 3) ; rightframe = gtk_frame_new ("Right channel source"); gtk_container_add(GTK_CONTAINER(rightframe), r_tbl) ; gtk_widget_show (rightframe); gtk_table_attach_defaults(GTK_TABLE(dialog_table), rightframe, 0, 2, row, row+1) ; row++ ; amount_first_entry_l[1] = add_number_entry_with_label_double(amount_first_l[1], "Left Channel beginning:", r_tbl, 0) ; amount_last_entry_l[1] = add_number_entry_with_label_double(amount_last_l[1], "Left Channel end:", r_tbl, 1) ; amount_first_entry_r[1] = add_number_entry_with_label_double(amount_first_r[1], "Right Channel beginning:", r_tbl, 2) ; amount_last_entry_r[1] = add_number_entry_with_label_double(amount_last_r[1], "Right Channel end:", r_tbl, 3) ; feather_width_entry = add_number_entry_with_label_int(feather_width, "Feather width", dialog_table, row++) ; gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)) ; if(dres == 0) { int i ; for(i = 0 ; i < 2 ; i++) { amount_first_l[i] = atof(gtk_entry_get_text((GtkEntry *)amount_first_entry_l[i])) ; amount_last_l[i] = atof(gtk_entry_get_text((GtkEntry *)amount_last_entry_l[i])) ; amount_first_r[i] = atof(gtk_entry_get_text((GtkEntry *)amount_first_entry_r[i])) ; amount_last_r[i] = atof(gtk_entry_get_text((GtkEntry *)amount_last_entry_r[i])) ; } feather_width = atoi(gtk_entry_get_text((GtkEntry *)feather_width_entry)) ; dclose = 1 ; } /* { */ /* int i ; */ /* */ /* gtk_curve_get_vector(GTK_CURVE(curve), 10, curve_data) ; */ /* */ /* for(i = 0 ; i < 10 ; i++) { */ /* printf("%lg %lg\n", curve_data[i*2], curve_data[i*2+1]) ; */ /* } */ /* */ /* } */ gtk_widget_destroy(dlg) ; if(dres == 0) return 1 ; return 0 ; } void batch_normalize(struct sound_prefs *p, long first, long last, int channel_mask) { amount_first_l[0] = (double)1.0/(double)p->max_value; amount_last_l[0] = amount_first_l[0] ; amount_first_r[1] = amount_first_l[0] ; amount_last_r[1] = amount_first_l[0] ; feather_width = 2000; //fprintf(stderr, "Maximum amplification without clipping is %f \n", amount_first_l[0]) ; amplify_audio(p,first,last,channel_mask); } gtk-wave-cleaner-0.22-04/ar.c0000777000175000017500000001467413120075106016766 0ustar00alisteralister00000000000000/* This code was graciously provided by Paul Bourke */ /* File - ar.h */ int AutoRegression( double *inputseries, int length, int degree, double *coefficients, int method) { double mean; int i, t; double *w=NULL; /* Input series - mean */ double *h=NULL; double *g=NULL; /* Used by mempar() */ double *per=NULL; double *pef=NULL; /* Used by mempar() */ double **ar=NULL; /* AR coefficients, all degrees */ int success = TRUE; /* Allocate space for working variables */ if ((w = (double *)malloc(length*sizeof(double))) == NULL) { success = FALSE; goto skip; } if ((h = (double *)malloc((degree+1)*sizeof(double))) == NULL) { success = FALSE; goto skip; } if ((g = (double *)malloc((degree+2)*sizeof(double))) == NULL) { success = FALSE; goto skip; } if ((per = (double *)malloc((length+1)*sizeof(double))) == NULL) { success = FALSE; goto skip; } if ((pef = (double *)malloc((length+1)*sizeof(double))) == NULL) { success = FALSE; goto skip; } if ((ar = (double **)malloc((degree+1)*sizeof(double*))) == NULL) { success = FALSE; goto skip; } for (i=0;i max) { max = h; maxi = j; } } if (maxi != i) { mswap = mat[i]; mat[i] = mat[maxi]; mat[maxi] = mswap; vswap = vec[i]; vec[i] = vec[maxi]; vec[maxi] = vswap; } hvec = mat[i]; pivot = hvec[i]; if (fabs(pivot) == 0.0) { /* fprintf(stderr,"Singular matrix! Exiting!\n"); */ return(FALSE); } for (j=i+1;j=0;i--) { hvec = mat[i]; for (j=n-1;j>i;j--) vec[i] -= (hvec[j] * vec[j]); vec[i] /= hvec[i]; } return(TRUE); } gtk-wave-cleaner-0.22-04/ar.h0000777000175000017500000000054713120075106016765 0ustar00alisteralister00000000000000/* This code was graciously provided by Paul Bourke */ /* File - ar.h */ #define MAXENTROPY 0 #define LEASTSQUARES 1 int AutoRegression(double *,int,int,double *,int); int ARMaxEntropy(double *,int,int,double **, double *,double *,double *,double * ); int ARLeastSquare(double *,int,int,double *); int SolveLE(double **,double *,unsigned int); gtk-wave-cleaner-0.22-04/audio_alsa.c0000777000175000017500000002316313120075106020456 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2003 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* alsa interface impl. ...frank 12.09.03 */ #include #include #include #include #ifdef ALSA_IN_SYS #include #else #include #endif #include "audio_device.h" #include "gwc.h" static snd_pcm_t *handle = NULL; static snd_pcm_uframes_t written_frames = 0; static long drain_delta = 0 ; static long last_processed_bytes0 = -1 ; static long last_processed_bytes = -1 ; snd_pcm_uframes_t buffer_total_frames; /* number of frames in alsa device buffer */ static void snd_perr(char *text, int err) { fprintf(stderr, "##########################################################\n"); fprintf(stderr, "%s\n", text); fprintf(stderr, "%s\n", snd_strerror(err)); warning(text) ; } int audio_device_open(char *output_device) { int err = snd_pcm_open(&handle, output_device, /*"default",*/ SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); if (err < 0) { snd_perr("ALSA audio_device_open: snd_pcm_open", err); return -1; } written_frames = 0; drain_delta=0 ; last_processed_bytes0 = -1 ; last_processed_bytes = -1 ; return 0; } int audio_device_set_params(AUDIO_FORMAT *format, int *channels, int *rate) { unsigned int utmp ; int err; snd_pcm_format_t alsa_format; snd_pcm_hw_params_t *params; snd_pcm_sw_params_t *swparams; snd_pcm_hw_params_alloca(¶ms); snd_pcm_sw_params_alloca(&swparams); err = snd_pcm_hw_params_any(handle, params); if (err < 0) { snd_perr("ALSA audio_device_set_params: snd_pcm_hw_params_any", err); return -1; } err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { snd_perr("ALSA audio_device_set_params: snd_pcm_hw_params_set_access", err); return -1; } switch (*format) { case GWC_U8: alsa_format = SND_PCM_FORMAT_U8; break; case GWC_S8: alsa_format = SND_PCM_FORMAT_S8; break; case GWC_S16_BE: alsa_format = SND_PCM_FORMAT_S16_BE; break; default: case GWC_S16_LE: alsa_format = SND_PCM_FORMAT_S16_LE; break; } if (snd_pcm_hw_params_set_format(handle, params, alsa_format) < 0) { snd_perr("ALSA audio_device_set_params: snd_pcm_hw_params_set_format", err); return -1; } if (snd_pcm_hw_params_get_format(params, &alsa_format) < 0) { snd_perr("ALSA audio_device_set_params: snd_pcm_hw_params_get_format", err); return -1; } switch (alsa_format) { case SND_PCM_FORMAT_U8: *format = GWC_U8; break; case SND_PCM_FORMAT_S8 : *format = GWC_S8; break; case SND_PCM_FORMAT_S16_BE: *format = GWC_S16_BE; break; case SND_PCM_FORMAT_S16_LE: *format = GWC_S16_LE; break; default: *format = GWC_UNKNOWN; break; } err = snd_pcm_hw_params_set_channels(handle, params, *channels); if (err < 0) { snd_perr("ALSA audio_device_set_params: snd_pcm_hw_params_set_channels", err); return -1; } utmp = (unsigned int)*channels ; if (snd_pcm_hw_params_get_channels(params, &utmp) < 0) { snd_perr("ALSA audio_device_set_params: snd_pcm_hw_params_get_channels", err); return -1; } *channels = (int)utmp ; utmp = (unsigned int)*rate ; err = snd_pcm_hw_params_set_rate_near(handle, params, &utmp, 0); if (err < 0) { snd_perr("ALSA audio_device_set_params: snd_pcm_hw_params_set_rate_near", err); return -1; } *rate = (int)utmp ; err = snd_pcm_hw_params(handle, params); if (err < 0) { snd_perr("ALSA audio_device_set_params: snd_pcm_hw_params", err); return -1; } err = snd_pcm_prepare(handle); if (err < 0) { snd_perr("ALSA audio_device_set_params: snd_pcm_prepare", err); return -1; } fprintf(stderr, "audio_device_handle %d\n",(int)handle); return 0; } int audio_device_read(unsigned char *buffer, int buffersize) { /* not implemented */ return -1; } /* recover underrun and suspend */ static int recover_snd_handle(int err) { if (err == -EPIPE) { /* underrun */ fprintf(stderr, "recover_snd_handle: err == -EPIPE\n"); err = snd_pcm_prepare(handle); if (err < 0) snd_perr("ALSA recover_snd_handle: can't recover underrun, prepare failed", err); return 0; } else if (err == -ESTRPIPE) { /* suspend */ fprintf(stderr, "recover_snd_handle: err == -ESTRPIPE\n"); while ((err = snd_pcm_resume(handle)) == -EAGAIN) sleep(1); if (err < 0) { err = snd_pcm_prepare(handle); if (err < 0) snd_perr("ALSA recover_snd_handle: can't recover suspend, prepare failed", err); } return 0; } return err; } int audio_device_write(unsigned char *data, int count) { snd_pcm_sframes_t err; snd_pcm_uframes_t result_frames = 0; snd_pcm_uframes_t count_frames = snd_pcm_bytes_to_frames(handle, count); while (count_frames > 0) { err = snd_pcm_writei(handle, data, count_frames); if (err > 0) { result_frames += err; count_frames -= err; data += snd_pcm_frames_to_bytes(handle, err); } else if (err == -EAGAIN) { snd_pcm_wait(handle, 1000); } else if (err < 0) { if(err == -EINVAL) { fprintf(stderr, "snd_pcm_writei invalid argument: %d %d %d\n",(int)handle,(int)data,(int)count_frames); exit(1) ; } else if (recover_snd_handle(err) < 0) { fprintf(stderr, "audio_device_write %d %d %d\n",(int)handle,(int)data,(int)count_frames); snd_perr("ALSA audio_device_write: snd_pcm_writei", err); exit(1) ; return -1; } } } written_frames += result_frames; return snd_pcm_frames_to_bytes(handle, result_frames); } /* Number of bytes processed since opening the device. */ long query_processed_bytes(void) { if(handle != NULL) { snd_pcm_sframes_t avail_frames_in_buf = snd_pcm_avail_update(handle); return snd_pcm_frames_to_bytes(handle, (written_frames - (buffer_total_frames - avail_frames_in_buf))); } return 0 ; } long _audio_device_processed_bytes = 0 ; /* Number of bytes processed since opening the device. */ long audio_device_processed_bytes(void) { if(handle != NULL) _audio_device_processed_bytes = query_processed_bytes() ; return _audio_device_processed_bytes ; } void audio_device_close(int drain) { if (handle != NULL) { int err; printf("Closing the ALSA audio device\n") ; _audio_device_processed_bytes = query_processed_bytes() ; if(drain) err = snd_pcm_drain(handle); err = snd_pcm_drop(handle); if (err < 0) { snd_perr("ALSA audio_device_close: snd_pcm_drop", err); } err = snd_pcm_close(handle); if (err < 0) { snd_perr("ALSA audio_device_close: snd_pcm_close", err); } handle = NULL; } drain_delta=0 ; } int audio_device_best_buffer_size(int playback_bytes_per_block) { int err; snd_pcm_status_t *status; int frame_size ; snd_pcm_status_alloca(&status); err = snd_pcm_status(handle, status); if (err < 0) { snd_perr("ALSA audio_device_best_buffer_size: snd_pcm_status", err); return 0; } buffer_total_frames = snd_pcm_status_get_avail(status); frame_size = snd_pcm_frames_to_bytes(handle, buffer_total_frames); /* fprintf(stderr, "ALSA audio_device_best_buffer_size:%d (frames:%ld)\n", frame_size, buffer_total_frames) ; */ if(frame_size < 4096 && frame_size > 0) { int s = frame_size ; while(frame_size < 4096) frame_size += s ; printf("ALSA audio_device_adjusted_buffer_size:%d\n", frame_size) ; } if(frame_size == 0) { warning("Your ALSA audio device driver gives invalid information for its buffer size, defaulting to 4K bytes, this may produce strange playback results") ; frame_size = 4096 ; } return frame_size ; } int audio_device_nonblocking_write_buffer_size(int maxbufsize, int playback_bytes_remaining) { int len = 0; snd_pcm_sframes_t frames = snd_pcm_avail_update(handle); if (frames < 0) { snd_perr("audio_device_nonblocking_write_buffer_size: snd_pcm_avail_update", frames); if (recover_snd_handle(frames) < 0) { fprintf(stderr, "audio_device_nonblocking_write_buffer_size: could not recover handle\n"); return -1 ; } } len = snd_pcm_frames_to_bytes(handle, frames); if (len > maxbufsize) len = maxbufsize; if (len > playback_bytes_remaining) len = playback_bytes_remaining; /* printf("audio_device_nonblocking_write_buffer_size:%d\n", len); */ return len; } gtk-wave-cleaner-0.22-04/audio_device.c0000666000175000017500000000234413453574021021001 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2003 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* gwc audio device interface impl. ...frank 12.09.03 */ #ifdef HAVE_ALSA # include "audio_alsa.c" #else # ifdef HAVE_PULSE_AUDIO # include "audio_pa.c" # else # ifdef MAC_OS_X /* MacOSX */ # include "audio_osx.c" # else # include "audio_oss.c" # endif # endif #endif gtk-wave-cleaner-0.22-04/audio_device.h0000777000175000017500000000352713120075106021004 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2003 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* gwc audio device interface ...frank 12.09.03 */ #ifndef AUDIO_DEVICE_H #define AUDIO_DEVICE_H #define AUDIO_IS_IDLE 0x00 #define AUDIO_IS_MONITOR 0x01 #define AUDIO_IS_RECORDING 0x02 #define AUDIO_IS_PLAYBACK 0x04 typedef enum { GWC_U8, GWC_S8, GWC_S16_BE, GWC_S16_LE, GWC_UNKNOWN } AUDIO_FORMAT; #define MAXBUFSIZE 32768 int audio_device_open(char *output_device); int audio_device_set_params(AUDIO_FORMAT *format, int *channels, int *rate); int audio_device_read(unsigned char *buffer, int buffersize); int audio_device_write(unsigned char *buffer, int buffersize); void audio_device_close(int); long audio_device_processed_bytes(void); int audio_device_best_buffer_size(int playback_bytes_per_block); int audio_device_nonblocking_write_buffer_size(int maxbufsize, int playback_bytes_remaining); #endif /* AUDIO_DEVICE_H */ gtk-wave-cleaner-0.22-04/audio_edit.c0000777000175000017500000001501213120075106020455 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2003 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* audio_edit.c some functions to cut, copy, paste, ...frank 4.10.03 */ #include #include "audio_edit.h" #include "gwc.h" #include "soundfile.h" #ifndef TRUNCATE_OLD extern struct sound_prefs prefs; static void adjust_view(struct view *v) { prefs.n_samples = soundfile_count_samples(); v->n_samples = prefs.n_samples; if (v->last_sample > v->n_samples - 1) { v->first_sample = v->n_samples - 1 - (v->last_sample - v->first_sample); v->last_sample = v->n_samples - 1; } if (v->first_sample < 0) v->first_sample = 0; set_scroll_bar(prefs.n_samples - 1, v->first_sample, v->last_sample); } static void begin_operation(char *status_text) { push_status_text(status_text); update_progress_bar(0.0, PROGRESS_UPDATE_INTERVAL, TRUE) ; } static void end_operation(void) { pop_status_text(); update_progress_bar(0.0, PROGRESS_UPDATE_INTERVAL, TRUE); } static void resample(long first, long last) { begin_operation("Resampling audio data"); resample_audio_data(&prefs, first, last); end_operation(); save_sample_block_data(&prefs); display_times(); } long audioedit_count_samples_in_clipdata(void) { return soundfile_count_samples_in_file(CLIPBOARD_FILE); } int audioedit_has_clipdata(void) { return soundfile_count_samples_in_file(CLIPBOARD_FILE) > 0; } int audioedit_cut_selection(struct view *v) { int rc = audioedit_copy_selection(v); if (rc == 0) { rc = audioedit_delete_selection(v); } return rc; } int audioedit_copy_selection(struct view *v) { int rc; long first, last; get_region_of_interest(&first, &last, v); begin_operation("Saving internal clipboard"); rc = soundfile_save_file(CLIPBOARD_FILE, first, last - first + 1, 1); end_operation(); return rc; } int audioedit_paste_selection(struct view *v) { int rc = -1; long sample_count; sample_count = audioedit_count_samples_in_clipdata(); if (sample_count > 0) { long first, last; char undo_label[200]; get_region_of_interest(&first, &last, v); sprintf(undo_label, "Paste audio data from %ld to %ld.", first, last); if (start_save_undo(undo_label, v) < 0) return -1; save_undo_data_insert(first, last, 1); close_undo(); begin_operation("Inserting space for clipboard data") ; rc = soundfile_shift_samples_right(first, sample_count, 1); end_operation(); if (rc == 0) { begin_operation("Inserting clipboard data"); rc = soundfile_load_file(CLIPBOARD_FILE, first, sample_count, 1); end_operation(); adjust_view(v); v->selection_region = FALSE; resample(first, prefs.n_samples-1); } } return rc; } int audioedit_delete_selection(struct view *v) { int rc = -1; long first, last; char undo_label[200]; get_region_of_interest(&first, &last, v); sprintf(undo_label, "Delete audio data from %ld to %ld.", first, last); if (start_save_undo(undo_label, v) < 0) return -1; rc = save_undo_data_remove(first, last, 1); close_undo(); if (rc == 1) /* canceled */ return -1; begin_operation("Deleting audio data") ; rc = soundfile_remove_samples(first, last - first + 1, 1); end_operation(); if (rc == 0) { adjust_view(v); v->selection_region = FALSE; resample(first, prefs.n_samples-1); } return rc; } int audioedit_insert_silence(struct view *v) { long first, last; get_region_of_interest(&first, &last, v); if (v->selection_region) { char undo_label[200]; sprintf(undo_label, "Insert silence from %ld to %ld.", first, last); if (start_save_undo(undo_label, v) < 0) return -1; save_undo_data_insert(first, last, 1); close_undo(); begin_operation("Inserting silence") ; soundfile_insert_silence(first, last - first + 1, 1); end_operation(); adjust_view(v); resample(first, prefs.n_samples-1); return 0; } return -1; } void truncate_wavfile(struct view *v, int save_undo) { int rc; long first, last; long end_pos = soundfile_count_samples(); char undo_label[200]; get_region_of_interest(&first, &last, v); if (save_undo) { /* split undo-data to undo separately in case of failure */ sprintf(undo_label, "Delete audio data from %ld to %ld.", last+1, end_pos); if (start_save_undo(undo_label, v) < 0) return; rc = save_undo_data_remove(last+1, end_pos, 1); close_undo(); if (rc == 1) /* canceled */ return; } begin_operation("Deleting audio data") ; rc = soundfile_remove_samples(last+1, end_pos, 1); end_operation(); if (rc != 0) { /* failure; FIX: needs cleanup of undo and more */ return; } if (save_undo) { /* second part of undo */ sprintf(undo_label, "Delete audio data from 0 to %ld.", first-1); if (start_save_undo(undo_label, v) < 0) return; rc = save_undo_data_remove(0, first-1, 1); close_undo(); /* cancel ignored */ } begin_operation("Deleting audio data") ; rc = soundfile_remove_samples(0, first-1, 1); end_operation(); if (rc != 0) { /* failure; FIX: needs cleanup of undo and more */ return; } adjust_view(v); v->first_sample = 0; v->last_sample = v->n_samples - 1; v->selection_region = FALSE; resample(0, prefs.n_samples-1); } #endif /* !TRUNCATE_OLD */ gtk-wave-cleaner-0.22-04/audio_edit.h0000777000175000017500000000276113120075106020471 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2003 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* audio_edit.h some functions to cut, copy, paste, ...frank 4.10.03 */ #ifndef AUDIO_EDIT_H #define AUDIO_EDIT_H struct view; int audioedit_has_clipdata(void); int audioedit_cut_selection(struct view *v); int audioedit_copy_selection(struct view *v); int audioedit_paste_selection(struct view *v); int audioedit_delete_selection(struct view *v); int audioedit_insert_silence(struct view *v); #ifdef TRUNCATE_OLD void truncate_wavfile(struct view *v); #else void truncate_wavfile(struct view *v, int save_undo); #endif #endif /* AUDIO_EDIT_H */ gtk-wave-cleaner-0.22-04/audio_oss.c0000777000175000017500000001011613120075106020334 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2003 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* oss interface impl. ...frank 12.09.03 */ #include #include #include #include #if defined(__OpenBSD__) || defined(__NetBSD__) #include #else #include #endif #include "audio_device.h" static int audio_fd = -1 ; int audio_device_open(char *output_device) { if( (audio_fd = open(output_device, O_WRONLY)) == -1) { return -1; } return 0; } int audio_device_set_params(AUDIO_FORMAT *format, int *channels, int *rate) { int oss_format; switch (*format) { case GWC_U8: oss_format = AFMT_U8; break; case GWC_S8: oss_format = AFMT_S8; break; case GWC_S16_BE: oss_format = AFMT_S16_BE; break; default: case GWC_S16_LE: oss_format = AFMT_S16_LE; break; } if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &oss_format) == -1) { return -1; } switch (oss_format) { case AFMT_U8: *format = GWC_U8; break; case AFMT_S8: *format = GWC_S8; break; case AFMT_S16_BE: *format = GWC_S16_BE; break; case AFMT_S16_LE: *format = GWC_S16_LE; break; default: *format = GWC_UNKNOWN; break; } if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, channels) == -1) { return -1; } if (ioctl(audio_fd, SNDCTL_DSP_SPEED, rate) == -1) { return -1; } return 0; } int audio_device_read(unsigned char *buffer, int buffersize) { int len = read(audio_fd, buffer, buffersize); if (len == -1) return -1; return len; } int audio_device_write(unsigned char *buffer, int buffersize) { int len = write(audio_fd, buffer, buffersize); if (len == -1) return -1; return len; } void audio_device_close(int drain) { if(audio_fd != -1) { ioctl(audio_fd, SNDCTL_DSP_RESET, NULL) ; close(audio_fd) ; audio_fd = -1 ; } } /* Number of bytes processed since opening the device. */ long audio_device_processed_bytes(void) { count_info info; if (audio_fd != -1) { ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &info); return info.bytes; } return 0; } int audio_device_best_buffer_size(int playback_bytes_per_block) { int bufsize; audio_buf_info oss_info; ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &oss_info); for (bufsize = oss_info.fragsize; bufsize < oss_info.fragsize*oss_info.fragstotal/2; bufsize += oss_info.fragsize) { if (bufsize >= playback_bytes_per_block) break; } return bufsize; } int audio_device_nonblocking_write_buffer_size(int maxbufsize, int playback_bytes_remaining) { audio_buf_info info; int len = 0; ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info); /* g_print("fragsize:%d\n", info.fragsize) ; */ /* g_print("fragstotal:%d\n", info.fragstotal) ; */ /* g_print("bytes:%ld\n", info.bytes) ; */ len = info.fragsize*info.fragments; while(len > maxbufsize) len -= info.fragsize; if (len > playback_bytes_remaining) { len = playback_bytes_remaining; } /* g_print("len:%d\n", len) ; */ if(len > info.bytes) { /* g_print("No free audio buffers\n") ; */ return 0 ; } return len; } gtk-wave-cleaner-0.22-04/audio_osx.c0000666000175000017500000002523713450764342020365 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.20. * Copyright (C) 2003 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. */ /* * audio_osx.h * gwc_mac * * Created by Rob Frohne on 11/8/04. * Copyright 2004 * */ #ifdef MAC_OS_X /* MacOSX */ #include #include #include #include #include #include #include #include #include #include "gwc.h" #include "audio_device.h" extern int wavefile_fd ; extern int stereo; typedef struct { AudioStreamBasicDescription format ; UInt32 buf_size ; AudioDeviceID device ; SNDFILE *sndfile ; SF_INFO sfinfo ; int done_playing ; bool done_reading ; } MacOSXAudioData ; MacOSXAudioData audio_data ; extern SNDFILE *sndfile; extern SF_INFO sfinfo; extern int audio_state; extern long playback_end_position ; extern long playback_position ; extern long playback_start_position; extern long playback_samples_remaining; extern long playback_total_bytes ; extern int FRAMESIZE; int BUFFERSIZE = 1024; // The size of the buffers we will send. long buff_num; // An index to allow us to create the array to run the VU meters. long num_buffers; // The number of buffers we will send. long buff_num_play; // The index of the buffer we are playing. gfloat* pL_global; gfloat* pR_global; bool p_global_mem_alloced = FALSE; //Tells if we have reserved memory for the two above arrays. Float64 start_sample_time; struct timeval playback_start_time; bool playback_just_started = FALSE; static OSStatus macosx_audio_out_callback (AudioDeviceID device, const AudioTimeStamp* current_time, const AudioBufferList* data_in, const AudioTimeStamp* time_in, AudioBufferList* data_out, const AudioTimeStamp* time_out, void* client_data) { MacOSXAudioData *audio_data ; int size, sample_count, read_count, i ; float maxl = 0, maxr = 0; float *p_float; if (playback_just_started) { playback_just_started = FALSE; start_sample_time = time_out->mSampleTime; } audio_data = (MacOSXAudioData*) client_data ; size = data_out->mBuffers[0].mDataByteSize ; sample_count = size / sizeof (float) ; // The number of bytes to send. p_float = (float*) data_out->mBuffers [0].mData ; // Makes buffer point to the data. if((!(audio_data->done_reading))&&(buff_num < num_buffers)) { read_count = sf_read_float (audio_data->sndfile, p_float, sample_count) ; if(read_count < sample_count) { memset (&(p_float [read_count]), 0, (sample_count - read_count) * sizeof (float)) ; //set the rest of the buffer to 0. audio_data->done_reading = SF_TRUE; } for(i = 0; i < read_count; i++) //Find the level for the VU meters { float vl, vr; vl = p_float[i]; vr = p_float[i+1]; if(vl > maxl) maxl = vl ; if(-vl > maxl) maxl = -vl ; if(stereo) { i++ ; if(vr > maxr) maxr = vr ; if(-vr > maxr) maxr = -vr ; } else { maxr = maxl ; } } pL_global[buff_num] = (gfloat) maxl; pR_global[buff_num] = (gfloat) maxr; buff_num++; return noErr ; } return noErr; } int process_audio(gfloat *pL, gfloat *pR) //This function must be called repeatedly from the gint play_a_block until the section is played. { //The pointers pL and pR passed in above return the levels for the VU meters. if(audio_state == AUDIO_IS_IDLE) { d_print("process_audio says AUDIO_IS_IDLE is going on.\n") ; return 1 ; } else if(audio_state == AUDIO_IS_PLAYBACK) { *pL = pL_global[buff_num_play]; *pR = pR_global[buff_num_play]; buff_num_play++; return 0 ; } return 1 ; } int audio_device_open(char *output_device) { OSStatus err ; UInt32 count ; audio_data.device = kAudioDeviceUnknown ; /* get the default output device for the HAL */ count = sizeof (AudioDeviceID) ; if ((err = AudioHardwareGetProperty (kAudioHardwarePropertyDefaultOutputDevice, &count, (void *) &(audio_data.device))) != noErr) { printf ("AudioHardwareGetProperty failed.\n") ; return -1 ; // return of -1 means it didn't open } return 0; //All went well. } int audio_device_set_params(AUDIO_FORMAT *format, int *channels, int *rate) //And start the audio playing. (This is different from linux.) { //stereo is 1 if it is stereo //playback_bits is the number of bits per sample //rate is the number of samples per second OSStatus err ; UInt32 count; audio_data.sfinfo = sfinfo; audio_data.sndfile = sndfile; /* get a description of the data format used by the default device */ count = sizeof (AudioStreamBasicDescription) ; if ((err = AudioDeviceGetProperty (audio_data.device, 0, false, kAudioDevicePropertyStreamFormat, &count, &(audio_data.format))) != noErr) { printf ("AudioDeviceGetProperty (kAudioDevicePropertyStreamFormat) failed.\n") ; return -1 ; } rate = (int *) &(audio_data.format.mSampleRate); channels = (int *) &(audio_data.format.mChannelsPerFrame); //Don't mess with the format. OS X uses floats which don't match GWC_S16_LE which is what is called for. /* Base setup completed. Now play. */ if (audio_data.sfinfo.channels < 1 || audio_data.sfinfo.channels > 2) { printf ("Error : channels = %d.\n", audio_data.sfinfo.channels) ; return -1; } audio_data.format.mSampleRate = audio_data.sfinfo.samplerate ; audio_data.format.mChannelsPerFrame = audio_data.sfinfo.channels ; rate = (int *) &(audio_data.format.mSampleRate); channels = (int *) &(audio_data.format.mChannelsPerFrame); if ((err = AudioDeviceSetProperty (audio_data.device, NULL, 0, false, kAudioDevicePropertyStreamFormat, sizeof (AudioStreamBasicDescription), &(audio_data.format))) != noErr) { printf ("AudioDeviceSetProperty (kAudioDevicePropertyStreamFormat) failed.\n") ; return -1; } ; /* we want linear pcm */ if (audio_data.format.mFormatID != kAudioFormatLinearPCM) { printf ("Data is not PCM.\n") ; return -1; } /*We want to set the buffer size so that we can get one point per buffer size to run the VU meters. */ buff_num = 0; buff_num_play = 0; num_buffers = (playback_end_position - playback_start_position)/BUFFERSIZE; if (!p_global_mem_alloced) { p_global_mem_alloced = TRUE; pL_global = (gfloat*) malloc(num_buffers*sizeof(gfloat)); // When do I need to free this? pR_global = (gfloat*) malloc(num_buffers*sizeof(gfloat)); } UInt32 bufferSize = BUFFERSIZE; if((err = AudioDeviceSetProperty( audio_data.device, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, sizeof(UInt32), &bufferSize)) != noErr) { printf("AudioDeviceAddIOProc failed to set buffer size. \n"); } /* Fire off the device. */ if ((err = AudioDeviceAddIOProc (audio_data.device, macosx_audio_out_callback, (void *) &audio_data)) != noErr) { printf ("AudioDeviceAddIOProc failed.\n") ; return -1; } err = AudioDeviceStart (audio_data.device, macosx_audio_out_callback) ; if (err != noErr) return -1; playback_just_started = TRUE; audio_data.done_playing = SF_FALSE ; audio_data.done_reading = FALSE; return 0; //All went well. } int audio_device_read(unsigned char *buffer, int buffersize){return 0;} // Leave this stub function because we don't want to read data. int audio_device_write(unsigned char *buffer, int buffersize){return 0;} // Not quite what the title says in OS X. long audio_device_processed_bytes(void) { AudioTimeStamp this_time; OSStatus err; UInt32 num_processes; UInt32 count; extern int audio_playback ; count = sizeof(UInt32); if ((err = AudioDeviceGetProperty (audio_data.device, 0, false, kAudioDevicePropertyDeviceIsRunning, &count, &num_processes)) != noErr) { printf ("AudioDeviceGetProperty (AudioDeviceGetProperty) failed. The device probably isn't running.\n") ; return -1; } else { if((err = AudioDeviceGetCurrentTime(audio_data.device, &this_time)) != noErr) { printf("Could not get the current time. The error number is: %i \n", err); } else { playback_position = (long) (this_time.mSampleTime - start_sample_time);//*FRAMESIZE; //led_bar_light_percent(dial[0], l); //led_bar_light_percent(dial[1], r); } } if (playback_position >= playback_end_position) //We are done playing. { /* Tell the main application to terminate. */ audio_data.done_playing = SF_TRUE ; audio_playback = FALSE; } return playback_position*FRAMESIZE ; } // This is used to set the cursor. We need to make this return a number controlled by a timer. int audio_device_best_buffer_size(int playback_bytes_per_block) //The result of this doesn't make any difference. { OSStatus err ; UInt32 count, buffer_size ; /* get the buffersize that the default device uses for IO */ count = sizeof (UInt32) ; if ((err = AudioDeviceGetProperty (audio_data.device, 0, false, kAudioDevicePropertyBufferSize, &count, &buffer_size)) != noErr) { printf ("AudioDeviceGetProperty (AudioDeviceGetProperty) failed.\n") ; return -1; } ; return (int) buffer_size; } int audio_device_nonblocking_write_buffer_size(int maxbufsize, //Normally returns the number of bytes the send buffer is ready for. int playback_bytes_remaining) { return 1; // This allows the process_audio to move the VU meters. } void audio_device_close(int drain) //Reminder: check to make sure this works when no device has been opened. { OSStatus err ; if(p_global_mem_alloced) { free(pL_global); free(pR_global); p_global_mem_alloced = FALSE; } if ((err = AudioDeviceStop (audio_data.device, macosx_audio_out_callback)) != noErr) { //printf ("AudioDeviceStop failed.\n") ; //Need to comment out this line in deployment build. return ; } ; err = AudioDeviceRemoveIOProc (audio_data.device, macosx_audio_out_callback) ; if (err != noErr) { printf ("AudioDeviceRemoveIOProc failed.\n") ;//Need to comment out this line in deployment build. return ; } ; } #endif /* MacOSX */ gtk-wave-cleaner-0.22-04/audio_pa.c0000666000175000017500000001262713450764342020153 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2003 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* pulse audio interface jw Nov 14, 2010 */ #include #include #include #include #include #include #include #include "audio_device.h" #include "gwc.h" /* The Sample format to use */ static pa_sample_spec ss = { .format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 2 }; static pa_simple *pa_device = NULL; static long written_frames = 0; static int framesize ; double frames_per_usec ; static int last_written_size ; static int latency_flag ; static void pa_perr(char *text, int err) { fprintf(stderr, "##########################################################\n"); fprintf(stderr, "%s\n", text); fprintf(stderr, "err=%d, %s\n", err, pa_strerror(err)); warning(text) ; } int audio_device_open(char *output_device) { int err ; ss.format = PA_SAMPLE_S16LE ; ss.rate = 44100 ; ss.channels = 2 ; //printf("Open the Pulse audio device\n") ; pa_device = pa_simple_new(NULL,"GWC",PA_STREAM_PLAYBACK,NULL,"GWC Playback", &ss, NULL, NULL, &err) ; if (pa_device == NULL) { pa_perr("audio_device_open: pa_simple_new", err); return -1; } written_frames = 0; last_written_size = -1 ; latency_flag = 1 ; return 0; } int audio_device_set_params(AUDIO_FORMAT *format, int *channels, int *rate) { int err ; // Alister: is there any reason we shouldn't combine audio_device_set_params and audio_device_open? // Why do they need to be two separate steps? //printf("First close the Pulse audio device in case we are playing a mono file, as we don't seem to be able to switch\n") ; audio_device_close(0) ; ss.rate = *rate ; ss.channels = *channels ; switch (*format) { case GWC_U8: ss.format = PA_SAMPLE_U8; framesize=1 ; break; case GWC_S8: ss.format = PA_SAMPLE_ALAW; framesize=1 ; break; case GWC_S16_BE: ss.format = PA_SAMPLE_S16BE; framesize=2 ; break; default: case GWC_S16_LE: ss.format = PA_SAMPLE_S16LE; framesize=2 ; break; } //printf("Open the Pulse audio device again\n") ; pa_device = pa_simple_new(NULL,"GWC",PA_STREAM_PLAYBACK,NULL,"GWC Playback", &ss, NULL, NULL, &err) ; if (pa_device == NULL) { pa_perr("audio_device_open: pa_simple_new", err); return -1; } written_frames = 0; last_written_size = -1 ; latency_flag = 1 ; framesize *= *channels ; frames_per_usec = (double)(*rate) / 1000000.0 ; return 0; } int audio_device_read(unsigned char *buffer, int buffersize) { /* not implemented */ return -1; } int audio_device_write(unsigned char *data, int count) { int err ; pa_simple_write(pa_device, data, (size_t) count, &err) ; written_frames += count/framesize ; return written_frames*framesize ; } /* Number of bytes processed since opening the device. */ long query_processed_bytes(void) { if(pa_device != NULL) { int err ; pa_usec_t latency = pa_simple_get_latency(pa_device, &err) ; int bytes_unprocessed = (latency*ss.rate)/1000000 * framesize ; if((written_frames) *framesize == last_written_size) { latency_flag++ ; if(latency_flag > 4) { bytes_unprocessed = 0 ; } else { bytes_unprocessed /= latency_flag ; } } last_written_size = (written_frames) *framesize ; return (written_frames) *framesize - bytes_unprocessed ; } return 0 ; } long _audio_device_processed_bytes = 0 ; /* Number of bytes processed since opening the device. */ long audio_device_processed_bytes(void) { if(pa_device != NULL) _audio_device_processed_bytes = query_processed_bytes() ; return _audio_device_processed_bytes ; } void audio_device_close(int drain) { if (pa_device != NULL) { int err; //printf("Closing the Pulse audio device\n") ; _audio_device_processed_bytes = query_processed_bytes() ; if(drain) err = pa_simple_drain(pa_device, &err); pa_simple_free(pa_device) ; pa_device = NULL; } } #define BEST_BUFSIZE 4096 int audio_device_best_buffer_size(int playback_bytes_per_block) { return BEST_BUFSIZE ; } int audio_device_nonblocking_write_buffer_size(int maxbufsize, int playback_bytes_remaining) { int len = BEST_BUFSIZE ; if (len > maxbufsize) len = maxbufsize; if (len > playback_bytes_remaining) len = playback_bytes_remaining; /* printf("audio_device_nonblocking_write_buffer_size:%d\n", len); */ return len; } gtk-wave-cleaner-0.22-04/audio_util.c0000666000175000017500000011046013453574021020516 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* audio_util.c */ #include #include #include #include #include #ifdef MAC_OS_X /* this seems to give wrong results on intel macs :( */ #include /* doing this doesn't seem to fix it, and would presumably break it on */ /* powerpc macs (but are we otherwise supported there?) */ /*#define __BYTE_ORDER __LITTLE_ENDIAN */ #else #include #endif #include #include #include #include #ifdef HAVE_OGG #include "vorbis/codec.h" #include "vorbis/vorbisfile.h" #endif #include "gwc.h" #ifdef HAVE_MP3 #include "mpg123.h" #endif #include "fmtheaders.h" #include "encoding.h" #include "audio_device.h" #include "soundfile.h" int audio_state = AUDIO_IS_IDLE ; int wavefile_fd = -1 ; long audio_bytes_written ; int rate = 44100 ; int stereo = 1 ; int audio_bits = 16 ; int BYTESPERSAMPLE = 2 ; int MAXSAMPLEVALUE = 1 ; int PLAYBACK_FRAMESIZE = 4 ; int FRAMESIZE = 4 ; int current_ogg_bitstream = 0 ; int nonzero_seek ; /* int dump_sample = 0 ; */ long wavefile_data_start ; SNDFILE *sndfile = NULL ; SF_INFO sfinfo ; #ifdef HAVE_OGG OggVorbis_File oggfile ; #endif FILE *fp_ogg = NULL ; #ifdef HAVE_MP3 mpg123_handle *fp_mp3 = NULL ; #endif int audiofileisopen = 0 ; long current_ogg_or_mp3_pos ; #define SNDFILE_TYPE 0x01 #define OGG_TYPE 0x02 #define MP3_TYPE 0x04 int audio_type ; extern struct view audio_view ; extern struct sound_prefs prefs ; extern struct encoding_prefs encoding_prefs; int current_sample ; void position_wavefile_pointer(long sample_number) ; void audio_normalize(int flag) { if(audio_type == SNDFILE_TYPE) { if(flag == 0) sf_command(sndfile, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; else sf_command(sndfile, SFC_SET_NORM_DOUBLE, NULL, SF_TRUE) ; } } void write_wav_header(int thefd, int speed, long bcount, int bits, int stereo) { /* Spit out header here... */ wavhead header; char *riff = "RIFF"; char *wave = "WAVE"; char *fmt = "fmt "; char *data = "data"; memcpy(&(header.main_chunk), riff, 4); header.length = sizeof(wavhead) - 8 + bcount; memcpy(&(header.chunk_type), wave, 4); memcpy(&(header.sub_chunk), fmt, 4); header.sc_len = 16; header.format = 1; header.modus = stereo + 1; header.sample_fq = speed; header.byte_p_sec = ((bits > 8)? 2:1)*(stereo+1)*speed; /* Correction by J.A. Bezemer: */ header.byte_p_spl = ((bits > 8)? 2:1)*(stereo+1); /* was: header.byte_p_spl = (bits > 8)? 2:1; */ header.bit_p_spl = bits; memcpy(&(header.data_chunk), data, 4); header.data_length = bcount; write(thefd, &header, sizeof(header)); } void config_audio_device(int rate_set, int bits_set, int stereo_set) { AUDIO_FORMAT format,format_set; int channels ; /* int fragset = 0x7FFF000F ; */ bits_set = 16 ; /* play everything as 16 bit, signed integers */ /* using the appropriate endianness */ /* Alister: I have swapped this around as an intel mac seems to think */ /* the first test is true regardless of whether you test for BE or LE */ /* Presumably it might fail on a powerpc mac now? */ /* Also, does it break other platforms (since LE is normal these days */ /* it should really stay default */ #if __BYTE_ORDER == __LITTLE_ENDIAN format_set = GWC_S16_LE ; #elif __BYTE_ORDER == __BIG_ENDIAN format_set = GWC_S16_BE ; #else format_set = GWC_S16_LE ; #endif rate = rate_set ; audio_bits = bits_set ; stereo = stereo_set ; format = format_set ; /* if(ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &fragset) == -1) { */ /* warning("error setting buffer size on audio device") ; */ /* } */ channels = stereo + 1 ; // Alister: Eh? Isn't this set above? rate = rate_set ; if (audio_device_set_params(&format_set, &channels, &rate) == -1) { warning("unknown error setting device parameter") ; } if(format != format_set) { char *buf_fmt_str ; char buf[85] ; switch(format_set) { case GWC_U8 : buf_fmt_str = "8 bit (unsigned)" ; bits_set = 8 ; break ; case GWC_S8 : buf_fmt_str = "8 bit (signed)" ; bits_set = 8 ; break ; case GWC_S16_BE : case GWC_S16_LE : buf_fmt_str = "16 bit" ; bits_set = 16 ; break ; default : buf_fmt_str = "unknown!" ; bits_set = 8 ; break ; } snprintf(buf, sizeof(buf), "Set bits to %s - does your soundcard support what you requested?\n", buf_fmt_str) ; warning(buf) ; } if(channels != stereo + 1) { char buf[80] ; if(stereo == 0) snprintf(buf, sizeof(buf), "Failed to set mono mode\nYour sound card may not support mono\n") ; else snprintf(buf, sizeof(buf), "Failed to set stereo mode\nYour sound card may not support stereo\n") ; warning(buf) ; } stereo_set = channels - 1 ; // Alister: eh? does this make sense if rate has been set from rate_set above? if(ABS(rate_set-rate) > 10) { char buf[80] ; snprintf(buf, sizeof(buf), "Rate set to %d instead of %d\nYour sound card may not support the desired rate\n", rate_set, rate) ; warning(buf) ; } // Alister: Eh? Isn't this set above? rate = rate_set ; audio_bits = bits_set ; stereo = stereo_set ; } long playback_samples_remaining = 0 ; long playback_total_bytes ; int playback_bytes_per_block ; int looped_count ; #define MAXBUFSIZE 32768 int BUFSIZE ; unsigned char audio_buffer[MAXBUFSIZE] ; unsigned char audio_buffer2[MAXBUFSIZE] ; long playback_start_position ; long playback_end_position ; long playback_position ; long first_playback_sample ; long set_playback_cursor_position(struct view *v, long millisec_per_visual_frame) { long first, last ; if(audio_state == AUDIO_IS_PLAYBACK) { long bytes = audio_device_processed_bytes()-looped_count*playback_total_bytes ; get_region_of_interest(&first, &last, v) ; v->cursor_position = first_playback_sample+bytes/(PLAYBACK_FRAMESIZE) ; return playback_total_bytes - bytes ; } { long inc = rate*millisec_per_visual_frame/1000 ; /* g_print("inc:%ld\n", inc) ; */ v->cursor_position += inc ; return 1 ; } } long start_playback(char *output_device, struct view *v, struct sound_prefs *p, double seconds_per_block, double seconds_to_preload) { long first, last ; long playback_samples ; gfloat lv, rv ; if(audio_type == SNDFILE_TYPE && sndfile == NULL) return 1 ; #ifdef HAVE_OGG if(audio_type == OGG_TYPE && fp_ogg == NULL) return 1 ; #endif audio_device_close(1) ; if (audio_device_open(output_device) == -1) { char buf[255] ; snprintf(buf, sizeof(buf), "Failed to open OSS audio output device %s, check settings->miscellaneous for device information", output_device) ; #ifdef HAVE_ALSA snprintf(buf, sizeof(buf), "Failed to open alsa output device %s, check settings->miscellaneous for device information", output_device) ; #endif #ifdef HAVE_PULSE_AUDIO snprintf(buf, sizeof(buf), "Failed to open Pulse audio output device, recommend internet search about pulse audio configuration for your OS") ; #endif warning(buf) ; return 0 ; } get_region_of_interest(&first, &last, v) ; /* g_print("first is %ld\n", first) ; */ /* g_print("last is %ld\n", last) ; */ /* g_print("rate is %ld\n", (long)p->rate) ; */ first_playback_sample = first ; playback_start_position = first ; playback_end_position = last+1; playback_position = playback_start_position ; playback_samples = p->rate*seconds_per_block ; playback_bytes_per_block = playback_samples*PLAYBACK_FRAMESIZE ; // This was moved down 8 lines to make it work in OS X. Rob config_audio_device(p->rate, p->playback_bits, p->stereo); //Set up the audio device. //stereo is 1 if it is stereo //playback_bits is the number of bits per sample //rate is the number of samples per second BUFSIZE = audio_device_best_buffer_size(playback_bytes_per_block); playback_bytes_per_block = BUFSIZE ; if(playback_bytes_per_block > MAXBUFSIZE) { playback_bytes_per_block = MAXBUFSIZE ; } playback_samples = playback_bytes_per_block/PLAYBACK_FRAMESIZE ; BUFSIZE = playback_bytes_per_block ; playback_samples_remaining = (last-first+1) ; playback_total_bytes = playback_samples_remaining*PLAYBACK_FRAMESIZE ; audio_state = AUDIO_IS_PLAYBACK ; position_wavefile_pointer(playback_start_position) ; /* g_print("playback_start_position is %ld\n", playback_start_position) ; */ /* put some data in the buffer queues, to avoid underflows */ if(0) { int n = (int)(seconds_to_preload / seconds_per_block+0.5) ; int old_playback_bytes = playback_bytes_per_block ; playback_bytes_per_block *= n ; if(playback_bytes_per_block > MAXBUFSIZE) playback_bytes_per_block = MAXBUFSIZE ; process_audio(&lv, &rv) ; v->cursor_position = first+playback_bytes_per_block/(PLAYBACK_FRAMESIZE) ; playback_bytes_per_block = old_playback_bytes ; } /* g_print("playback_samples is %ld\n", playback_samples) ; */ /* g_print("BUFSIZE %ld (%lg fragments)\n", (long)BUFSIZE, (double)BUFSIZE/(double)oss_info.fragsize) ; */ v->prev_cursor_position = -1 ; looped_count = 0 ; return playback_samples ; } void *wavefile_data ; #ifdef TRUNCATE_OLD void truncate_wavfile(struct view *v) { #define REALLY_TRUNCATE #ifndef REALLY_TRUNCATE warning("Truncation temporarily disabled, while incorporating libsndfile...") ; #else /* we must do 3 things: 1. Shift all samples forward by v->truncate_head 2. Rescan the sample blocks (along the way) 3. Physically truncate the size of the file on the filesystem by (v->truncate_head + (n_samples-1)-v->truncate_tail) samples */ long prev ; long new ; int n_in_buf ; long first, last ; #define TMPBUFSIZE (SBW*1000) long left[TMPBUFSIZE], right[TMPBUFSIZE] ; push_status_text("Truncating audio data") ; update_progress_bar(0.0, PROGRESS_UPDATE_INTERVAL, TRUE) ; /* something like this, gotta buffer this or the disk head will burn a hole in the platter */ if(v->truncate_head > 0) { for(prev = v->truncate_head ; prev <= v->truncate_tail ; prev += TMPBUFSIZE) { update_progress_bar((gfloat)(prev-v->truncate_head)/(gfloat)(v->truncate_tail-v->truncate_head), PROGRESS_UPDATE_INTERVAL, FALSE) ; last = MIN((prev+TMPBUFSIZE-1), v->truncate_tail) ; n_in_buf = read_wavefile_data(left, right, prev, last) ; new = prev - v->truncate_head ; first = new ; last = new + n_in_buf - 1 ; write_wavefile_data(left, right, first, last) ; resample_audio_data(&prefs, first, last) ; } } prefs.n_samples = v->truncate_tail - v->truncate_head + 1 ; if(1) save_sample_block_data(&prefs) ; if(1) { sf_count_t total_samples = prefs.n_samples ; if(sf_command(sndfile, SFC_FILE_TRUNCATE, &total_samples, sizeof(total_samples))) warning("Libsndfile reports truncation of audio file failed") ; } pop_status_text() ; #endif } #endif /* !TRUNCATE_OLD */ void sndfile_truncate(long n_samples) { sf_count_t total_samples = n_samples ; if(sf_command(sndfile, SFC_FILE_TRUNCATE, &total_samples, sizeof(total_samples))) warning("Libsndfile reports truncation of audio file failed") ; } int close_wavefile(struct view *v) { if(audio_type == SNDFILE_TYPE) { #ifdef TRUNCATE_OLD int r ; if(v->truncate_head > 0 || v->truncate_tail < v->n_samples -1) { r = yesnocancel("Part of the waveform is selected for truncation, do you really want to truncate?") ; if(r == 2) return 0 ; if(r == 0) truncate_wavfile(v) ; } #endif /* TRUNCATE_OLD */ if(sndfile != NULL) { sf_close(sndfile) ; } audio_device_close(0) ; sndfile = NULL ; #ifdef HAVE_OGG } else if(audio_type == OGG_TYPE) { if(fp_ogg != NULL) { ov_clear(&oggfile) ; } fp_ogg = NULL ; #endif #ifdef HAVE_MP3 } else if(audio_type == MP3_TYPE) { if(fp_mp3 != NULL) { mpg123_close(fp_mp3) ; } fp_mp3 = NULL ; #endif } return 1 ; } void save_as_wavfile(char *filename_new, long first_sample, long last_sample) { SNDFILE *sndfile_new ; SF_INFO sfinfo_new ; long total_samples ; long total_bytes ; total_samples = last_sample-first_sample+1 ; if(total_samples < 0) { warning("Invalid selection") ; return ; } total_bytes = total_samples*FRAMESIZE ; sfinfo_new = sfinfo ; sfinfo_new.frames = total_samples ; if (! (sndfile_new = sf_open (filename_new, SFM_WRITE, &sfinfo_new))) { /* Open failed so print an error message. */ char buf[PATH_MAX] ; snprintf(buf, sizeof(buf), "Failed to save selection %s", filename_new) ; warning(buf) ; return ; } ; push_status_text("Saving selection") ; /* something like this, gotta buffer this or the disk head will burn a hole in the platter */ position_wavefile_pointer(first_sample) ; { long n_copied ; #define TMPBUFSIZE (SBW*1000) unsigned char buf[TMPBUFSIZE] ; long framebufsize = (TMPBUFSIZE/FRAMESIZE) * FRAMESIZE ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; for(n_copied = 0 ; n_copied < total_bytes ; n_copied += framebufsize) { long n_to_copy = framebufsize ; #ifdef MAC_OS_X /* MacOSX */ usleep(2) ; // prevents segfault on OSX, who knows, something to do with status bar update... #endif update_progress_bar((gfloat)(n_copied)/(gfloat)(total_bytes),PROGRESS_UPDATE_INTERVAL,FALSE) ; if(n_copied + n_to_copy > total_bytes) n_to_copy = total_bytes - n_copied ; n_to_copy = sf_read_raw(sndfile, buf, n_to_copy) ; sf_write_raw(sndfile_new, buf, n_to_copy) ; } } update_progress_bar((gfloat)0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; sf_close(sndfile_new) ; pop_status_text() ; } void save_selection_as_wavfile(char *filename_new, struct view *v) { SNDFILE *sndfile_new ; SF_INFO sfinfo_new ; long total_samples ; long total_bytes ; total_samples = v->selected_last_sample-v->selected_first_sample+1 ; if(total_samples < 0 || total_samples > v->n_samples) { warning("Invalid selection") ; return ; } save_as_wavfile(filename_new, v->selected_first_sample, v->selected_last_sample) ; } #ifdef HAVE_MP3 int gwc_mpg123_open(char *filename) { int r ; mpg123_init() ; fp_mp3 = mpg123_new(NULL,NULL) ; r = mpg123_open(fp_mp3,filename) ; if(r != MPG123_OK) { mpg123_delete(fp_mp3) ; fp_mp3 = NULL ; } return r ; } int gwc_mpg123_close(void) { mpg123_close(fp_mp3) ; mpg123_delete(fp_mp3) ; mpg123_exit() ; return 0 ; } #endif int is_valid_audio_file(char *filename) { SNDFILE *sndfile ; SF_INFO sfinfo ; sfinfo.format = 0 ; #ifdef HAVE_OGG if((fp_ogg = fopen(filename, "r")) != NULL) { if(ov_open(fp_ogg, &oggfile, NULL, 0) < 0) { fclose(fp_ogg) ; fp_ogg = NULL ; } else { ov_clear(&oggfile) ; fclose(fp_ogg) ; fp_ogg = NULL ; audio_type = OGG_TYPE ; return 1 ; } } #endif #ifdef HAVE_MP3 if(gwc_mpg123_open(filename) == MPG123_OK) { gwc_mpg123_close() ; fp_mp3 = NULL ; audio_type = MP3_TYPE ; return 1 ; } #endif if((sndfile = sf_open(filename, SFM_RDWR, &sfinfo)) != NULL) { sf_close(sndfile) ; audio_type = SNDFILE_TYPE ; return 1 ; } else { char buf[180+PATH_MAX] ; snprintf(buf, sizeof(buf), "Failed to open %s, \'%s\'", filename, sf_strerror(NULL)) ; warning(buf) ; } return 0 ; } struct sound_prefs open_wavefile(char *filename, struct view *v) { struct sound_prefs wfh ; /* initialize all wfh structure members to defaults. Will be overwritten on successful file open */ wfh.rate = 44100 ; wfh.n_channels = 2 ; wfh.stereo = 1 ; wfh.n_samples = 2 ; wfh.playback_bits = wfh.bits = 16 ; wfh.max_allowed = MAXSAMPLEVALUE-1 ; wfh.wavefile_fd = wavefile_fd ; wfh.sample_buffer_exists = FALSE ; if(close_wavefile(v)) { wfh.successful_open = TRUE ; } else { wfh.successful_open = FALSE ; return wfh ; } if(audio_type == SNDFILE_TYPE) { if (! (sndfile = sf_open (filename, SFM_RDWR, &sfinfo))) { /* Open failed so print an error message. */ char buf[80+PATH_MAX] ; snprintf(buf, sizeof(buf), "Failed to open %s, no permissions or unknown audio format", filename) ; warning(buf) ; wfh.successful_open = FALSE ; return wfh ; /* Print the error message from libsndfile. */ /* sf_perror (NULL) ; */ /* return 1 ; */ } ; } #ifdef HAVE_OGG if(audio_type == OGG_TYPE) { if((fp_ogg = fopen(filename, "r")) != NULL) { if(ov_open(fp_ogg, &oggfile, NULL, 0) < 0) { /* Open failed so print an error message. */ char buf[80+PATH_MAX] ; snprintf(buf, sizeof(buf), "Failed to open %s", filename) ; warning(buf) ; wfh.successful_open = FALSE ; fclose(fp_ogg) ; fp_ogg = NULL ; return wfh ; } } } #endif #ifdef HAVE_MP3 if(audio_type == MP3_TYPE) { if(gwc_mpg123_open(filename) != MPG123_OK) { /* Open failed so print an error message. */ char buf[80+PATH_MAX] ; snprintf(buf, sizeof(buf), "Failed to open %s", filename) ; warning(buf) ; wfh.successful_open = FALSE ; fp_mp3 = NULL ; return wfh ; } } #endif wfh.wavefile_fd = 1 ; if(audio_type == SNDFILE_TYPE) { /* determine soundfile properties */ wfh.rate = sfinfo.samplerate ; wfh.n_channels = sfinfo.channels ; wfh.stereo = stereo = sfinfo.channels-1 ; wfh.n_samples = sfinfo.frames ; switch(sfinfo.format & 0x00000F) { case SF_FORMAT_PCM_U8 : BYTESPERSAMPLE=1 ; MAXSAMPLEVALUE = 1 << 8 ; break ; case SF_FORMAT_PCM_S8 : BYTESPERSAMPLE=1 ; MAXSAMPLEVALUE = 1 << 7 ; break ; case SF_FORMAT_PCM_16 : BYTESPERSAMPLE=2 ; MAXSAMPLEVALUE = 1 << 15 ; break ; case SF_FORMAT_PCM_24 : BYTESPERSAMPLE=3 ; MAXSAMPLEVALUE = 1 << 23 ; break ; case SF_FORMAT_PCM_32 : BYTESPERSAMPLE=4 ; MAXSAMPLEVALUE = 1 << 31 ; break ; default : warning("Soundfile format not allowed") ; break ; } /* do some simple error checking on the wavfile header , so we don't seek data where it isn't */ if(wfh.n_samples < 2) { char tmp[140] ; snprintf(tmp, sizeof(tmp), "Audio file is possibly corrupt, only %ld samples reported by audio header", wfh.n_samples) ; info(tmp) ; if(sndfile != NULL) { sf_close(sndfile) ; } wfh.successful_open = FALSE ; return wfh ; } } #ifdef HAVE_OGG if(audio_type == OGG_TYPE) { vorbis_info *vi = ov_info(&oggfile,-1) ; wfh.rate = vi->rate ; wfh.n_channels = vi->channels ; wfh.stereo = stereo = vi->channels-1 ; wfh.n_samples = ov_pcm_total(&oggfile,-1) ; BYTESPERSAMPLE=2 ; MAXSAMPLEVALUE = 1 << 15 ; current_ogg_or_mp3_pos = 0 ; fprintf(stderr, "Oggfile: FRAMESIZE=%d\n", BYTESPERSAMPLE*wfh.n_channels) ; wfh.successful_open = TRUE ; } #endif #ifdef HAVE_MP3 if(audio_type == MP3_TYPE) { long rate ; int channels ; int encoding ; mpg123_getformat(fp_mp3,&rate,&channels,&encoding) ; mpg123_scan(fp_mp3) ; wfh.n_samples = mpg123_length(fp_mp3) ; wfh.rate = rate ; wfh.n_channels = channels ; wfh.stereo = stereo = channels-1 ; BYTESPERSAMPLE=2 ; MAXSAMPLEVALUE = 1 << 15 ; off_t pos = mpg123_tell(fp_mp3) ; off_t curr_frame = mpg123_tellframe(fp_mp3) ; current_ogg_or_mp3_pos = 0 ; fprintf(stderr, "Mp3file: FRAMESIZE=%d, pos=%d, frame=%d\n", BYTESPERSAMPLE*wfh.n_channels, (int)pos, (int)curr_frame) ; wfh.successful_open = TRUE ; } #endif FRAMESIZE = BYTESPERSAMPLE*wfh.n_channels ; PLAYBACK_FRAMESIZE = 2*wfh.n_channels ; wfh.playback_bits = audio_bits = wfh.bits = BYTESPERSAMPLE*8 ; wfh.max_allowed = MAXSAMPLEVALUE-1 ; gwc_window_set_title(filename) ; return wfh ; } void position_wavefile_pointer(long sample_number) { if(audio_type == SNDFILE_TYPE) { sf_seek(sndfile, sample_number, SEEK_SET) ; } else if(audio_type == MP3_TYPE) { #ifdef HAVE_MP3 if(current_ogg_or_mp3_pos != sample_number) { off_t new_pos ; current_ogg_or_mp3_pos = sample_number ; if(sample_number != 0) { unsigned char buf[1152*4] ; new_pos = mpg123_seek(fp_mp3,sample_number,SEEK_SET) ; off_t curr_frame = mpg123_tellframe(fp_mp3) ; /* if(curr_frame > 0) curr_frame-- ; */ mpg123_seek_frame(fp_mp3,curr_frame,SEEK_SET) ; int presample_number = (int)mpg123_tell(fp_mp3) ; /* if(presample_number > 0) presample_number-- ; */ int samples_to_read = sample_number - presample_number ; new_pos = mpg123_seek(fp_mp3,presample_number,SEEK_SET) ; /* fprintf(stderr, "position_wf_ptr, samples_to_read:%d > 1152!!\n", samples_to_read) ; */ /* fprintf(stderr, "curr_frame:%d presample_number:%d\n", curr_frame,presample_number) ; */ /* fprintf(stderr, "position_wf_ptr, want:%d got%d\n", (int)sample_number, (int)new_pos) ; */ if(samples_to_read > 1152) { exit(1) ; } unsigned int done ; int err ; err = mpg123_read(fp_mp3, buf, samples_to_read*FRAMESIZE, &done) ; } else { new_pos = mpg123_seek(fp_mp3,sample_number,SEEK_SET) ; nonzero_seek = 0 ; } /* fprintf(stderr, "position_wf_ptr, want:%d got%d\n", (int)sample_number, (int)new_pos) ; */ } #endif } else { #ifdef HAVE_OGG if(current_ogg_or_mp3_pos != sample_number) { fprintf(stderr, "pos_wv_ptr, was %ld, want %ld\n", current_ogg_or_mp3_pos, sample_number) ; ov_pcm_seek(&oggfile, sample_number) ; current_ogg_or_mp3_pos = sample_number ; } #endif } } int read_raw_wavefile_data(char buf[], long first, long last) { long n = last - first + 1 ; int n_read = 0 ; int n_bytes_read = 0 ; int bufsize = n * FRAMESIZE ; position_wavefile_pointer(first) ; if(audio_type == SNDFILE_TYPE) { n_bytes_read = sf_read_raw(sndfile, buf, n*FRAMESIZE) ; return n_bytes_read/FRAMESIZE ; } #ifdef HAVE_OGG if(audio_type == OGG_TYPE) { int ret ; while(n_read < n) { ret = ov_read(&oggfile, (char *)&buf[n_bytes_read], bufsize-n_bytes_read,0,2,1,¤t_ogg_bitstream) ; if(ret > 0) { n_read += ret/FRAMESIZE ; n_bytes_read += ret ; } else { break ; } } current_ogg_or_mp3_pos += n_read ; return n_read ; } #endif #ifdef HAVE_MP3 if(audio_type == MP3_TYPE) { size_t done ; int err ; struct mpg123_frameinfo mi ; while(n_read < n) { err = mpg123_read(fp_mp3, (unsigned char *)&buf[n_bytes_read], bufsize-n_bytes_read, &done) ; if(err != MPG123_OK) fprintf(stderr, "read had a problem, %d\n", err) ; err = mpg123_info(fp_mp3, &mi) ; /* fprintf(stderr, "fs %d\n", (int)mi.framesize) ; */ n_bytes_read += done ; n_read += done/FRAMESIZE ; } current_ogg_or_mp3_pos += n_read ; return n_read ; } #endif return n_read ; } int write_raw_wavefile_data(char buf[], long first, long last) { long n = last - first + 1 ; int n_read ; position_wavefile_pointer(first) ; n_read = sf_write_raw(sndfile, buf, n*FRAMESIZE) ; return n_read/FRAMESIZE ; } int read_wavefile_data(long left[], long right[], long first, long last) { long n = last - first + 1 ; long s_i = 0 ; long bufsize_long ; long j ; int *p_int ; position_wavefile_pointer(first) ; p_int = (int *)audio_buffer ; bufsize_long = sizeof(audio_buffer) / sizeof(long) ; while(s_i < n) { long n_read ; #define TRY_NEW_ABSTRACTION_NOT #ifdef TRY_NEW_ABSTRACTION n_read = read_raw_wavefile_data((char *)p_int, first, last) ; #else long n_this = MIN((n-s_i)*(stereo+1), bufsize_long) ; if(audio_type == SNDFILE_TYPE) { n_read = sf_read_int(sndfile, p_int, n_this) ; } #ifdef HAVE_OGG if(audio_type == OGG_TYPE) { n_read = ov_read(&oggfile, (char *)p_int, n_this*FRAMESIZE,0,2,1,¤t_ogg_bitstream) ; n_read /= FRAMESIZE ; } #endif #ifdef HAVE_MP3 if(audio_type == MP3_TYPE) { /* size_t done ; */ /* int err = mpg123_read(fp_mp3, (unsigned char *)&buf[n_bytes_read], bufsize-n_bytes_read, &done) ; */ /* if(err != MPG123_OK) fprintf(stderr, "read had a problem, %d\n", err) ; */ /* n_read = done/FRAMESIZE ; */ } #endif #endif for(j = 0 ; j < n_read ; ) { left[s_i] = p_int[j] ; j++ ; if(stereo) { right[s_i] = p_int[j] ; j++ ; } else { right[s_i] = left[s_i] ; } s_i++ ; } if(n_read == 0) { char tmp[100] ; snprintf(tmp, sizeof(tmp), "Attempted to read past end of audio, first=%ld, last=%ld", first, last) ; warning(tmp) ; exit(1) ; } } return s_i ; } int read_fft_real_wavefile_data(fftw_real left[], fftw_real right[], long first, long last) { long n = last - first + 1 ; long s_i = 0 ; long j ; double *buffer = (double *)audio_buffer ; int bufsize_double = sizeof(audio_buffer) / sizeof(double) ; position_wavefile_pointer(first) ; if(audio_type != SNDFILE_TYPE) { long pos = first ; short *buffer2 ; int bufsize_short ; buffer2 = (short *)audio_buffer2 ; bufsize_short = sizeof(audio_buffer2) / sizeof(short) ; while(s_i < n) { long n_this = MIN((n-s_i), bufsize_short) ; int n_read = read_raw_wavefile_data((char *)audio_buffer2, pos, pos+n_this-1) ; pos += n_read ; for(j = 0 ; j < n_read ; j++) { left[s_i] = buffer2[j] ; if(stereo) { j++ ; right[s_i] = buffer2[j] ; } else { right[s_i] = left[s_i] ; } left[s_i] /= MAXSAMPLEVALUE ; right[s_i] /= MAXSAMPLEVALUE ; if(first == 0) { /* fprintf(stderr, "%4d %d %d\n", (int)s_i, (int)left[s_i], (int)right[s_i]) ; */ } s_i++ ; } if(n_read == 0) { char tmp[100] ; snprintf(tmp, sizeof(tmp), "read_fft_real Attempted to read past end of audio, first=%ld, last=%ld", first, last) ; warning(tmp) ; //exit(1) ; } } } else { while(s_i < n) { long n_this = MIN((n-s_i)*(stereo+1), bufsize_double) ; long n_read = sf_read_double(sndfile, buffer, n_this) ; for(j = 0 ; j < n_read ; j++) { left[s_i] = buffer[j] ; if(stereo) { j++ ; right[s_i] = buffer[j] ; } else { right[s_i] = left[s_i] ; } s_i++ ; } if(n_read == 0) { char tmp[100] ; snprintf(tmp, sizeof(tmp), "Attempted to read past end of audio, first=%ld, last=%ld", first, last) ; warning(tmp) ; exit(1) ; } } } return s_i ; } int read_float_wavefile_data(float left[], float right[], long first, long last) { long n = last - first + 1 ; long s_i = 0 ; long j ; float *buffer = (float *)audio_buffer ; int bufsize_float = sizeof(audio_buffer) / sizeof(float) ; position_wavefile_pointer(first) ; while(s_i < n) { long n_this = MIN((n-s_i)*(stereo+1), bufsize_float) ; long n_read = sf_read_float(sndfile, buffer, n_this) ; for(j = 0 ; j < n_read ; j++) { left[s_i] = buffer[j] ; if(stereo) { j++ ; right[s_i] = buffer[j] ; } else { right[s_i] = left[s_i] ; } s_i++ ; } if(n_read == 0) { char tmp[100] ; snprintf(tmp, sizeof(tmp), "Attempted to read past end of audio, first=%ld, last=%ld", first, last) ; warning(tmp) ; exit(1) ; } } return s_i ; } int sf_write_values(void *ptr, int n_samples) { int n = 0 ; if(n_samples > 0) { n = sf_write_int(sndfile, ptr, n_samples) ; } return n * BYTESPERSAMPLE ; } long n_in_buf = 0 ; int WRITE_VALUE_TO_AUDIO_BUF(char *ivalue) { int i ; int n_written = 0 ; if(BYTESPERSAMPLE+n_in_buf > MAXBUFSIZE) { n_written = sf_write_values(audio_buffer, n_in_buf/BYTESPERSAMPLE) ; n_in_buf = 0 ; } for(i = 0 ; i < BYTESPERSAMPLE ; i++, n_in_buf++) audio_buffer[n_in_buf] = ivalue[i] ; return n_written ; } #define FLUSH_AUDIO_BUF(n_written) {\ n_written += sf_write_values(audio_buffer, n_in_buf/BYTESPERSAMPLE) ;\ n_in_buf = 0 ;\ } int write_fft_real_wavefile_data(fftw_real left[], fftw_real right[], long first, long last) { long n = last - first + 1 ; long j ; long n_written = 0 ; /* make SURE MAXBUF is a multiple of 2 */ #define MAXBUF 500 double buf[MAXBUF] ; n_in_buf = 0 ; position_wavefile_pointer(first) ; for(j = 0 ; j < n ; j++) { buf[n_in_buf] = left[j] ; n_in_buf++ ; if(stereo) { buf[n_in_buf] = right[j] ; n_in_buf++ ; } if(n_in_buf == MAXBUF) { n_written += sf_write_double(sndfile, buf, n_in_buf) ; n_in_buf = 0 ; } } if(n_in_buf > 0) { n_written += sf_write_double(sndfile, buf, n_in_buf) ; n_in_buf = 0 ; } return n_written/2 ; #undef MAXBUF } int write_float_wavefile_data(float left[], float right[], long first, long last) { long n = last - first + 1 ; long j ; long n_written = 0 ; /* make SURE MAXBUF is a multiple of 2 */ #define MAXBUF 500 float buf[MAXBUF] ; n_in_buf = 0 ; position_wavefile_pointer(first) ; for(j = 0 ; j < n ; j++) { buf[n_in_buf] = left[j] ; n_in_buf++ ; if(stereo) { buf[n_in_buf] = right[j] ; n_in_buf++ ; } if(n_in_buf == MAXBUF) { n_written += sf_write_float(sndfile, buf, n_in_buf) ; n_in_buf = 0 ; } } if(n_in_buf > 0) { n_written += sf_write_float(sndfile, buf, n_in_buf) ; n_in_buf = 0 ; } return n_written/2 ; #undef MAXBUF } int write_wavefile_data(long left[], long right[], long first, long last) { long n = last - first + 1 ; long j ; long n_written = 0 ; /* make SURE MAXBUF is a multiple of 2 */ #define MAXBUF 500 int buf[MAXBUF] ; n_in_buf = 0 ; position_wavefile_pointer(first) ; for(j = 0 ; j < n ; j++) { buf[n_in_buf] = left[j] ; n_in_buf++ ; if(stereo) { buf[n_in_buf] = right[j] ; n_in_buf++ ; } if(n_in_buf == MAXBUF) { n_written += sf_write_int(sndfile, buf, n_in_buf) ; n_in_buf = 0 ; } } if(n_in_buf > 0) { n_written += sf_write_int(sndfile, buf, n_in_buf) ; n_in_buf = 0 ; } return n_written/2 ; #undef MAXBUF } void flush_wavefile_data(void) { fsync(wavefile_fd) ; } /* process_audio for mac_os_x is found in the audio_osx.c */ #if !defined MAC_OS_X || defined HAVE_PULSE_AUDIO int process_audio(gfloat *pL, gfloat *pR) { int len = 0 ; int i, frame ; short *p_short ; int *p_int ; unsigned char *p_char ; short maxl = 0, maxr = 0 ; extern int audio_playback ; long n_samples_to_read, n_read ; double maxpossible ; double feather_out_N ; int feather_out = 0 ; *pL = 0.0 ; *pR = 0.0 ; if(audio_state == AUDIO_IS_IDLE) { d_print("process_audio says NOTHING is going on.\n") ; return 1 ; } if(audio_state == AUDIO_IS_RECORDING) { if((len = audio_device_read(audio_buffer, BUFSIZE)) == -1) { warning("Error on audio read...") ; } } else if(audio_state == AUDIO_IS_PLAYBACK) { len = audio_device_nonblocking_write_buffer_size( MAXBUFSIZE, playback_samples_remaining*PLAYBACK_FRAMESIZE); if (len <= 0) { return 0 ; } } n_samples_to_read = len/PLAYBACK_FRAMESIZE ; if(n_samples_to_read*PLAYBACK_FRAMESIZE != len) g_print("ACK!!\n") ; p_char = (unsigned char *)audio_buffer ; p_short = (short *)audio_buffer ; p_int = (int *)audio_buffer ; /* for now force playback to 16 bit... */ #define BYTESPERSAMPLE 2 if(audio_type == SNDFILE_TYPE) { if(BYTESPERSAMPLE < 3) { maxpossible = 1 << 15 ; n_read = sf_readf_short(sndfile, p_short, n_samples_to_read) ; } else { maxpossible = 1 << 23 ; n_read = sf_readf_int(sndfile, p_int, n_samples_to_read) ; } } else { #if defined(HAVE_MP3) || defined(HAVE_OGG) maxpossible = 1 << 15 ; n_read = read_raw_wavefile_data((char *)p_char, current_ogg_or_mp3_pos, current_ogg_or_mp3_pos+n_samples_to_read-1) ; #endif } #define FEATHER_WIDTH 30000 if(playback_samples_remaining - n_read < 0) { feather_out = 1 ; feather_out_N = MIN(n_read, FEATHER_WIDTH) ; fprintf(stderr, "Feather out n_read=%ld, playback_samples_remaining=%ld, N=%lf\n", n_read, playback_samples_remaining, feather_out_N) ; } for(frame = 0 ; frame < n_read ; frame++) { int vl, vr ; // I don't understand how all this code works, but if I remove the multiplication by two then the level meter actually works for mono files in ALSA, and for some reason there seem to be no side effects. // However, note that the level meters work quite differently in different configurations, and arguably don't show anything helpful, anyway. // Perhaps we should multiply by (stereo + 1) though? // i = frame*2 ; i = frame; if(BYTESPERSAMPLE < 3) { if(feather_out == 1 && n_read-(frame+1) < FEATHER_WIDTH) { int j = ((n_read-(frame))-1) ; double p = (double)(j)/feather_out_N ; if(i > n_read - 100) { //printf("j:%d %lf %hd %hd ", j, p, p_short[i], p_short[i+1]) ; } p_short[i] *= p ; p_short[i+1] *= p ; //if(i > n_read - 100) { // printf("%hd %hd\n", p_short[i], p_short[i+1]) ; //} if(frame == n_read-1) fprintf(stderr, "Feather out final %lf, n_read=%ld", p, n_read) ; } vl = p_short[i] ; vr = p_short[i+1] ; } else { if(feather_out == 1 && n_read-(i+1) < 10000) { double p = 1.0 - (double)(n_read-(i+1))/9999.0 ; printf(".") ; p_int[i] *= p ; p_int[i+1] *= p ; } vl = p_int[i] ; vr = p_int[i+1] ; } if(vl > maxl) maxl = vl ; if(-vl > maxl) maxl = -vl ; if(stereo) { if(vr > maxr) maxr = vr ; if(-vr > maxr) maxr = -vr ; } else { maxr = maxl ; } } #undef BYTESPERSAMPLE if(feather_out == 1) printf("\n") ; *pL = (gfloat) maxl / maxpossible ; *pR = (gfloat) maxr / maxpossible ; if(audio_state == AUDIO_IS_RECORDING) { len = write(wavefile_fd, audio_buffer, len) ; audio_bytes_written += len ; } else if(audio_state == AUDIO_IS_PLAYBACK) { len = audio_device_write(p_char, len) ; playback_position += n_read ; playback_samples_remaining -= n_read ; if(playback_samples_remaining < 1) { extern int audio_is_looping ; if(audio_is_looping == FALSE) { unsigned char zeros[1024] ; long zeros_needed ; memset(zeros,0,sizeof(zeros)) ; audio_state = AUDIO_IS_PLAYBACK ; audio_playback = FALSE ; zeros_needed = playback_bytes_per_block - (playback_total_bytes % playback_bytes_per_block) ; if(zeros_needed < PLAYBACK_FRAMESIZE) zeros_needed = PLAYBACK_FRAMESIZE ; do { len = audio_device_write(zeros, MIN(zeros_needed, sizeof(zeros))) ; zeros_needed -= len ; } while (len >= 0 && zeros_needed > 0) ; g_print("Stop playback with playback_samples_remaining:%ld\n", playback_samples_remaining) ; return 1 ; } else { playback_position = playback_start_position ; playback_samples_remaining = (playback_end_position-playback_start_position) ; sf_seek(sndfile, playback_position, SEEK_SET) ; g_print("Loop with playback_samples_remaining:%ld\n", playback_samples_remaining) ; looped_count++ ; } } } return 0 ; } #endif void stop_playback(int force) { if(!force) { /* Robert altered */ int new_playback = audio_device_processed_bytes(); int old_playback; while(new_playback < playback_total_bytes) { /* Robert altered */ usleep(100) ; old_playback = new_playback; new_playback=audio_device_processed_bytes(); /* check if more samples have been processed, if not,quit */ if (old_playback==new_playback){ fprintf(stderr,"Playback appears frozen\n Breaking\n"); break; } } usleep(100) ; } /* fprintf(stderr, "Usleeping 300000\n") ; */ /* usleep(300000) ; */ /* fprintf(stderr, "Done usleeping 300000\n") ; */ audio_state = AUDIO_IS_IDLE ; audio_device_close(1-force) ; } gtk-wave-cleaner-0.22-04/biquad.c0000666000175000017500000004466413450764342017645 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* biquad.c */ #include #include #include "gwc.h" struct { int filter_type ; int feather_width ; double dbGain ; double Fc ; double bandwidth ; int harmonics ; } filter_prefs ; #define BIQUAD #ifdef BIQUAD #include "biquad.h" #else #include "iir_lp.h" #endif #define BUFSIZE 10000 static gfloat dbGain; static gfloat bandwidth; static gfloat Fc; static int filter_type; static int feather_width; int row2filter(int row) { if(row == 0) return LPF ; if(row == 1) return HPF ; if(row == 2) return NOTCH ; if(row == 3) return BPF ; if(row == 4) return PEQ ; if(row == 5) return LSH ; if(row == 6) return HSH ; return 0 ; } int filter2row(gint filter_type) { if(filter_type == LPF) return 0 ; if(filter_type == HPF) return 1 ; if(filter_type == NOTCH) return 2 ; if(filter_type == BPF) return 3 ; if(filter_type == PEQ) return 4 ; if(filter_type == LSH) return 5 ; if(filter_type == HSH) return 6 ; return 0 ; } void load_filter_preferences(void) { //looks like confusion in the previous source. Should this default to NOTCH? filter_prefs.filter_type = 0; filter_prefs.feather_width = 20; //looks like confusion in the previous source. Should this default to 3? filter_prefs.dbGain = 2; filter_prefs.Fc = 120; filter_prefs.bandwidth = 0.5; GKeyFile *key_file = read_config(); int row ; // We should probably have a separate test for each preference... //if (g_key_file_get_string(key_file, "filter_params", "filter_type", NULL) != NULL) { if (g_key_file_has_group(key_file, "filter_params") == TRUE) { row = g_key_file_get_integer(key_file, "filter_params", "filter_type", NULL); filter_prefs.filter_type = row2filter(row) ; filter_prefs.feather_width = g_key_file_get_integer(key_file, "filter_params", "feather_width", NULL); filter_prefs.dbGain = g_key_file_get_double(key_file, "filter_params", "dbGain", NULL); filter_prefs.Fc = g_key_file_get_double(key_file, "filter_params", "Fc", NULL); filter_prefs.bandwidth = g_key_file_get_double(key_file, "filter_params", "bandwidth", NULL); } g_key_file_free (key_file); } void save_filter_preferences(void) { GKeyFile *key_file = read_config(); int row = filter2row(filter_prefs.filter_type) ; g_key_file_set_integer(key_file, "filter_params", "filter_type", row) ; g_key_file_set_integer(key_file, "filter_params", "feather_width", filter_prefs.feather_width); g_key_file_set_double(key_file, "filter_params", "dbGain", filter_prefs.dbGain); g_key_file_set_double(key_file, "filter_params", "Fc", filter_prefs.Fc); g_key_file_set_double(key_file, "filter_params", "bandwidth", filter_prefs.bandwidth); write_config(key_file); } void filter_audio(struct sound_prefs *p, long first, long last, int channel_mask) { long left[BUFSIZE], right[BUFSIZE] ; long x_left[3], x_right[3] ; long y_left[3], y_right[3] ; long current, i, f ; int loops = 0 ; long ring_buffer_length ; double rb_left[BUFSIZE], rb_right[BUFSIZE] ; load_filter_preferences() ; filter_type = filter_prefs.filter_type ; feather_width = filter_prefs.feather_width ; dbGain = filter_prefs.dbGain ; Fc = filter_prefs.Fc ; bandwidth = filter_prefs.bandwidth ; switch(filter_type) { case LPF: g_print("LPF") ; break ; case HPF: g_print("HPF") ; break ; case BPF: g_print("BPF") ; break ; case NOTCH: g_print("NOTCH") ; break ; case PEQ: g_print("PEQ") ; break ; case LSH: g_print("LSH") ; break ; case HSH: g_print("HSH") ; break ; default: g_print("UNKNOWN! ") ; break ; } g_print(" Fc:%lg bandwidth:%lg srate:%d\n", Fc, bandwidth,p->rate) ; /* filtered_sample = current_sample - ring_buffer[j]; */ /* ring_buffer[j] = ring_buffer[j] * 0.9 + current_sample * 0.1; */ /* j++; */ /* j %= ring_buffer_length; */ #define MAXH 5 #ifdef BIQUAD_CALL extern biquad *BiQuad_new(int type, smp_type dbGain, /* gain of filter */ smp_type freq, /* center frequency */ smp_type srate, /* sampling rate */ smp_type bandwidth); /* bandwidth in octaves */ #endif #ifdef BIQUAD biquad *iir_left, *iir_right ; iir_left = BiQuad_new(filter_type, dbGain, Fc, p->rate, bandwidth) ; iir_right = BiQuad_new(filter_type, dbGain, Fc, p->rate, bandwidth) ; ring_buffer_length = p->rate / Fc + 0.5 ; for(i = 0 ; i < ring_buffer_length ; i++) { rb_left[i] = 0.0 ; rb_right[i] = 0.0 ; } #else FILTER iir_left, iir_right ; get_iir_lp_coefs(Fc, &iir_left, p->rate) ; get_iir_lp_coefs(Fc, &iir_right, p->rate) ; #endif /* testing for filter response */ { double freq, d_freq = 10 ; g_print("left a0:%lg\n", iir_left->a0) ; g_print("left a1:%lg\n", iir_left->a1) ; g_print("left a2:%lg\n", iir_left->a2) ; g_print("left b1:%lg\n", iir_left->a3) ; g_print("left b2:%lg\n", iir_left->a4) ; for(freq = 10 ; freq < 20001 ; freq += d_freq) { double from_formula ; double rr = BiQuad_response(freq, p->rate, iir_right, &from_formula) ; g_print("freq:%5.0lf response(dB):%10.2lg formula(dB):%10.2lg\n", freq, rr, from_formula) ; if(freq > 90) d_freq = 100 ; if(freq > 900) d_freq = 1000 ; if(freq > 9000) d_freq = 2000 ; } } current = first ; push_status_text("Filtering audio") ; g_print("Filtering audio %ld to %ld\n", first, last) ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; { while(current <= last) { long n = MIN(last - current + 1, BUFSIZE) ; long tmplast = current + n - 1 ; gfloat p = (gfloat)(current-first)/(last-first+1) ; n = read_wavefile_data(left, right, current, tmplast) ; update_progress_bar(p,PROGRESS_UPDATE_INTERVAL,FALSE) ; for(i = 0 ; i < n ; i++) { long icurrent = current + i ; double feather_p = 1.0 ; double wet_left, wet_right ; x_left[0] = x_left[1] ; x_left[1] = x_left[2] ; x_right[0] = x_right[1] ; x_right[1] = x_right[2] ; y_left[0] = y_left[1] ; y_left[1] = y_left[2] ; y_right[0] = y_right[1] ; y_right[1] = y_right[2] ; x_right[2] = right[i] ; if(icurrent - first < feather_width) feather_p = (double)(icurrent-first)/(feather_width) ; if(last - icurrent < feather_width) feather_p = (double)(last - icurrent)/(feather_width) ; if(channel_mask & 0x01) { long dry_left = left[i]; #ifdef BIQUAD wet_left = 32768.*BiQuad(dry_left/32768., iir_left) ; #else wet_left = iir_filter(dry_left, &iir_left) ; #endif left[i] = lrint(dry_left*(1.0-feather_p) + wet_left*feather_p) ; } if(channel_mask & 0x02) { long dry_right = right[i] ; #ifdef BIQUAD wet_right = 32768.0*BiQuad(dry_right/32768., iir_right) ; #else wet_right = iir_filter(dry_right, &iir_right) ; #endif right[i] = lrint(dry_right*(1.0-feather_p) + wet_right*feather_p) ; } } write_wavefile_data(left, right, current, tmplast) ; current += n ; if(last - current < 10) loops++ ; if(loops > 5) { warning("infinite loop in filter_audio, programming error\n") ; } } resample_audio_data(p, first, last) ; save_sample_block_data(p) ; } update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; #ifdef BIQUAD free(iir_left) ; free(iir_right) ; #else filter_free(&iir_left) ; filter_free(&iir_right) ; #endif main_redraw(FALSE, TRUE) ; } void type_window_select(GtkWidget * clist, gint row, gint column, GdkEventButton * event, gpointer data) { filter_type = row2filter(row) ; } static GtkWidget *dbGain_entry ; static GtkWidget *freq_entry ; static GtkWidget *bandwidth_entry ; static struct sound_prefs local_sound_prefs ; static long first_sample, last_sample ; void show_response(GtkWidget *w, gpointer gdata) { biquad *iir_left ; double freq, d_freq=10 ; Fc = atof(gtk_entry_get_text((GtkEntry *)freq_entry)) ; dbGain = atof(gtk_entry_get_text((GtkEntry *)dbGain_entry)) ; bandwidth = atof(gtk_entry_get_text((GtkEntry *)bandwidth_entry)) ; iir_left = BiQuad_new(filter_type, dbGain, Fc, 44100, bandwidth) ; for(freq = 10 ; freq < 20001 ; freq += d_freq) { double from_formula ; double rl = BiQuad_response(freq, 44100, iir_left, &from_formula) ; g_print("freq:%5.0lf response(dB):%10.4lg formula(dB):%10.4lg\n", freq, rl, from_formula) ; if(freq > 90) d_freq = 100 ; if(freq > 900) d_freq = 1000 ; if(freq > 9000) d_freq = 2000 ; } free(iir_left) ; g_print("first_sample:%ld last_sample:%ld\n", first_sample, last_sample) ; { struct denoise_prefs p ; p.n_noise_samples = 10 ; p.FFT_SIZE = 8192 ; print_noise_sample(&local_sound_prefs, &p, first_sample, last_sample) ; } } int filter_dialog(struct sound_prefs current, struct view *v) { GtkWidget *dlg, *dialog_table ; GtkWidget *feather_entry ; int dclose = 0 ; int row = 0 ; int dres ; GtkWidget *type_window_list; GtkWidget *show_response_button ; gchar *type_window_titles[] = { "Filter Type" }; gchar *type_window_parms[7][1] = { {"Low Pass"}, {"High Pass"}, {"Notch"}, {"Band Pass"}, {"Peaking EQ"}, {"Low Shelf Filter"}, {"High Shelf Filter"}, }; local_sound_prefs = current ; first_sample = v->selected_first_sample ; last_sample = v->selected_last_sample ; load_filter_preferences(); filter_type = filter_prefs.filter_type ; type_window_list = gtk_clist_new_with_titles(1, type_window_titles); gtk_clist_set_selection_mode(GTK_CLIST(type_window_list), GTK_SELECTION_SINGLE); gtk_clist_append(GTK_CLIST(type_window_list), type_window_parms[0]); gtk_clist_append(GTK_CLIST(type_window_list), type_window_parms[1]); gtk_clist_append(GTK_CLIST(type_window_list), type_window_parms[2]); gtk_clist_append(GTK_CLIST(type_window_list), type_window_parms[3]); gtk_clist_append(GTK_CLIST(type_window_list), type_window_parms[4]); gtk_clist_append(GTK_CLIST(type_window_list), type_window_parms[5]); gtk_clist_append(GTK_CLIST(type_window_list), type_window_parms[6]); gtk_clist_select_row(GTK_CLIST(type_window_list), filter2row(filter_prefs.filter_type), 0); gtk_signal_connect(GTK_OBJECT(type_window_list), "select_row", GTK_SIGNAL_FUNC(type_window_select), NULL); gtk_widget_show(type_window_list); dialog_table = gtk_table_new(5,2,0) ; gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 4) ; gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6) ; gtk_widget_show (dialog_table); dlg = gtk_dialog_new_with_buttons("Biquad filter", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), type_window_list, TRUE, TRUE, 0); feather_entry = add_number_entry_with_label_int(filter_prefs.feather_width, "Feather Width", dialog_table, row++) ; dbGain_entry = add_number_entry_with_label_double(filter_prefs.dbGain, "Gain (db)", dialog_table, row++) ; freq_entry = add_number_entry_with_label_double(filter_prefs.Fc, "Center frequency freq (hertz)", dialog_table, row++) ; bandwidth_entry = add_number_entry_with_label_double(filter_prefs.bandwidth, "bandwidth (octaves)", dialog_table, row++) ; gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); show_response_button = gtk_button_new_with_label("Show Response") ; gtk_signal_connect(GTK_OBJECT(show_response_button), "clicked", GTK_SIGNAL_FUNC(show_response), NULL) ; gtk_widget_show(show_response_button) ; gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), show_response_button, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)) ; if(dres == 0) { feather_width = atoi(gtk_entry_get_text((GtkEntry *)feather_entry)) ; Fc = atof(gtk_entry_get_text((GtkEntry *)freq_entry)) ; dbGain = atof(gtk_entry_get_text((GtkEntry *)dbGain_entry)) ; bandwidth = atof(gtk_entry_get_text((GtkEntry *)bandwidth_entry)) ; filter_prefs.feather_width = feather_width ; filter_prefs.dbGain = dbGain ; filter_prefs.Fc = Fc ; filter_prefs.bandwidth = bandwidth ; filter_prefs.filter_type = filter_type ; dclose = 1 ; } gtk_widget_destroy(dlg) ; save_filter_preferences() ; if(dres == 0) return 1 ; return 0 ; } /* Simple implementation of Biquad filters -- Tom St Denis * * Based on the work Cookbook formulae for audio EQ biquad filter coefficients --------------------------------------------------------- by Robert Bristow-Johnson, pbjrbj@viconet.com a.k.a. robert@audioheads.com * Available on the web at http://www.smartelectronix.com/musicdsp/text/filters005.txt * Enjoy. * * This work is hereby placed in the public domain for all purposes, whether * commercial, free [as in speech] or educational, etc. Use the code and please * give me credit if you wish. * * Tom St Denis -- http://tomstdenis.home.dhs.org */ /* Computes a BiQuad filter on a sample */ smp_type BiQuad(smp_type sample, biquad * b) { smp_type result; /* compute result */ result = b->a0 * sample + b->a1 * b->x1 + b->a2 * b->x2 - b->a3 * b->y1 - b->a4 * b->y2; /* shift x1 to x2, sample to x1 */ b->x2 = b->x1; b->x1 = sample; /* shift y1 to y2, result to y1 */ b->y2 = b->y1; b->y1 = result; return result; } /* sets up a BiQuad Filter */ biquad *BiQuad_new(int type, smp_type dbGain, smp_type freq, smp_type srate, smp_type bandwidth) { biquad *b; smp_type A, omega, sn, cs, alpha, beta; smp_type a0, a1, a2, b0, b1, b2; b = malloc(sizeof(biquad)); if (b == NULL) return NULL; /* setup variables */ A = pow(10.0, dbGain /40.0); omega = 2.0 * M_PI * freq /srate; sn = sin(omega); cs = cos(omega); alpha = sn * sinh(M_LN2 /2.0 * bandwidth * omega /sn); beta = sqrt(A + A); switch (type) { case LPF: b0 = (1.0 - cs) /2.0; b1 = 1.0 - cs; b2 = (1.0 - cs) /2.0; a0 = 1.0 + alpha; a1 = -2.0 * cs; a2 = 1.0 - alpha; break; case HPF: b0 = (1.0 + cs) /2.0; b1 = -(1.0 + cs); b2 = (1.0 + cs) /2.0; a0 = 1.0 + alpha; a1 = -2.0 * cs; a2 = 1.0 - alpha; break; case BPF: b0 = alpha; b1 = 0.0; b2 = -alpha; a0 = 1.0 + alpha; a1 = -2.0 * cs; a2 = 1.0 - alpha; break; case NOTCH: b0 = 1.0; b1 = -2.0 * cs; b2 = 1.0; a0 = 1.0 + alpha; a1 = -2.0 * cs; a2 = 1.0 - alpha; break; case PEQ: b0 = 1.0 + (alpha * A); b1 = -2.0 * cs; b2 = 1.0 - (alpha * A); a0 = 1.0 + (alpha /A); a1 = -2.0 * cs; a2 = 1.0 - (alpha /A); break; case LSH: b0 = A * ((A + 1.0) - (A - 1.0) * cs + beta * sn); b1 = 2.0 * A * ((A - 1.0) - (A + 1.0) * cs); b2 = A * ((A + 1.0) - (A - 1.0) * cs - beta * sn); a0 = (A + 1.0) + (A - 1.0) * cs + beta * sn; a1 = -2.0 * ((A - 1.0) + (A + 1.0) * cs); a2 = (A + 1.0) + (A - 1.0) * cs - beta * sn; break; case HSH: b0 = A * ((A + 1.0) + (A - 1.0) * cs + beta * sn); b1 = -2.0 * A * ((A - 1.0) + (A + 1.0) * cs); b2 = A * ((A + 1.0) + (A - 1.0) * cs - beta * sn); a0 = (A + 1.0) - (A - 1.0) * cs + beta * sn; a1 = 2.0 * ((A - 1.0) - (A + 1.0) * cs); a2 = (A + 1.0) - (A - 1.0) * cs - beta * sn; break; default: free(b); return NULL; } /* the canonical coefficients */ b->can_a0 = a0 ; b->can_a1 = a1 ; b->can_a2 = a2 ; b->can_b0 = b0 ; b->can_b1 = b1 ; b->can_b2 = b2 ; /* precompute the coefficients */ b->a0 = b0 /a0; b->a1 = b1 /a0; b->a2 = b2 /a0; b->a3 = a1 /a0; b->a4 = a2 /a0; #ifdef HARDWIRE /* hardwire BPF at 10 kHz, srate = 44.1 kHz */ b->a0 = 1.0 ; b->a1 = 0.0 ; b->a2 = -1.0 ; b->a3 = 0.1 ; b->a4 = 0.9 ; b->can_a0 = b->a0 ; b->can_a1 = b->a1 ; b->can_a2 = b->a2 ; b->can_b0 = 1.0 ; b->can_b1 = b->a3 ; b->can_b2 = b->a4 ; #endif /* zero initial samples */ b->x1 = b->x2 = 0; b->y1 = b->y2 = 0; return b; } #define M_SQR(x) ((x)*(x)) double BiQuad_response(double freq, double srate, biquad *p, double *from_formula) { double omega = 2.0 * M_PI * freq /(double)srate; double phi = sin(omega/2) ; double a0 = p->can_a0 ; double a1 = p->can_a1 ; double a2 = p->can_a2 ; double b0 = p->can_b0 ; double b1 = p->can_b1 ; double b2 = p->can_b2 ; double phi2 = phi*phi ; *from_formula = 10*log10( M_SQR(b0+b1+b2) - 4.0*(b0*b1 + 4.0*b0*b2 + b1*b2)*phi + 16.0*b0*b2*phi2 ) -10*log10( M_SQR(a0+a1+a2) - 4.0*(a0*a1 + 4.0*a0*a2 + a1*a2)*phi + 16.0*a0*a2*phi2 ) ; int i ; double sum_dry2 = 0, sum_wet2 = 0; p->x1 = p->x2 = 0; p->y1 = p->y2 = 0; for(i = 0 ; i < srate ; i++) { double x = sin(2.0*M_PI*freq/srate*(double)i) ; double y ; sum_dry2 += x*x ; y = BiQuad(x, p) ; sum_wet2 += y*y ; } return 20.0*log10(sum_wet2/sum_dry2) ; } /* from robert bristow-johnson's response, march 1, 2005 http://groups.google.com/group/comp.dsp/browse_frm/thread/8c0fa8d396aeb444/a1bc5b63ac56b686 20*log10[|H(e^jw)|] = 10*log10[ (b0+b1+b2)^2 - 4*(b0*b1 + 4*b0*b2 + b1*b2)*phi + 16*b0*b2*phi^2 ] -10*log10[ (a0+a1+a2)^2 - 4*(a0*a1 + 4*a0*a2 + a1*a2)*phi + 16*a0*a2*phi^2 ] */ gtk-wave-cleaner-0.22-04/biquad.h0000777000175000017500000000350113120075106017621 0ustar00alisteralister00000000000000/* Simple implementation of Biquad filters -- Tom St Denis * * Based on the work Cookbook formulae for audio EQ biquad filter coefficients --------------------------------------------------------- by Robert Bristow-Johnson, pbjrbj@viconet.com a.k.a. robert@audioheads.com * Available on the web at http://www.smartelectronix.com/musicdsp/text/filters005.txt * Enjoy. * * This work is hereby placed in the public domain for all purposes, whether * commercial, free [as in speech] or educational, etc. Use the code and please * give me credit if you wish. * * Tom St Denis -- http://tomstdenis.home.dhs.org */ /* this would be biquad.h */ #include #include #ifndef M_LN2 #define M_LN2 0.69314718055994530942 #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* whatever sample type you want */ typedef double smp_type; /* this holds the data required to update samples thru a filter */ typedef struct { smp_type a0, a1, a2, a3, a4; smp_type can_a0, can_a1, can_a2 ; /* canonical a0,a1,a2 */ smp_type can_b0, can_b1, can_b2 ; /* canonical b0,b1,b2 */ smp_type x1, x2, y1, y2; } biquad; extern smp_type BiQuad(smp_type sample, biquad * b); extern biquad *BiQuad_new(int type, smp_type dbGain, /* gain of filter */ smp_type freq, /* center frequency */ smp_type srate, /* sampling rate */ smp_type bandwidth); /* bandwidth in octaves */ /* filter types */ enum { LPF, /* low pass filter */ HPF, /* High pass filter */ BPF, /* band pass filter */ NOTCH, /* Notch Filter */ PEQ, /* Peaking band EQ filter */ LSH, /* Low shelf filter */ HSH /* High shelf filter */ }; double BiQuad_response(double freq, double srate, biquad *p, double *from_formula) ; gtk-wave-cleaner-0.22-04/chbevl.c0000777000175000017500000000405313120075106017615 0ustar00alisteralister00000000000000/* chbevl.c * * Evaluate Chebyshev series * * * * SYNOPSIS: * * int N; * double x, y, coef[N], chebevl(); * * y = chbevl( x, coef, N ); * * * * DESCRIPTION: * * Evaluates the series * * N-1 * - ' * y = > coef[i] T (x/2) * - i * i=0 * * of Chebyshev polynomials Ti at argument x/2. * * Coefficients are stored in reverse order, i.e. the zero * order term is last in the array. Note N is the number of * coefficients, not the order. * * If coefficients are for the interval a to b, x must * have been transformed to x -> 2(2x - b - a)/(b-a) before * entering the routine. This maps x from (a, b) to (-1, 1), * over which the Chebyshev polynomials are defined. * * If the coefficients are for the inverted interval, in * which (a, b) is mapped to (1/b, 1/a), the transformation * required is x -> 2(2ab/x - b - a)/(b-a). If b is infinity, * this becomes x -> 4a/x - 1. * * * * SPEED: * * Taking advantage of the recurrence properties of the * Chebyshev polynomials, the routine requires one more * addition per loop than evaluating a nested polynomial of * the same degree. * */ /* chbevl.c */ /* Cephes Math Library Release 2.0: April, 1987 Copyright 1985, 1987 by Stephen L. Moshier Direct inquiries to 30 Frost Street, Cambridge, MA 02140 Some software in this archive may be from the book _Methods and Programs for Mathematical Functions_ (Prentice-Hall, 1989) or from the Cephes Mathematical Library, a commercial product. In either event, it is copyrighted by the author. What you see here may be used freely but it comes with no support or guarantee. The two known misprints in the book are repaired here in the source listings for the gamma function and the incomplete beta integral. Stephen L. Moshier moshier@world.std.com */ double chbevl( x, array, n ) double x; double array[]; int n; { double b0, b1, b2, *p; int i; p = array; b0 = *p++; b1 = 0.0; i = n - 1; do { b2 = b1; b1 = b0; b0 = x * b1 - b2 + *p++; } while( --i ); return( 0.5*(b0-b2) ); } gtk-wave-cleaner-0.22-04/compile0000777000175000017500000001624513120075106017567 0ustar00alisteralister00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: gtk-wave-cleaner-0.22-04/configure0000777000175000017500000062051713455314766020146 0ustar00alisteralister00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for Gtk Wave Cleaner 0.22-04. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org and $0: http://gwc.sourceforge.net about your system, including $0: any error possibly output before this message. Then $0: install a modern shell, or manually run the script $0: under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='Gtk Wave Cleaner' PACKAGE_TARNAME='gtk-wave-cleaner' PACKAGE_VERSION='0.22-04' PACKAGE_STRING='Gtk Wave Cleaner 0.22-04' PACKAGE_BUGREPORT='http://gwc.sourceforge.net' PACKAGE_URL='' # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS GTK_LIBS GTK_CFLAGS EGREP GREP CPP ALSA_LIBS ALSA_CFLAGS OSXLIBS MP3HDR MP3LIB OGGHDR OGGLIB ALSACFLAGS ALSADEF ALSALIB PAHDR PALIB OSXDEF FFTWPREC FFTWHDR FFTWLIB am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC PULSEAUDIO_LIBS PULSEAUDIO_CFLAGS DEBUG_FALSE DEBUG_TRUE SNDFILE_LIBS SNDFILE_CFLAGS PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_debug enable_dependency_tracking enable_ogg enable_mp3 enable_alsa enable_pa enable_single_fftw3 ' ac_precious_vars='build_alias host_alias target_alias PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR SNDFILE_CFLAGS SNDFILE_LIBS PULSEAUDIO_CFLAGS PULSEAUDIO_LIBS CC CFLAGS LDFLAGS LIBS CPPFLAGS ALSA_CFLAGS ALSA_LIBS CPP GTK_CFLAGS GTK_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures Gtk Wave Cleaner 0.22-04 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/gtk-wave-cleaner] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of Gtk Wave Cleaner 0.22-04:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-debug enable debugging, default: no --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-ogg compile experimental Ogg file reading support (default disabled) --enable-mp3 compile experimental mp3 file reading support (default disabled) --disable-alsa disable ALSA support (default enabled) --enable-pa compile Pulse Audio support (default disabled) --enable-single-fftw3 compile single precision FFTW3 support (default double precision) Some influential environment variables: PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path SNDFILE_CFLAGS C compiler flags for SNDFILE, overriding pkg-config SNDFILE_LIBS linker flags for SNDFILE, overriding pkg-config PULSEAUDIO_CFLAGS C compiler flags for PULSEAUDIO, overriding pkg-config PULSEAUDIO_LIBS linker flags for PULSEAUDIO, overriding pkg-config CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory ALSA_CFLAGS C compiler flags for ALSA, overriding pkg-config ALSA_LIBS linker flags for ALSA, overriding pkg-config CPP C preprocessor GTK_CFLAGS C compiler flags for GTK, overriding pkg-config GTK_LIBS linker flags for GTK, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF Gtk Wave Cleaner configure 0.22-04 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_c_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval \${$3+:} false; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ( $as_echo "## ----------------------------------------- ## ## Report this to http://gwc.sourceforge.net ## ## ----------------------------------------- ##" ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_type LINENO TYPE VAR INCLUDES # ------------------------------------------- # Tests whether TYPE exists after having included INCLUDES, setting cache # variable VAR accordingly. ac_fn_c_check_type () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_type # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by Gtk Wave Cleaner $as_me 0.22-04, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.15' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='gtk-wave-cleaner' VERSION='0.22-04' # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar plaintar pax cpio none' # The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether UID '$am_uid' is supported by ustar format" >&5 $as_echo_n "checking whether UID '$am_uid' is supported by ustar format... " >&6; } if test $am_uid -le $am_max_uid; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } _am_tools=none fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GID '$am_gid' is supported by ustar format" >&5 $as_echo_n "checking whether GID '$am_gid' is supported by ustar format... " >&6; } if test $am_gid -le $am_max_gid; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } _am_tools=none fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a ustar tar archive" >&5 $as_echo_n "checking how to create a ustar tar archive... " >&6; } # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_ustar-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do { echo "$as_me:$LINENO: $_am_tar --version" >&5 ($_am_tar --version) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && break done am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"' am__tar_="$_am_tar --format=ustar -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x ustar -w "$$tardir"' am__tar_='pax -L -x ustar -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H ustar -L' am__tar_='find "$tardir" -print | cpio -o -H ustar -L' am__untar='cpio -i -H ustar -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_ustar}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5 (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } rm -rf conftest.dir if test -s conftest.tar; then { echo "$as_me:$LINENO: $am__untar &5 ($am__untar &5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { echo "$as_me:$LINENO: cat conftest.dir/file" >&5 (cat conftest.dir/file) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } grep GrepMe conftest.dir/file >/dev/null 2>&1 && break fi done rm -rf conftest.dir if ${am_cv_prog_tar_ustar+:} false; then : $as_echo_n "(cached) " >&6 else am_cv_prog_tar_ustar=$_am_tool fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_ustar" >&5 $as_echo "$am_cv_prog_tar_ustar" >&6; } # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 $as_echo "$PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : $as_echo_n "(cached) " >&6 else case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 $as_echo "$ac_pt_PKG_CONFIG" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 $as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } PKG_CONFIG="" fi fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SNDFILE" >&5 $as_echo_n "checking for SNDFILE... " >&6; } if test -n "$SNDFILE_CFLAGS"; then pkg_cv_SNDFILE_CFLAGS="$SNDFILE_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sndfile >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "sndfile >= 1.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SNDFILE_CFLAGS=`$PKG_CONFIG --cflags "sndfile >= 1.0.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$SNDFILE_LIBS"; then pkg_cv_SNDFILE_LIBS="$SNDFILE_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sndfile >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "sndfile >= 1.0.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_SNDFILE_LIBS=`$PKG_CONFIG --libs "sndfile >= 1.0.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then SNDFILE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "sndfile >= 1.0.0" 2>&1` else SNDFILE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "sndfile >= 1.0.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$SNDFILE_PKG_ERRORS" >&5 HAVE_LIBSNDFILE1="no" elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } HAVE_LIBSNDFILE1="no" else SNDFILE_CFLAGS=$pkg_cv_SNDFILE_CFLAGS SNDFILE_LIBS=$pkg_cv_SNDFILE_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_LIBSNDFILE1="yes" fi if test "x$HAVE_LIBSNDFILE1" = xno ; then as_fn_error $? " Libsndfile 1.0.2 or greater needed, find it at http://www.zip.com.au/~erikd/libsndfile/ OR perhaps configure can not file libsndfile, in which you can try 1 of 3 things: 1) set the environment variable PKG_CONFIG_PATH to find the package file for libsndfile for example: export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig 2) re-install libsndfile in /usr instead of /usr/local, where it installs by default. 3) There are some packages for libsndfile now, be sure to install libsndfile-devel " "$LINENO" 5 fi # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; case "${enable_debug}" in yes) debug=true ;; no) debug=false ;; *) as_fn_error $? "bad value ${enable_debug} for --enable-debug" "$LINENO" 5 ;; esac else debug=false fi if test x"$debug" = x"true"; then DEBUG_TRUE= DEBUG_FALSE='#' else DEBUG_TRUE='#' DEBUG_FALSE= fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PULSEAUDIO" >&5 $as_echo_n "checking for PULSEAUDIO... " >&6; } if test -n "$PULSEAUDIO_CFLAGS"; then pkg_cv_PULSEAUDIO_CFLAGS="$PULSEAUDIO_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse-simple >= 0.9.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libpulse-simple >= 0.9.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PULSEAUDIO_CFLAGS=`$PKG_CONFIG --cflags "libpulse-simple >= 0.9.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$PULSEAUDIO_LIBS"; then pkg_cv_PULSEAUDIO_LIBS="$PULSEAUDIO_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libpulse-simple >= 0.9.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libpulse-simple >= 0.9.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_PULSEAUDIO_LIBS=`$PKG_CONFIG --libs "libpulse-simple >= 0.9.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then PULSEAUDIO_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libpulse-simple >= 0.9.0" 2>&1` else PULSEAUDIO_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libpulse-simple >= 0.9.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$PULSEAUDIO_PKG_ERRORS" >&5 HAVE_PULSE_AUDIO="no" elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } HAVE_PULSE_AUDIO="no" else PULSEAUDIO_CFLAGS=$pkg_cv_PULSEAUDIO_CFLAGS PULSEAUDIO_LIBS=$pkg_cv_PULSEAUDIO_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } HAVE_PULSE_AUDIO="yes" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5 $as_echo_n "checking for cos in -lm... " >&6; } if ${ac_cv_lib_m_cos+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cos (); int main () { return cos (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_m_cos=yes else ac_cv_lib_m_cos=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5 $as_echo "$ac_cv_lib_m_cos" >&6; } if test "x$ac_cv_lib_m_cos" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBM 1 _ACEOF LIBS="-lm $LIBS" fi OGGLIB="" OGGHDR="" # Check whether --enable-ogg was given. if test "${enable_ogg+set}" = set; then : enableval=$enable_ogg; fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ogg" >&5 $as_echo_n "checking for ogg... " >&6; } if test "$enable_ogg" = "yes" then ogg="yes";OGGLIB="-lvorbis -logg -lvorbisfile";OGGHDR="-DHAVE_OGG" else ogg="disabled" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ogg" >&5 $as_echo "$ogg" >&6; } MP3LIB="" MP3HDR="" # Check whether --enable-mp3 was given. if test "${enable_mp3+set}" = set; then : enableval=$enable_mp3; fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mp3" >&5 $as_echo_n "checking for mp3... " >&6; } if test "$enable_mp3" = "yes" then mp3="yes";MP3LIB="-lmpg123";MP3HDR="-DHAVE_MP3" else mp3="disabled" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mp3" >&5 $as_echo "$mp3" >&6; } ALSALIB="" ALSADEF="" alsa="enabled" # Check whether --enable-alsa was given. if test "${enable_alsa+set}" = set; then : enableval=$enable_alsa; fi if test "$enable_alsa" != "no" then pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ALSA" >&5 $as_echo_n "checking for ALSA... " >&6; } if test -n "$ALSA_CFLAGS"; then pkg_cv_ALSA_CFLAGS="$ALSA_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"alsa >= 0.9.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "alsa >= 0.9.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ALSA_CFLAGS=`$PKG_CONFIG --cflags "alsa >= 0.9.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$ALSA_LIBS"; then pkg_cv_ALSA_LIBS="$ALSA_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"alsa >= 0.9.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "alsa >= 0.9.0") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_ALSA_LIBS=`$PKG_CONFIG --libs "alsa >= 0.9.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then ALSA_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "alsa >= 0.9.0" 2>&1` else ALSA_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "alsa >= 0.9.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$ALSA_PKG_ERRORS" >&5 alsa="disabled" elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } alsa="disabled" else ALSA_CFLAGS=$pkg_cv_ALSA_CFLAGS ALSA_LIBS=$pkg_cv_ALSA_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } alsa="yes";ALSALIB=$ALSA_LIBS;ALSADEF="-DHAVE_ALSA";ALSACFLAGS=$ALSA_CFLAGS fi else alsa="disabled" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ALSA" >&5 $as_echo_n "checking for ALSA... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $alsa" >&5 $as_echo "$alsa" >&6; } fi PALIB="" PAHDR="" # Check whether --enable-pa was given. if test "${enable_pa+set}" = set; then : enableval=$enable_pa; enablepa="yes" else enablepa="no" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking Pulse Audio enabled" >&5 $as_echo_n "checking Pulse Audio enabled... " >&6; } if test "$enablepa" == "yes" then if test "x$HAVE_PULSE_AUDIO" = xyes ; then pa="yes"; PALIB=$PULSEAUDIO_LIBS PAHDR="-DHAVE_PULSE_AUDIO" ; alsa="disabled"; ALSALIB=""; ALSADEF=""; { $as_echo "$as_me:${as_lineno-$LINENO}: ***********************!!!!!!! Notice !!!!!!!********************** The Pulseaudio libraries were found and you have chosen to use the Pulseaudio driver. Note that ALSA is recommended as a better sound driver to use, but on some systems (e.g. Ubuntu), getting ALSA to work may be complicated. ******************************************************************* " >&5 $as_echo "$as_me: ***********************!!!!!!! Notice !!!!!!!********************** The Pulseaudio libraries were found and you have chosen to use the Pulseaudio driver. Note that ALSA is recommended as a better sound driver to use, but on some systems (e.g. Ubuntu), getting ALSA to work may be complicated. ******************************************************************* " >&6;} fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enablepa" >&5 $as_echo "$enablepa" >&6; } pa="disabled" fi # Check whether --enable-single-fftw3 was given. if test "${enable_single_fftw3+set}" = set; then : enableval=$enable_single_fftw3; FFTWLIB="-lfftw3f";FFTWHDR="-DHAVE_FFTW3";FFTWPREC="-DFFTWPREC=1" fi if test "$FFTWLIB" = "" then FFTWPREC="" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftw_plan_r2r_1d in -lfftw3" >&5 $as_echo_n "checking for fftw_plan_r2r_1d in -lfftw3... " >&6; } if ${ac_cv_lib_fftw3_fftw_plan_r2r_1d+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfftw3 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fftw_plan_r2r_1d (); int main () { return fftw_plan_r2r_1d (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_fftw3_fftw_plan_r2r_1d=yes else ac_cv_lib_fftw3_fftw_plan_r2r_1d=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fftw3_fftw_plan_r2r_1d" >&5 $as_echo "$ac_cv_lib_fftw3_fftw_plan_r2r_1d" >&6; } if test "x$ac_cv_lib_fftw3_fftw_plan_r2r_1d" = xyes; then : FFTWLIB="-lfftw3";FFTWHDR="-DHAVE_FFTW3";FFTWPREC="-DFFTWPREC=2" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftwf_plan_r2r_1d in -lfftw3f" >&5 $as_echo_n "checking for fftwf_plan_r2r_1d in -lfftw3f... " >&6; } if ${ac_cv_lib_fftw3f_fftwf_plan_r2r_1d+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfftw3f $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fftwf_plan_r2r_1d (); int main () { return fftwf_plan_r2r_1d (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_fftw3f_fftwf_plan_r2r_1d=yes else ac_cv_lib_fftw3f_fftwf_plan_r2r_1d=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fftw3f_fftwf_plan_r2r_1d" >&5 $as_echo "$ac_cv_lib_fftw3f_fftwf_plan_r2r_1d" >&6; } if test "x$ac_cv_lib_fftw3f_fftwf_plan_r2r_1d" = xyes; then : FFTWLIB="-lfftw3f";FFTWHDR="-DHAVE_FFTW3";FFTWPREC="-DFFTWPREC=1" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftw_create_plan in -lfftw" >&5 $as_echo_n "checking for fftw_create_plan in -lfftw... " >&6; } if ${ac_cv_lib_fftw_fftw_create_plan+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lfftw $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fftw_create_plan (); int main () { return fftw_create_plan (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_fftw_fftw_create_plan=yes else ac_cv_lib_fftw_fftw_create_plan=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_fftw_fftw_create_plan" >&5 $as_echo "$ac_cv_lib_fftw_fftw_create_plan" >&6; } if test "x$ac_cv_lib_fftw_fftw_create_plan" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBFFTW 1 _ACEOF LIBS="-lfftw $LIBS" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftw_create_plan in -ldfftw" >&5 $as_echo_n "checking for fftw_create_plan in -ldfftw... " >&6; } if ${ac_cv_lib_dfftw_fftw_create_plan+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldfftw $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char fftw_create_plan (); int main () { return fftw_create_plan (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dfftw_fftw_create_plan=yes else ac_cv_lib_dfftw_fftw_create_plan=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dfftw_fftw_create_plan" >&5 $as_echo "$ac_cv_lib_dfftw_fftw_create_plan" >&6; } if test "x$ac_cv_lib_dfftw_fftw_create_plan" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_LIBDFFTW 1 _ACEOF LIBS="-ldfftw $LIBS" fi fi fi fi if test "$FFTWLIB" = "" then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rfftw_one in -lrfftw" >&5 $as_echo_n "checking for rfftw_one in -lrfftw... " >&6; } if ${ac_cv_lib_rfftw_rfftw_one+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lrfftw $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char rfftw_one (); int main () { return rfftw_one (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_rfftw_rfftw_one=yes else ac_cv_lib_rfftw_rfftw_one=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rfftw_rfftw_one" >&5 $as_echo "$ac_cv_lib_rfftw_rfftw_one" >&6; } if test "x$ac_cv_lib_rfftw_rfftw_one" = xyes; then : FFTWLIB="-lrfftw -lfftw";FFTWHDR="-DHAVE_FFTW" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rfftw_one in -ldrfftw" >&5 $as_echo_n "checking for rfftw_one in -ldrfftw... " >&6; } if ${ac_cv_lib_drfftw_rfftw_one+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldrfftw $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char rfftw_one (); int main () { return rfftw_one (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_drfftw_rfftw_one=yes else ac_cv_lib_drfftw_rfftw_one=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_drfftw_rfftw_one" >&5 $as_echo "$ac_cv_lib_drfftw_rfftw_one" >&6; } if test "x$ac_cv_lib_drfftw_rfftw_one" = xyes; then : FFTWLIB="-ldrfftw -ldfftw";FFTWHDR="-DHAVE_DFFTW" else as_fn_error $? "\"You need to install the fftw 3.x libraries from www.fftw.org\"" "$LINENO" 5 fi fi fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in fcntl.h limits.h malloc.h sys/ioctl.h sys/time.h unistd.h sndfile.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_time=yes else ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 $as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 $as_echo_n "checking for an ANSI C-conforming const... " >&6; } if ${ac_cv_c_const+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __cplusplus /* Ultrix mips cc rejects this sort of thing. */ typedef int charset[2]; const charset cs = { 0, 0 }; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this sort of thing. */ char tx; char *t = &tx; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; } bx; struct s *b = &bx; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_c_const=yes else ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 $as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then $as_echo "#define const /**/" >>confdefs.h fi ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" if test "x$ac_cv_type_size_t" = xyes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi pkg_failed=no { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GTK" >&5 $as_echo_n "checking for GTK... " >&6; } if test -n "$GTK_CFLAGS"; then pkg_cv_GTK_CFLAGS="$GTK_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gtk+-2.0 >= 2.16 glib-2.0 >= 2.30 \""; } >&5 ($PKG_CONFIG --exists --print-errors " gtk+-2.0 >= 2.16 glib-2.0 >= 2.30 ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_CFLAGS=`$PKG_CONFIG --cflags " gtk+-2.0 >= 2.16 glib-2.0 >= 2.30 " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$GTK_LIBS"; then pkg_cv_GTK_LIBS="$GTK_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \" gtk+-2.0 >= 2.16 glib-2.0 >= 2.30 \""; } >&5 ($PKG_CONFIG --exists --print-errors " gtk+-2.0 >= 2.16 glib-2.0 >= 2.30 ") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_GTK_LIBS=`$PKG_CONFIG --libs " gtk+-2.0 >= 2.16 glib-2.0 >= 2.30 " 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then GTK_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs " gtk+-2.0 >= 2.16 glib-2.0 >= 2.30 " 2>&1` else GTK_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs " gtk+-2.0 >= 2.16 glib-2.0 >= 2.30 " 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$GTK_PKG_ERRORS" >&5 as_fn_error $? "Package requirements ( gtk+-2.0 >= 2.16 glib-2.0 >= 2.30 ) were not met: $GTK_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. Alternatively, you may set the environment variables GTK_CFLAGS and GTK_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details. To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else GTK_CFLAGS=$pkg_cv_GTK_CFLAGS GTK_LIBS=$pkg_cv_GTK_LIBS { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi if test $ac_cv_c_compiler_gnu = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 $as_echo_n "checking whether $CC needs -traditional... " >&6; } if ${ac_cv_prog_gcc_traditional+:} false; then : $as_echo_n "(cached) " >&6 else ac_pattern="Autoconf.*'x'" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TIOCGETP _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes else ac_cv_prog_gcc_traditional=no fi rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Autoconf TCGETA _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "$ac_pattern" >/dev/null 2>&1; then : ac_cv_prog_gcc_traditional=yes fi rm -f conftest* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_gcc_traditional" >&5 $as_echo "$ac_cv_prog_gcc_traditional" >&6; } if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5 $as_echo_n "checking return type of signal handlers... " >&6; } if ${ac_cv_type_signal+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_type_signal=int else ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5 $as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF for ac_func in vprintf do : ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" if test "x$ac_cv_func_vprintf" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_VPRINTF 1 _ACEOF ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" if test "x$ac_cv_func__doprnt" = xyes; then : $as_echo "#define HAVE_DOPRNT 1" >>confdefs.h fi fi done for ac_func in gettimeofday do : ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" if test "x$ac_cv_func_gettimeofday" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_GETTIMEOFDAY 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Mac OS X platform" >&5 $as_echo_n "checking for Mac OS X platform... " >&6; } case `uname -s` in Darwin) platform_osx=yes ;; *) platform_osx=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $platform_osx" >&5 $as_echo "$platform_osx" >&6; } if test x$platform_osx = xyes; then OSXDEF="-DMAC_OS_X" if test "$enablepa" == "yes"; then # pulseaudio is enabled (recommended until issues are fixed with coreaudio backend) OSXLIBS="$LIBS -lgtkmacintegration-gtk2" else # pulseaudio is not enabled so we need to build CoreAudio backend instead { $as_echo "$as_me:${as_lineno-$LINENO}: **********************!!!!!!! Warning !!!!!!!********************** You are building on Apple OSX with the CoreAudio backend. This currently does not seem to work. Use --enable-pa to build with the pulseaudio backend instead. ******************************************************************* " >&5 $as_echo "$as_me: **********************!!!!!!! Warning !!!!!!!********************** You are building on Apple OSX with the CoreAudio backend. This currently does not seem to work. Use --enable-pa to build with the pulseaudio backend instead. ******************************************************************* " >&6;} OSXLIBS="$LIBS -framework CoreAudio -lgtkmacintegration-gtk2" fi fi ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. # # If the first sed substitution is executed (which looks for macros that # take arguments), then branch to the quote section. Otherwise, # look for a macro that doesn't take arguments. ac_script=' :mline /\\$/{ N s,\\\n,, b mline } t clear :clear s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g t quote s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g t quote b any :quote s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g s/\[/\\&/g s/\]/\\&/g s/\$/$$/g H :any ${ g s/^\n// s/\n/ /g p } ' DEFS=`sed -n "$ac_script" confdefs.h` ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${DEBUG_TRUE}" && test -z "${DEBUG_FALSE}"; then as_fn_error $? "conditional \"DEBUG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by Gtk Wave Cleaner $as_me 0.22-04, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE Configuration files: $config_files Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ Gtk Wave Cleaner config.status 0.22-04 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --he | --h | --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi gtk-wave-cleaner-0.22-04/configure.in0000666000175000017500000001406713455314752020540 0ustar00alisteralister00000000000000dnl Process this file with autoconf to produce a configure script. AC_INIT([Gtk Wave Cleaner], [0.22-04], [http://gwc.sourceforge.net]) AM_INIT_AUTOMAKE([1.12 foreign no-define tar-ustar]) PKG_CHECK_MODULES(SNDFILE, sndfile >= 1.0.0, HAVE_LIBSNDFILE1="yes", HAVE_LIBSNDFILE1="no") if test "x$HAVE_LIBSNDFILE1" = xno ; then AC_MSG_ERROR([ Libsndfile 1.0.2 or greater needed, find it at http://www.zip.com.au/~erikd/libsndfile/ OR perhaps configure can not file libsndfile, in which you can try 1 of 3 things: 1) set the environment variable PKG_CONFIG_PATH to find the package file for libsndfile for example: export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig 2) re-install libsndfile in /usr instead of /usr/local, where it installs by default. 3) There are some packages for libsndfile now, be sure to install libsndfile-devel ]) fi AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [enable debugging, default: no]), [case "${enable_debug}" in yes) debug=true ;; no) debug=false ;; *) AC_MSG_ERROR([bad value ${enable_debug} for --enable-debug]) ;; esac], [debug=false]) AM_CONDITIONAL(DEBUG, test x"$debug" = x"true") PKG_CHECK_MODULES(PULSEAUDIO, libpulse-simple >= 0.9.0, HAVE_PULSE_AUDIO="yes", HAVE_PULSE_AUDIO="no") dnl Checks for programs. AC_PROG_CC AC_LANG(C) dnl Checks for libraries. dnl Replace `main' with a function in -lm: AC_CHECK_LIB(m, cos) dnl setup macros variables to be replaced in Makefile.in AC_SUBST(FFTWLIB) AC_SUBST(FFTWHDR) AC_SUBST(FFTWPREC) AC_SUBST(OSXDEF) AC_SUBST(PALIB) AC_SUBST(PAHDR) AC_SUBST(ALSALIB) AC_SUBST(ALSADEF) AC_SUBST(ALSACFLAGS) AC_SUBST(OGGLIB) AC_SUBST(OGGHDR) AC_SUBST(MP3LIB) AC_SUBST(MP3HDR) AC_SUBST(OSXLIBS) dnl enable ogg/vorbis libs on user request and check installation OGGLIB="" OGGHDR="" AC_ARG_ENABLE(ogg, [ --enable-ogg compile experimental Ogg file reading support (default disabled)]) AC_MSG_CHECKING([for ogg]) if test "$enable_ogg" = "yes" then ogg="yes";OGGLIB="-lvorbis -logg -lvorbisfile";OGGHDR="-DHAVE_OGG" else ogg="disabled" fi AC_MSG_RESULT($ogg) dnl enable mp3 libs on user request and check installation MP3LIB="" MP3HDR="" AC_ARG_ENABLE(mp3, [ --enable-mp3 compile experimental mp3 file reading support (default disabled)]) AC_MSG_CHECKING([for mp3]) if test "$enable_mp3" = "yes" then mp3="yes";MP3LIB="-lmpg123";MP3HDR="-DHAVE_MP3" else mp3="disabled" fi AC_MSG_RESULT($mp3) dnl enable alsa on user request and check installation ALSALIB="" ALSADEF="" alsa="enabled" AC_ARG_ENABLE(alsa, [ --disable-alsa disable ALSA support (default enabled)]) if test "$enable_alsa" != "no" then PKG_CHECK_MODULES(ALSA, alsa >= 0.9.0, alsa="yes";ALSALIB=$ALSA_LIBS;ALSADEF="-DHAVE_ALSA";ALSACFLAGS=$ALSA_CFLAGS, alsa="disabled") else alsa="disabled" AC_MSG_CHECKING([for ALSA]) AC_MSG_RESULT($alsa) fi dnl enable pulseaudio on user request and check installation PALIB="" PAHDR="" AC_ARG_ENABLE(pa, [ --enable-pa compile Pulse Audio support (default disabled)],enablepa="yes",enablepa="no") AC_MSG_CHECKING([Pulse Audio enabled]) if test "$enablepa" == "yes" then if test "x$HAVE_PULSE_AUDIO" = xyes ; then pa="yes"; PALIB=$PULSEAUDIO_LIBS PAHDR="-DHAVE_PULSE_AUDIO" ; alsa="disabled"; ALSALIB=""; ALSADEF=""; AC_MSG_NOTICE([ ***********************!!!!!!! Notice !!!!!!!********************** The Pulseaudio libraries were found and you have chosen to use the Pulseaudio driver. Note that ALSA is recommended as a better sound driver to use, but on some systems (e.g. Ubuntu), getting ALSA to work may be complicated. ******************************************************************* ]) fi else AC_MSG_RESULT($enablepa) pa="disabled" fi dnl enable single precision FFTW3 if installed AC_ARG_ENABLE(single-fftw3, [ --enable-single-fftw3 compile single precision FFTW3 support (default double precision)], FFTWLIB="-lfftw3f";FFTWHDR="-DHAVE_FFTW3";FFTWPREC="-DFFTWPREC=1") if test "$FFTWLIB" = "" then dnl Detect which version of fftw libs exist, if any FFTWPREC="" AC_CHECK_LIB(fftw3, fftw_plan_r2r_1d,FFTWLIB="-lfftw3";FFTWHDR="-DHAVE_FFTW3";FFTWPREC="-DFFTWPREC=2", AC_CHECK_LIB(fftw3f, fftwf_plan_r2r_1d,FFTWLIB="-lfftw3f";FFTWHDR="-DHAVE_FFTW3";FFTWPREC="-DFFTWPREC=1", AC_CHECK_LIB(fftw, fftw_create_plan, , AC_CHECK_LIB(dfftw, fftw_create_plan)))) if test "$FFTWLIB" = "" then AC_CHECK_LIB(rfftw, rfftw_one, FFTWLIB="-lrfftw -lfftw";FFTWHDR="-DHAVE_FFTW", AC_CHECK_LIB(drfftw, rfftw_one, FFTWLIB="-ldrfftw -ldfftw";FFTWHDR="-DHAVE_DFFTW", AC_MSG_ERROR("You need to install the fftw 3.x libraries from www.fftw.org"))) fi fi dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/ioctl.h sys/time.h unistd.h sndfile.h) AC_HEADER_TIME dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T dnl refer to comments in gwc.c where these versions are required: PKG_CHECK_MODULES(GTK, [ gtk+-2.0 >= 2.16 glib-2.0 >= 2.30 ]) dnl Checks for library functions. AC_PROG_GCC_TRADITIONAL AC_TYPE_SIGNAL AC_FUNC_VPRINTF AC_CHECK_FUNCS(gettimeofday) dnl check for osx platform AC_MSG_CHECKING([for Mac OS X platform]) case `uname -s` in Darwin) platform_osx=yes ;; *) platform_osx=no ;; esac AC_MSG_RESULT([$platform_osx]) if [test x$platform_osx = xyes]; then OSXDEF="-DMAC_OS_X" if test "$enablepa" == "yes"; then # pulseaudio is enabled (recommended until issues are fixed with coreaudio backend) OSXLIBS="$LIBS -lgtkmacintegration-gtk2" else # pulseaudio is not enabled so we need to build CoreAudio backend instead AC_MSG_NOTICE([ **********************!!!!!!! Warning !!!!!!!********************** You are building on Apple OSX with the CoreAudio backend. This currently does not seem to work. Use --enable-pa to build with the pulseaudio backend instead. ******************************************************************* ]) OSXLIBS="$LIBS -framework CoreAudio -lgtkmacintegration-gtk2" fi fi AC_OUTPUT(Makefile) gtk-wave-cleaner-0.22-04/data/0000755000175000017500000000000013252653016017116 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/applications/0000755000175000017500000000000013252653016021604 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/applications/gtk-wave-cleaner.desktop0000777000175000017500000000047313120374056026344 0ustar00alisteralister00000000000000[Desktop Entry] Version=1.0 Type=Application Terminal=false Name=Gtk Wave Cleaner Comment=Removes noise from audio recordings e.g. of scratchy vinyl records Keywords=audio;sound;noise;filter; TryExec=gtk-wave-cleaner Exec=gtk-wave-cleaner %f Icon=gtk-wave-cleaner Categories=GTK;AudioVideo;Audio;AudioVideoEditing; gtk-wave-cleaner-0.22-04/data/icons/0000755000175000017500000000000013252653016020231 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/0000755000175000017500000000000013252653016021670 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/128x128/0000755000175000017500000000000013252653016022625 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/128x128/apps/0000755000175000017500000000000013252653016023570 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/128x128/apps/gtk-wave-cleaner.png0000777000175000017500000001200713120445571027440 0ustar00alisteralister00000000000000‰PNG  IHDR€€Ã>aËsBIT|dˆ pHYs7]7]€F]tEXtSoftwarewww.inkscape.org›î<„IDATxÚí] ¸UãŽÓiЈR*S‘ÈPH‘$]Ñ êÁ­Qn(¢R¡rÕ%%In¥+’¡‘T2‡¨4Gs)}÷{—õï¾õŸµ÷ÙÃÚk¯µözŸç}ž:{ïµ×úÿwÿÃ÷C"*2{ü,R¤³³ófgfæ#̧™™ÿbþ“Ù‰ÙŽÙŒy>³L(ÿttef³3Ç11·1)E®gÎcþ‡™o ©|(€Ìwxyæ?˜Ã˜_9Ðщð/æbæffÉPîtúñæ¯0V'wÜqt饗R§NhРA4vìXzóÍ7éÃ?¤E‹Ñ×_MkÖ¬¡Õ«WÓ—_~I , ÷ߟ&MšD/¿ü2=ñÄtóÍ7Ó…^HåÊ•+Lû˜³Íé¥|(g;ý(æÌ÷¢uzÅŠ©]»vô /ûûï¿“ÓØ°aÍ›7ž~úijÖ¬•)S&šö2ÿËlÉ, ùŽ?“9š¹CoäÒ¥KÓµ×^KÏ=÷œñë=tè¹ÐÂ… ©ÿþÔ¸qc*Z´¨623«†ˆ¿ãë2'3ÉÆ<òÈ#©I“&ôꫯҮ]»œëIîD “ĦM›hذaT¯^½hSÄ Ì“CDïø‹™ÓõÆ«U«–1‡¯[·.=?e4¤øæ›oèᇦ*UªèB8Àì àpÇW3çLKcÕ­[—&Ožœþá= PØ¿?5ŠªW¯® á ¹{)—µ`äš+ú²q.¾øbz÷ÝwÝ›ÌÓ(¹^7nqƺ60oÊ:02WÊÆ8çœshöìÙ®/æÜ€F³ &PÕªUu!ÀÐT;ð`gŽíÔСCéàÁƒ”¸(…;wÒý÷߯ï°>èX0j0—ÉÎÇÞ=m‹; @[ؼ¼<}4˜Ê<:P`´en—V:Wçy @áÅ_¤£Ž:JŠ`5³¾ïÀ(Æ|^*üŠ+® õëדgà_}õÕ®][ŠàOfwß G©Ì™êrrr¨oß¾ô×_‘§à{öì1Î.´)a$óH_ €Q‘¹T=ÄñÇOsæÌ!OÂCPxíµ×ô)a оã$æwêæO?ýtúå—_ȳð œNsÌ1RsÓa8rºók3ש›ÆQêæÍ›ÉÓð¨Ôº ZµjR+˜•<)FuÓ{Ƹ٫¯¾ÚÙC›,€Ñç!šÊyJP%s•ºÉöíÛÓŸþI¾€ÇlÙ²….¸à}:(î 0Ê2?S7×¼ysÃöíø@JÚH0ʼnݦÝ9ê¦4h@»wï&_Á'PÓvŽ02ÓxEÝÌ™gžI[·n%ßÁGPæãòåËK<˜0nS7q '–¾„Ï|üñÇT²dIé[çªÌíÞnÜ@nn.}úé§ä[øPœeÄ(°0®ÀôÒøá2„| Ÿ èÒ¥‹Á æn`¬úÒ–-[’ïácìÝ»×p¤"x(­`\'ç}lMBdp@-Uª”0zôh9 ÌN—žR_r÷ÝwS`5’"èè¨0¬˜Ã‹áͳmÛ¶Pœ °#ÞÆåœÀ,¥®W^y……€èÕ«—F8"FkuÑË.»Œ‡ fø“N:I†°×vB†'ïGa˜!CøÊ@4>%0š«‹]ýõHL>Î¥0WOEŸ(|öÙg¡|‚ñãÇÇ}b«óÉ3þÀ"€@”•HEhz•dð¾À'Ÿ| Àg@¶1 NHŒÌU$]~ùåhDæRäš5kVZRΤûöí3ÜñMlEN"è¥Ô3qâĬž÷šk®¡c=Ö Q£F êС-[¶Ì7öÐCÉghˆ¾Æ‡ 'NÙ$€ÂRÄa;|ÓM7y;ÖÁF0t—õÔ‡¦x"€(ÉŸ¨D‰FN ¯Cxïg†©‡DZ´l¼oÇŒC?þø£áá¼dÉ#‡ŽÀu!ÜyçžvG&5q¿]c %ÌMxóÉ'Ÿœ‘ôk™ ^;vì°}+¦Ã§žzŠÊ–-kAÆ =ë‹ìebû¸0ÔQ… A‡±ÀMbøÓO?é¡ÜtÞyçEN¦qå•WÊ,$¥c à~õ@Ó§Otç#GVúÉÚ¶oßnȤp&í—×€QKÜgÓXxW-|¼ªf§Ð¶m[£AR1ÁâvÝu×YD€ÿg,ßQ,^¼XÞã [˜iÛŒ”m]tQ ;ÿçŸ6ÜÚR€\€bˆ5عsgO=/)‚I–DÀ%êàXdäççG:Ë S0²~!^Š wïÞžzfäV'„åìÐ[ÝñÄ-m׳•+WZ;1 À1žëÉF<Î;¨‹(¾ÿN)€1ê$,Ž„"À"¤xñâFE¯Çœ†N·Ür‹m]=rܸq£ëxýõ×-ûr‹››‹^Á0èh™? ŦâJÖI£Va£ÒÏŠïÊ—˜¬2zÇ‚¾HÁ6Êûí·ß ¼BÂy{Íš5-ŸWÍòåË]*€FqpÙ-¿\ýÜ@?¢DN±þ’fí=zÄ|?BûÄ÷õ“0bpb`§‚‰äøño^êeÒ¤· ¼Oç† ¿óƒ]mùl¥J•iÕª5…~Ö îÙsˆ*T¨(ìó#,¯ëpãžvî<@½zõ‘™¾¨M›ö´}ûþ„¯…ëȵÀºu[ ¼‡×¡àÈ*úáY)€ñGÃA‚)ÒÚ.+˜2}9†±•dw–bσÌšâë2w'pd¹\ûÞ­?ø>ä"1×0˜ÿN曵¾éYà=õëÿ-¤òm1\ `jäp¤€¶ ^þ T»,É›í£uF›<^ßwjÁ?£pŠùâ!†¶ÐÜÄûKŒS/`ßzXøå6Ö:mBŠŠo£]ï±47޼ÿ®À&f)ñœÝm€|Žz†Q%€H]ìI?ø€xeO¼(ìn鬜œžÆßSãn^<ž'®›Ã#Ï2®kÇ=„¤Úê»rsÿWà=zk¦ç>ÒÏœœE›–à6ý-òš:ßÓúH P/à$ ÀÊ‘Aêï0è8Uïs‘<2E™Øtdï½÷,F)8r@@‚Cá"·ÞØ"ê˜:ujDRJ«äYó·ß~k”|9í´Ó„ùXŽ.°S; l‹¤ І‰¹N:FGÛ™‘Q¾V´y+)€.ÑÜÁàF: =jq²9 qguVäú0R]X¿Å 拚@žÀ•êâ¸øæËÔçEw* S˜a¢&´h~;tíÚU¶IU)€mJ\ÀK/½dé(TÑtòÄ Õ·¢®_²HGvDðL±8„ &p^¼êª«\¿1y‚Áδœ(àï§®‰ ¨È"ˆàÖ¥dãø^Dž9·WiÅÚ  _yÍìW‡È.nc0 «N„9:Þ„Lèléú,Y…"  ŽŒ%€¾^Èϸ™©{—q<¢·ÞzËÞõ;Ëãžh—v±ÐP½ñ±ÇËèM8ÐÒ™Hv 0ô ¯A©í³@­[·–my\,Sõ1 gèPéÊi ‡SÑ Ù¹ GÐPïÿ…ëþJŠ#MÜëªᲜI FAº>Ÿþù¶§’8¬’ïƒÉ3n\ZæðGã@3õž={zmþ¢³Ï>ÛâþŒ‘k9«|BaÚíW=ä0×ãðawÊ $Y`ñ‡ ݵ¡^ï¼óŽáJÈZ!›€3S G ÅÈúHúA~_!ÑN €´’204¤#¢7@b@T°VͬIB}š Š2çª/{àBd°÷Ë|ÌéÏ„`Š Š*-‡aÇ÷Å¥|,ÍmîË"Èß“n˜"¸Ê´1S… âÊR ÀY Y§ˆ¡ØÅ¬•T_&ó!Sý•úêׯO»ví àðƒÓNÞœt?¦ }$SÈøÒ>à3lÛ¶Í’øBVÿpUt¸ÐÄ*i*ö]¹Y A»¢è8 –ÚŒ ÀA æuSpÖà<°ånÕª•ìüå̲)÷_ª0EP—¹]Ý\ß¾}C8„¼!·èüŸ™•é;'.bŠà ³F}d$ðÅtàqÀëI}73k:ÖoN]ÈAk)8”z~aèa Cœ]Eçoe^àhŸ9y11ì)Ðã©– À 8ßœ{î¹²óá˜s†ãýåôÅš ²0D~üx*‘„øH”qÊ)§èV¾ªié«t\TìV®P‰>@âP1ñüóÏ[Bã™ó¢ùô{ZÂN°HVAO"zDÈcŒ²°ZÀ uK¤µÒyq:ìX:DáŠ7ëG6C¾¬Ìܧ²y§½ÜøS­ÌUl¤äÌСC3?dPXççç[c™u\ë·¾ˆ§¤](GT¾ÄÉV¶ eåm*ˆMd–qµOÜü2:|ˆÔMn±6@åQ86]È[¤Åìƒë˜íÝ€¬Ž%õ²èÝ»ww׿À% S̹ÚpÕ»œ°éûNBMÌyÏRñŽ;Œ­—°dÉ#I“L^ir¡›s½g`Š 8³;s­µFQޱ5‚ý m™J JHV9^Ï^¢51oD†vO´½n‚¬QH¥I™.ᄊ‚^¾àžPzYCp1óZ¯t¼' -;0?·Ë‚ä8rž?~F›à‡BÔØÊi¦[É9‰ºjg½41Ô3«›o¶k`äÀkÖ¬™‘5‰ÓiW€G~娡œ——G¹¹¹Ñ:}µ™}½¦çÛ×ë7¨Y¯1ëì‹–+«l¬nÙ²¥Q5lÔ¨QF„/¾øÂ(ÜŒ@ »<È8wGŽ!äDn}”ZG%ô{î¹Ç˜ËQHÃf!' ‡˜ÑÌ˽6ÌBšJ2›¿²Ì…eÓ‰j%# RÛšÅK”Ø™ÉìÍl€ _¶¥oÚF¥Í—Äs¥½?‰NFÄD.cN`þ‹yYªÎ˜¡ÜYHâHºó^³ã!]ºÙ‘ÓM·v„ºMCæ¿Í*ªøUßmŽ2Õ‚ÚF@ÈøøLʶ»k‚(IEND®B`‚gtk-wave-cleaner-0.22-04/data/icons/hicolor/16x16/0000755000175000017500000000000013252653016022455 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/16x16/apps/0000755000175000017500000000000013252653016023420 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/16x16/apps/gtk-wave-cleaner.png0000777000175000017500000000133113120445571027266 0ustar00alisteralister00000000000000‰PNG  IHDR(-SsBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<>PLTEÿÿÿ222222555222777999222<<¼ú—6øqœ7;ÃFê`7Úß‹BEQ”Z§OÏÍ|Tu˜6½Í_hPÕ.*æ|;¹Ó êR-4nú¨ÕB3ÙR ja"K,«AWZâ@M÷ØÔÚxOÀ?ÓB;¯{Q“IEND®B`‚gtk-wave-cleaner-0.22-04/data/icons/hicolor/22x22/0000755000175000017500000000000013252653016022447 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/22x22/apps/0000755000175000017500000000000013252653016023412 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/22x22/apps/gtk-wave-cleaner.png0000777000175000017500000000172013120445571027262 0ustar00alisteralister00000000000000‰PNG  IHDRÄ´l;sBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<MIDAT8ÕÍKcWð'M3& ºLD¬üJeLI ˜(Rµ ! 1  ³mÿpѵZ)ÑLTŠB%"X°‚Õ‚Ó)Šu¡b’k’‘\ãO£i4W3í gñžß=÷åÜs$! …â™V«ý¼¶¶Ö¡ÓéêJKKË>}óæù¦Í¶‰Dö–///wI^Ë$sZCCCGooïÛÕÕU13I22ˆ.—ë]]]]θŸêæææïgggÏ)·pvLMM V«õ;*Y€Æétþ‡eÍÇ`’<==Mwvvþ  ¶Z­?„B¡ÇÑ'`’<;;K›Íæ‰{pMMMçÌÌLôiõi˜$§§§ÃUUU-¼=êžžž·yÑ[ØçóqooïÑ)n·ûw*ÛƒÁ`*Ÿ) ptt”f³™²ó–——E­Vk‚ÅbùVż›Δ"•JÑápÐï÷gÆC¡%I¢ lll|õqEEEuAADQ„Z­–=ëétëëë™\¥RÁï÷£½½:eeeèîî†F£ÁÜÜJJJ Š¡¡¡-FóE @2™Äøø8:::îÁkkkXZZÂØø8õ¥F"¸\.\\\Àçóáää^¯*•j Jå—ià¾_%`!ðëm~×^ø™ô“@’ÀuVÞʯ“p:?e×òèèˆ&“‰wuO§Ó4 ”$)ïq#ÉD"A§ÓùãGñx|?•Je^¯²²###€ÍÍM455A©TÊÖÿaH’„p8¼½^ß¶³³#e?õææ†mmmôz½liiáÆÆÆûØñÊÊÊUQQ‘4>œ‰DØßßÏÉÉÉ;?îëëÛð $a4_,..þwUxaaA¨¯¯ÿŠÙ—ÍfóÇb±ÿ ŸŸŸÓjµ¾&s¯ÍB—˵›H$þ3‹ÅØÕÕðI|‡·¶¶Îù²ÈÀóóóQ»Ýþ€æž•Ü5£Ñøbppðííméêê*E‘Á`ðÚãñ¼3 9CÁǦ½^ßT]]Ý^^^þ™^¯¯¨3m¹Ý ÇÇÇA’åÖÿƒy5mIEND®B`‚gtk-wave-cleaner-0.22-04/data/icons/hicolor/24x24/0000755000175000017500000000000013252653016022453 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/24x24/apps/0000755000175000017500000000000013252653016023416 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/24x24/apps/gtk-wave-cleaner.png0000777000175000017500000000205513120445571027270 0ustar00alisteralister00000000000000‰PNG  IHDRàw=øsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<ªIDATH‰¥•MHcWÇÏÓ)ÍŠ ±‰ˆ˜€ 1F'/É4%‹’gtíBnºRÚÔ•´…"Tl!*]Y¬â¢t§ ˆ†ú1“X¦Â˜@¢!_M†¼‚M26yÿ.ü šÄ¾2îâ¼ûîÿwνçžË ‡Œa–eÙ'mmmB}}½žˆŠ¢(Âáðz.—û@þÁõÕjµš×ëõßéõú¦ÞÞ^•ÅbQ(•J"†Ò>ùýþ¼×ëMƒÁÓ£££/’ɤ¿¢€;ƒˆ>0›ÍÏ\.W •ŒèŽ+IfggO9Žûžˆ•é•:ÍÍÍN§Ó‹ÅŠÅ+n,‰AxÑÔÔÔV@DŠþþþ—’$UÕ~Åb‚ ¼(Íä`2™~ŒÇãÕ#—€“““‚Édúá µµÕ677—þOq˜™™yÝØØh¾‚ð»,ñkÀêê*‚Á`Õ_$I‚Ãáø Õ0 Ó`µZ¼ ×–Édˆˆ(‰Ðèè(ÍÏÏW»;ÔÝÝÝÄ0Œ‚œ{{{9ÁßnÑåå%AÀÚÚÚí|*•B¡p%åv»ÿfYö)™L¦gÙlË媊 Æ;gpqqžç±½½P(ƒÁ‹Å‚X,Qa0¾&‡Ã±0 ÐjµØØØ(lnnbll¬ìÓé4xžGgg'<†‡‡v»ýÁ­P|¢ÏA‰ z ¢ç×þÍø D[ѽïQDÿ”øŸ ½ýv»ýWâ8n!Þ‰*Âl6#ŸÏ¸º@Wû+£LÏÏÏ!Š"ººº¾­I$žt:-•VF£¡‘‘ššš""¢ýý}²Z­T[[+§Ø¨®®Žò¡PhˆH9==ýú~’$Án·cyy6› ;;;W22€ÉÉÉ(=®ðÆçó¥*ÕòÊÊ mmmÑÐÐõôôÈŠþÆÀ)€, N׿´´$Ê MF‹‹‹)µZmCi³³X,?Ÿ½7 ‘H9Ž[ÊÛõGƒƒƒ¯Þ I^чe\uU«Óé $“Éÿ ˆF£’Ãáx¥ÕjŸ”jVz2s·²°°ð—\€ËåÊp÷±÷õª>ú:ÎÙÞÞþ Ïóʾ¾>•Ñh¬aY–ˆa(—ÍÒáá¡äõzS»»»oÂáð—ÇÇÇžJ:U%åú±R©ä[ZZ>U©TšGïÞÕþùöm8»3™Ìs™‡Öÿ &˜¾°¡È²IEND®B`‚gtk-wave-cleaner-0.22-04/data/icons/hicolor/256x256/0000755000175000017500000000000013252653016022631 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/256x256/apps/0000755000175000017500000000000013252653016023574 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/256x256/apps/gtk-wave-cleaner.png0000777000175000017500000002535013120445571027451 0ustar00alisteralister00000000000000‰PNG  IHDR\r¨fsBIT|dˆ pHYsnºnºÖÞ±tEXtSoftwarewww.inkscape.org›î<*eIDATxÚí]y¼MUÿ6]C×tM™Þ"DBd¾¤Ì¢Þ •Œ™™’!/ÊP†Œ/2“dˆ^Rxõ3B"ó2]3±~ëÙï¾\ÇZkïsÎ>çìáû|>ÏÇ?îÞ묵¾Ï^ÃwHÂKB$½Iê"‘€è©AO’$gÎ\œ98Ór&¥¾! :Ϙsr>ÇÙ–s ç(Î)œó8—s®ãÜÉyˆó,çuN&à]ÎxÎSœ¿rnã\ù„sçDÎaœ}9ßä,řޯ€€z#OÍù竜}8gqnÕ –E˜'9WsŽçìÄY“3g2;¢ÿÆž‰óŸœ#9—qþÎydžî/±ÒøY_‰`ÕP3ŠÆ˜€ø Ácÿ]‹óSΟjìfyEß–tç|†V $^]Î?§ï××sÞv±Áñ<ç"Îw8‹Ðü póA¾z«‡pA1eÊ”¬@¬téÒ¬jÕª¬~ýú¬qãÆ¬]»v¬GlàÀlÔ¨QlêÔ©lþüùlÅŠlݺulíÚµlÉ’%lΜ9lâĉlذa¬_¿~¬K—.ìí·ßf 6dµk×f•*UbÅ‹g¹sçfI“& • œÑ@(iî8Ùè£9ßâ\iå²>{öì¬råʬuëÖløðáléÒ¥ìàÁƒìï¿ÿfáÂÕ«WÙŽ;ØÜ¹sYÿþýÙo¼Ážyæ–.]:+Åàç$ΊtEIà£OÆùç }¿°ÄÄݺuë²>}ú°Y³f±-[¶°K—.1»ãäÉ“lõêÕìßÿþ7ëÔ©+W®K‘"E°b€ƒÐþœùiž‘ØÑð‹pá<è$ŽŽf5kÖdC‡ÕŒ=œ_ôPãòåËlÙ²e¬[·nÚJ!Y²dÁˆÁÝç!#Í=€H=<é:snd"§NZÛ«co¾~ýzvëÖ-æ\¸p-^¼X[!+V,Ð3…›œ 9ëÓm @8 ?–sç%'mÁ‚Yß¾}Ùš5kØ7áøóÏ?µƒI:f̘11€çb3¸8Ó%•áÃoþ3ΫþLÎÌ™3³:°Í›7“¥›„qÁ‚¬^½z,**Ê_!8ÂÙžnH¬4üÇôÓè›f'bªT©Ø+¯¼¢-sm¿´9Rͯ ÆŒ£]mú)ˆg芛šÃ$þ“œ³9ÿ6;ñÊ—/Ï&L˜ÀΟ?ïœO.¦€Š6ÁþýûY¯^½Xž>ž 2„eÍšÕŒœãlãUg"¯~RÎæœš9Ñÿá‡ÜñîBHÀµk×´Høb˜‚Íœ%IÜküOéùñ”!66–M›6ͽ_| @â­¢'M¸#js,g €»2à6J¼ÄÎ;êŸÀ/ÀÁH&óÔ"p¾ñçÖ³î(žf[·než„‡À!îøñãÍâ|h¨Û¯ Ýlüuõé c nÝu'û$†8{ö,kÖ¬™™m> yHœcøQz‚Mé ?½yóæÚ$ð<<* @Z4\ñš¸)x‘ÀþÆŸ‡s£j0 .¬ : H¾2räHöÈ# Áp·¥6w“ñ¿h´äÇ’ùì$"ìÙ³Gû@˜¸.ÌG`¯%ÿp£t[3fÌ c'0>M›65“°ôe€È6ÎMªÁ*Z´(Û»w/: €_˜>}º™-Á'NÏXìôDUÔ²eKÍŒ@ðá(R¤ˆ‘ÌtòU¡S¿8çiÙ  *löìÙdÜ$–l Z´ha$Ëš}ȉÆ_Eº‹+d!X‰™3gjgI ÀV43 @hUso¨NùŸ ƒÀ¶Ø·o+T¨Jö9ÍiÈIÆßFUb é¶ $¡Æ_ýÅÊ–-«‡)J`­ñ÷UñŒ7Žf& @XÏP0Õàš°" €5µöƪÒo£  ܸ}û¶–˜T!×8ë‘—«o®¬ƒÓ§O¯¡$D Èѽ{w• ¥|c€À`²*7ÊSHì”iWD"EmÿŒÌøóçÏÏ:D³ŽÀV€ß‰¢NÊÉ•'0güdÆ_²dIöÇÐl#°%V¬X¡ò82ò$jã]Ç«d{%Ø7nT‰®󒈿:ç-Y ?;Hœ€ï¾ûNµØo§Zv1þg9¯ˆ:,W®\Z ( €“ðÅ_¨·r¦%øŸñ”åéGÎ>$i 8#FŒP]~Ï™ÒÓÀñ(çQ¥I“†­_¿žf €£š… ø*Ò‰"iüi9w‹:&yòäZ9. €`ah˜Wà Y§L™2…f €k·á:uê¨D ž§€£•¬3 D3†Àu@Q¹råT>yq‹ÌýÀØØXvòäIš$žÆ´iÓTçu-õeå¹—/_N£O@`JOAÄÈdr¤p<"óóïÙ³': AÇ•+WTU‰'9U‹~PÅŠ5×H á>õ*9ÀV Œ£€£°(¹~à‘#Gh´IŒ=Z¶ ØŽ,ÙN€ÕäçO@ð¸+Q¢„L::B8Þýø@ß¼y“F™€ À¦M›d™„.rf³µpÄpž ÀªU«htI&ЪU+Ù*`¦Ý`Œ¨á5¢Q% ˜ fΜY&•m)%EÕ{Ó¥KG>$?ñùçŸË`•nÂVñÜ"jðÈ‘#i4I~ueÈ»ÙMš‹Z¬X1òõ' Ô¿D~Lm]æÌj Ыø¹û®[·ŽF‘€%K² lxCÔ@Ä;HÁáâÅ‹Z5l]âÌQàHªJ<иT©RÑÁ Á"Œ?^¶ èixYÔ°víÚѨ‘,Â7XŽ9DðW°%Æ‚€­¾J‘";|ø0 ÁB 6,$7Á QƒÛL  X „ KœƒNs¦Ž„ü(Jð¹oß>-B0pà@Ù* }X€£’¨!¯½ö !D¸páKŸ>½HŽZT$PX!8.H¡C¯^½d«€faŽR¢ ø!€Zœ={V–9è×@J"óD°aÃBйsgÙ* aH€##çMß?÷Üs4*$„0éôál'€•¡€¶"åY±bŠGKPŒ÷”)SXÿþý5_uü;yòd-Õ;Õzš7o.„ãç ¥¬÷}i®\¹Ø;whD\,—/_f3gÎd5kÖ”E§=VºtiíÊj÷îÝÔ¿!ÂÚµkecÐ=$À‘_ôÂ÷ߟFÃÅ€|iÓ¦U½Šõë×gû÷ï§~¶È/_>QŸï•ô 0ò™Ü+I, ÜÃ;tè mÖ¡OŸ>²>/ 8äû¢’%KÒ(˜&œX† ®_¿Nýn~ýõWY_°T8*Š^ôÙgŸÑ(øÍ”ôq-K€#çòü#@°WíÚµÙ_|Áâããx 2×|ûí·¬mÛ¶,kÖ¬¦…ÿÿÖ­[4)ÄS¦L)êÛ/­€×D7wî\ê} @‘"EL{{âÚTiÒ¤1%•+WÖ&2!0¼ôÒK¢~½Æ™Þ Xâûð˜˜:Èñ¼ûu;~ü8kÒ¤‰¬ÔÕüÇ?þA~â믿–õk‹ €ãQ•ß–-[R¯»çÎ3€~ýúýžíÛ·³ *Šü –.]Jã' Î8ôé‚` ºh Ö¬YC½î¼òÊ+a‹¸}û¶*Åõ=b?K"à?Ú´i#êÏsHÜŒ ©4“àlÀŸ?‰‘ñ‡ hÒ¤I,**J)tùî»ïhüÀ¢E‹dýY<x(é'üÁ βÌ(P "üøã,66V)8@\½z5 –I [ni}Ù5 @Ñο}8tèPêm‡ã£>º7ž‘ >rä{úé§•"­½Ì¡T©R¢~\¨Ô ÊÖ­[©§ ^âë¹Hæ@¦ÛêÕ« ®_¿žÎzôè!êÃxU5a•Œ]ÿQ±Og%Ûi¤‚\»vMK(cC@càÜDÒ‡å€Ý¾ªW¯õ²ƒqôèчàì+Š+*EÞ…¿ÿþ; ¢W¯^•yööKPz˜ó®ïƒNp.:vìøÐä°KJ0¸K[îqçÏŸ§T R¥J¢¾[å¯4 ÀÎ;©‡Š3gÎ]sí”'Ù1W‰@\\\@^‰^Á¿þõ/Q¿]GL?ðPôÊ! Á™@æ&‘AÙ-)(bžzê)¥¼ñÆ4%À«¤ßžóG~ó}€æ5Fp$el™øôéÓ,oÞ¼J@ ÂÃÀêHR7` )àH#ÚÿSì¶s³™!Ù5-ø/¿üb˜gàóÏ?§Á@rµºÜ¬<-êltœ‰¢E‹ ~í\ž€’Sí{IE¾ÿþ{`tëÖMÔ_¿›á b¼ ÎÖ-[¤Ô¨Q#ÛA:rÕ*«„HW¤ÆyöÞ‹/ÖîâὸiÓ¦ˆ…Ìce$©ÊŒ|èûÇ>ú(Y’CŒ;2ãÑ¢:PhÀ€Jxì±ÇØŸþövíÝ»—}ðÁZŽCQ»ŠcÇŽ…µ]ŠƒÀ¢fà ß?¬Zµ*Y’/;xoÊŒF;IwHi0I%œ{„#Q¸®Oœ8aè½è»ÕjذaØ|«SÒ–WÌÀvß?l×®Y“1{ölé¤Då ä „€ÊÐ}(Ôøá‡üÊy˜˜?þ8ÛµkWXúKr€ú¸ìû‡£F"kr °rMD„"]—“@£üùó+ìã?Ù>Q”’[ÓÄÝW_}ò¾’xUNW G.*þéà.]6YkÔ¨qÿ?:¬:0Šad̘QY›pþüù–¾p/¿ü²eu°%@åP«!Á»7 Àó¢>|˜,Êa˜6mšt>ðr`yp^ª² Áå·V¡}ûö–GA˜óO?ý²>ÂJHðÞóFÐÁ÷R§NMÕˆ HÓm!jÌÉL:Ui`9rä°äô}Ĉ†ÆŒÓþ÷Þ{O YÆ!êe"6_v›Àœ9s†ì†`Á‚²÷ƪ`´ïÀ/›à,`É*󢃗Øp¨={öT2ã¿‚{}£=?¶S²+ÈC‡Æ5<ÿüó!é¤X—¼³¢JVúþÁ«¯¾Jå0üßÿýŸtÂ=TÏÑÁ€ƒ9Ĩ¨ ìÅ_ h»mÛ6™Oý½ƒTܤ%!×DBÕÆ/¿üÒò¾AÞG‰xµP ÀAß?èÝ»7Y”ÃçÙdÃ!š[€¯CéÒ¥•Ö¹sg¿ŸitÛ0fÌÓÏÃ*D•ÿÛ•K—.YÞ7ðõ¼ïc•üé Àpb˜1c†vˆÑ·o_Ö½{w-Ÿ<ˆ}Ü>)T%JHï¡‚ÃÀGîܹ• =³…N*(βgÏ.}&ª/Y Ir±*¸éûS¦L ù2nãÆìÃ?Ô²šš)#…k ©œ5kÕ(ðÁ©S§¤}ˆŒ@nàçŸféÒ¥SÎ3«Ù;vhAF²gÔ¯_?àCq\Oª®­¾@_Á»f€#JÔ°yóæ…lÐ4ñÌ3Ïu’/_>6~üxªU¨Cu:¾lÙ2× €»u’j¾`U©:P¿ýö›¥Ž`¶lÙ4!ð:ph+»ÇÞÖÍÀkÕh®`; úŠ6LY² 9 ‚›ªª&Oœ8Ѳ¾hÕª•è+eWÔ uëÖYÖ †têÔIã,±ì9{ö¬'Û!ÙÝ3¾¦‚öÉ ›è¥¨…æ ¤ 6õR$0iÒ$e»VmìØ±Òß‚+ Sð' Sðæ›oJNj̦$ëСƒèkd-z!|í}iYÖÔ *ÄJ´nÝZY·íÀŽ™(ˆoåL4=$¶Š…à ^4¶Èø—f3@œàK˜")èß?˜9s¦ðáñññ½ïèÑ£¶î\$¤K¾'`N¨„„À&YL¿j9؃~(¤Ûß$7/½ô’h~ÌQ À%ß?7nœò%ˆ„‰ˆ{G§D†©âÎîP‘`«Càl ¿`Á‚Úª‡y„åKä&ªà„ï 4ÈðEHòé£I ÔPe#Bý;CUüé×HœíÛ·µ¢.^¼¸h~ S Àß?@fQ7‰tA•¢ÙÎg¨¡ j7¾~Àµœ#tQ À,ß?ˆ‹‹sm!‰¦*SÌ'Ÿ|bËv£¥¬ÝXÙàÀ'™×uTÐ[”oßÍ@º,™@Aíx¨‰b’²6/Y²„€ÀV­Ze ,€WEdöÚÁ‰@òQä=P¥³š7o.-^áw9lWErDù“ÀG\!E¼Ý¤-Wm¾ùæ[µÙ“Eí¬R¥Šÿ#p%P€G0Gö%¶w‘¤öÇÀM”QÒˆd’ð°öìÙ#m§™o@’lô¥è"ð»S\{­Ä¹sç”ÅKP¦ÜP%\ݶm AƒÄÙí3°Ì÷‘qÖ ˜1c†²zÌ®]»"ÞFYöcÔ” (ƒ, €ë€,Ð’-mK30Ò÷QšË+À>Zå&É*CgΜ‘–¿~ýõ×{( €ë Ø&V4#mDžqNð·ðT•2CŽHAUú:às×A’ ÌjFª„ªH¨S **™)S¦ ë%ŠgŸ}V꺜8u €·Ã`Á<¹àkë2È!šd‹/öL^¿~]1Ø¢E‹°· ñ²ö ÈdÀ p$aÀ›L €.ý*0éB¬X±B™wĈÖþÇcïÞ½²ù2Ð è-zøÏ?ÿìéN‡ÿ=öâªêB;wîôû¹0pÙ3qþ”ß? €+!)±Bòêw‰<¼[·nžïx^ȼôÀœ9s²ƒš~ÞÆ•GóæÍ³þG88ýÏ;·h¾l7²mS ‹ÀßäÈ‘ÃÖ¥³Â¥j+€ŒÂfMh%HeË– Í p4WÓ¬€¢— fžÀX»ví”"€ä"ª„¢8Ô«^½ºò–Ýû“¸ M›6•þgµRÒs^ó}Ñ›o¾I# °¤ë=¦I“†M˜0á!oÁcÇŽ±Ò¥K+ÿ¶uëÖ¡k< €cZiӦ͙oÍØµiÐEàKß¡v¹ß¥¨\ ”äÆr_eÈ Ê}ôÑGlúôéZteLLŒòÿã ÑÒk?×`Ö¬Y²yÓ0PKô2LdÂÿ€¼}81³DÒLJ¶Ñ$ŽEµjÕDóéüR‡B’sžñ}aÕªUi$w²ª Cf‰Â 9H DŸJŠ|nÖ¦ý]Fˆ&*ö±„Wp– Ôø±µB ð°€À‘¸þ‚q¡aª°=zЈøáê‚£2"£+ÂÇáöíÛ²´õ‡‘Í+d ‹Ànßã$Å5 cþüùZFe3Æ_£Fð'^%pPJ2‡ømÏ€0SP¿~ýhd@òN !fÙ|ú é¾û÷ïÏ8™†‘8 ¸FFj> Þ@QŸp@*ÎS¢üôñññ4B&«=[¬šHdæ–|ýÇûkË €.]E2dÓ@à(”(QBæù—/œ-JŽXõk×®Ñ(‘BEžˆéØqÀ ‹@_QcPHƒ@@°åË—ÿ$ð„dà¼äÛ D´Y³N ð8V¯^-ûúÏ Ô†ƒ]‰…úd‚uxþùçeðt$ –óª(s å  Xdš–ÿ’`ì7hÐEà3Qã&MšD#G@í׿¬ çM߯eΜYK¡M  ޹sçÊŒU°¶k‰è"0)$µë $ëWR"Uí$98ã}‰Ê6VUÊ!x ]ºt‘ÿ·VØ­e ‹@gQcK–,©e.%Ìc÷îÝÄŒ$âuÎÇì(H²ÓÊ"¯"..NöõÿÐ*›µTt(/ª!!CöÇШ’L@îû‚ñl+ºL5é‹ $5.^¼È²eË&€š–Ûk ç9Ñ`ÈrÛH\‚wÞyGfü ­¶Õ€.­D?™qÈC€ RÁ%Ož\düW8ó8I’rn‰râHt¸1“|ý{†ÂNC&º”àüÛ÷Ç@á~üñGqB"(ÊÍïãŒrœè"0Fô£}ôÑð'¿$Ø‹-R%‹­R ±Äpý°Zµj=T'@à5 ¤òiJŒr(í3äÀîûܦ‚$„qëÖ-­ì»Äø÷p>âxÐE ‡èGÂÕ‘®I¼Šîݻˌ96 ‡Å6Ã$¸X*ú±H!FaÃ$^|Â7F"MÃa—a]2sýà:uêÐy €g€ÂžY²d‘ÿ´pÙdX@вó€O?ý”f €ëG¸J•*ÉŒÿ—pìû#&ºô” |ÀÍ@!]ž¿HØí1€ó€å¢Nˆ‰‰a»ví¢YBàJŒ3Fußß<ܶ`÷†Nˆ:)p7J pÛ/Y²d2㟠;Œ˜è"PIvP°`Aò$p ¾ÿþ{–2eJ™ñïE©=Ï €.E DÀgŸ}–]¹r…f €£±uëV–6mZ™ñŸ¶2½—ã€)* ƒ5kÖÔ¼¥$NÄXll¬ÌøQV¯xÄí/Ò ÐEà™¼õÖ[ä#@à8œ:uŠåË—Ofü78«ØÂöl"¸˜!nݺь"p .\¸ %¿‘ÌgTóý§ìÎ6 ‹@ ™»08lØ0šY$¶Çõë×UŽ>`k»Øœ­@G87Š:~ÓǧF`[ ’¢ŽØ×Nöf;`÷cöÉ:Tt&@`7 í½"¥8Ön¶fKÐE ÌQlÒ¤ »}û6Í:[àСC,þü*ãÿŠ3 €"PD”^<µk×fW¯^¥ÙGQ “oöìÙUÆÿgJÛÚ™]¦‹@QΓ²ÎE6Ê%@)¬^½š¥OŸ^eüËÂÝç*ÐE /ç~Y'*Tˆ=z”f# @X1þ|–*U*•ñÏÄÍ–ííËî d÷ƒ‡¶È:Y†÷ìÙC³’ ,@±[E`ø)|[a[Nh¤.i9¿“u:2«R½€P·O}úôQ>âZº:Ŧ%ºDqΑ ’Š :”® I,¢S‘Ê^aü·Üæ${rœ°ûnã¡ÝÐá €UÀÊÛLÅœ»ŠÊ½$j!è¥\¹rQÊq€ —üƒ ’ìLà_œekGNm¸.o‹ê&Þ <˜¶$~ãìÙ³¬F*Ãrt´ 9¹ñì~å¡cªB^Ê0D`k×®ÕRÓ?òZfq¼ý8ýè"‰s‰jÀ°‡£[£%?Ê×,ù‘Æî}§\óyBv“åL(MþñÇk¹Ù $‰qúôiV½zu£¯>VšÜb3®€DBPNß›I²D‰lãÆdü$ÚÇ麑’ÞÀø±ÂÌì:{qÛJ´%øj@‘_àí·ß¦ëB >øþ-=oeRWÚŠT"!袠t€3gÎÌ&MšäÝ› „[¶l©*ΙÀ#N¾âó¼è"PFHå`—)S†ýôÓO$.€;wî° &°L™2>¸ˆ3£ëíÃí?P œõ„ŒLuHرcGvñâE— òó—.]ڌ៷[Þ>ë„àYÎmF“ [¶llƌڃÀÙ8wîkÛ¶­Qô^B ÏTÎXOÙ„—~¬.É8;p^0”(›6mš»Ó¹TΜ9£åTTåIÌp(óš-xR AVU-‚ÄÌ›7/?~<»qã €Íä0ØÆ¥NÚŒá£:Ï»œÉ=k^ýቄ Žs·!È‘#‡–šÜU5 ]"(ÃÕ¢E eÆðÁÙœÙ=?ÿ½Þì~QÜõ^63ypu8pà@w:\vïÞÍ^ýu#÷ÝÄü…³2Í{‘<Ê9‰ó¦™É„„½zõb'Nœ 3ê]¿~}3wù‰+ñvFRšë$FB‹ó3Îkf&N˜_xá6sæLçmbbÔ´>Ì À (`ÖèœyÚs¦¦¹MÈAá`ý°ÈÔ„‹ŽŽÖ*¯\¹Ò׈!¶Y“'Ofqqqþ|íÁ_9›ÑŸÀ*G¢¾zöÓ“!È=zôÐö©óÀµëÒ¥KYÆ Ížæ'æÏœ íZ‰‡ÀÙB­žòsRjA'#FŒpöyAXŒmÛ¶±÷Þ{OsÄò·97q¾èÖ { Aj}_ù{U+fÒ¡C¶páBÍSÍ«ÀÕ|ó4hÀbcc1zxï}Ïù<ÍK€H%!©Äù9çÅ@Ĉ¨*Û­[7¶lÙ2vùòe×ü±cÇØôéÓµâ®HÚHéD¥¨Þ¨EóÀN«‚œßª²Ž,*T`}ûöÕ?îÈPå[·n±ýû÷³¹sç²6mÚUÏ5Cœ¿ŒE<Í7'ÜtâÜ䤿w³€3„F±~ýú±9sæ°íÛ·ÛbµŸ{$ÑDN…®]»²ºuëj×tÈÈlÁo¿Á¹€³>æ“8U žäb”¦,P⦡jÕª¬]»vläÈ‘š/Ââŋ٪U«Ø–-[´¯ðÉ“'Y||¼©•NàÏŸ?ÏŽ9¢Ý^lذ­X±B+†9uêTͲqãÆZh­‰4Z!Ûë8Ûz!ŸÀ[bP€³ çWœgC!FiÐÒ¥K§¥¼ÆAd©R¥XñâÅÙã?βfÍÈ•›U„{îΗÈèI¼t€ø”¾Uø&ÐCD‡ò~pú:g6š$4I’$×–ôä\ÉyÕE’sgs:¹' šP|Bwnéª)­å>>@@@DDDJJJNNNOOOPPPVVVWWW[[[cccfffgggjjjjjómmmpppuuu„„솆†ŠŠŠžžž   £££¥¥¥¦¦¦®®®°°°µµµ¶¶¶···¸¸¸ººº½½½¾¾¾ÁÁÁÂÂÂÄÄÄÅÅÅÆÆÆÇÇÇÐÐÐÑÑÑÒÒÒÔÔÔÛÛÛÞÞÞßßßàààáááãããäääæææçççèèèêÛÛêêêìììíííïïïðððñññöööùùùúúúûûûüüüýýýþþþÿÿÿÿsü¬[“z윸m'O?™„!Å/©É»MMn…¶@añ@ôøDÃW$³ÞS¨zÛmöÓ¼ /US¨ÚÙÑËiòܪ~–A UK£€™å4=½x½‚* â¶1ÌWFR¨Xç‚fáw*„¶o³ ‹M¦BhKlCϽ´ #¶vFؘ£ŒZ€Å9z-°]ÃêÁÖ=ùMBCéšxÔ»`K:¡&¸i~ j‹›½òP¯ªÒ›`ÅTêݶ÷ȹs†÷jí„í?·à3ó\¨" IEND®B`‚gtk-wave-cleaner-0.22-04/data/icons/hicolor/48x48/0000755000175000017500000000000013252653016022467 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/48x48/apps/0000755000175000017500000000000013252653016023432 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/48x48/apps/gtk-wave-cleaner.png0000777000175000017500000000242113120445571027301 0ustar00alisteralister00000000000000‰PNG  IHDR00`Ü µsBITÛáOà pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<æPLTEÿÿÿ  222666PPP:::OOO lllqqq2=NRV ” ¤ § ôùûÿ ###%%%&&&'''000222777888:::<<<>>>AAAEEEGGGHHHKKKMMMNNNQQQRRRVVVWWWXXX[[[^^^bbbcccfffiiinnnoootttuuuyyyzzz{{{}}}€€€‘‘‘–––———™™™œœœ   ¦¦¦«««­­­®®®¯¯¯µµµ···¿¿¿ÂÂÂÃÃÃÃÃÿÄÄÄÅÅÅÉÉÉÊÊÊÐÐÐÒÒÒÒÒÿÓÓÓÔÔÔ×××ÙÙÙÚÚÚÝÝÝßßßáááåååæææçççèèèéééêêêëëëìììíííîîîïïïðððññòòòôôôõõõöööøøøøùùùú úúúûûûüüüýýýþþþþÿÿiiÿ¥¥ÿÿÿ2å*R!tRNS &':@Z^ctvx•ºÕÜäëïòòòóóóôõøúú‘çáipIDATHÇ–ç[ÓPÆO¡#)t¤MwÜ;ˆ¸À=NÜ 7¢RGÅѪÔ[kUD±M}ÿS?4­MšÐ†ó%÷¹Ïû»Iî}Ï9—¨>̆u8XÆb¦&Âêò$/<Hx\Ö¹Õ­N_(ž’ ‡”Ї|ÎV]¹Éîd*â?ò3ñÛMÚz›7˜F5f«£tÐkÓÒ·Å’€$cmuòw4 =Ù¨»E¥oç  nWîps(†ÝŠïªÖ¯‹Öü‡-–E#ÙXu¯LÞ$Hz+ça¢A»ìº9 í/»ÄAs"N""òe4ñ¡Sê_Ëøˆˆ¬!-=~u]¾¶óð{ådÈJD®¸–þÕ—G@áb÷KÅlÜEDž”pâ`xûÇÚÙ”‡Èœ4ô?×ý..ì™|*€”0“% õ‚Ûû*»tüP (­ì€€…09­oT€BÿéœïûðxcÇËHö,í|Hýû÷Ò‘‘AƒA5eÈ&±‚Çma@™¯^½Òlñ0³6• =~üxÂŒ3Ty.(Ê6ëg€¿ŸEC§åÛ?~ü¸XXCV‰—Áƒ‹{ñöÔ ÄÄÄo¥ vÿD~MKžg½c—|÷îõèÑœ:dÓáY´h‘HŒÜ¸qÃê}&LÀ³Ïšà‹7j¡k!‰HiiivûåååOl©,Z$B"##MÖ„÷¹Õ0~Á‚ˆî*ÛߡـʌVO“ܱc‡CŽ %aaaJwîÜ1}ëLÑÑÑ¢êtõêUˆ¹˜sçÎÕgóæÍ€ #²„êÓ§OiÊ”)”’’"ì2Rqq±Ë°¹Å ŠŠ ‡=ÁK—.!åEááᢼešœœLìÅÒµk×L÷=þ\HYÏž=ëQTTd”_‘øÀŃjÝTPP@mÛ¶7Y »Œë‰'’³Áì<œu…KJJˆÃuĀĜV¬XQï¾… ŠßêÆ6Ð ±à˜…ššÓ ‹/7´oߞΟ?oúå©‘#GŠß ÎxpskMÊÉX[R‰± ™Ö”g»ví¨C‡µœ)è”潆#¼uKVæñð&˜I/¯J2·Tùe€,+¿Ûâ!ÌÌïŒ^ˆâ ““\ÞÀn×11D(è(ô_ᢸø1q—9˜9†ùïÎRYãÀd¨óÐ/Þeb‰9–9šùƒàæÍ›Fâ½”î ¡P ž7W&Ö[¦[·nbÞ¿ß.±Ý¿?ÕË2kCëC‡õL¦@€±]…Ž9br&ì%˜(FøìöЈ#„¶~óæ¦ÔMìnÛ¶ ~B•¹#T™““ãÔàÓ¦MhnݺµAç§uëÖ”ššê‘„H]ë€vsWøÞܹs š6..97zöì™ÕûhPGO3îëë{΋ÃQvK. ›SšžžnõžÌÌL±]`‚< džrÌÃáq¼ ôŽìÿº4iÒ$ñ†÷ìÙc1ô…„ôîÝÛc9As_F)™ 2 ÜÕl0¶xhèþ²$þ«V­ò8È6¡­ÇX)2Ï_ÎÈÈp)íráÂ!æˆòŒšÊQ$ žø{€êx˶”ÎZZvµ ‚Ì.Þö AƒD€5jÔ(qmµ±BCªªªêÐÇh €LôôéÓ.=i,T”Í;@Ñ$ééºhß¾}ØÿzóYÝÂÈ%µRcð,ÑAvöìY»²Âî&lIô1²ø‘Ò˜ˆ Ða¡uZÜ݄䋢ý»’­â(Rnï ÐÄ-QQQè0Í%;ÊãŸ)Õ»Á<ÀÊ•+aàüD‘= @*""BrG}Nkx¡*¼˜è‰BoÍèÑ£õMlc¶ûè).ç5‘ƒMRiØ ÐäM˜c´õ¢·™œl“û  ŠÓÔ@é~ô6“+’ЭZµ’oß¾ÝdÀ wèm&:E}x°ÒèèhÉ- ¨ À•+WaߢÁ›Tj–+{÷îEÊMÇ|’çÜšTn—÷A2tÂ’%Kˆ?PÜUÊÞËÐàMn<0!#‡Îz—NЍ’8C† Ñ)`™¤Ñ‘™4ø ì^Ö ÅíR÷†“ oùÅððð´õ¢ÄGšŠdÔ· ¼ìÒ¥‹têÔ)Í@Ý2>>¾½N9`J<6×¢È>}úÈ(\:HÙ 5ˆR“’’ÐæßþŽßR#:8Ù‹-ÅLm©ãÆ3 ÒäJÛ28xÛì’pBM9^û‡-ÏŽÁÑYd–¦³)*…²D§öСCuèÊÀž…EyùAè0jùׯ_§cǎц hÞ¼yÈ+ÊH_¡{?KxÌÐË@Mìðtów¼EŽ(‡¢kœæïõJã¢ùê·|ïþ>Ÿ¯G3·¡¦zzÜ (~JcjóéèO`þMÌèØÐz>ÿE9"†¨Ÿ¼IEND®B`‚gtk-wave-cleaner-0.22-04/data/icons/hicolor/scalable/0000755000175000017500000000000013252653016023436 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/scalable/apps/0000755000175000017500000000000013252653016024401 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/data/icons/hicolor/scalable/apps/gtk-wave-cleaner.svg0000777000175000017500000000551713120453655030276 0ustar00alisteralister00000000000000 image/svg+xml gtk-wave-cleaner-0.22-04/declick.c0000777000175000017500000010244713120075106017756 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* declick.c */ #include #include #include #include #include "gwc.h" #include "stat.h" #undef warning #define MESCHACH #ifndef MESCHACH #include #include #include #include #endif void fit_cubic(fftw_real data[], int n, fftw_real estimated[]) ; #define FFT_MAX 8192 double high_pass_filter(fftw_real x[], int N) { int i ; double sum2 = 0.0 ; double d2x ; for(i = 1 ; i < N-1 ; i++) { d2x = x[i-1] - 2.0 * x[i] + x[i+1] ; sum2 += d2x*d2x ; } return sqrt(sum2/( (double)N - 2) ) ; } void stats(double x[], int n, double *pMean, double *pStderr, double *pVar, double *pCv, double *pStddev) { double sum_wgt = 0.0 ; double sum = 0.0 ; double sum2 = 0.0 ; double wgt ; int i ; for(i = 0 ; i < n ; i++) { wgt = 1./((double)(n-i)) ; wgt = 1. ; sum += x[i]*wgt ; sum2 += x[i]*x[i]*wgt ; sum_wgt += wgt ; } if(sum_wgt > -DBL_MIN && sum_wgt < DBL_MIN) sum_wgt = 10.0*DBL_MIN ; *pMean = sum / sum_wgt ; if(n > 1) { *pVar = (sum2 - 2.0*(*pMean*sum) + *pMean**pMean*sum_wgt) / ((double)n - 1.0) ; *pStddev = sqrt(*pVar) ; *pCv = 100.0 * *pStddev / (*pMean+1.e-100) ; *pStderr = sqrt(*pVar / sum_wgt) ; } else { *pVar = 0.0 ; *pStddev = 0.0 ; *pCv = 0.0 ; *pStderr = 0.0 ; } } ; #ifdef UNUSED_FUNCTION_IN_DECLICK void get_windowed_ps(fftw_real ps[], fftw_real in[], double window_coef[], int FFT_SIZE, rfftw_plan pFor) { fftw_real out[FFT_MAX], windowed[FFT_MAX] ; int k ; for(k = 0 ; k < FFT_SIZE ; k++) { windowed[k] = window_coef[k] * in[k] ; } rfftw_one(pFor, windowed, out); for (k = 1; k <= FFT_SIZE/2 ; ++k) ps[k] = k < FFT_SIZE/2 ? out[k]*out[k] + out[FFT_SIZE-k]*out[FFT_SIZE-k] : out[k]*out[k] ; } #endif void fit_trig_basis(fftw_real data[], int n, fftw_real estimated[], int click_start, int click_end) { int leftmin = 0 ; int leftmax = click_start ; int rightmax = n-1 ; int rightmin = click_end+1 ; #define ORDER 3 #define NPARAMS (ORDER*2+1) int o ; double B[ORDER*2+1+1] ; int i ; double x[ORDER*2+1] ; init_reg(ORDER*2+1) ; for(i = leftmin ; i <= leftmax ; i++) { double v = (double)(i-leftmin)/(double)n ; for(o = 0 ; o < ORDER ; o++) { x[o*2] = cos((o+1)*M_PI*v) ; x[o*2+1] = sin((o+1)*M_PI*v) ; } x[NPARAMS-1] = v ; sum_reg(x, data[i]) ; } for(i = rightmin ; i <= rightmax ; i++) { double v = (double)(i-leftmin)/(double)n ; for(o = 0 ; o < ORDER ; o++) { x[o*2] = cos((o+1)*M_PI*v) ; x[o*2+1] = sin((o+1)*M_PI*v) ; } x[NPARAMS-1] = v ; sum_reg(x, data[i]) ; } estimate_reg(B) ; for(i = 0 ; i < ORDER ; i++) printf("B[%d,%d]=%10lg %10lg\n", i*2+1, i*2+1+1, B[i*2+1], B[i*2+1+1]) ; printf("B[%d,%d]=%10lg %10lg\n", 0, NPARAMS, B[0], B[NPARAMS]) ; for(i = leftmin ; i <= rightmax ; i++) { double v = (double)(i-leftmin)/(double)n ; estimated[i] = B[0] + B[NPARAMS]*v ; for(o = 0 ; o < ORDER ; o++) { estimated[i] += B[o*2+1] * cos((o+1)*M_PI*v) ; estimated[i] += B[o*2+1+1] * sin((o+1)*M_PI*v) ; } } } #ifndef MESCHACH gsl_matrix *gsl_transp(gsl_matrix *m) { int i,j,rows,cols ; gsl_matrix *t ; rows = m->size1 ; cols = m->size2 ; t = gsl_matrix_alloc(cols,rows) ; for(i = 0 ; i < rows ; i++) for(j = 0 ; j < cols ; j++) gsl_matrix_set(t, j, i, gsl_matrix_get(m, i, j)) ; return t ; } gsl_vector *gsl_mv_mlt(gsl_matrix *m, gsl_vector *v) { gsl_vector *r ; int i,j,rows,cols ; rows = m->size1 ; cols = m->size2 ; r = gsl_vector_alloc(cols) ; for(j = 0 ; j < cols ; j++) { double x = gsl_matrix_get(m, 0, j)*gsl_vector_get(v,0) ; for(i = 1 ; i < rows ; i++) x += gsl_matrix_get(m, i, j)*gsl_vector_get(v,i) ; gsl_vector_set(r, i, x) ; } return r ; } gsl_matrix *gsl_m_mlt(gsl_matrix *m1, gsl_matrix *m2) { gsl_matrix *r ; int i,j,k,rows,cols,out_cols ; rows = m1->size1 ; cols = m1->size2 ; out_cols = m2->size2 ; r = gsl_matrix_alloc(rows,out_cols) ; for(i = 0 ; i < rows ; i++) { for(k = 0 ; k < out_cols ; k++) { double x = gsl_matrix_get(m1, i, 0)*gsl_matrix_get(m2,0,k) ; for(j = 1 ; j < cols ; j++) x += gsl_matrix_get(m1, i, j)*gsl_matrix_get(m2,j,k) ; gsl_matrix_set(r, i, k, x) ; } } return r ; } gsl_matrix * gsl_m_inverse(gsl_matrix *m) { gsl_matrix *inverse,*ludecomp ; gsl_permutation *perm ; int s ; inverse = gsl_matrix_alloc(m->size1,m->size2) ; ludecomp = gsl_matrix_alloc(m->size1,m->size2) ; perm = gsl_permutation_alloc(m->size1) ; gsl_matrix_memcpy(ludecomp,m) ; gsl_linalg_LU_decomp(ludecomp,perm,&s) ; gsl_linalg_LU_invert(ludecomp,perm,inverse) ; gsl_matrix_free(ludecomp) ; gsl_permutation_free(perm) ; return inverse ; } #endif int lsar_sample_restore(fftw_real data[], int firstbad, int lastbad, int siglen) { #ifdef MESCHACH int n_bad = lastbad - firstbad + 1 ; int autolen = 60 ; int i, j, rows, cols ; int rcode ; gboolean clipped ; double x[100], auto_coefs[101] ; static MAT *A=MNULL, *Au=MNULL, *Aut=MNULL, *AutmAu=MNULL, *iAutmAu=MNULL, *final=MNULL ; /* static MAT *A, *Au, *Aut, *AutmAu, *iAutmAu, *final ; */ static VEC *rhs, *sig, *sig_final ; //estimate_region(data, firstbad, lastbad, siglen) ; //return REPAIR_SUCCESS ; autolen = (siglen-n_bad)/4 ; //autolen *= 2 ; if(autolen < 0) { d_print("Autolen < 0!\n") ; return REPAIR_FAILURE; } if(autolen > 3*n_bad) autolen = 3*n_bad ; if(autolen > 100) autolen = 100 ; //g_print("siglen:%d n_bad:%d Autolen:%d\n",siglen,n_bad,autolen) ; sig = v_get(siglen) ; A = m_resize(A,siglen-autolen, siglen) ; Au = m_resize(Au, siglen-autolen, n_bad) ; for(i = 0 ; i < siglen ; i++) sig->ve[i] = data[i] ; init_reg(autolen) ; for(i = autolen ; i < firstbad ; i++) { for(j = 0 ; j < autolen ; j++) x[j] = data[i - autolen + j] ; sum_reg(x, data[i]) ; } for(i = lastbad+autolen+1 ; i < siglen ; i++) { for(j = 0 ; j < autolen ; j++) x[j] = data[i - autolen + j] ; sum_reg(x, data[i]) ; } if(estimate_reg(auto_coefs) == 1) { rcode = SINGULAR_MATRIX ; } else { for(i = firstbad ; i <= lastbad ; i++) sig->ve[i] = 0.0 ; rows = siglen - autolen ; cols = siglen ; for(i = 0 ; i < rows ; i++) { for(j = 0 ; j < autolen ; j++) A->me[i][i+j]= -auto_coefs[j] ; A->me[i][i+autolen] = 1. ; for(j = firstbad ; j <= lastbad ; j++) Au->me[i][j-firstbad] = A->me[i][j] ; } for(j = firstbad ; j <= lastbad ; j++) sig->ve[j] = 0.0 ; Aut = m_transp(Au, Aut) ; rhs = mv_mlt(A,sig,rhs) ; AutmAu = m_mlt(Aut,Au, AutmAu) ; iAutmAu = m_inverse(AutmAu, iAutmAu) ; final = m_mlt(iAutmAu,Aut, final) ; sig_final = mv_mlt(final,rhs, sig_final) ; clipped = FALSE ; for(j = firstbad ; j <= lastbad ; j++) { double tmp = -sig_final->ve[j-firstbad] ; if(tmp > 1.0) clipped = TRUE ; if(tmp < -1.0) clipped = TRUE ; } if(clipped == FALSE) { for(j = firstbad ; j <= lastbad ; j++) { data[j] = -sig_final->ve[j-firstbad] ; if(data[j] > 1.0) data[j] = 1.0 ; if(data[j] < -1.0) data[j] = -1.0 ; } } if(clipped == FALSE) rcode = REPAIR_SUCCESS ; else rcode = REPAIR_CLIPPED ; } M_FREE(A) ; M_FREE(Au) ; M_FREE(Aut) ; M_FREE(AutmAu) ; M_FREE(iAutmAu) ; M_FREE(final) ; V_FREE(sig) ; V_FREE(sig_final) ; V_FREE(rhs) ; return rcode ; #else int n_bad = lastbad - firstbad + 1 ; int autolen = 60 ; int i, j, rows, cols ; int rcode ; gboolean clipped ; double x[100], auto_coefs[101] ; static gsl_matrix *A, *Au, *Aut, *AutmAu, *iAutmAu, *final ; static gsl_vector *rhs, *sig, *sig_final ; //estimate_region(data, firstbad, lastbad, siglen) ; //return REPAIR_SUCCESS ; autolen = (siglen-n_bad)/4 ; //autolen *= 2 ; if(autolen < 0) { d_print("Autolen < 0!\n") ; return REPAIR_FAILURE; } if(autolen > 3*n_bad) autolen = 3*n_bad ; if(autolen > 100) autolen = 100 ; //g_print("siglen:%d n_bad:%d Autolen:%d\n",siglen,n_bad,autolen) ; sig = gsl_vector_alloc(siglen) ; A = gsl_matrix_alloc(siglen-autolen, siglen) ; Au = gsl_matrix_alloc(siglen-autolen, n_bad) ; for(i = 0 ; i < siglen ; i++) gsl_vector_set(sig,i, data[i]) ; init_reg(autolen) ; for(i = autolen ; i < firstbad ; i++) { for(j = 0 ; j < autolen ; j++) x[j] = data[i - autolen + j] ; sum_reg(x, data[i]) ; } for(i = lastbad+autolen+1 ; i < siglen ; i++) { for(j = 0 ; j < autolen ; j++) x[j] = data[i - autolen + j] ; sum_reg(x, data[i]) ; } if(estimate_reg(auto_coefs) == 1) { rcode = SINGULAR_MATRIX ; } else { for(i = firstbad ; i <= lastbad ; i++) gsl_vector_set(sig,i,0.0) ; rows = siglen - autolen ; cols = siglen ; for(i = 0 ; i < rows ; i++) { for(j = 0 ; j < autolen ; j++) gsl_matrix_set(A,i,i+j,-auto_coefs[j]) ; gsl_matrix_set(A,i,i+autolen, 1.) ; for(j = firstbad ; j <= lastbad ; j++) gsl_matrix_set(A,i,j-firstbad, gsl_matrix_get(A,i,j)) ; } for(j = firstbad ; j <= lastbad ; j++) gsl_vector_set(sig,j, 0.0) ; Aut = gsl_transp(Au) ; rhs = gsl_mv_mlt(A,sig) ; AutmAu = gsl_m_mlt(Aut,Au) ; iAutmAu = gsl_m_inverse(AutmAu) ; final = gsl_m_mlt(iAutmAu,Aut) ; sig_final = gsl_mv_mlt(final,rhs) ; clipped = FALSE ; for(j = firstbad ; j <= lastbad ; j++) { double tmp = -gsl_vector_get(sig_final,j-firstbad) ; if(tmp > 1.0) clipped = TRUE ; if(tmp < -1.0) clipped = TRUE ; } if(clipped == FALSE) { for(j = firstbad ; j <= lastbad ; j++) { double tmp = -gsl_vector_get(sig_final,j-firstbad) ; if(data[j] > 1.0) data[j] = 1.0 ; if(data[j] < -1.0) data[j] = -1.0 ; } } if(clipped == FALSE) rcode = REPAIR_SUCCESS ; else rcode = REPAIR_CLIPPED ; } gsl_matrix_free(A) ; gsl_matrix_free(Au) ; gsl_matrix_free(Aut) ; gsl_matrix_free(AutmAu) ; gsl_matrix_free(iAutmAu) ; gsl_matrix_free(final) ; gsl_vector_free(sig) ; gsl_vector_free(sig_final) ; gsl_vector_free(rhs) ; return rcode ; #endif } #define DECLICK_CUBIC 0x01 #define DECLICK_LSAR 0x02 int declick_a_click(struct sound_prefs *p, long first_sample, long last_sample, int channel_mask) { long n_samples = last_sample - first_sample + 1; long first ; int ch, k, last ; int click_start, click_end ; int repair_method ; int FFT_SIZE ; int result = REPAIR_FAILURE ; fftw_real estimated[FFT_MAX*3], window_coef[FFT_MAX] ; fftw_real data[2][FFT_MAX] ; /* choose a repair strategy based on the length of the click */ if(n_samples < 1) { d_print("Whoa there, trying to declick %d samples!\n", n_samples) ; return 1 ; } else if(n_samples < 6) { /* cubic function -- interpolation */ first = first_sample-4 ; if(first < 0) first = 0 ; last = last_sample+4 ; if(last > p->n_samples-1) last = p->n_samples-1 ; repair_method = DECLICK_CUBIC ; } else { /* LSAR */ first = first_sample-200; if(first < 0) first = 0 ; last = last_sample+200; if(last > p->n_samples-1) last = p->n_samples-1 ; repair_method = DECLICK_LSAR ; } repair_method = DECLICK_LSAR ; FFT_SIZE = last-first+1 ; read_fft_real_wavefile_data(data[0], data[1], first, last) ; save_undo_data( first, last, p, FALSE) ; /* compute click starting and ending positions in the buffer data_all */ click_start = first_sample-first ; click_end = last_sample-first ; for(k = 0 ; k < FFT_SIZE ; k++) { window_coef[k] = blackman(k, FFT_SIZE) ; window_coef[k] = 1.0 ; } for(ch = 0 ; ch < 2 ; ch++) { if(channel_mask & (ch+1)) { if(repair_method == DECLICK_CUBIC) { fit_cubic(data[ch], FFT_SIZE, estimated) ; /* fit_trig_basis(data_all[ch], FFT_SIZE*3, windowed, click_start, click_end) ; */ /* merge results back into sample data based on window function */ for(k = 0 ; k < FFT_SIZE ; k++) { double w = window_coef[k] ; w = blackman(k, FFT_SIZE) ; w = blackman_hybrid(k, click_end-click_start+2, FFT_SIZE) ; data[ch][k] = (1.0-w) * data[ch][k] + w*estimated[k+FFT_SIZE] ; } } else result = lsar_sample_restore(data[ch], click_start, click_end, FFT_SIZE) ; } } write_fft_real_wavefile_data(data[0], data[1], first, last) ; return result ; } /* bj 10/2002 * WINDOW_SIZE = number of data points to read at a time * WINDOW_OVERLAP = number of data points to overlap between windows * (set this to maximum click size you think reasonable) * HPF_AVE_WING_BASE = number of points about current point (each side) * to use as baseline rms average * HPF_AVE_WING_LOCAL = number of points about current point (each side) * to average to get rms value for current point * HPF_DATA_WING = number of points about current point (each side) * required to get rms value for current point * (only change this if you change the hpf from 2nd * derivative to something else) * HPF_DELTA_WIDTH = number of previous points used as base to compare * current change in hpf. used to detect trailing * edge of a click */ #define WINDOW_SIZE 30000 #define HPF_AVE_WING_BASE 500 #define HPF_AVE_WING_LOCAL 8 #define HPF_DATA_WING 1 #define HPF_DELTA_WIDTH 50 #define WINDOW_OVERLAP 300 #define HPF_AVE_WIDTH_BASE (HPF_AVE_WING_BASE * 2 + 1) #define HPF_AVE_WIDTH_LOCAL (HPF_AVE_WING_LOCAL * 2 + 1) #define EXTRA_DATA_WING (HPF_AVE_WING_BASE + HPF_AVE_WING_LOCAL + HPF_DATA_WING) #define MAX_WINDOW_SIZE (WINDOW_SIZE + EXTRA_DATA_WING * 2) #define INC_POS(a,b,c) ( ((a)+(b)+(c)) % (c) ) /* maintain running sum of 2nd derivative rms so that we avoid excessive * calculation time. * 1) local rms value across small number of data points (HPF_AVE_WING_LOCAL * about current point) * 2) compare local rms value with HPF_AVE_WING_BASE local rms values about * current point * * Also used to get change in hpf near a point (pass in sample=-N as flag) * * do_declick runs backward thru data points, so this does too. * To get first real datapoint, have to run through (HPF_AVE_WIDTH_BASE * + HPF_AVE_WING_LOCAL) * 2 calculations first in order to fill up * the hpfl & hpfb arrays with correct rms values */ void get_hpf (long sample, fftw_real channel_data[], double *hpf, double *hpf_ave, double *hpf_dev) { static double hpfl[HPF_AVE_WIDTH_LOCAL]; static double suml; static int posl; static double hpfb[HPF_AVE_WIDTH_BASE]; static double sumb; static int posb; /* if real sample, get next hpf value into array */ if (sample >= 0) { fftw_real *data = &channel_data[sample - (HPF_AVE_WING_BASE+HPF_AVE_WING_LOCAL)]; posl = INC_POS(posl,-1,HPF_AVE_WIDTH_LOCAL); posb = INC_POS(posb,-1,HPF_AVE_WIDTH_BASE); /* get updated sum of rms values of actual data points * and get updated sum of local average of rms values */ suml -= hpfl[posl]; hpfl[posl] = data[-1] - 2. * data[0] + data[1]; hpfl[posl] *= hpfl[posl]; suml += hpfl[posl]; /* bugfix -- thanks Paul Sanders 1/12/2007 */ *hpf = (suml > 0.0) ? sqrt(suml/(HPF_AVE_WIDTH_LOCAL-2)) : 0.0 ; sumb -= hpfb[posb]; hpfb[posb] = *hpf; sumb += *hpf; *hpf_ave = sumb / HPF_AVE_WIDTH_BASE; /* hpf of current point was read in a while back; * retrieve that value now */ *hpf = hpfb[INC_POS(posb,HPF_AVE_WING_BASE,HPF_AVE_WIDTH_BASE)]; } /* negative sample; get change in hpf */ else { int posF, pos0, n = -sample; double x = 0, sumx = 0, sumx2 = 0; pos0 = INC_POS(posb,HPF_AVE_WING_BASE+n,HPF_AVE_WIDTH_BASE); while (sample < 0) { posF = INC_POS(pos0,-2,HPF_AVE_WIDTH_BASE); x = hpfb[posF] - hpfb[pos0]; sumx += x; sumx2 += x*x; pos0 = INC_POS(pos0,-1,HPF_AVE_WIDTH_BASE); sample++; } *hpf = x; /* last value in x is value at "current" position */ *hpf_ave = sumx / n; *hpf_dev = sqrt((sumx2 - sumx*sumx/n)/(n-1)); } } /* bj 10/2002 end, but several changes in do_declick also */ char *do_declick(struct sound_prefs *p, long first_sample, long last_sample, int channel_mask, double sensitivity, int repair, struct click_data *clicks, int iterate_flag, int leave_click_marks) { extern int declick_detector_type ; if(declick_detector_type == FFT_DETECT) return do_declick_fft(p,first_sample,last_sample,channel_mask,sensitivity,repair,clicks,iterate_flag,leave_click_marks) ; else return do_declick_hpf(p,first_sample,last_sample,channel_mask,sensitivity,repair,clicks,iterate_flag,leave_click_marks) ; } #define DECLICK_MAX_FFT 128 char *do_declick_fft(struct sound_prefs *p, long first_sample, long last_sample, int channel_mask, double sensitivity, int repair, struct click_data *clicks, int iterate_flag, int leave_click_marks) { static char results_buf[200] ; long window_first ; long i,k ; int FFT_SIZE = 64 ; int n_repaired[2] , n_this_pass ; int n_not_repaired[2] ; char max_exceeded_notice = 0 ; #define FFT_WINDOW 1000 char level[2][2*FFT_WINDOW+1][DECLICK_MAX_FFT] ; #ifdef HAVE_FFTW3 FFTW(plan) pLeft, pRight ; #else /* HAVE_FFTW3 */ rfftw_plan fftw_p ; #endif /* HAVE_FFTW3 */ fftw_real data[2][2*FFT_WINDOW+1] ; fftw_real out[2*DECLICK_MAX_FFT] ; fftw_real window[2*DECLICK_MAX_FFT] ; fftw_real power_spectrum[2*DECLICK_MAX_FFT] ; int in_click ; int window_size = FFT_WINDOW * MIN((p->rate/44100.0),2) ; int window_step ; int channel ; int done = 0 ; if(last_sample > p->n_samples-20) last_sample = p->n_samples-20 ; if(first_sample < 20) first_sample = 20 ; if(first_sample >= last_sample) { return "Region to small to declick." ; } start_timer(); if(repair == FALSE || leave_click_marks == FALSE) clicks->n_clicks = 0 ; n_repaired[0] = n_repaired[1] = 0 ; n_not_repaired[0] = n_not_repaired[1] = 0 ; window_step = 700 ; window_size = 801 ; g_print("Declick_fft first_sample:%ld last_sample:%ld window_size:%d\n", first_sample, last_sample, window_size) ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; #ifdef HAVE_FFTW3 pLeft = FFTW(plan_r2r_1d)(FFT_SIZE, data[0], out, FFTW_R2HC, FFTW_ESTIMATE); pRight = FFTW(plan_r2r_1d)(FFT_SIZE, data[1], out, FFTW_R2HC, FFTW_ESTIMATE); #else /* HAVE_FFTW3 */ fftw_p = rfftw_create_plan(FFT_SIZE, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); #endif /* HAVE_FFTW3 */ for(k = 0 ; k < FFT_SIZE ; k++) { window[k] = blackman(k,FFT_SIZE) ; } for(window_first = first_sample ; !done && window_first < last_sample ; window_first += window_step ) { int clicks_repaired = 1 ; int min_sample,max_sample ; if(window_first + window_size > last_sample) { window_first = last_sample - window_size ; done = 1 ; } double percentage = (double)(window_first-first_sample)/(double)(last_sample-first_sample) ; update_progress_bar(percentage,PROGRESS_UPDATE_INTERVAL,FALSE) ; for(i=0 ; i < window_size ; i += 2) { min_sample = i+window_first-FFT_SIZE/2 ; min_sample = MAX(0, min_sample) ; max_sample = min_sample+FFT_SIZE-1 ; if(max_sample > p->n_samples-1) max_sample = p->n_samples-1 ; read_fft_real_wavefile_data(data[0], data[1], min_sample, max_sample) ; for(k = 0 ; k < FFT_SIZE ; k++) { data[0][k] *= window[k] ; data[1][k] *= window[k] ; } for (channel = 0; channel < 2; channel++) { double min_p = 1.e30, max_p = -1.e30 ; if(! ((channel+1) & channel_mask) ) continue ; #ifdef HAVE_FFTW3 if (channel == 0) FFTW(execute)(pLeft); else FFTW(execute)(pRight); #else /* HAVE_FFTW3 */ if (channel == 0) rfftw_one(fftw_p, data[0], out); else rfftw_one(fftw_p, data[1], out); #endif /* HAVE_FFTW3 */ power_spectrum[0] = out[0]*out[0]; /* DC component */ for (k = 1; k < (FFT_SIZE+1)/2; ++k) /* (k < FFT_SIZE/2 rounded up) */ power_spectrum[k] = out[k]*out[k] + out[FFT_SIZE-k]*out[FFT_SIZE-k]; if (FFT_SIZE % 2 == 0) /* N is even */ power_spectrum[FFT_SIZE/2] = (out[FFT_SIZE/2]*out[FFT_SIZE/2]); /* Nyquist freq. */ for(k = 1 ; k <= FFT_SIZE/2 ; k++) { double p = 10.0*log10(power_spectrum[k]) ; if(p < -127.0) p = -127.0 ; if(p > 127.0) p = 127.0 ; if(p > max_p) max_p = p ; if(p < min_p) min_p = p ; level[channel][i][k-1] = (char)p ; } } } for(channel = 0 ; channel < 2 ; channel++) { double mean_level[FFT_SIZE] ; double offset[FFT_WINDOW*2+1] ; double hgt_sum = 0 ; double mean, std_err, var, cv, stddev ; long click_start = 0 ; if(! ((channel+1) & channel_mask) ) continue ; for(k = 0 ; k < FFT_SIZE/2 ; k++) { mean_level[k] = 0.0 ; for(i = 0 ; i < window_size ; i += 2) mean_level[k] += level[channel][i][k] ; mean_level[k] /= (double)window_size ; } for(i = 0 ; i < window_size ; i += 2) { offset[i] = 0.0 ; for(k = 0 ; k < FFT_SIZE/2 ; k++) { offset[i] += level[channel][i][k] - mean_level[k] ; } offset[i] /= (double)FFT_SIZE/2.0 ; } for(i = 1 ; i < window_size ; i += 2) { offset[i] = (offset[i-1]+offset[i+1])/2.0 ; } /* for(i = 0 ; i < window_size ; i++) { */ /* if(offset[i] < 0.0) offset[i] = 0.0 ; */ /* } */ stats(offset, window_size, &mean, &std_err, &var, &cv, &stddev) ; in_click = 0 ; for(i = 0 ; i < window_size ; i++) { //double z = (offset[i]-mean)/stddev ; double z = (offset[i]-mean) ; //printf("i:%d z:%lg\n", i, z) ; if(z < 0.0) z = 0.0 ; if(z > 1.e-30) { if(!in_click) { in_click = 1 ; click_start = i+window_first ; hgt_sum = z ; } else { hgt_sum += z ; } } else { if(in_click) { int click_end = i-1+window_first; double click_width = (click_end - click_start+1) ; int click_mid = (click_start + click_width/2+0.5) ; int result = DETECT_ONLY ; double mean_hgt = hgt_sum / click_width ; if(click_width > 8) { click_start += click_width/4.0+0.5 ; /* leave the end, more audio artifacts there that need fixed */ /* click_end -= click_width/4.0+0.5 ; */ click_width = (click_end - click_start+1) ; } if(mean_hgt > sensitivity && click_width < 100) { printf("%d %d %lg\n", channel, click_mid, mean_hgt) ; if(repair == TRUE) { result = declick_a_click(p, click_start, click_end, channel+1) ; if(result == SINGULAR_MATRIX) { click_start -= 10 ; click_end += 10 ; click_start = MAX(0, click_start) ; click_end = MIN(p->n_samples, click_start) ; result = declick_a_click(p, click_start, click_end, channel+1) ; } } } else { result = REPAIR_OOB ; } if(result == REPAIR_OOB) { } else if(result != REPAIR_SUCCESS) { if(clicks->n_clicks < clicks->max_clicks) { clicks->start[clicks->n_clicks] = click_start ; clicks->end[clicks->n_clicks] = click_end ; clicks->channel[clicks->n_clicks] = channel ; clicks->n_clicks++ ; } else { if( max_exceeded_notice == 0) { warning("Exceeded 1000 clicks in selection, additional detections not marked") ; max_exceeded_notice = 1 ; } } n_not_repaired[channel]++ ; } else { n_repaired[channel]++ ; n_this_pass ++ ; clicks_repaired = 1 ; } } in_click = 0 ; } } } } #ifdef HAVE_FFTW3 FFTW(destroy_plan)(pLeft); FFTW(destroy_plan)(pRight); #else /* HAVE_FFTW3 */ rfftw_destroy_plan(fftw_p); #endif /* HAVE_FFTW3 */ { sprintf(results_buf, "%d clicks repaired, %d clicks marked, but remain unrepaired", n_repaired[0] + n_repaired[1], n_not_repaired[0] + n_not_repaired[1]) ; g_print("%s\n",results_buf); stop_timer("DECLICK"); /* warning(results_buf) ; */ } update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; return results_buf ; } char *do_declick_hpf(struct sound_prefs *p, long first_sample, long last_sample, int channel_mask, double sensitivity, int repair, struct click_data *clicks, int iterate_flag, int leave_click_marks) { static char results_buf[200] ; long min_sample, max_sample ; long sample ; long window_first ; long i ; long n_samples = last_sample - first_sample + 1 ; int n_repaired[2] , n_this_pass, n_last_pass; int n_not_repaired[2] ; int n ; int offset0,offsetF; char max_exceeded_notice = 0 ; fftw_real left[2*MAX_WINDOW_SIZE+1], right[2*MAX_WINDOW_SIZE+1], *pdata[2] ; double hpf, hpf_ave, hpf_dev; int in_click ; int window_size = MAX_WINDOW_SIZE * MIN((p->rate/44100.0),2) ; int window_overlap = WINDOW_OVERLAP * MIN((p->rate/44100.0),2) ; int window_step ; int channel ; if(last_sample > p->n_samples-20) last_sample = p->n_samples-20 ; if(first_sample < 20) first_sample = 20 ; if(first_sample >= last_sample) { return "Region to small to declick." ; } start_timer(); if(repair == FALSE || leave_click_marks == FALSE) clicks->n_clicks = 0 ; n_repaired[0] = n_repaired[1] = 0 ; n_not_repaired[0] = n_not_repaired[1] = 0 ; if(window_size > n_samples + 2 * EXTRA_DATA_WING) window_size = n_samples + 2 * EXTRA_DATA_WING; if (p->n_samples < EXTRA_DATA_WING+1) return "Audio file too small."; window_step = window_size - 2*EXTRA_DATA_WING - window_overlap ; if (window_step < 1) {window_step = window_size;} //g_print("Declick first_sample:%ld last_sample:%ld window_size:%d\n", first_sample, last_sample, window_size) ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; for(window_first = first_sample ; window_first < last_sample ; window_first += window_step ) { int nclicks_not_repaired_start = clicks->n_clicks ; int clicks_repaired = 1 ; int loop_flag = 1 ; double percentage = (double)(window_first-first_sample)/(double)(last_sample-first_sample) ; update_progress_bar(percentage,PROGRESS_UPDATE_INTERVAL,FALSE) ; n_last_pass = INT_MAX; while(loop_flag) { clicks->n_clicks = nclicks_not_repaired_start ; clicks_repaired = 0 ; n_this_pass = 0 ; /* read some to the left & right of our window so that we can get * local averages even at the ends of our window */ min_sample = window_first - EXTRA_DATA_WING; offset0 = -MIN(min_sample,0); min_sample += offset0; max_sample = window_first + window_size-1 - EXTRA_DATA_WING; offsetF = MAX(max_sample - p->n_samples+1,0); max_sample -= offsetF; offsetF = MIN(offsetF,EXTRA_DATA_WING); n = read_fft_real_wavefile_data(&left[offset0], &right[offset0], min_sample, max_sample); /* Now fill in any gaps; if we were too close to sample 0, mirror about zero and if too close to the last sample, mirror about last sample */ for (i = 1; i <= offset0; i++) { left[offset0-i] = -left[offset0+i]; right[offset0-i] = -right[offset0+i]; } sample = offset0 + n - 1; for (i = 1; i <= offsetF; i++) { left[sample+i] = -left[sample-i]; right[sample+i] = -right[sample-i]; } /* set up arrays where element 0 is window_first sample */ pdata[0] = &left[EXTRA_DATA_WING]; pdata[1] = &right[EXTRA_DATA_WING]; for(channel = 0 ; channel < 2 ; channel++) { long click_start, click_end=0 ; if(! ((channel+1) & channel_mask) ) continue ; in_click = 0 ; sample = offset0 + n-1 + offsetF - HPF_DATA_WING * 2; for(i = sample; i >= 0 ; i--) { get_hpf(i,pdata[channel],&hpf,&hpf_ave,&hpf_dev); if(i <= sample - 2*(HPF_AVE_WING_BASE+HPF_AVE_WING_LOCAL)) { int sample_is_in_click = 0 ; if(hpf > 2.0*hpf_ave/sensitivity) sample_is_in_click = 1 ; #define test_clicks_as_dB 1 if(test_clicks_as_dB) { sample_is_in_click = 0 ; if(10.0*log10(hpf/hpf_ave) > sensitivity) sample_is_in_click = 1 ; } if(in_click == 0 && sample_is_in_click) { get_hpf(-HPF_DELTA_WIDTH,pdata[channel],&hpf,&hpf_ave,&hpf_dev); if (hpf > 2. * hpf_dev/sensitivity + hpf_ave) { in_click = 1 ; click_end = window_first + i ; } } else if(in_click == 1 && !sample_is_in_click) { long width ; int result = DETECT_ONLY ; click_start = window_first+i ; width = click_end - click_start ; /* click_start -= width ; */ /* click_end += width ; */ if(click_start < 0) click_start = 0 ; if(click_end > p->n_samples) click_end = p->n_samples ; if(click_start >= first_sample && click_end <= last_sample) { if(repair == TRUE) { //g_print("Repairing %s start:%ld end:%ld\n", channel == 0 ? "left" : "right", click_start, click_end) ; /* push_status_text("Repairing a click") ; */ /* update_progress_bar(percentage,PROGRESS_UPDATE_INTERVAL,TRUE) ; */ result = declick_a_click(p, click_start, click_end, channel+1) ; if(result == SINGULAR_MATRIX) { click_start -= 10 ; click_end += 10 ; click_start = MAX(0, click_start) ; click_end = MIN(p->n_samples, click_start) ; result = declick_a_click(p, click_start, click_end, channel+1) ; } /* pop_status_text() ; */ /* update_progress_bar(percentage,PROGRESS_UPDATE_INTERVAL,TRUE) ; */ } } else { result = REPAIR_OOB ; } if(result == REPAIR_OOB) { } else if(result != REPAIR_SUCCESS) { if(clicks->n_clicks < clicks->max_clicks) { clicks->start[clicks->n_clicks] = click_start ; clicks->end[clicks->n_clicks] = click_end ; clicks->channel[clicks->n_clicks] = channel ; clicks->n_clicks++ ; } else { if( max_exceeded_notice == 0) { warning("Exceeded 1000 clicks in selection, additional detections not marked") ; max_exceeded_notice = 1 ; } } n_not_repaired[channel]++ ; } else { n_repaired[channel]++ ; n_this_pass ++ ; clicks_repaired = 1 ; } in_click = 0 ; } /* if (in_click... */ } /* if (sample <= ... */ } /* for (...sample... */ /* bj 10/30/02 if in middle of click at window_first, mark it * as not repaired */ if (in_click && clicks->n_clicks < clicks->max_clicks) { clicks->start[clicks->n_clicks] = window_first; clicks->end[clicks->n_clicks] = click_end; clicks->channel[clicks->n_clicks] = channel; clicks->n_clicks++; n_not_repaired[channel]++; } } /* for (channel... */ /* stopping criteria for this declick window */ loop_flag = 0 ; if(iterate_flag && clicks_repaired && n_this_pass < n_last_pass) loop_flag = 1 ; n_last_pass = n_this_pass; } /* while (loop_flag) */ } /* for (window_first... */ d_print("channel_mask: %d\n", channel_mask) ; { sprintf(results_buf, "%d clicks repaired, %d clicks marked, but remain unrepaired", n_repaired[0] + n_repaired[1], n_not_repaired[0] + n_not_repaired[1]) ; g_print("%s\n",results_buf); stop_timer("DECLICK"); /* warning(results_buf) ; */ } update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; return results_buf ; } void fit_cubic(fftw_real data[], int n, fftw_real estimated[]) { int one_fourth = n / 4 ; int leftmin = 0 ; int leftmax = leftmin + (one_fourth-1) ; int rightmax = n-1 ; int rightmin = rightmax - (one_fourth-1) ; int n_sel = leftmax-leftmin + rightmax - rightmin + 2 ; if(n_sel < 3 ) { double B[2] ; int i ; double x[1] ; init_reg(1) ; for(i = leftmin ; i <= leftmax ; i++) { x[0] = i ; sum_reg(x, data[i]) ; } for(i = rightmin ; i <= rightmax ; i++) { x[0] = i ; sum_reg(x, data[i]) ; } estimate_reg(B) ; for(i = leftmin ; i <= rightmax ; i++) estimated[i] = B[0] +B[1]*i ; return ; } if(n_sel < 4) { double B[3] ; int i ; double x[2] ; init_reg(2) ; for(i = leftmin ; i <= leftmax ; i++) { x[0] = i ; x[1] = i*i ; sum_reg(x, data[i]) ; } for(i = rightmin ; i <= rightmax ; i++) { x[0] = i ; x[1] = i*i ; sum_reg(x, data[i]) ; } estimate_reg(B) ; for(i = leftmin ; i <= rightmax ; i++) estimated[i] = B[0] +B[1]*i +B[2]*i*i ; return ; } if(1) { double B[4] ; int i ; double x[3] ; init_reg(3) ; for(i = leftmin ; i <= leftmax ; i++) { x[0] = i ; x[1] = i*i ; x[2] = i*i*i ; sum_reg(x, data[i]) ; } for(i = rightmin ; i <= rightmax ; i++) { x[0] = i ; x[1] = i*i ; x[2] = i*i*i ; sum_reg(x, data[i]) ; } estimate_reg(B) ; for(i = leftmin ; i <= rightmax ; i++) estimated[i] = B[0] +B[1]*i + B[2]*i*i + B[3]*i*i*i ; } } gtk-wave-cleaner-0.22-04/decrackle.c0000666000175000017500000001155613450764342020307 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* decrackle.c */ #include #include "gwc.h" int do_decrackle(struct sound_prefs *pPrefs, long first_sample, long last_sample, int channel_mask, double factor, gint nmax, gint width) { long i ; long current ; long final, last_read ; long n ; int ch ; double scaled_factor, absum ; fftw_real *y[2], *y_hat[2], *y_hat_tmp; int *cflag /*[ASIZE]*/, asize ; int scount; asize=nmax+2*width; for (ch = 0; ch < 2; ch++) { y[ch] = calloc(asize, sizeof(fftw_real)); y_hat[ch] = calloc(asize, sizeof(fftw_real)); } y_hat_tmp = calloc(asize, sizeof(fftw_real)); cflag = calloc(asize, sizeof(int)); /* scaled_factor = factor * pPrefs -> max_allowed; */ push_status_text("Decrackling audio") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; for (current = first_sample; current < last_sample; current += nmax) { gfloat p = (gfloat)(current-first_sample)/ (gfloat)(last_sample-first_sample) ; update_progress_bar(p,PROGRESS_UPDATE_INTERVAL,FALSE) ; final = current+nmax-1; if (final > last_sample) final=last_sample; last_read = final+width; if (last_read >= pPrefs -> n_samples) last_read = pPrefs -> n_samples - 1; /* printf ("[%d - %d], start @ %d, end @ %d (%d)\n", */ /* first_sample, last_sample, current, final, last_read); */ /* printf ("%d %d %d\n", pPrefs->n_samples, pPrefs->bits, pPrefs->stereo); */ n = read_fft_real_wavefile_data(y[0]+width, y[1]+width, current, last_read); /* printf ("Got %d samples\n", n); */ /* Fill anything beyond the end of the file with zeros */ if (n < final + width + 1 - current) { /* printf ("Filling\n"); */ for (i = current+n; i <= final; i++) { for (ch = 0; ch < 2; ch ++) { y[ch][i] = 0.; } } /* printf ("Filled\n"); */ } for(ch = 0 ; ch < 2 ; ch++) { if((ch+1) & channel_mask) { scount = 0 ; absum = 0. ; for (i = width+1; i scaled_factor) { cflag[i-1]=1; } else if(dy2dx < -scaled_factor) { cflag[i-1]=1; } else { cflag[i-1]=0; } } } for(i = width ; i < n ; i++) { int first, last, j; int w = width ; int flag =0; double sum = 0.0 ; double sumwgt = 0.0 ; first = i-w ; if(first < 0) { first = 0 ; printf("first < 0\n"); } last = i+w ; if(last > asize-1) { last = asize-1 ; printf("last > asize\n"); } for(j = first ; j <= last ; j++) { sum += y_hat[ch][j]; sumwgt ++; } flag = cflag[i-1] | cflag[i] | cflag[i+1]; if (cflag[i]) { y_hat_tmp[i] = sum/sumwgt ; } else if (flag) { y_hat_tmp[i] = (sum/sumwgt+ y_hat[ch][i])/2.; } else { y_hat_tmp[i] = y_hat[ch][i] ; } } for(i = 0 ; i < n+width ; i++) { y_hat[ch][i] = y_hat_tmp[i] ; } } else { for(i = 0 ; i < n+width ; i++) { y_hat[ch][i] = y[ch][i] ; } } } write_fft_real_wavefile_data(y_hat[0]+width, y_hat[1]+width, current, final) ; /* Copy the last width points of this window to the "pre-window" of the next window */ for (i = 0; i < width; i++) { for (ch = 0; ch < 2; ch ++) { y_hat[ch][i] = y_hat[ch][i+n-width]; y[ch][i] = y[ch][i+n-width]; } } } update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; main_redraw(FALSE, TRUE) ; for (ch = 0; ch < 2; ch++) { free(y[ch]) ; free(y_hat[ch]); } free(y_hat_tmp); free(cflag); return 0; } gtk-wave-cleaner-0.22-04/denoise.c0000666000175000017500000010521513450764342020014 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* denoise.c */ #include #include "gwc.h" #include #include #include #include //struct timeb start_time, middle_time, end_time ; struct timeval start_time, middle_time, end_time ; struct timezone tzp; void start_timer(void) { gettimeofday(&start_time,&tzp); } void stop_timer(char *message) { gettimeofday(&end_time,&tzp) ; { double fstart = start_time.tv_sec + (double)start_time.tv_usec/1000000.0 ; double fend = end_time.tv_sec + (double)end_time.tv_usec/1000000.0 ; fprintf(stderr, "%s in %7.3lf real seconds\n", message, fend-fstart) ; } } #ifdef OLD_TIMER struct timeb start_time, middle_time, end_time ; void start_timer(void) { ftime(&start_time) ; } void stop_timer(char *message) { ftime(&end_time) ; { double fstart = start_time.time + (double)start_time.millitm/1000.0 ; double fend = end_time.time + (double)end_time.millitm/1000.0 ; fprintf(stderr, "%s in %7.3lf real seconds\n", message, fend-fstart) ; } } #endif double bark_z[DENOISE_MAX_FFT] ; double window_coef[DENOISE_MAX_FFT] ; double sum_window_wgts[DENOISE_MAX_FFT] ; double jg_upper[DENOISE_MAX_FFT][11] ; double jg_lower[DENOISE_MAX_FFT][11] ; /* double *two_way_probs[DENOISE_MAX_FFT] ; */ void compute_bark_z(int FFT_SIZE, int rate) { int k ; /* compute the bark z value for this frequency bin */ for(k = 1 ; k <= FFT_SIZE/2 ; k++) { double freq = (double)rate / 2.0 /(double)(FFT_SIZE/2)*(double)k ; bark_z[k] = 7.0*log(freq/650.0 + sqrt(1 + (freq/650.0)*(freq/650.0))) ; } } void compute_johnston_gain(int FFT_SIZE, double tonality_factor) { int k ; for (k = 1; k <= FFT_SIZE/2 ; ++k) { int j ; for(j = k-1 ; j > 0 ; j--) { double bark_diff = bark_z[k] - bark_z[j] ; double johnston = 15.81 + 7.5*(bark_diff+.474) - 17.5*sqrt(1.0+(bark_diff+0.474)*(bark_diff+0.474)) ; double johnston_masked = johnston - (tonality_factor*(14.5+bark_z[j])+5.5*(1.0 - tonality_factor)) ; double gain = pow(10.0, johnston_masked/10.0) ; jg_lower[k][k-j] = gain ; if(k - j > 10) break ; } for(j = k ; j <= FFT_SIZE/2 ; j++) { double bark_diff = bark_z[j] - bark_z[k] ; double johnston = 15.81 + 7.5*(bark_diff+.474) - 17.5*sqrt(1.0+(bark_diff+0.474)*(bark_diff+0.474)) ; double johnston_masked = johnston - (tonality_factor*(14.5+bark_z[j])+5.5*(1.0 - tonality_factor)) ; double gain = pow(10.0, johnston_masked/10.0) ; jg_upper[k][j-k] = gain ; if(j - k > 10) break ; } } } int get_window_delta(struct denoise_prefs *pDnprefs) { if(pDnprefs->window_type == DENOISE_WINDOW_HANNING_OVERLAP_ADD) { return pDnprefs->FFT_SIZE/2 ; #ifdef DENOISE_TRY_ONE_SAMPLE } else if(pDnprefs->window_type == DENOISE_WINDOW_ONE_SAMPLE) { return 1 ; #endif } else { if(pDnprefs->window_type == DENOISE_WINDOW_BLACKMAN) return pDnprefs->FFT_SIZE/pDnprefs->smoothness ; else return 3*pDnprefs->FFT_SIZE/4 ; } } void compute_sum_window_wgts(struct denoise_prefs *pDnprefs) { int delta = get_window_delta(pDnprefs) ; int i, k ; for(i = 0 ; i < pDnprefs->FFT_SIZE ; i++) { sum_window_wgts[i] = 0.0 ; for(k = i ; k < pDnprefs->FFT_SIZE+i ; k += delta) { sum_window_wgts[i] += window_coef[k%pDnprefs->FFT_SIZE] ; } } /* for(i = 0 ; i < pDnprefs->FFT_SIZE ; i++) { */ /* g_print("i:%d sww:%lf\n", i, sum_window_wgts[i]) ; */ /* } */ } double gain_weiner(double Yk2, double Dk2) { double gain ; double Xk2 = Yk2 - Dk2 ; if(Yk2 > Dk2) gain = (Xk2) / (Xk2+Dk2) ; else gain = 0.0 ; return gain ; } double gain_power_subtraction(double Yk2, double Dk2) { double level = MAX(Yk2-Dk2, 0.0) ; if(Yk2 > DBL_MIN) return level/Yk2 ; else return 0.0 ; } double alpha_lorber(double snr) { double snr_db = 10.*log10(snr) ; double alpha ; if(snr_db > 20) return 1.0 ; alpha = MIN((3.0 - 0.10*snr_db), 3.5) ; return alpha ; } #define SLOW_EM #ifdef SLOW_EM double hypergeom(double theta) { double i0(double), i1(double) ; if(theta < 7.389056) return exp(-theta/2.0)*(1.0+theta*i0(theta/2.0)+theta*i1(theta/2.0)) ; else return exp(0.09379 + 0.50447*log(theta)) ; } double gain_em(double Rprio, double Rpost, double alpha) { /* Ephraim-Malah classic noise suppression, from 1984 paper */ double gain = 0.886226925*sqrt(1.0/(1.0+Rpost)*(Rprio/(1.0+Rprio))) ; gain *= hypergeom((1.0+Rpost)*(Rprio/(1.0+Rprio))) ; return gain ; } #else double gain_em(double Rprio, double Rpost, double alpha) { /* Ephraim-Malah noise suppression, from Godsill and Wolfe 2001 paper */ double r = MAX(Rprio/(1.0+Rprio),DBL_MIN) ; double V = Rprio/(1.+Rprio)*Rpost ; return sqrt( r * (1.0+V)/Rpost ) ; } #endif double blackman(int k, int N) { double p = ((double)(k))/(double)(N-1) ; return 0.42-0.5*cos(2.0*M_PI*p) + 0.08*cos(4.0*M_PI*p) ; } double hanning(int k, int N) { double p = ((double)(k))/(double)(N-1) ; return 0.5 - 0.5 * cos(2.0*M_PI*p) ; } double blackman_hybrid(int k, int n_flat, int N) { if(k >= (N-n_flat)/2 && k <= n_flat+(N-n_flat)/2-1) { return 1.0 ; } else { double p ; if(k >= n_flat+(N-n_flat)/2-1) k -= n_flat ; p = (double)(k)/(double)(N-n_flat-1) ; return 0.42-0.5*cos(2.0*M_PI*p) + 0.08*cos(4.0*M_PI*p) ; } } double welty_alpha(double w, double x) { double alpha = ( log(acos(-2.0*w+1)) - log(M_PI) ) / log(1.0 - x) ; /* d_print("Welty alpha=%g\n", alpha) ; */ return alpha ; } /* double welty(int k, int N, double alpha) */ /* { */ /* double n2 = (double)N/2.0 ; */ /* double x = fabs(((double)k - n2) / (n2)) ; */ /* double tx = pow(1.0-x, alpha)*M_PI ; */ /* double w = -( cos(tx)-1.0 )/2.0 ; */ /* d_print("Welty x=%g, w=%g, k=%d N=%d\n", x, w, k, N) ; */ /* } */ double fft_window(int k, int N, int window_type) { if(window_type == DENOISE_WINDOW_BLACKMAN) { return blackman(k, N) ; } else if(window_type == DENOISE_WINDOW_BLACKMAN_HYBRID) { return blackman_hybrid(k, N-N/4, N) ; #ifdef DENOISE_TRY_ONE_SAMPLE } else if(window_type == DENOISE_WINDOW_ONE_SAMPLE) { return hanning(k, N) ; #endif } else if(window_type == DENOISE_WINDOW_HANNING_OVERLAP_ADD) { return hanning(k, N) ; } return 0.0 ; } double db2w(double db) { return pow(10,db/10) ; } double ceramic_mic_response(double f) { double db = 0.0 ; if(f < 4000.0) { db = 0.0 ; } else if(f < 7000.0) { db = (f-4000.0)/7000.0*2.0 ; } else if(f < 20000.0) { db = 2.0 - ((f-7000.0)/13000.0)*12.0 ; } else { db = -10.0 ; } return db2w(db) ; } void cdivide(double *a, double *b, double c, double d) { double denom = (c*c + d*d) ; double anew, bnew ; if(denom < 1.e-60) { *a = 0.0 ; *b = 0.0 ; return ; } anew = (*a*c + *b*d) / denom ; bnew = (*b*c - *a*d) / denom ; } #define bin2freq(r,s,k) ((double)r / 2.0 /(double)(s/2)*(double)k) int prev_sample[2] ; static fftw_real windowed[DENOISE_MAX_FFT] ; static fftw_real out[DENOISE_MAX_FFT] ; #ifdef HAVE_FFTW3 static void fft_remove_noise(fftw_real sample[], fftw_real noise_min2[], fftw_real noise_max2[], fftw_real noise_avg2[], FFTW(plan) *pFor, FFTW(plan) *pBak, #else /* HAVE_FFTW3 */ void fft_remove_noise(fftw_real sample[], fftw_real noise_min2[], fftw_real noise_max2[], fftw_real noise_avg2[], rfftw_plan *pFor, rfftw_plan *pBak, #endif /* HAVE_FFTW3 */ struct denoise_prefs *pPrefs, int ch) { int k ; fftw_real noise2[DENOISE_MAX_FFT/2+1] ; fftw_real noise[DENOISE_MAX_FFT/2+1] ; fftw_real Y2[DENOISE_MAX_FFT/2+1] ; fftw_real Y[DENOISE_MAX_FFT/2+1] ; fftw_real masked[DENOISE_MAX_FFT/2+1] ; fftw_real gain_k[DENOISE_MAX_FFT] ; static fftw_real bsig_prev[2][DENOISE_MAX_FFT],bY2_prev[2][DENOISE_MAX_FFT/2+1],bgain_prev[2][DENOISE_MAX_FFT/2+1] ; fftw_real *sig_prev,*Y2_prev,*gain_prev ; static int debug_frame = 1 ; double SFM, tonality_factor ; sig_prev = bsig_prev[ch] ; Y2_prev = bY2_prev[ch] ; gain_prev = bgain_prev[ch] ; if(0 || pPrefs->window_type == DENOISE_WINDOW_HANNING_OVERLAP_ADD) { /* with overlap-add pre-window the sample */ for(k = 0 ; k < pPrefs->FFT_SIZE ; k++) { windowed[k] = sample[k]*window_coef[k] ; //if(debug_frame == 3) g_print("k:%d window_coef:%lf windowed:%lf\n", k, window_coef[k], windowed[k]) ; } } else { /* with other methods don't window the sample for FFT, but window the result back into the original sample the FFT noise-removal process */ for(k = 0 ; k < pPrefs->FFT_SIZE ; k++) { windowed[k] = sample[k] ; } } #ifdef HAVE_FFTW3 FFTW(execute)(*pFor); #else /* HAVE_FFTW3 */ rfftw_one(*pFor, windowed, out); #endif /* HAVE_FFTW3 */ { double sum_log_p = 0.0 ; double sum_p = 0.0 ; double kinv = 1./(double)(pPrefs->FFT_SIZE/2.0) ; for (k = 1; k <= pPrefs->FFT_SIZE/2 ; ++k) { noise2[k] = noise_max2[k] ; noise2[k] = noise_min2[k] + 0.5*(noise_max2[k] - noise_min2[k]) ; noise2[k] = noise_avg2[k] ; noise[k] = sqrt(noise2[k]) ; if(k < pPrefs->FFT_SIZE/2) { Y2[k] = out[k]*out[k] + out[pPrefs->FFT_SIZE-k]*out[pPrefs->FFT_SIZE-k] ; Y[k] = sqrt(Y2[k]) ; } else { Y2[k] = out[k]*out[k] ; Y[k] = out[k] ; } sum_log_p += log10(Y2[k]) ; sum_p += Y2[k] ; } SFM = 10.0*( kinv*sum_log_p - log10(sum_p*kinv) ) ; tonality_factor = MIN(SFM/-60.0, 1) ; } if(pPrefs->noise_suppression_method == DENOISE_LORBER) tonality_factor = 0.0 ; /* g_print("SFM:%f tonality:%lf\n", SFM, tonality_factor) ; */ if(pPrefs->noise_suppression_method == DENOISE_LORBER) { for (k = 1; k <= pPrefs->FFT_SIZE/2 ; ++k) { double sum = 0 ; double sum_wgts = 0 ; int j ; int j1 = MAX(k-10,1) ; int j2 = MIN(k+10,pPrefs->FFT_SIZE/2) ; for(j = j1 ; j <= j2 ; j++) { double d = ABS(j-k)+1.0 ; double wgt = 1./sqrt(d) ; sum += Y2[j]*wgt ; sum_wgts += wgt ; } masked[k] = sum / (sum_wgts+1.e-300) ; } } /* if(pPrefs->noise_suppression_method == DENOISE_LORBER || pPrefs->noise_suppression_method == DENOISE_WOLFE_GODSILL) { */ if(pPrefs->noise_suppression_method == DENOISE_WOLFE_GODSILL) { for (k = 1; k <= pPrefs->FFT_SIZE/2 ; ++k) { int j ; masked[k] = 0.0 ; for(j = k-1 ; j > 0 ; j--) { #ifdef OLD_N_SLOW double bark_diff = bark_z[k] - bark_z[j] ; double johnston = 15.81 + 7.5*(bark_diff+.474) - 17.5*sqrt(1.0+(bark_diff+0.474)*(bark_diff+0.474)) ; double johnston_masked = johnston - (tonality_factor*(14.5+bark_z[j])+5.5*(1.0 - tonality_factor)) ; double gain = pow(10.0, johnston_masked/10.0) ; if(gain < 1.e-2) break ; #else double gain = jg_lower[k][k-j] ; #endif if(k - j > 10) break ; masked[k] += MAX((Y2[j]-noise2[j]),0.0)*gain ; } for(j = k ; j <= pPrefs->FFT_SIZE/2 ; j++) { #ifdef OLD_N_SLOW double bark_diff = bark_z[j] - bark_z[k] ; double johnston = 15.81 + 7.5*(bark_diff+.474) - 17.5*sqrt(1.0+(bark_diff+0.474)*(bark_diff+0.474)) ; double johnston_masked = johnston - (tonality_factor*(14.5+bark_z[j])+5.5*(1.0 - tonality_factor)) ; double gain = pow(10.0, johnston_masked/10.0) ; #else double gain = jg_upper[k][j-k] ; #endif if(gain < 1.e-2) break ; if(j - k > 10) break ; masked[k] += MAX((Y2[j]-noise2[j]),0.0)*gain ; } /* if(debug_frame == 3) g_print("k:%d Y:%lf masked:%lf bark:%lf\n", k, Y[k], masked[k], bark_z[k]) ; */ } } #ifdef TEST if(pPrefs->noise_suppression_method == DENOISE_AUDACITY) { for(i=0; i<=len/2; i++) plog[i] = log(power[i]); int half = len/2; for(i=0; i<=half; i++) { float smooth; if (plog[i] < noiseGate[i] + (level/2.0)) smooth = 0.0; else smooth = 1.0; smoothing[i] = smooth * 0.5 + smoothing[i] * 0.5; } /* try to eliminate tinkle bells */ for(i=2; i<=half-2; i++) { if (smoothing[i]>=0.5 && smoothing[i]<=0.55 && smoothing[i-1]<0.1 && smoothing[i-2]<0.1 && smoothing[i+1]<0.1 && smoothing[i+2]<0.1) smoothing[i] = 0.0; } outr[0] *= smoothing[0]; outi[0] *= smoothing[0]; outr[half] *= smoothing[half]; outi[half] *= smoothing[half]; for(i=1; inoise_suppression_method == DENOISE_EXPERIMENTAL) { /* this whole section is starting to play around with audio *restoration*, i.e. trying * to guess what was missing, and adding it back in. Think of very old recordings * with that have a damped high frequency response */ if(0) { static int first=1 ; /* try simple deconvolution */ for (k = 0 ; k <= pPrefs->FFT_SIZE/2 ; ++k) { /* Gk needs to look like the original response filter */ double Gk = hanning(k,pPrefs->FFT_SIZE/2) ; double freq = bin2freq(pPrefs->rate,pPrefs->FFT_SIZE,k) ; Gk = ceramic_mic_response(bin2freq(pPrefs->rate,pPrefs->FFT_SIZE,k)) ; Gk = Gk * Gk ; if( !(k % 100) && first ) printf("k:%d freq:%0.1f Gk:%f\n", k, freq, Gk) ; if(k < pPrefs->FFT_SIZE/2) { /* cdivide(&out[k],&out[pPrefs->FFT_SIZE-k],Gk,0) ; */ out[pPrefs->FFT_SIZE-k] /= Gk ; out[k] /= Gk ; } else { out[k] /= Gk ; } out[k] *= Gk ; } first=0 ; } else { // Step 1. Compute the linear regression coefs(a,b) for the function ln(power2) = a*k + b ; double sumx = 0.0 ; double sumy = 0.0 ; double sumx2 = 0.0 ; double sumxy = 0.0 ; double n = 0 ; double a, b ; int k_cut_off = 2*pPrefs->FFT_SIZE/8 ; fftw_real *r = gain_k ; for (k = 1 ; k <= pPrefs->FFT_SIZE/2 ; ++k) { r[k] = 1.0 ; } for (k = 1 ; k < k_cut_off ; ++k) { double y = log(Y2[k]) ; sumx += (double)k ; sumy += y ; sumxy += (double)k*y ; sumx2 += (double)k*(double)k ; n++ ; } a = (n*(sumxy)-sumx*sumy) / (n*sumx2 - sumx*sumx) ; b = (sumy - a*sumx) / n ; printf("a,b %f %f\n", a, b) ; // Step 2. Compute r[k], amount of energy present for each frequency bin relative to predicted for (k = 1 ; k < k_cut_off ; ++k) { r[k] = log(Y2[k]) / (a*(double)k+b) ; } #define MAX_HARMONIC 3 // Step 3. Compute gain in each bin >= k_cutoff ; double harmonic_factor[6] = {1.0,1.0,1.0,1.0,1.0,1.0/8.0} ; int harmonic ; for(harmonic = 1 ; harmonic < MAX_HARMONIC+1 ; harmonic++) { double harmonic_fraction = 1.0 - ((double)harmonic / (double)(harmonic+1)) ; for (k = k_cut_off ; k <= pPrefs->FFT_SIZE/2 ; ++k) { /* compute j, the index of the fundamental freq of which k is the harmonic */ int j = (int)((double)k * harmonic_fraction + 0.5) ; double ln_p2_hat = r[j]*(a * (double)k + b) ; double p2_hat = harmonic_factor[harmonic]*exp(ln_p2_hat) ; double Gk = sqrt((p2_hat+Y2[k]) / Y2[k]) ; if (k == pPrefs->FFT_SIZE/2) printf("harmonic, hf, j, p2_hat, Gk[maxfft], ln_p2_hat %d %f %d %f %f %f\n", harmonic, harmonic_fraction, j, p2_hat, Gk, ln_p2_hat) ; out[k] *= Gk ; if(k < pPrefs->FFT_SIZE/2) out[pPrefs->FFT_SIZE-k] *= Gk ; } } } } else { for (k = 1; k <= pPrefs->FFT_SIZE/2 ; ++k) { if(noise2[k] > DBL_MIN) { double gain, Fk, Gk ; if(pPrefs->noise_suppression_method == DENOISE_EM) { double Rpost = MAX(Y2[k]/noise2[k]-1.0, 0.0) ; double alpha = pPrefs->dn_gamma ; double Rprio ; if(prev_sample[ch] == 1) Rprio = (1.0-alpha)*Rpost+alpha*gain_prev[k]*gain_prev[k]*Y2_prev[k]/noise2[k] ; else Rprio = Rpost ; gain = gain_em(Rprio, Rpost, alpha) ; /* g_print("Rpost:%lg Rprio:%lg gain:%lg gain_prev:%lg y2_prev:%lg\n", Rpost, Rprio, gain, gain_prev[k], Y2_prev[k]) ; */ gain_prev[k] = gain ; Y2_prev[k] = Y2[k] ; } else if(pPrefs->noise_suppression_method == DENOISE_LORBER) { double SNRlocal = MAX(masked[k]/noise2[k]-1.0, 0.0) ; double SNRfilt, SNRprio ; double alpha ; if(prev_sample[ch] == 1) { double eta = (1.0 + pPrefs->dn_gamma) / 2.0 ; /* eta seems to be better closer to 1.0 than gamma */ SNRfilt = (1.-pPrefs->dn_gamma)*SNRlocal + pPrefs->dn_gamma*(sig_prev[k]/noise2[k]) ; SNRprio = SNRfilt ; /* note, could use another parameter, like pPrefs->dn_gamma, here to compute SNRprio */ SNRprio = (1.-eta)*SNRlocal + eta*(sig_prev[k]/noise2[k]) ; }else { SNRfilt = SNRlocal ; SNRprio = SNRfilt ; } alpha = alpha_lorber(SNRprio) ; gain = 1.0 - alpha/(SNRfilt+1) ; sig_prev[k] = MAX(Y2[k]*gain,0.0) ; } else if(pPrefs->noise_suppression_method == DENOISE_WOLFE_GODSILL) { double Rpost = MAX(Y2[k]/noise2[k]-1.0, 0.0) ; double alpha = pPrefs->dn_gamma ; double Rprio ; if(prev_sample[ch] == 1) Rprio = (1.0-alpha)*Rpost+alpha*gain_prev[k]*gain_prev[k]*Y2_prev[k]/noise2[k] ; else Rprio = Rpost ; Y2_prev[k] = Y2[k] ; if(Y2[k] > masked[k]) { gain = MAX(masked[k]/Y2[k], Rprio/(Rprio+1.0)) ; } else { gain = 1.0 ; } gain_prev[k] = gain ; } else if(pPrefs->noise_suppression_method == DENOISE_WEINER) gain = gain_weiner(Y2[k], noise2[k]) ; else gain = gain_power_subtraction(Y2[k], noise2[k]) ; Fk = pPrefs->amount*(1.0-gain) ; if(Fk < 0.0) Fk = 0.0 ; if(Fk > 1.0) Fk = 1.0 ; Gk = 1.0 - Fk ; out[k] *= Gk ; if(k < pPrefs->FFT_SIZE/2) out[pPrefs->FFT_SIZE-k] *= Gk ; gain_k[k] = Gk ; } } } } /* the inverse fft */ #ifdef HAVE_FFTW3 FFTW(execute)(*pBak); #else /* HAVE_FFTW3 */ rfftw_one(*pBak, out, windowed); #endif /* !HAVE_FFTW3 */ for(k = 0 ; k < pPrefs->FFT_SIZE ; k++) windowed[k] /= (double)(pPrefs->FFT_SIZE) ; if(0|| pPrefs->window_type == DENOISE_WINDOW_HANNING_OVERLAP_ADD) { /** HANNING - OVERLAP - ADD */ /* make sure the tails of the sample approach zero magnitude */ double offset = windowed[0] ; double hs1 = pPrefs->FFT_SIZE/2 - 1 ; for(k = 0 ; k < pPrefs->FFT_SIZE/2 ; k++) { double p = (hs1-(double)k)/hs1 ; sample[k] = windowed[k] - offset*p ; } offset = windowed[pPrefs->FFT_SIZE-1] ; for(k = pPrefs->FFT_SIZE/2 ; k < pPrefs->FFT_SIZE ; k++) { double p = ((double)k-hs1)/hs1 ; sample[k] = windowed[k] - offset*p ; } } else { /* merge results back into sample data based on window function */ for(k = 0 ; k < pPrefs->FFT_SIZE ; k++) { double w = window_coef[k] ; sample[k] = (1.0-w)*sample[k] + w*windowed[k] ; } } prev_sample[ch] = 1 ; debug_frame++ ; } int denoise_normalize = 0 ; #define NO_DEBUG #ifdef DEBUG void print_denoise(char *header, struct denoise_prefs *pDnprefs) { int k ; g_print("******** %s ************\n", header) ; g_print("FFT_SIZE:%d\n", pDnprefs->FFT_SIZE) ; g_print("n_noise_samples:%d\n", pDnprefs->n_noise_samples) ; g_print("amount:%lf\n", pDnprefs->amount) ; g_print("smoothness:%d\n", pDnprefs->smoothness) ; g_print("window_type:") ; switch(pDnprefs->window_type) { case DENOISE_WINDOW_BLACKMAN : g_print("Blackman\n") ; break ; case DENOISE_WINDOW_BLACKMAN_HYBRID : g_print("Blackman-hybrid\n") ; break ; case DENOISE_WINDOW_HANNING_OVERLAP_ADD : g_print("Hanning-overlap-add\n") ; break ; #ifdef DENOISE_TRY_ONE_SAMPLE case DENOISE_WINDOW_ONE_SAMPLE : g_print("One Sample\n") ; break ; #endif default : g_print("!!!!!!!!! UNKNOWN !!!!!!!!!!!!\n") ; break ; } g_print("Suppression method:") ; switch(pDnprefs->noise_suppression_method) { case DENOISE_LORBER : g_print("Lorber-Hoeldrich\n") ; break ; case DENOISE_WEINER : g_print("Weiner\n") ; break ; case DENOISE_EM : g_print("Ephram\n") ; break ; case DENOISE_WOLFE_GODSILL : g_print("Wolfe-Godsill\n") ; break ; default : g_print("Spectral Subtraction\n") ; break ; } for(k = 0 ; k < pDnprefs->FFT_SIZE ; k++) { g_print("k:%d wc:%lg\n", k, window_coef[k]) ; } } #else void print_denoise(char *header, struct denoise_prefs *pDnprefs) {} #endif void get_noise_sample(struct sound_prefs *pPrefs, struct denoise_prefs *pDnprefs, long noise_start, long noise_end, fftw_real *left_noise_min, fftw_real *left_noise_max, fftw_real *left_noise_avg, fftw_real *right_noise_min, fftw_real *right_noise_max, fftw_real *right_noise_avg) ; int denoise(struct sound_prefs *pPrefs, struct denoise_prefs *pDnprefs, long noise_start, long noise_end, long first_sample, long last_sample, int channel_mask) { long current ; int k ; fftw_real left[DENOISE_MAX_FFT], right[DENOISE_MAX_FFT] ; fftw_real left_noise_max[DENOISE_MAX_FFT], right_noise_max[DENOISE_MAX_FFT], left_noise_avg[DENOISE_MAX_FFT] ; fftw_real left_noise_min[DENOISE_MAX_FFT], right_noise_min[DENOISE_MAX_FFT], right_noise_avg[DENOISE_MAX_FFT] ; fftw_real tmp[DENOISE_MAX_FFT] ; fftw_real left_prev_frame[DENOISE_MAX_FFT] ; fftw_real right_prev_frame[DENOISE_MAX_FFT] ; #ifdef HAVE_FFTW3 FFTW(plan) pForLeft, pForRight ; FFTW(plan) pFor, pBak ; #else /* HAVE_FFTW3 */ rfftw_plan pFor, pBak ; #endif /* HAVE_FFTW3 */ int framenum = 0 ; double alpha ; double s_amount ; /* amount, reduced to account for oversampling due to smoothness */ start_timer() ; current = first_sample ; push_status_text("Denoising audio") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; #ifdef HAVE_FFTW3 pFor = FFTW(plan_r2r_1d)(pDnprefs->FFT_SIZE, windowed, out, FFTW_R2HC, FFTW_ESTIMATE); pBak = FFTW(plan_r2r_1d)(pDnprefs->FFT_SIZE, out, windowed, FFTW_HC2R, FFTW_ESTIMATE); #endif /* HAVE_FFTW3 */ #ifdef HAVE_FFTW3 pForLeft = FFTW(plan_r2r_1d)(pDnprefs->FFT_SIZE, left, tmp, FFTW_R2HC, FFTW_ESTIMATE); pForRight = FFTW(plan_r2r_1d)(pDnprefs->FFT_SIZE, right, tmp, FFTW_R2HC, FFTW_ESTIMATE); #else /* HAVE_FFTW3 */ pFor = rfftw_create_plan(pDnprefs->FFT_SIZE, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); pBak = rfftw_create_plan(pDnprefs->FFT_SIZE, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE); #endif /* HAVE_FFTW3 */ alpha = welty_alpha(0.5, 1.0/(double)pDnprefs->smoothness) ; alpha = 1.0 ; for(k = 0 ; k < pDnprefs->FFT_SIZE ; k++) { window_coef[k] = fft_window(k,pDnprefs->FFT_SIZE, pDnprefs->window_type) ; d_print("k:%d wc:%lg\n", k, window_coef[k]) ; left_prev_frame[k] = 0.0 ; left[k] = 0.0 ; right_prev_frame[k] = 0.0 ; right[k] = 0.0 ; /* two_way_probs[k] = (double *)calloc(pDnprefs->FFT_SIZE,sizeof(double)) ; */ /* if(two_way_probs[k] == NULL) { */ /* fprintf(stderr, "Failed to malloc two_way_probs, %d of %d\n", k+1, pDnprefs->FFT_SIZE) ; */ /* exit(1) ; */ /* } */ } audio_normalize(denoise_normalize) ; get_noise_sample(pPrefs, pDnprefs, noise_start, noise_end, left_noise_min, left_noise_max, left_noise_avg, right_noise_min, right_noise_max, right_noise_avg) ; pDnprefs->rate = pPrefs->rate ; audio_normalize(denoise_normalize) ; /* if(smoothness <= 4 || window_type == DENOISE_WINDOW_BLACKMAN_HYBRID) */ s_amount = pDnprefs->amount ; /* else */ /* s_amount = amount/(double)(smoothness-3) ; */ prev_sample[0] = 0 ; prev_sample[1] = 0 ; if(pDnprefs->amount > DBL_MIN) { while(current <= last_sample-pDnprefs->FFT_SIZE) { long n = pDnprefs->FFT_SIZE ; long tmplast = current + n - 1 ; gfloat p = (gfloat)(current-first_sample)/(last_sample-first_sample) ; n = read_fft_real_wavefile_data(left, right, current, current+pDnprefs->FFT_SIZE-1) ; if(n < pDnprefs->FFT_SIZE) break ; /* hit the end of all data? */ #ifdef MAC_OS_X // This usleep fixes a segfault on OS X. Rob Frohne usleep(2); #endif update_progress_bar(p,PROGRESS_UPDATE_INTERVAL,FALSE) ; /* */ if(framenum == 0) { for(k = 0 ; k < pDnprefs->FFT_SIZE ; k++) { if(k < pDnprefs->FFT_SIZE/2) { d_print("OA sum %d:%lg\n", k, window_coef[k]+window_coef[k+pDnprefs->FFT_SIZE/2]) ; window_coef[k] = 1.0 ; } } compute_sum_window_wgts(pDnprefs) ; framenum = 1 ; } else if(framenum == 1) { for(k = 0 ; k < pDnprefs->FFT_SIZE ; k++) { window_coef[k] = fft_window(k,pDnprefs->FFT_SIZE, pDnprefs->window_type) ; } compute_sum_window_wgts(pDnprefs) ; framenum = 2 ; } if(channel_mask & 0x01) fft_remove_noise(left, left_noise_min, left_noise_max, left_noise_avg, &pFor, &pBak, pDnprefs,0) ; if(channel_mask & 0x02) fft_remove_noise(right, right_noise_min, right_noise_max, right_noise_avg, &pFor, &pBak, pDnprefs,1) ; if(pDnprefs->window_type == DENOISE_WINDOW_HANNING_OVERLAP_ADD) { for(k = 0 ; k < pDnprefs->FFT_SIZE/2 ; k++) { if(channel_mask & 0x01) { /* add in the last half of the previous output frame */ left[k] += left_prev_frame[k+pDnprefs->FFT_SIZE/2] ; /* save the last half of this output frame */ left_prev_frame[k+pDnprefs->FFT_SIZE/2] = left[k+pDnprefs->FFT_SIZE/2] ; } if(channel_mask & 0x02) { /* add in the last half of the previous output frame */ right[k] += right_prev_frame[k+pDnprefs->FFT_SIZE/2] ; /* save the last half of this output frame */ right_prev_frame[k+pDnprefs->FFT_SIZE/2] = right[k+pDnprefs->FFT_SIZE/2] ; } } write_fft_real_wavefile_data(left, right, current, current+pDnprefs->FFT_SIZE/2-1) ; #ifdef DENOISE_TRY_ONE_SAMPLE } else if(pDnprefs->window_type == DENOISE_WINDOW_ONE_SAMPLE) { if(current == first_sample) { write_fft_real_wavefile_data(left, right, current, current+pDnprefs->FFT_SIZE/2-1) ; } else { write_fft_real_wavefile_data(left, right, current, current) ; } #endif } else { write_fft_real_wavefile_data(left, right, current, MIN(tmplast, last_sample)) ; } current += get_window_delta(pDnprefs) ; } } #ifdef HAVE_FFTW3 FFTW(destroy_plan)(pForLeft); FFTW(destroy_plan)(pForRight); FFTW(destroy_plan)(pBak); FFTW(destroy_plan)(pFor); #else /* HAVE_FFTW3 */ rfftw_destroy_plan(pFor); rfftw_destroy_plan(pBak); #endif /* HAVE_FFTW3 */ for(k = 0 ; k < pDnprefs->FFT_SIZE ; k++) { /* free(two_way_probs[k]) ; */ } audio_normalize(1) ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; main_redraw(FALSE, TRUE) ; stop_timer("DENOISE") ; return 0 ; } int print_noise_sample(struct sound_prefs *pPrefs, struct denoise_prefs *pDnprefs, long noise_start, long noise_end) { int k ; FILE *fp ; fftw_real left_noise_max[DENOISE_MAX_FFT], right_noise_max[DENOISE_MAX_FFT], left_noise_avg[DENOISE_MAX_FFT] ; fftw_real left_noise_min[DENOISE_MAX_FFT], right_noise_min[DENOISE_MAX_FFT], right_noise_avg[DENOISE_MAX_FFT] ; extern int MAXSAMPLEVALUE ; double max = MAXSAMPLEVALUE * MAXSAMPLEVALUE ; get_noise_sample(pPrefs, pDnprefs, noise_start, noise_end, left_noise_min, left_noise_max, left_noise_avg, right_noise_min, right_noise_max, right_noise_avg) ; fp = fopen("noise.dat", "w") ; fprintf(stderr, "FFT_SIZE in print_noise_sample is %d\n", pDnprefs->FFT_SIZE) ; for(k = 1 ; k <= pDnprefs->FFT_SIZE/2 ; k++) { double freq = (double)pPrefs->rate / 2.0 /(double)(pDnprefs->FFT_SIZE/2)*(double)k ; double db_left = 20.0*log10(left_noise_avg[k]/(max/2.0)) ; double db_right = 20.0*log10(right_noise_avg[k]/(max/2.0)) ; fprintf(fp, "%10lgHz %12.1lfdB %12.1lfdB\n", freq, db_left, db_right) ; } fclose(fp) ; return 0 ; } void get_noise_sample(struct sound_prefs *pPrefs, struct denoise_prefs *pDnprefs, long noise_start, long noise_end, fftw_real *left_noise_min, fftw_real *left_noise_max, fftw_real *left_noise_avg, fftw_real *right_noise_min, fftw_real *right_noise_max, fftw_real *right_noise_avg) { int i, j, k ; #ifdef HAVE_FFTW3 FFTW(plan) pForLeft, pForRight ; #else /* HAVE_FFTW3 */ rfftw_plan pFor, pBak ; #endif /* HAVE_FFTW3 */ fftw_real left[DENOISE_MAX_FFT], right[DENOISE_MAX_FFT] ; fftw_real tmp[DENOISE_MAX_FFT] ; #ifdef HAVE_FFTW3 pForLeft = FFTW(plan_r2r_1d)(pDnprefs->FFT_SIZE, left, tmp, FFTW_R2HC, FFTW_ESTIMATE); pForRight = FFTW(plan_r2r_1d)(pDnprefs->FFT_SIZE, right, tmp, FFTW_R2HC, FFTW_ESTIMATE); #else /* HAVE_FFTW3 */ pFor = rfftw_create_plan(pDnprefs->FFT_SIZE, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); pBak = rfftw_create_plan(pDnprefs->FFT_SIZE, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE); #endif /* HAVE_FFTW3 */ for(k = 0 ; k < pDnprefs->FFT_SIZE ; k++) { if(0 || pDnprefs->window_type == DENOISE_WINDOW_HANNING_OVERLAP_ADD) { window_coef[k] = fft_window(k,pDnprefs->FFT_SIZE, pDnprefs->window_type) ; } else { window_coef[k] = 1.0 ; } left_noise_max[k] = 0.0 ; right_noise_max[k] = 0.0 ; left_noise_avg[k] = 0.0 ; right_noise_avg[k] = 0.0 ; left_noise_min[k] = DBL_MAX ; right_noise_min[k] = DBL_MAX ; } audio_normalize(denoise_normalize) ; for(i = 0 ; i < pDnprefs->n_noise_samples ; i++) { long first = noise_start + i*(noise_end-noise_start-pDnprefs->FFT_SIZE)/pDnprefs->n_noise_samples ; read_fft_real_wavefile_data(left, right, first, first+pDnprefs->FFT_SIZE-1) ; for(k = 0 ; k < pDnprefs->FFT_SIZE ; k++) { left[k] *= window_coef[k] ; right[k] *= window_coef[k] ; } if(0 && pDnprefs->noise_suppression_method == DENOISE_EXPERIMENTAL) { for(k = 1 ; k <= pDnprefs->FFT_SIZE/2 ; k++) { for(j = 1 ; j <= pDnprefs->FFT_SIZE/2 ; j++) { /* two_way_probs[j][k] = 0.0 ; */ } } } #ifdef HAVE_FFTW3 FFTW(execute)(pForLeft); #else /* HAVE_FFTW3 */ rfftw_one(pFor, left, tmp); #endif /* HAVE_FFTW3 */ /* convert noise sample to power spectrum */ for(k = 1 ; k <= pDnprefs->FFT_SIZE/2 ; k++) { double p2 ; if(k < pDnprefs->FFT_SIZE/2) { p2 = tmp[k] * tmp[k] + tmp[pDnprefs->FFT_SIZE-k]*tmp[pDnprefs->FFT_SIZE-k] ; } else { /* Nyquist Frequency */ p2 = tmp[k] * tmp[k] ; } left_noise_min[k] = MIN(left_noise_min[k], p2) ; left_noise_max[k] = MAX(left_noise_max[k], p2) ; left_noise_avg[k] += p2 ; } if(0 && pDnprefs->noise_suppression_method == DENOISE_EXPERIMENTAL) { for(k = 1 ; k <= pDnprefs->FFT_SIZE/2 ; k++) { double p2 ; if(k < pDnprefs->FFT_SIZE/2) { p2 = tmp[k] * tmp[k] + tmp[pDnprefs->FFT_SIZE-k]*tmp[pDnprefs->FFT_SIZE-k] ; } else { /* Nyquist Frequency */ p2 = tmp[k] * tmp[k] ; } for(j = k+k/2 ; j <= pDnprefs->FFT_SIZE/2 ; j++) { double p2j ; if(j < pDnprefs->FFT_SIZE/2) { p2j = tmp[j] * tmp[j] + tmp[pDnprefs->FFT_SIZE-j]*tmp[pDnprefs->FFT_SIZE-j] ; } else { /* Nyquist Frequency */ p2j = tmp[j] * tmp[j] ; } /* two_way_probs[j][k] = MAX(two_way_probs[j][k],p2j/p2) ; */ } } } #ifdef HAVE_FFTW3 FFTW(execute)(pForRight); #else /* HAVE_FFTW3 */ rfftw_one(pFor, right, tmp); #endif /* HAVE_FFTW3 */ /* convert noise sample to power spectrum */ for(k = 1 ; k <= pDnprefs->FFT_SIZE/2 ; k++) { double p2 ; if(k < pDnprefs->FFT_SIZE/2) { p2 = tmp[k] * tmp[k] + tmp[pDnprefs->FFT_SIZE-k]*tmp[pDnprefs->FFT_SIZE-k] ; } else { /* Nyquist Frequency */ p2 = tmp[k] * tmp[k] ; } right_noise_min[k] = MIN(right_noise_min[k], p2) ; right_noise_max[k] = MAX(right_noise_max[k], p2) ; right_noise_avg[k] += p2 ; } if(0 && pDnprefs->noise_suppression_method == DENOISE_EXPERIMENTAL) { for(k = 1 ; k <= pDnprefs->FFT_SIZE/2 ; k++) { double p2 ; if(k < pDnprefs->FFT_SIZE/2) { p2 = tmp[k] * tmp[k] + tmp[pDnprefs->FFT_SIZE-k]*tmp[pDnprefs->FFT_SIZE-k] ; } else { /* Nyquist Frequency */ p2 = tmp[k] * tmp[k] ; } for(j = k+k/2 ; j <= pDnprefs->FFT_SIZE/2 ; j++) { double p2j ; if(j < pDnprefs->FFT_SIZE/2) { p2j = tmp[j] * tmp[j] + tmp[pDnprefs->FFT_SIZE-j]*tmp[pDnprefs->FFT_SIZE-j] ; } else { /* Nyquist Frequency */ p2j = tmp[j] * tmp[j] ; } /* two_way_probs[j][k] = MAX(two_way_probs[j][k],p2j/p2) ; */ } } } } /* average out the power spectrum samples */ for(k = 1 ; k <= pDnprefs->FFT_SIZE/2 ; k++) { left_noise_avg[k] /= (double)pDnprefs->n_noise_samples ; right_noise_avg[k] /= (double)pDnprefs->n_noise_samples ; } compute_bark_z(pDnprefs->FFT_SIZE, pPrefs->rate) ; compute_johnston_gain(pDnprefs->FFT_SIZE, 0.0) ; if(pDnprefs->freq_filter) { if(pDnprefs->estimate_power_floor) { double half_freq_w = (pDnprefs->max_sample_freq - pDnprefs->min_sample_freq)/2.0 ; double sum_left = 0.0 ; double n_left = 0.0 ; double sum_right = 0.0 ; double n_right = 0.0 ; for(k = 1 ; k <= pDnprefs->FFT_SIZE/2 ; k++) { double freq = (double)pPrefs->rate / 2.0 /(double)(pDnprefs->FFT_SIZE/2)*(double)k ; if(freq < pDnprefs->min_sample_freq && freq > pDnprefs->min_sample_freq-half_freq_w) { sum_left += left_noise_avg[k] ; n_left += 1.0 ; sum_right += right_noise_avg[k] ; n_right += 1.0 ; } if(freq > pDnprefs->max_sample_freq && freq < pDnprefs->max_sample_freq+half_freq_w) { sum_left += left_noise_avg[k] ; n_left += 1.0 ; sum_right += right_noise_avg[k] ; n_right += 1.0 ; } } if(n_left > 1.e-30) sum_left /= n_left ; if(n_right > 1.e-30) sum_right /= n_left ; for(k = 1 ; k <= pDnprefs->FFT_SIZE/2 ; k++) { double freq = (double)pPrefs->rate / 2.0 /(double)(pDnprefs->FFT_SIZE/2)*(double)k ; if(freq < pDnprefs->min_sample_freq || freq > pDnprefs->max_sample_freq) { left_noise_avg[k] -= sum_left ; right_noise_avg[k] -= sum_right ; } } } for(k = 1 ; k <= pDnprefs->FFT_SIZE/2 ; k++) { double freq = (double)pPrefs->rate / 2.0 /(double)(pDnprefs->FFT_SIZE/2)*(double)k ; if(freq < pDnprefs->min_sample_freq || freq > pDnprefs->max_sample_freq) { left_noise_avg[k] = 0.0 ; right_noise_avg[k] = 0.0 ; } } } #ifdef HAVE_FFTW3 FFTW(destroy_plan)(pForLeft); FFTW(destroy_plan)(pForRight); #else /* HAVE_FFTW3 */ rfftw_destroy_plan(pFor); rfftw_destroy_plan(pBak); #endif /* HAVE_FFTW3 */ audio_normalize(1) ; } gtk-wave-cleaner-0.22-04/dethunk.c0000666000175000017500000004565513450764342020043 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* dethunk.c */ #include #include "gwc.h" #include "stat.h" #define FFT_MAX 32768 void print_spectral(char *str, fftw_real tmp_l[], long FFT_SIZE) { fftw_real tmp[FFT_MAX], amp[FFT_MAX], phase[FFT_MAX] ; long k ; double hdfs = FFT_SIZE / 2 ; return ; /* bias */ k = 0 ; amp[0] = tmp_l[0]/hdfs ; phase[0] = 0 ; printf("%s: %ld %10lg %10lg\n", str, k, amp[k], phase[k]) ; for(k = 1 ; k < FFT_SIZE ; k++) { tmp[k] = tmp_l[k] / hdfs ; } /* convert noise sample to power spectrum */ for(k = 1 ; k <= FFT_SIZE/2 ; k++) { if(k < FFT_SIZE/2) { amp[k] = tmp[k] * tmp[k] + tmp[FFT_SIZE-k]*tmp[FFT_SIZE-k] ; phase[k] = atan2(tmp[FFT_SIZE-k],tmp[k]); } else { /* Nyquist Frequency */ amp[k] = tmp[k] * tmp[k] ; phase[k] = 0.0 ; } amp[k] = sqrt(amp[k]) ; printf("%s: %ld %10lg %10lg\n", str, k, amp[k], phase[k]) ; } } int dethunk_new(struct sound_prefs *pPrefs, long first_sample, long last_sample, int channel_mask) { long i ; long n_samples = last_sample - first_sample + 1 ; int cancel, k ; fftw_real left[FFT_MAX], right[FFT_MAX] ; fftw_real pre_left[FFT_MAX] ; fftw_real pre_right[FFT_MAX] ; fftw_real post_left[FFT_MAX] ; fftw_real post_right[FFT_MAX] ; fftw_real window_coef[FFT_MAX] ; fftw_real windowed[FFT_MAX] ; #ifdef HAVE_FFTW3 fftw_real tmp_l[FFT_MAX] ; fftw_real tmp_r[FFT_MAX] ; FFTW(plan) pPreLeft, pPreRight, pPostLeft, pPostRight, pBakLeft, pBakRight; #else /* HAVE_FFTW3 */ rfftw_plan pFor,pBak ; #endif /* HAVE_FFTW3 */ double dfs, hdfs ; extern struct view audio_view ; int FFT_SIZE ; int repair_size ; int window, n_windows ; int n_want = 4 ; for(FFT_SIZE = 8 ; FFT_SIZE < n_samples/n_want && FFT_SIZE < 8192 ; FFT_SIZE *= 2) ; repair_size = FFT_SIZE * n_want ; n_windows = 2*n_want - 1 ; dfs = FFT_SIZE ; hdfs = FFT_SIZE / 2 ; { long extra_samples = repair_size - n_samples ; first_sample -= extra_samples/2 ; if(first_sample < 0) first_sample = 0 ; last_sample = first_sample+repair_size-1 ; if(last_sample > pPrefs->n_samples-1) { last_sample = pPrefs->n_samples-1 ; first_sample = last_sample-repair_size-1 ; } } push_status_text("Saving undo information") ; start_save_undo("Undo dethunk", &audio_view) ; cancel = save_undo_data( first_sample, last_sample, pPrefs, TRUE) ; close_undo() ; pop_status_text() ; n_samples = last_sample - first_sample + 1 ; push_status_text("Dethunking audio") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; g_print("FFTSIZE:%d repair_size:%d\n", FFT_SIZE, repair_size) ; #ifdef HAVE_FFTW3 pPreLeft = FFTW(plan_r2r_1d)(FFT_SIZE, left, pre_left, FFTW_R2HC, FFTW_ESTIMATE); pPreRight = FFTW(plan_r2r_1d)(FFT_SIZE, right, pre_right, FFTW_R2HC, FFTW_ESTIMATE); pPostLeft = FFTW(plan_r2r_1d)(FFT_SIZE, left, post_left, FFTW_R2HC, FFTW_ESTIMATE); pPostRight = FFTW(plan_r2r_1d)(FFT_SIZE, right, post_right, FFTW_R2HC, FFTW_ESTIMATE); pBakLeft = FFTW(plan_r2r_1d)(FFT_SIZE, tmp_l, windowed, FFTW_HC2R, FFTW_ESTIMATE); pBakRight = FFTW(plan_r2r_1d)(FFT_SIZE, tmp_r, windowed, FFTW_HC2R, FFTW_ESTIMATE); #else /* HAVE_FFTW3 */ pFor = rfftw_create_plan(FFT_SIZE, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); pBak = rfftw_create_plan(FFT_SIZE, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE); #endif /* HAVE_FFTW3 */ audio_normalize(0) ; for(k = 0 ; k < FFT_SIZE ; k++) { double p = ((double)(k))/(double)(FFT_SIZE) ; window_coef[k] = 0.5 - 0.5 * cos(2.0*M_PI*p) ; /* printf("window_coef: %ld %10lg\n", k, window_coef[k]) ; */ /* double hanning(int, int) ; */ /* window_coef[k] = hanning(k,FFT_SIZE) ; */ } /* get fft of samples ahead of thunk */ { long first = first_sample-FFT_SIZE ; if(first < 0) first = 0 ; read_fft_real_wavefile_data(left, right, first, first+FFT_SIZE-1) ; /* for(k = 0 ; k < FFT_SIZE ; k++) { */ /* left[k] *= window_coef[k] ; */ /* right[k] *= window_coef[k] ; */ /* } */ #ifdef HAVE_FFTW3 FFTW(execute)(pPreLeft); FFTW(execute)(pPreRight); #else /* HAVE_FFTW3 */ rfftw_one(pFor, left, pre_left); rfftw_one(pFor, right, pre_right); #endif /* HAVE_FFTW3 */ } /* get fft of samples behind thunk */ { long first = last_sample+1 ; if(first+FFT_SIZE-1 > pPrefs->n_samples-1) first = pPrefs->n_samples-FFT_SIZE ; read_fft_real_wavefile_data(left, right, first, first+FFT_SIZE-1) ; /* for(k = 0 ; k < FFT_SIZE ; k++) { */ /* left[k] *= window_coef[k] ; */ /* right[k] *= window_coef[k] ; */ /* } */ #ifdef HAVE_FFTW3 FFTW(execute)(pPostLeft); FFTW(execute)(pPostRight); #else /* HAVE_FFTW3 */ rfftw_one(pFor, left, post_left); rfftw_one(pFor, right, post_right); #endif /* HAVE_FFTW3 */ } read_fft_real_wavefile_data(left, right, first_sample, first_sample+repair_size-1) ; for(i = FFT_SIZE/2 ; i < repair_size-1-FFT_SIZE/2 ; i++) { if(channel_mask & 0x01) left[i] = 0 ; if(channel_mask & 0x02) right[i] = 0 ; } for(i = 0 ; i < FFT_SIZE/2 ; i++) { if(channel_mask & 0x01) { left[i] *= window_coef[i+FFT_SIZE/2] ; } if(channel_mask & 0x02) { right[i] *= window_coef[i+FFT_SIZE/2] ; } } for(i = FFT_SIZE/2 ; i < FFT_SIZE ; i++) { int j = i - FFT_SIZE/2 ; int sample = repair_size-FFT_SIZE/2-1 + j; if(channel_mask & 0x01) { left[sample] *= window_coef[j] ; } if(channel_mask & 0x02) { right[sample] *= window_coef[j] ; } } for(window = 0 ; window < n_windows ; window++) { /* double wgt_post = (double)window/(double)(n_windows-1) ; */ double wgt_post = 0.0 ; double wgt_pre = 1.0 - wgt_post ; long i = window * FFT_SIZE/2 ; #ifndef HAVE_FFTW3 fftw_real tmp_l[FFT_MAX] ; fftw_real tmp_r[FFT_MAX] ; #endif /* not HAVE_FFTW3 */ for(k = 0 ; k < FFT_SIZE ; k++) { tmp_l[k] = wgt_pre*pre_left[k] + wgt_post*post_left[k] ; tmp_r[k] = wgt_pre*pre_right[k] + wgt_post*post_right[k] ; } if(channel_mask & 0x01) { double offset ; double hs1 ; /* the inverse fft */ #ifdef HAVE_FFTW3 FFTW(execute)(pBakLeft); #else /* HAVE_FFTW3 */ rfftw_one(pBak, tmp_l, windowed); #endif /* HAVE_FFTW3 */ if(0) { /* make sure the tails of the sample approach zero magnitude */ offset = windowed[0] ; hs1 = FFT_SIZE/2 - 1 ; for(k = 0 ; k < FFT_SIZE/2 ; k++) { double p = (hs1-(double)k)/hs1 ; windowed[k] -= offset*p ; } offset = windowed[FFT_SIZE-1] ; for(k = FFT_SIZE/2 ; k < FFT_SIZE ; k++) { double p = ((double)k-hs1)/hs1 ; windowed[k] -= offset*p ; } } else { for(k = 0 ; k < FFT_SIZE ; k++) { windowed[k] *= window_coef[k] ; /* windowed[k] = window_coef[k] * 32000*FFT_SIZE ; */ } } for(k = 0 ; k < FFT_SIZE ; k++) left[i+k] += windowed[k] / (double)(FFT_SIZE) ; } if(channel_mask & 0x02) { double offset ; double hs1 ; /* the inverse fft */ #ifdef HAVE_FFTW3 FFTW(execute)(pBakRight); #else /* HAVE_FFTW3 */ rfftw_one(pBak, tmp_r, windowed); #endif /* HAVE_FFTW3 */ if(0) { /* make sure the tails of the sample approach zero magnitude */ offset = windowed[0] ; hs1 = FFT_SIZE/2 - 1 ; for(k = 0 ; k < FFT_SIZE/2 ; k++) { double p = (hs1-(double)k)/hs1 ; windowed[k] -= offset*p ; } offset = windowed[FFT_SIZE-1] ; for(k = FFT_SIZE/2 ; k < FFT_SIZE ; k++) { double p = ((double)k-hs1)/hs1 ; windowed[k] -= offset*p ; } } else { for(k = 0 ; k < FFT_SIZE ; k++) { windowed[k] *= window_coef[k] ; /* windowed[k] = -window_coef[k] * 32000*FFT_SIZE ; */ } } for(k = 0 ; k < FFT_SIZE ; k++) right[i+k] += windowed[k] / (double)(FFT_SIZE) ; } } write_fft_real_wavefile_data(left, right, first_sample, last_sample) ; #ifdef HAVE_FFTW3 FFTW(destroy_plan)(pPreLeft); FFTW(destroy_plan)(pPreRight); FFTW(destroy_plan)(pPostLeft); FFTW(destroy_plan)(pPostRight); FFTW(destroy_plan)(pBakLeft); FFTW(destroy_plan)(pBakRight); #else /* HAVE_FFTW3 */ rfftw_destroy_plan(pFor); rfftw_destroy_plan(pBak); #endif /* HAVE_FFTW3 */ update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; audio_normalize(1) ; main_redraw(FALSE, TRUE) ; return 0 ; } int dethunk_current(struct sound_prefs *pPrefs, long first_sample, long last_sample, int channel_mask) { long i ; long n_samples = last_sample - first_sample + 1 ; int cancel, k ; fftw_real left[FFT_MAX], right[FFT_MAX] ; fftw_real pre_left_amp[FFT_MAX], pre_left_phase[FFT_MAX] ; fftw_real pre_right_amp[FFT_MAX], pre_right_phase[FFT_MAX] ; fftw_real post_left_amp[FFT_MAX], post_left_phase[FFT_MAX] ; fftw_real post_right_amp[FFT_MAX], post_right_phase[FFT_MAX] ; fftw_real tmp_l[FFT_MAX] ; fftw_real tmp_r[FFT_MAX] ; #ifdef HAVE_FFTW3 FFTW(plan) pPreLeft, pPreRight; #else /* HAVE_FFTW3 */ rfftw_plan pFor ; #endif /* HAVE_FFTW3 */ double dfs, hdfs ; extern struct view audio_view ; int FFT_SIZE ; /* return dethunk_new(pPrefs,first_sample,last_sample,channel_mask) ; */ for(FFT_SIZE = 8 ; FFT_SIZE < n_samples && FFT_SIZE < 8192 ; FFT_SIZE *= 2) ; dfs = FFT_SIZE ; hdfs = FFT_SIZE / 2 ; { long extra_samples = FFT_SIZE - n_samples ; first_sample -= extra_samples/2 ; if(first_sample < 0) first_sample = 0 ; last_sample = first_sample+FFT_SIZE-1 ; if(last_sample > pPrefs->n_samples-1) { last_sample = pPrefs->n_samples-1 ; first_sample = last_sample-FFT_SIZE-1 ; } } push_status_text("Saving undo information") ; start_save_undo("Undo dethunk", &audio_view) ; cancel = save_undo_data( first_sample, last_sample, pPrefs, TRUE) ; close_undo() ; pop_status_text() ; n_samples = last_sample - first_sample + 1 ; push_status_text("Dethunking audio") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; g_print("FFTSIZE:%d\n", FFT_SIZE) ; g_print("first_sample:%ld\n", first_sample) ; g_print("last_sample:%ld\n", last_sample) ; #ifdef HAVE_FFTW3 pPreLeft = FFTW(plan_r2r_1d)(FFT_SIZE, left, tmp_l, FFTW_R2HC, FFTW_R2HC); pPreRight = FFTW(plan_r2r_1d)(FFT_SIZE, right, tmp_r, FFTW_R2HC, FFTW_R2HC); #else /* HAVE_FFTW3 */ pFor = rfftw_create_plan(FFT_SIZE, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); #endif /* HAVE_FFTW3 */ /* get fft of samples ahead of thunk */ { long first = first_sample-FFT_SIZE ; if(first < 0) first = 0 ; read_fft_real_wavefile_data(left, right, first, first+FFT_SIZE-1) ; #ifdef HAVE_FFTW3 FFTW(execute)(pPreLeft); FFTW(execute)(pPreRight); #else /* HAVE_FFTW3 */ rfftw_one(pFor, left, tmp_l); rfftw_one(pFor, right, tmp_r); #endif /* HAVE_FFTW3 */ /* bias */ pre_left_amp[0] = tmp_l[0]/hdfs ; pre_right_amp[0] = tmp_r[0]/hdfs ; for(k = 1 ; k < FFT_SIZE ; k++) { tmp_l[k] /= hdfs ; tmp_r[k] /= hdfs ; } /* convert noise sample to power spectrum */ for(k = 1 ; k <= FFT_SIZE/2 ; k++) { if(k < FFT_SIZE/2) { pre_left_amp[k] = tmp_l[k] * tmp_l[k] + tmp_l[FFT_SIZE-k]*tmp_l[FFT_SIZE-k] ; pre_left_phase[k] = atan2(tmp_l[FFT_SIZE-k],tmp_l[k]); pre_right_amp[k] = tmp_r[k] * tmp_r[k] + tmp_r[FFT_SIZE-k]*tmp_r[FFT_SIZE-k] ; pre_right_phase[k] = atan2(tmp_r[FFT_SIZE-k],tmp_r[k]); } else { /* Nyquist Frequency */ pre_left_amp[k] = tmp_l[k] * tmp_l[k] ; pre_right_amp[k] = tmp_r[k] * tmp_r[k] ; pre_left_phase[k] = 0.0 ; pre_right_phase[k] = 0.0 ; } pre_left_amp[k] = sqrt(pre_left_amp[k]) ; pre_right_amp[k] = sqrt(pre_right_amp[k]) ; } } /* get fft of samples behind of thunk */ { long first = last_sample+1 ; if(first+FFT_SIZE-1 > pPrefs->n_samples-1) first = pPrefs->n_samples-FFT_SIZE ; read_fft_real_wavefile_data(left, right, first, first+FFT_SIZE-1) ; #ifdef HAVE_FFTW3 FFTW(execute)(pPreLeft); FFTW(execute)(pPreRight); #else /* HAVE_FFTW3 */ rfftw_one(pFor, left, tmp_l); rfftw_one(pFor, right, tmp_r); #endif /* HAVE_FFTW3 */ /* bias */ post_left_amp[0] = tmp_l[0]/hdfs ; post_right_amp[0] = tmp_r[0]/hdfs ; for(k = 1 ; k < FFT_SIZE ; k++) { tmp_l[k] /= hdfs ; tmp_r[k] /= hdfs ; } /* convert noise sample to power spectrum */ for(k = 1 ; k <= FFT_SIZE/2 ; k++) { if(k < FFT_SIZE/2) { post_left_amp[k] = tmp_l[k] * tmp_l[k] + tmp_l[FFT_SIZE-k]*tmp_l[FFT_SIZE-k] ; post_left_phase[k] = atan2(tmp_l[FFT_SIZE-k],tmp_l[k]); post_right_amp[k] = tmp_r[k] * tmp_r[k] + tmp_r[FFT_SIZE-k]*tmp_r[FFT_SIZE-k] ; post_right_phase[k] = atan2(tmp_r[FFT_SIZE-k],tmp_r[k]); } else { /* Nyquist Frequency */ post_left_amp[k] = tmp_l[k] * tmp_l[k] ; post_right_amp[k] = tmp_r[k] * tmp_r[k] ; post_left_phase[k] = 0.0 ; post_right_phase[k] = 0.0 ; } post_left_amp[k] = sqrt(post_left_amp[k]) ; post_right_amp[k] = sqrt(post_right_amp[k]) ; } } /* for(k = 1 ; k <= FFT_SIZE/2 ; k++) { */ /* printf("pre k:%d a:%lg p:%lg\n", k, pre_left_amp[k], pre_left_phase[k]) ; */ /* printf("post k:%d a:%lg p:%lg\n", k, post_left_amp[k], post_left_phase[k]) ; */ /* } */ read_fft_real_wavefile_data(left, right, first_sample, first_sample+FFT_SIZE-1) ; for(i = 0 ; i < FFT_SIZE ; i++) { double wgt_post = (double)i/(double)(FFT_SIZE-1) ; double wgt_pre = 1.0 - wgt_post ; double theta = ((double)i/(double)(FFT_SIZE-1))*2.0*M_PI ; update_progress_bar((double)i/(double)FFT_SIZE,PROGRESS_UPDATE_INTERVAL,FALSE) ; if(channel_mask & 0x01) left[i] = wgt_pre*pre_left_amp[0] + wgt_post*post_left_amp[0] ; if(channel_mask & 0x02) right[i] = wgt_pre*pre_right_amp[0] + wgt_post*post_right_amp[0] ; for(k = 1 ; k <= FFT_SIZE/2 ; k++) { double f = (double)k ; if(channel_mask & 0x01) { double phase = wgt_pre*pre_left_phase[k] + wgt_post*post_left_phase[k] ; double amp = wgt_pre*pre_left_amp[k] + wgt_post*post_left_amp[k] ; left[i] += amp*cos(f*theta + phase) ; } if(channel_mask & 0x02) { double phase = wgt_pre*pre_right_phase[k] + wgt_post*post_right_phase[k] ; double amp = wgt_pre*pre_right_amp[k] + wgt_post*post_right_amp[k] ; right[i] += amp*cos(f*theta + phase) ; } } } g_print("write first_sample:%ld\n", first_sample) ; g_print("write last_sample:%ld\n", last_sample) ; write_fft_real_wavefile_data(left, right, first_sample, last_sample) ; #ifdef HAVE_FFTW3 FFTW(destroy_plan)(pPreLeft); FFTW(destroy_plan)(pPreRight); #else /* HAVE_FFTW3 */ rfftw_destroy_plan(pFor); #endif /* HAVE_FFTW3 */ update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; main_redraw(FALSE, TRUE) ; return 0 ; } #include "ar.h" #include "ar.c" #define ORDER 2048 int forward_extrapolate(fftw_real data[], int firstbad, int lastbad, int siglen) { int n_bad = lastbad - firstbad + 1 ; int autolen = 60 ; int i, j ; double auto_coefs[ORDER+1] ; /* int AutoRegression( double *inputseries, int length, int degree, double *coefficients, int method) */ autolen = (siglen-n_bad)/4 ; //autolen *= 2 ; if(autolen < 0) { d_print("Autolen < 0!\n") ; return REPAIR_FAILURE; } if(autolen > ORDER) autolen = ORDER ; g_print("siglen:%d n_bad:%d Autolen:%d\n",siglen,n_bad,autolen) ; AutoRegression(data,firstbad,autolen,auto_coefs,0) ; for(i = firstbad ; i < lastbad ; i++) { data[i] = 0 ; for(j = 0 ; j < autolen ; j++) data[i] += data[i - j - 1]*auto_coefs[j] ; } return 0 ; } int reverse_extrapolate(fftw_real data[], int firstbad, int lastbad, int siglen) { int i ; fftw_real *x = calloc(siglen, sizeof(fftw_real)) ; for(i = 0 ; i < siglen ; i++) x[siglen-i-1] = data[i] ; forward_extrapolate(x, siglen-lastbad-1, siglen-firstbad-1, siglen) ; for(i = 0 ; i < siglen ; i++) data[i] = x[siglen-i-1] ; free(x) ; return 0 ; } void estimate_region(fftw_real data[], int firstbad, int lastbad, int siglen) { int i ; fftw_real *data_r = calloc(siglen, sizeof(fftw_real)) ; int n_samples = lastbad - firstbad + 1 ; if(n_samples < 1) return ; if(n_samples == 1) { data[firstbad] = (data[firstbad-1]+data[firstbad+1])/2.0 ; return ; } for(i = 0 ; i < siglen ; i++) data_r[siglen-i-1] = data[i] ; forward_extrapolate(data, firstbad, lastbad, siglen) ; forward_extrapolate(data_r, siglen-lastbad-1, siglen-firstbad-1, siglen) ; for(i = firstbad ; i <= lastbad ; i++) { double d = i - firstbad ; double w_r = d / (double)(n_samples-1) ; double w_f = 1.0 - w_r ; data[i] = w_f*data[i] + w_r*data_r[siglen - i - 1] ; } free(data_r) ; } int dethunk(struct sound_prefs *pPrefs, long first_sample, long last_sample, int channel_mask) { long n_samples = last_sample - first_sample + 1 ; int cancel ; fftw_real *left, *right ; int FFT_SIZE = MIN(ORDER*2,(last_sample-first_sample+1)*4) ; int siglen = last_sample-first_sample+1+2*FFT_SIZE ; extern struct view audio_view ; left = calloc(siglen, sizeof(fftw_real)) ; right = calloc(siglen, sizeof(fftw_real)) ; push_status_text("Saving undo information") ; start_save_undo("Undo dethunk", &audio_view) ; cancel = save_undo_data( first_sample, last_sample, pPrefs, TRUE) ; close_undo() ; pop_status_text() ; n_samples = last_sample - first_sample + 1 ; push_status_text("Dethunking audio") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; g_print("first_sample:%ld\n", first_sample) ; g_print("last_sample:%ld\n", last_sample) ; read_fft_real_wavefile_data(left, right, first_sample-FFT_SIZE, last_sample+FFT_SIZE) ; if(channel_mask & 0x01) { estimate_region(left, FFT_SIZE, FFT_SIZE+n_samples-1, last_sample-first_sample+1+2*FFT_SIZE) ; } if(channel_mask & 0x02) { estimate_region(right, FFT_SIZE, FFT_SIZE+n_samples-1, last_sample-first_sample+1+2*FFT_SIZE) ; } write_fft_real_wavefile_data(left, right, first_sample-FFT_SIZE, last_sample+FFT_SIZE) ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; free(left) ; free(right) ; main_redraw(FALSE, TRUE) ; return 0 ; } gtk-wave-cleaner-0.22-04/dialog.c0000777000175000017500000000522013120075106017606 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* dialog.c */ /* utility routines to help with gtk boxes */ #include #include "gwc.h" int gwc_dialog_run(GtkDialog *dlg) { int dres ; //we could do this and remove a bunch of other uses of gtk_widget_show() //gtk_widget_show_all(GTK_WIDGET(dlg)); dres = gtk_dialog_run(GTK_DIALOG(dlg)); if (dres == GTK_RESPONSE_OK) return 0 ; return 1 ; } GtkWidget *add_number_entry_with_label(char *entry_text, char *label_text, GtkWidget *table, int row) { GtkWidget *entry, *label ; entry = gtk_entry_new (); gtk_entry_set_text(GTK_ENTRY(entry), entry_text) ; // enables the enter key to press the OK button gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); gtk_widget_show (entry); gtk_table_attach_defaults(GTK_TABLE(table), entry, 0, 1, row, row+1) ; label = gtk_label_new (label_text); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_widget_show (label); gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, row, row+1) ; // Alternative way to enable the enter key if we pass dlg to this function // g_signal_connect_swapped (entry, "activate", // G_CALLBACK (gtk_window_activate_default), dlg); return entry ; } GtkWidget *add_number_entry_with_label_int(int value, char *label_text, GtkWidget *table, int row) { char buf[100] ; sprintf(buf, "%d", value) ; return add_number_entry_with_label(buf, label_text, table, row) ; } GtkWidget *add_number_entry_with_label_double(double value, char *label_text, GtkWidget *table, int row) { char buf[100] ; sprintf(buf, "%lg", value) ; return add_number_entry_with_label(buf, label_text, table, row) ; } gtk-wave-cleaner-0.22-04/doc/0000755000175000017500000000000013453635677016772 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/doc/gtk-wave-cleaner.html0000666000175000017500000004502613450764342023014 0ustar00alisteralister00000000000000 Using Gtk Wave Cleaner to record and clean up your old vinyl music

An important note on GWC editing

GWC commits all changes to the original file instantly, and saves the deltas needed for undo to get back to the original, so on exit all your changes are already saved. When you exit (or open a new file) GWC will notify you that changes have been made, and give you the chance to undo them all.

Creating your wavfiles

  • CLEAN YOUR RECORD AS WELL AS POSSIBLE!!  The safest method is to use distilled water, and spray it on with a perfectly clean spray bottle.  Let it sit for a few minutes and then wipe it off with clean, soft, pure cotton cloth. Don't do this on the turntable itself, lay the record on a soft cloth on top of a firm flat surface.  Any lint that gets on the record from the cloth will come off easily with your regular record duster that you will apply while the record is on the turntable and spinning.  There are plenty of places on the internet that have suggestions for how to clean LPs.  The other thing to try is to play the LP once before you copy it to disk, the action of the needle in the groove may be able to dislodge more remaining particles.
  • Make sure you stop any programs or processes which use a lot of cpu or memory, or intensive disk access !!
    Otherwise your recording software may fail to record some parts of the audio, without telling you there has been a problem !!
  • Record your track(s). I now use a tool like brec for OSS and arec for ALSA, and record a number of tracks (i.e. one entire side of an LP) at once. Because GWC can handle extremely large audio files, it is more convenient to work with one single file. With cdrdao you can even burn CDs using only one audio file for all the tracks. Be sure to get some "silent" audio at the start of each recording, this information is used by GWC to assess the background noise level for noise elimination.
  • If you try to open a wav file created by software such as a recent ffmpeg, GWC will produce an error like this: "Failed to open /root/whistle.wav, 'Error : Cannot open file in read/write mode due to string data in header.'". Libsndfile does not support RDWR mode for these files - one workaround is to open and save the file in mhwaveedit. Or if you are creating the files using ffmpeg try adding "-flags bitexact" into your command line (although this will reduce ffmpeg's performance), or writing to a different libsndfile supported format such as au or aiff.

Selecting audio

  • To select sections of audio for GWC to operate on you click and drag in the displayed audio waveform.
  • Start dragging anywhere between the centers of the left and right channels to select both channels, or start dragging above or below this region to select just one channel.
  • If you do not make a selection GWC will operate on all the audio in the current view, but note that if you have clicked in the top or bottom quarter of the waveform it will only operate on the left or right channel.
  • Use edit markers to help you navigate and select sections of audio. There are 200 markers available. You set them by using the "B" and "E" keys, and clear them using the "Markers>Clear markers" menu item. "B" toggles the first marker at the start of the currently selected region. "E" toggles the second marker at the end of the currently selected region.
  • When you select a region within 10 pixels of either an edit marker or a song marker, it will "snap" to that marker. This allows you to zoom in to a portion of the audio data, set a marker, zoom and pan to another portion, set another marker, and then zoom back out and select the region between the markers -- giving you a fine level of control on the precision of the selected region.
  • You may also press the 'm' key, to automatically select the region between edit markers. A button and icon are in the works...

Unselecting audio

  • To clear the selection click in the displayed audio waveform without dragging. Any subsequent cleaning operations will be applied to all the audio in the current view, but note that if you click anywhere between the centers of the left and right channels any subsequent cleaning operations will be applied to both channels; if you click above or below this area they will be applied to only the left or right channel.

Steps to restore audio quality

  • Denoise

    • Select a sample region which is entirely free of music.
    • If you have a "clean" LP, (i.e. almost no crackle in the "silent" region) you may use the declicker in the silent region to remove a few clicks, but make sure the result doesn't sound goofy.
    • Press the sample noise button (the one with the eyedropper).
    • If you do not have a good noise sample and cannot splice one in from another recording you can use Generate pink noise to overwrite a selected region with pink and or white noise, which is a good approximation for hiss. You can then use this for your noise sample.
    • Now select and test denoising on a couple of different areas on the audio file, just to be sure it works.  Take the defaults of:
      • FFT Size=4096
        reduction=0.5
        smoothness=11
        number of samples=16
        gamma=0.95
        Windowing Function=Hanning-overlap-add
        Noise Suppresion Method=Lorber & Hoeldrich

    • Try denoising a few seconds at the start of the track (include some of the pre-track noise section to see how well the denoise algorithm works on pure noise). Play the denoised region, see if you like it. Now do an Edit->Undo (Ctrl-Z)

      Repeat the above process at the end of the track and somewhere in the middle. This gives you a good idea of how the noise sample at the start of the track will work as an estimate of the actual noise at the middle and end of the track.

      If you find the result sounds "metallic" or "burbly", back off on the reduction amount, remember to use Edit->Undo (Ctrl-Z). You can also try varying the gamma factor. I have found if it gets too close to 1.0, it can distort the final sound a little. Anything between 0.5 and 0.99 is probably worth trying.

    • When you are satisfied you have the settings you want, go for the gold and select the entire track and denoise the whole thing. In most cases the defaults given above will work quite well, so don't think this is hard, it's really easy! At this point you may skip saving the undo data, which for most songs is tens of megabytes and will take some time to save.

  • Declicking

    • There are 3 levels of declicking:
      1. Declick-strong - searches for and repairs the loudest clicks.
      2. Declick-weak - searches for and repairs weaker clicks.
      3. Declick-manual - If both of the above methods failed to repair a click, you can zoom in on the click by listening, highlighting, zooming in on the selection as described above. Then, making sure you have only the damaged portion of the audio data selected (in most cases this will be less than 100 samples), push this button, and it repairs the highlighted selection (or current view) -- don't use on more than about 200 samples!

    • In general you should start with Declick-strong, followed by Declick-weak, and use Declick-manual as a last resort.
    • The highest quality declicking is done "manually".  I have had cases where automatic declicking has a "false positive", and inadvertently degrades the signal in a few places.  I do manual declicking by either going to spectrogram view (View>Spectral View), and looking for spikes which show up as bright lines, or just listening and highlighting an area around where I hear the click. There is no better click detector than your ears! I have found for a window which is 600 pixels wide, about 22050 samples (about 1/2 second at the 44100 Hz sample rate, which is CD quality...) displayed in the spectrogram view works quite well.
    • There is an optional FFT click detector implemented now. The settings are the dB above average that the click amplitude must be in order to be marked and or fixed. Humans generally can detect a 3 dB change, so that's the default level for weak click detection. While the FFT click detector appears to work better than the old click detector, it is only based on some limited observations of mine, and it is MUCH SLOWER.
    • <HINT> - use the spacebar to start and stop playback!!!
      left hand on spacebar, right hand on mouse - very efficient.
      You can get a good idea where the click is by watching where the cursor is when you hear the click</HINT>
    • If you hit the "s" key during playback, GWC will stop the playback and highlight the last 1/2 second of audio played

  • Decrackling

    • Recordings from very dirty or damaged vinyl may have thousands of small "clicks" per second, which sounds like bacon frying. First try to remove this with the decrackling algorithm. Use the default settings in preferences.
    • Decrackling will also attenuate the high frequencies somewhat.
    • If decrackling fails, I have sometimes had success by repeatedly applying the "remove strong clicks" filter over an area until the reported repairs is zero.
  • Estimating

    Sometimes, there are large sections in the audio (200 to 8000 samples) that are just bad. It may sound like a "thunk" or a dropout. The estimation repair looks at the frequencies to the left and right of the selection (or current view), and blends those frequencies across the repair area. The result will be better than what was there to begin with, as of version 0.20-08 this works quite well, but remember, UNDO is your friend!
  • Finishing up

    • You may want to look at the reverb and DSP filters if the audio needs a little bit of "presence". Reverb uses the TAP Reverb software to apply reverberation. For this application, I recommend your wet levels be very small, try -30 Db for wet, -1 Db for Dry, and 1500 ms with the "Ambience (Thick) - HD" Reverb setting. TODO: explain DSP Frequency Filters

    • Eliminate blank portions at start and end of track -- highlight the area at the start of the track and use the scissors icon to indicate you want that deleted, do the same for the end of the track.  You can't eliminate sections in the middle of the track.  Umm, I haven't tested what would happen if you tried, it could be bad. Always back up your data :-)

    • You can use the functions in the File menu to split your wav file into separate tracks, export a selection as wav, ogg or mp3, or create a TOC file to use with cdrdao (Do an internet search for more info on that great program).

    • For TOC files and splitting you must insert song markers to identify the songs - "Markers>Detect songs" can usually do this automatically.

    • Exit. -- GWC will ask if you really want to save your changes.

    • I wrote a little utility -- wavlist, which will list the *.wav files and append the time in minutes:sec to the list so you can use it with something like gcover to create jewel case covers.

Changing keyboard shortcuts:

    Most keyboard shortcuts (i.e. not the hard-coded ones listed below) can be changed if this is enabled in your gtk configuration - refer to the included gtkrc-example.txt for this and other useful options.

    The shortcut keys are saved to ~/.config/gtk-wave-cleaner/accels


Keyboard shortcuts for hidden features:

  • spacebar - start and stop playback
  • 'a' - Create or append "cdrdao.toc", with the currently selected (or viewed) audio segment
  • 'u' - increase the scale on audio display
  • 'd' - decrease the scale on audio display
  • 'r' - reset the scale on audio display to 1.0
  • 's' - stop playback, and automatically highlight last 1/2 second of audio played
  • TODO: there are more hidden away in gwc.c, but we should give them all menu entries so the shortcuts are user configurable

Settings

  • Declick
    • Weak Declick Sensitivity - Set this to something greater than 1 (1.5 is the largest you should try) to detect even weaker clicks (but you will get more "false positives"), set it lower to detect a little bit stronger clicks.
    • Strong Declick Sensitivity - This takes the value 0.75 by default. Lower values will only detect stronger clicks, higher values will detect weaker clicks.
    • FFT Weak Declick Sensitivity - Set this to something greater than 2 to detect even weaker clicks (but you will get more "false positives"), set it higher to detect a little bit stronger clicks.
    • FFT Strong Declick Sensitivity - This takes the value 5 by default. Lower values will only detect stronger clicks, higher values will detect weaker clicks.
    • Use FFT click detector - Check this box to use FFT click detection. It appears to generate fewer false positives and fewer false negatives, based on limited testing.
    • Iterate in repair clicks until all repaired - The click detection algorithm compares each candidate click against the overall sound profile in the general region of the candidate click. If the click "looks" a lot like the other sound energy (for example a cymbal crash contains a lot of the same frequencies as a click), then the candidate is ignored. But, sometimes a stronger click may mask out a weaker click because of this comparison process. So, this option causes the click detector to run on a region of the audio after any click is repaired, to re-check for more possible clicks in the absence of those clicks that were repaired. The iterate function does not yet work for FFT click detection/removal
  • Decrackle -
    • Decrackle level -
    • Decrackling window -
    • Decrackling average window -
  • Denoise
    • FFT_SIZE - You have to think about this standing on your head. (Took me a while at least). Since the samples are say, 1/44100 of a second apart, the highest frequency detectable by the FFT will always be 1/22050 of a second, regardless of the fft window size. A larger and larger fft window size allows you to detect lower and lower frequencies, and to get more of an "averaging" effect of the higher frequencies which are present in the fft window.
    • Reduction - The amount of noise you want removed from the audio, as a proportion. If you use 1.0, then all noise is removed, but unfortunately you get nasty artifacts in the resulting audio, it may get burbly or metallic sounding. In general, you should set this value as low as possible (0.3 for Blackman window, 0.5 for others), and test a few spots in the audio file (remembering to "undo" each test!!!).
    • Smoothness - For the Blackman window, it determines how the windowing function "steps along" the audio file. In general, this should be set between 5 and 11, usually just leave this at 11
    • # noise samples - The denoise algorithm sub-samples the audio data you marked for "sampling". Because noise varies from one millisecond to the next, GWC will take many sub-samples and take the "average" noise signature from those sub-samples. You should usually just leave this at 16. Don't worry if the (number of noise samples)*FFT_SIZE is greater than the sample area, GWC will just overlap the sub-samples.
    • gamma - The Ephraim-Malah and Lorber-Hoeldrich noise reduction algorithms attempt to reduce the metallic sounding artifact in denoising by holding the noise removal process very constant from one window frame to the next. Gamma is the parameter that controls this, if you set it to 0, you essentially get Weiner noise reduction on every frame, set it close to 1, and you get some weird sounding stuff. Setting it in the range of 0.5 to 0.95 usually is pretty good. Play around with this and the reduction amount if you have that metallic sound after denoising.
    • Windowing Function NEED SOME PICTURES HERE
      • Blackman - Try this second
      • Hybrid Blackman-Full Pass - Fastest, may work well for relatively "clean" audio files with only a little hiss.
      • Hanning-overlap-add - Usually, this is the one you want.
    • Noise Suppression Method
      • Weiner - A little better than Power Spectral Subtraction.
      • Power Spectral Subtraction - Crudest.
      • Ephram-Malah 1984 - Pretty darn good.
      • Lorber & Hoeldrich - Large improvement over Ephram-Malah.
  • MP3 settings
    • A bunch 'o settings here -
  • OGG settings
    • A bunch 'o settings here -
  • Miscellaneous
    • Seconds of audio preselected when "s" key is struck -
    • Seconds of audio preselected when "n" key is struck -
    • Normalize values for declick, denoise? - The normalize option asks libsndfile to normalize the audio data on the interval -1.0 to 1.0, it appears to make no difference, and is really only there for testing. Set to 1 for normalization, 0 for non-normalized data.
    • Silence estimate in seconds for marking songs -
    • Log frequency in spectrogram -
gtk-wave-cleaner-0.22-04/doc/gtkrc-example.txt0000777000175000017500000000605513122667634022302 0ustar00alisteralister00000000000000## HOW TO USE ## ## This file is distributed as an example of gtk settings which people might find useful. ## To apply these settings for all GTK2 programs they should typically be added to ~/.gtkrc-2.0 or ~/.gtkrc-2.0.mine ## Changes will take effect upon restarting the program. ## If a line is prefixed by a # that means it is commented out. ## To use a special gtkrc just for GWC save it along with the config file i.e. as ~/.config/gtk-wave-cleaner/gtkrc ## For reference, if we had not implemented reading this file, you could have still done it by launching GWC like this: ## GTK2_RC_FILES=/usr/share/doc/gtk-wave-cleaner/gtkrc-example.txt gtk-wave-cleaner ## USEFUL SETTINGS AND EXPLANATION ## ## If you are using a special gtkrc for GWC then you probably want to include your normal gtkrc first, which will bring in your theme, fonts etc. e.g.: # include "/home/alister/.gtkrc-2.0" ## It seems you need to specify the actual path of the included file i.e. don't use ~ or $HOME. ## Settings in the special gtkrc must be below the include for them to override anything explicitly set in the included file. ## GWC's toolbar icons are 28x28 and by default gtk scales them down. ## This will instead display the icons at their native size, so they will be bigger and clearer. ## Presumably we don't need all of these for GWC. gtk-icon-sizes = "panel-menu=28,28:panel=28,28:gtk-menu=28,28:gtk-large-toolbar=28,28:gtk-small-toolbar=28,28:gtk-button=28,28:gtk-dnd=28,28" ## Using this instead would in a default setup increase the icon size slightly but only in the toolbar. ## Combine it with part of the line above to set it to 28 pixels. # gtk-toolbar-icon-size = large-toolbar ## This is the obvious step to take it further and display them at 200% ## This is useful for high dpi screens like my cellphone, and I guess Apple "retina" displays. ## But how do we make other gui elements like scrollbars bigger too? ## And do we need to do anything to make text bigger, particularly on OSX or windows? Perhaps we need a theme designed for hidpi? # gtk-icon-sizes = "panel-menu=56,56:panel=56,56:gtk-menu=56,56:gtk-large-toolbar=56,56:gtk-small-toolbar=56,56:gtk-button=56,56:gtk-dnd=56,56" ## Allow users to change shortcut keys by hovering the mouse over the respective menu item, and pressing the desired key combination. ## Sadly this doesn't work in the osx native application menu, which GWC now supports. ## N.B. many other programs probably don't save the changes as this option is not well known. gtk-can-change-accels=1 ## Show icons in the menu. ## Helpful for people to learn which toolbar button is which. Sadly doesn't work in native osx app menu. gtk-menu-images=1 ## Show icons on buttons e.g. "Save" and "Cancel". ## Not typically used in windows or osx, although MS office is one of many exceptions. gtk-button-images=1 ## use the win32 button ordering instead of the GNOME HIG one. # gtk-alternative-button-order = 1 ## use the win32/osx sort indicators direction. # gtk-alternative-sort-arrows = 1 ## Disable beep on errors (not sure if this affects GWC). gtk-error-bell = 0 gtk-wave-cleaner-0.22-04/drawing.c0000777000175000017500000011314713120075106020012 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* drawing.c */ #include #include /* #include */ #include "gwc.h" #include #include #include #include #define THICKNESS 3 #define point_color "red" #define handle_color "green" #define point_handle_width 6 #define HANDLE_THICKNESS 1 extern int sonogram_log ; extern GdkPixmap *audio_pixmap ; extern GdkPixmap *highlight_pixmap ; extern GdkPixmap *cursor_pixmap ; int last_cursor_x = -1; extern GtkWidget *audio_drawing_area ; extern long markers[] ; extern long n_markers ; extern long num_song_markers, song_markers[] ; GdkColor red_gdk_color = {0, 65535, 0, 0} ; GdkColor green_gdk_color = {0, 0, 65535, 0} ; GdkColor blue_gdk_color = {1, 0, 0, 65535} ; GdkColor yellow_gdk_color = {2, 65535, 65535, 0} ; GdkColor grey_gdk_color = {3, 43000, 43000, 43000} ; GdkColor white_gdk_color = {4, 65535, 65535, 65535} ; GdkColor black_gdk_color = {5, 0, 0, 0} ; GdkColor orange_gdk_color = {6, 65535, 42240, 0} ; GdkColor sonogram_color[256] ; GdkColor *red_color = &red_gdk_color ; GdkColor *green_color = &green_gdk_color ; GdkColor *blue_color = &blue_gdk_color ; GdkColor *yellow_color = &yellow_gdk_color ; GdkColor *orange_color = &orange_gdk_color ; GdkColor *white_color = &white_gdk_color ; GdkColor *grey_color = &grey_gdk_color ; GdkColor *black_color = &black_gdk_color ; /* #define highlight_color white_color */ GdkColor *highlight_color = &white_gdk_color; #define cut_highlight_color red_color /* a utility function to draw a rect */ static void draw_a_rect(GdkGC *gc, gint x1, gint y1, gint x2, gint y2, GdkColor *color) { gdk_gc_set_foreground(gc, color) ; gdk_draw_rectangle(audio_pixmap, gc, TRUE, x1,y1,x2-x1+1,y2-y1+1) ; } /* a utility function to draw a rect */ static void draw_a_highlight_rect(GdkGC *gc, gint x1, gint y1, gint x2, gint y2, GdkColor *color) { /* gdk doesn't seems to clip before passing to X which only uses shorts for coordinates so at high zoom wrong regions would be highlighted */ if (x1 > SHRT_MAX) x1 = SHRT_MAX; if (y1 > SHRT_MAX) y1 = SHRT_MAX; if (x1 < SHRT_MIN) x1 = SHRT_MIN; if (y1 < SHRT_MIN) y1 = SHRT_MIN; if (x2 > SHRT_MAX) x2 = SHRT_MAX; if (y2 > SHRT_MAX) y2 = SHRT_MAX; if (x2 < SHRT_MIN) x2 = SHRT_MIN; if (y2 < SHRT_MIN) y2 = SHRT_MIN; gdk_gc_set_foreground(gc, color) ; gdk_gc_set_function(gc, GDK_XOR) ; gdk_draw_rectangle(highlight_pixmap, gc, TRUE, x1,y1,x2-x1+1,y2-y1+1) ; gdk_gc_set_function(gc, GDK_COPY) ; } /* a utility function to draw a line */ static void draw_a_line(GdkGC *gc, gint x1, gint y1, gint x2, gint y2, GdkColor *color, int end_shapes) { gdk_gc_set_foreground(gc, color) ; gdk_draw_line(audio_pixmap, gc, x1,y1,x2,y2) ; if (x1 > SHRT_MIN && x1 < SHRT_MAX) { gdk_draw_line(audio_pixmap, gc, x1,y1,x2,y2) ; if(end_shapes & GWC_POINT_HANDLE) { draw_a_rect(gc, (x1-point_handle_width/2), (y1-point_handle_width/2), (x1+point_handle_width/2), (y1+point_handle_width/2), white_color) ; } } } /* a utility function to draw a line */ static void draw_a_cursor_line(GdkGC *gc, gint x1, gint y1, gint x2, gint y2, GdkColor *color, int end_shapes) { gdk_gc_set_foreground(gc, color) ; if (x1 > SHRT_MIN && x1 < SHRT_MAX) gdk_draw_line(highlight_pixmap, gc, x1,y1,x2,y2) ; } int first_pick_x, last_pick_x ; int selecting_region = FALSE ; int region_select_min_x = -1 ; int region_select_max_x = -1 ; long pixel_to_sample(struct view *v, int pixel) { double p = (double)pixel / v->canvas_width ; double w = (v->last_sample - v->first_sample) ; long s = p*w + v->first_sample ; return s ; } int sample_to_pixel(struct view *v, long sample) { double p = (double)(sample-v->first_sample) / (double)(v->last_sample - v->first_sample) ; double w = (v->canvas_width) ; int pix = p*w ; return pix ; } #define MAX_BUF 10000 /* in macro AtoS, a is audio level, max_a is maximum possible audio level, channel is 0 for left, 1 for right ch is canvas_height */ extern double view_scale ; extern struct click_data click_data ; struct click_data *clicks = &click_data ; #if 0 #define AtoS(a,max_a,channel,ch) (long)(a*1000*view_scale)*(long)((ch-16)/4)/((max_a)*1000) + (long)((ch-16)/4) + (long)(channel)*ch/2+8 #endif /* Put 8 spaces in middle for separator bar and prevent one channel from running over into the other */ #define AtoS(a,max_a,channel,ch) (MAX(0,MIN(ch/2-5,lrint(((a)*view_scale/(max_a)+1.0)*(ch-9)/4.0))) + channel*(ch/2+4)) GdkPixmap *wave_image = NULL ; void draw_compressed_audio_image(struct view *v, struct sound_prefs *p, GtkWidget *da) { double samples_per_pixel = (double)(v->last_sample - v->first_sample + 1) / (double)v->canvas_width ; double blocks_per_pixel = samples_per_pixel / (double)SBW ; int draw_flag = 0 ; long pixel ; int x1=0, x2=0, ly1=0, ly2=0, ry1=0, ry2=0 ; if(p->sample_buffer_exists == FALSE) fill_sample_buffer(p) ; /* g_print("samples per pixel = %lg\n", samples_per_pixel) ; */ if(v->selection_region == FALSE) { region_select_min_x = -1 ; region_select_max_x = -1 ; } p->max_value = 0.0 ; for(pixel = 0 ; pixel < v->canvas_width ; pixel++) { long first = v->first_sample + lrint(pixel*samples_per_pixel) ; long last = first + lrint(samples_per_pixel) ; double avg_left = 0, avg_right = 0 ; struct sample_display_block sb ; if(first < 0) first = 0 ; if(first > v->last_sample) first = v->last_sample ; if(last < 0) last = 0 ; if(last > v->last_sample) last = v->last_sample ; /* d_print("data for pixel:%ld, first=%ld, last=%ld ", pixel, first, last) ; */ get_sample_stats(&sb, first, last, blocks_per_pixel) ; if(sb.max_value[0] > p->max_value) p->max_value = sb.max_value[0] ; if(sb.max_value[1] > p->max_value) p->max_value = sb.max_value[1] ; if(1 || samples_per_pixel > 50) { #if 0 avg_left = sb.rms[0] ; avg_right = sb.rms[1] ; avg_left = avg_left/2 + sb.max_value[0]/2 ; avg_right = avg_right/2 + sb.max_value[1]/2 ; #endif avg_left = sb.max_value[0] ; avg_right = sb.max_value[1] ; } else { avg_left = sb.rms[0] ; avg_right = sb.rms[1] ; } ly1 = AtoS(avg_left,1.0,0,v->canvas_height) ; ry1 = AtoS(avg_right,1.0,1,v->canvas_height) ; if(1 || samples_per_pixel > 50) { ly2 = AtoS(-avg_left,1.0,0,v->canvas_height) ; ry2 = AtoS(-avg_right,1.0,1,v->canvas_height) ; } if(1 || samples_per_pixel > 50) { x1 = pixel ; x2 = pixel ; draw_a_line(da->style->black_gc, x1, ly1, x2, ly2, black_color, draw_flag) ; draw_a_line(da->style->black_gc, x1, ry1, x2, ry2, black_color, draw_flag) ; } else if(pixel > 0) { x1 = pixel ; x2 = pixel - 1 ; draw_a_line(da->style->black_gc, x1, ly1, x2, ly2, black_color, draw_flag) ; draw_a_line(da->style->black_gc, x1, ry1, x2, ry2, black_color, draw_flag) ; } ly2 = ly1 ; ry2 = ry1 ; } } extern struct view audio_view ; int _audio_area_button_event(GtkWidget *c, GdkEventButton *event) { /* we ignore all events except for BUTTON_PRESS */ if(event->type == GDK_BUTTON_PRESS) { first_pick_x = last_pick_x = (int)event->x ; selecting_region = TRUE ; d_print("press mx:%d my:%d\n", (int)event->x, (int)event->y) ; if((int)event->y < audio_view.canvas_height/4) audio_view.channel_selection_mask = 0x01 ; else if((int)event->y > 3*audio_view.canvas_height/4) audio_view.channel_selection_mask = 0x02 ; else audio_view.channel_selection_mask = 0x03 ; audio_view.selection_region = FALSE ; main_redraw(FALSE, FALSE) ; display_times() ; return TRUE; } if(event->type == GDK_BUTTON_RELEASE) { region_select_min_x = MIN(first_pick_x, last_pick_x) ; region_select_max_x = MAX(first_pick_x, last_pick_x) ; region_select_min_x = MAX(region_select_min_x, 0) ; region_select_max_x = MIN(region_select_max_x, audio_view.canvas_width-1) ; if(region_select_max_x - region_select_min_x > 0) { audio_view.selected_first_sample = pixel_to_sample(&audio_view, region_select_min_x) ; audio_view.selected_last_sample = pixel_to_sample(&audio_view, region_select_max_x) ; audio_view.selection_region = TRUE ; } else { audio_view.selection_region = FALSE ; } selecting_region = FALSE ; display_times() ; main_redraw(FALSE, FALSE) ; return TRUE; } return FALSE ; } int _audio_area_motion_event(GtkWidget *c, GdkEventMotion *event) { int x, y ; GdkModifierType state ; if(event->is_hint ) { gdk_window_get_pointer(event->window, &x, &y, &state) ; } else { x = event->x ; y = event->y ; state = event->state ; } /* d_print("motion mx:%d my:%d\n", x, y) ; */ if(state & GDK_BUTTON1_MASK) { if(selecting_region == TRUE) { long marker_pix ; int i ; int min_marker_dist_to_first = 10 ; int min_marker_dist_to_last = 10 ; last_pick_x = x ; region_select_min_x = MIN(first_pick_x, last_pick_x) ; region_select_max_x = MAX(first_pick_x, last_pick_x) ; region_select_min_x = MAX(region_select_min_x, 0) ; region_select_max_x = MIN(region_select_max_x, audio_view.canvas_width-1) ; audio_view.selected_first_sample = pixel_to_sample(&audio_view, region_select_min_x) ; audio_view.selected_last_sample = pixel_to_sample(&audio_view, region_select_max_x+1) - 1 ; if(audio_view.selected_last_sample > audio_view.n_samples-1) audio_view.selected_last_sample = audio_view.n_samples-1 ; for(i = 0 ; i < n_markers ; i++) { if(markers[i] < 0) continue ; marker_pix = sample_to_pixel(&audio_view, markers[i]) ; if( ABS(region_select_min_x-marker_pix) < min_marker_dist_to_first) { min_marker_dist_to_first = ABS(region_select_min_x-marker_pix) ; //region_select_min_x = marker_pix ; audio_view.selected_first_sample = markers[i] ; } if( ABS(region_select_max_x-marker_pix) < min_marker_dist_to_last) { min_marker_dist_to_last = ABS(region_select_max_x-marker_pix) ; //region_select_max_x = marker_pix ; audio_view.selected_last_sample = markers[i] ; } } for(i = 0 ; i < num_song_markers ; i++) { if(song_markers[i] < 0) continue ; marker_pix = sample_to_pixel(&audio_view, song_markers[i]) ; if( ABS(region_select_min_x-marker_pix) < min_marker_dist_to_first) { min_marker_dist_to_first = ABS(region_select_min_x-marker_pix) ; //region_select_min_x = marker_pix ; audio_view.selected_first_sample = song_markers[i] ; } if( ABS(region_select_max_x-marker_pix) < min_marker_dist_to_last) { min_marker_dist_to_last = ABS(region_select_max_x-marker_pix) ; //region_select_max_x = marker_pix ; audio_view.selected_last_sample = song_markers[i] ; } } audio_view.selection_region = TRUE ; display_times() ; main_redraw(FALSE, FALSE) ; return TRUE ; } } /* return true as we have handled it */ return FALSE; } int psk_to_color(double pwr, double max_amp, int max_color) { double p = 10.0*log10(pwr/(max_amp*max_amp)) ; /* convert decibels in range 0 to -120 to range 1 to 0 */ p = (p - -80.0) / (80.0) ; if(p < 0.0) p = 0.0 ; if(p > 1.0) p = 1.0 ; return p * max_color ; } int jw_psk_to_color(double pwr, double max_amp, int max_color) { double p = 10.0*log10(pwr/(max_amp*max_amp)) ; /* convert decibels in range 0 to -120 to range 1 to 0 */ /* jjw version */ p = (p - -100.0) / (100.0) ; if(p < 0.0) p = 0.0 ; if(p > 1.0) p = 1.0 ; return p * max_color ; } #define sqr(x) (x)*(x) #define FFT_MAX 8192 double spectral_amp = 1.0 ; /* If COMBINE_MAX is set then we combine multiple frequency bins into each pixel with a max function else average them */ #define COMBINE_MAX void draw_sonogram(struct view *v, struct sound_prefs *pPrefs, GtkWidget *da, double samples_per_pixel, int cursor_flag) { int FFT_SIZE ; fftw_real left[FFT_MAX], right[FFT_MAX], out[FFT_MAX], power_spectrum[FFT_MAX/2+1], window[FFT_MAX] ; double merged_power_spectrum[FFT_MAX]; double merged_power_count[FFT_MAX]; #ifdef HAVE_FFTW3 FFTW(plan) pLeft, pRight ; #else /* HAVE_FFTW3 */ rfftw_plan p ; #endif /* HAVE_FFTW3 */ int ly1, ly2, color, k ; int ly1_tbl[FFT_MAX], ly2_tbl[FFT_MAX] ; int ly_offset[2]; long min_sample, max_sample ; long sample ; int x ; int m ; double view_scale_save = view_scale ; GdkImage *image ; int y ; int spec_start, spec_stop; int channel; double spectrum_scale; int index_20Hz; #define MAXSW 2000 #define MAXSH 400 unsigned char level[2][MAXSW][MAXSH] ; push_status_text("Building sonogram") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; /* only draw the sonogram at a scale of 1.0 */ view_scale = 1.0 ; /* Is gdk_visual_get_system the correct visual? */ image = gdk_image_new(GDK_IMAGE_FASTEST, gdk_visual_get_system(), v->canvas_width, v->canvas_height); if (image == NULL) { printf("Unable to create image\n"); exit(1); } for(y = 0 ; y < v->canvas_height ; y++) { for(x = 0 ; x < v->canvas_width ; x++) { gdk_image_put_pixel(image, x, y, black_color->pixel); } } for(FFT_SIZE = 64 ; FFT_SIZE < FFT_MAX ; FFT_SIZE *= 2) if(FFT_SIZE > samples_per_pixel*2) break ; /* g_print("Sonogram FFT_SIZE:%d\n", FFT_SIZE) ; */ m = FFT_SIZE/4 ; index_20Hz = MAX(1,(20 * FFT_SIZE + pPrefs->rate / 2) / pPrefs->rate); /* Normalize energy based on number of bins relative to maximum length FFT */ spectrum_scale = spectral_amp * sqrt((double) FFT_SIZE / FFT_MAX) * 4.0; #ifdef HAVE_FFTW3 pLeft = FFTW(plan_r2r_1d)(FFT_SIZE, left, out, FFTW_R2HC, FFTW_ESTIMATE); pRight = FFTW(plan_r2r_1d)(FFT_SIZE, right, out, FFTW_R2HC, FFTW_ESTIMATE); #else /* HAVE_FFTW3 */ p = rfftw_create_plan(FFT_SIZE, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE); #endif /* HAVE_FFTW3 */ for(k = 0 ; k < FFT_SIZE ; k++) { window[k] = blackman(k,FFT_SIZE) ; /* window[k] = pow(window[k],1.0) ; */ } { double shift = (log(FFT_SIZE/2-1) + log(index_20Hz))/2; double scale = shift - log(index_20Hz); for(k = 1 ; k <= FFT_SIZE/2 ; k++) { if (sonogram_log) { ly1_tbl[k] = AtoS(MIN(shift - log(k),scale),scale,0,v->canvas_height) ; ly2_tbl[k] = AtoS(MIN(shift - log(k+1),scale),scale,0,v->canvas_height) ; } else { ly1_tbl[k] = AtoS(-(k-m-1),FFT_SIZE/4.0,0,v->canvas_height) ; ly2_tbl[k] = AtoS(-(k-m),FFT_SIZE/4.0,0,v->canvas_height) ; } } } ly1_tbl[0] = 99999999; ly2_tbl[0] = 99999999; spec_start = ly2_tbl[FFT_SIZE/2]; spec_stop = ly1_tbl[1]-1; for(k = spec_start ; k <= spec_stop ; k++) { merged_power_count[k] = 0; } for(k = 1 ; k <= FFT_SIZE/2 ; k++) { merged_power_count[ly2_tbl[k]]++; } ly_offset[0] = 0; ly_offset[1] = AtoS(-(1-m-1),FFT_SIZE/4.0,1,v->canvas_height) - ly1_tbl[1]; for(x = 0 ; x < v->canvas_width ; x++) { long mid_sample ; update_progress_bar((double) x / v->canvas_width,PROGRESS_UPDATE_INTERVAL,FALSE) ; sample = pixel_to_sample(&audio_view, x) ; min_sample = sample-FFT_SIZE/2 ; min_sample = MAX(0, min_sample) ; max_sample = min_sample+FFT_SIZE-1 ; if(max_sample > audio_view.n_samples-1) max_sample = audio_view.n_samples-1 ; mid_sample = (max_sample-min_sample+1)/2 ; read_fft_real_wavefile_data(left, right, min_sample, max_sample) ; for(k = 0 ; k < FFT_SIZE ; k++) { left[k] *= window[k] ; right[k] *= window[k] ; } for (channel = 0; channel < 2; channel++) { #ifdef HAVE_FFTW3 if (channel == 0) FFTW(execute)(pLeft); else FFTW(execute)(pRight); #else /* HAVE_FFTW3 */ if (channel == 0) rfftw_one(p, left, out); else rfftw_one(p, right, out); #endif /* HAVE_FFTW3 */ power_spectrum[0] = out[0]*out[0]; /* DC component */ for (k = 1; k < (FFT_SIZE+1)/2; ++k) /* (k < FFT_SIZE/2 rounded up) */ /* power_spectrum[k] = out[k]*out[k] ; */ power_spectrum[k] = out[k]*out[k] + out[FFT_SIZE-k]*out[FFT_SIZE-k]; if (FFT_SIZE % 2 == 0) /* N is even */ power_spectrum[FFT_SIZE/2] = (out[FFT_SIZE/2]*out[FFT_SIZE/2]); /* Nyquist freq. */ if (FFT_SIZE/2 >= spec_stop - spec_start + 1 || sonogram_log) { for(k = spec_start ; k <= spec_stop ; k++) { #ifdef COMBINE_MAX merged_power_spectrum[k] = -DBL_MAX; #else merged_power_spectrum[k] = 0.0; #endif } for(k = sonogram_log ? index_20Hz : 1 ; k <= FFT_SIZE/2 ; k++) { #ifdef COMBINE_MAX if (power_spectrum[k] > merged_power_spectrum[ly1_tbl[k]]) merged_power_spectrum[ly1_tbl[k]] = power_spectrum[k]; #else merged_power_spectrum[ly1_tbl[k]] += power_spectrum[k]; #endif } #ifndef COMBINE_MAX for(k = spec_start ; k <= spec_stop ; k++) { merged_power_spectrum[k] /= merged_power_count[k]; } #endif for(k = spec_start ; k <= spec_stop ; k++) { ly1 = ly1_tbl[k]; ly2 = ly2_tbl[k]; for (y = ly2 + 1; y < ly1; y++) { merged_power_spectrum[y] = merged_power_spectrum[ly1]; } } } else { for(k = 1 ; k <= FFT_SIZE/2 ; k++) { ly1 = ly1_tbl[k]; ly2 = ly2_tbl[k]; for (y = ly2; y <= ly1; y++) { merged_power_spectrum[y] = power_spectrum[k]; } } } #define BOTH_DJG_JJW_NOT #ifdef BOTH_DJG_JJW for(k = spec_start ; k <= spec_stop ; k++) { color = psk_to_color(merged_power_spectrum[k], spectrum_scale, 255) ; if(color > 255) color=255 ; if(color < 0) color=0 ; gdk_image_put_pixel(image, x, k + ly_offset[0], sonogram_color[color].pixel); } for(k = 1 ; k <= FFT_SIZE/2 ; k++) { { int y ; color = jw_psk_to_color(power_spectrum[k]*spectral_amp, 1.0, 255) ; if(color > 255) color=255 ; if(color < 0) color=0 ; for(y = ly2_tbl[k] ; y < ly1_tbl[k] ; y++) { gdk_image_put_pixel(image, x, y + ly_offset[1], sonogram_color[color].pixel); } } } #else #ifdef DJG for(k = spec_start ; k <= spec_stop ; k++) { color = psk_to_color(merged_power_spectrum[k], spectrum_scale, 255) ; if(color > 255) color=255 ; if(color < 0) color=0 ; gdk_image_put_pixel(image, x, k + ly_offset[channel], sonogram_color[color].pixel); } #else for(k = 1 ; k <= FFT_SIZE/2 ; k++) { int y ; color = psk_to_color(power_spectrum[k]*spectral_amp, 1.0, 255) ; if(color < 0) color=0 ; level[channel][x][k-1] = color ; if(color > 255) color=255 ; { for(y = ly2_tbl[k] ; y < ly1_tbl[k] ; y++) { gdk_image_put_pixel(image, x, y + ly_offset[channel], sonogram_color[color].pixel); } } } #endif #endif } } gdk_draw_image(audio_pixmap, da->style->white_gc, image, 0, 0, 0, 0, v->canvas_width, v->canvas_height); gdk_image_destroy(image); #define DRAW_CLICKS_NOT #ifdef DRAW_CLICKS #define CLICK_WINDOW_SIZE 1000 #define CLICK_WINDOW_STEP 800 int iwindow ; /* this goes BACKWARDS through the data */ for(iwindow = v->last_sample; iwindow >= v->first_sample ; iwindow -= CLICK_WINDOW_STEP) { int ifirst = iwindow-CLICK_WINDOW_SIZE ; if(ifirst < 0) ifirst=0 ; int window_size = iwindow-ifirst ; fftw_real pdata[2][CLICK_WINDOW_SIZE] ; fprintf(stderr, "ifirst, iwindow, %d %d\n", ifirst, iwindow) ; read_fft_real_wavefile_data(pdata[0], pdata[1], ifirst, iwindow) ; int j ; for(j = 0 ; j < window_size+1 ; j++) { int i = iwindow-j ; for(channel = 0 ; channel < 2 ; channel++) { double hpf, hpf_ave, hpf_dev; double hpf2, hpf2_ave, hpf2_dev; get_hpf(i,pdata[channel],&hpf,&hpf_ave,&hpf_dev,&hpf2,&hpf2_ave,&hpf2_dev); ly1 = AtoS(hpf,200.0,channel,v->canvas_height) ; ly2 = AtoS(hpf2,200.0,channel,v->canvas_height) ; int x = sample_to_pixel(v, i) ; draw_a_line(da->style->white_gc, x, ly1, x, ly2, green_color, 0) ; } } } #endif /* DRAW_FFT_CLICKS */ #ifdef DRAW_FFT_CLICKS for(channel = 0 ; channel < 2 ; channel++) { double mean_level[MAXSH] ; double offset[MAXSW] ; double hgt_sum ; double mean, std_err, var, cv, stddev ; long click_start, click_end ; int in_click ; for(k = 0 ; k < FFT_SIZE/2 ; k++) { mean_level[k] = 0.0 ; for(x = 0 ; x < v->canvas_width ; x++) mean_level[k] += level[channel][x][k] ; mean_level[k] /= v->canvas_width ; } for(x = 0 ; x < v->canvas_width ; x++) { offset[x] = 0.0 ; for(k = 0 ; k < FFT_SIZE/2 ; k++) { offset[x] += level[channel][x][k] - mean_level[k] ; } offset[x] /= (double)FFT_SIZE/2.0 ; if(offset[x] < 0.0) offset[x] = 0.0 ; } stats(offset, v->canvas_width, &mean, &std_err, &var, &cv, &stddev) ; in_click = 0 ; for(x = 0 ; x < v->canvas_width-1 ; x++) { double z = (offset[x]-mean)/stddev ; double z1 = (offset[x+1]-mean)/stddev ; if(z < 0.0) z = 0.0 ; if(z1 < 0.0) z1 = 0.0 ; ly1 = AtoS(-40.0*z,200.0,channel,v->canvas_height) ; ly2 = AtoS(-40.0*z1,200.0,channel,v->canvas_height) ; if(z > 1.e-30) { if(!in_click) { in_click = 1 ; click_start = x ; hgt_sum = z ; } else { hgt_sum += z ; } } else { if(in_click) { double click_width = ((x-1) - click_start+1) ; int click_mid = (click_start + click_width/2+0.5) ; int y1,y2 ; hgt_sum /= click_width ; //printf("%d %lg\n", click_mid, hgt_sum) ; y1 = AtoS(0.0,200.0,channel,v->canvas_height) ; y2 = AtoS(-40.0*hgt_sum,200.0,channel,v->canvas_height) ; draw_a_line(da->style->white_gc, click_mid-1, y1, click_mid-1, y2, green_color, 0) ; draw_a_line(da->style->white_gc, click_mid, y1, click_mid, y2, green_color, 0) ; draw_a_line(da->style->white_gc, click_mid+1, y1, click_mid+1, y2, green_color, 0) ; } in_click = 0 ; } draw_a_line(da->style->white_gc, x, ly1, x+1, ly2, green_color, 0) ; } } #endif /* DRAW_FFT_CLICKS */ #ifdef HAVE_FFTW3 FFTW(destroy_plan)(pLeft); FFTW(destroy_plan)(pRight); #else /* HAVE_FFTW3 */ rfftw_destroy_plan(p); #endif /* HAVE_FFTW3 */ update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text(); #ifdef TEST_DRAW_CLICK_FINDER in_click = 0 ; #define N 50 { double mean_right, stderr_right, var_right, cv_right, stddev_right ; stats(&right_hpf[0], v->canvas_width, &mean_right, &stderr_right, &var_right, &cv_right, &stddev_right) ; d_print("mean_right:%g\n", mean_right) ; /* draw 2 reference lines, for mean height and z values on first derivative */ ly1 = AtoS(100-ABS(2.0*mean_right),200.0,1,v->canvas_height) ; draw_a_line(da->style->white_gc, 0, ly1, v->canvas_width-1, ly1, green_color, 0) ; ly1 = AtoS(2.5-ABS(1.0),5.0,1,v->canvas_height) ; draw_a_line(da->style->white_gc, 0, ly1, v->canvas_width-1, ly1, red_color, 0) ; } #endif gdk_gc_set_foreground(da->style->white_gc, white_color) ; gdk_gc_set_foreground(da->style->black_gc, black_color) ; view_scale = view_scale_save ; } void paint_screen_with_highlight(struct view *v, GtkWidget *da, int y1, int y2, int cursor_flag) { int x = sample_to_pixel(v, v->cursor_position) ; GdkGC *MyGC = gdk_gc_new(da->window) ; gdk_draw_pixmap(highlight_pixmap, da->style->fg_gc[GTK_WIDGET_STATE (da)], audio_pixmap, 0,0, 0,0, v->canvas_width, v->canvas_height); if(v->selection_region == TRUE) { gint minx = region_select_min_x ; gint maxx = region_select_max_x ; if(audio_view.channel_selection_mask == 0x01) draw_a_highlight_rect(MyGC, minx, 0, maxx, v->canvas_height/2, highlight_color) ; else if(audio_view.channel_selection_mask == 0x02) draw_a_highlight_rect(MyGC, minx, v->canvas_height/2, maxx, v->canvas_height-1, highlight_color) ; else draw_a_highlight_rect(MyGC, minx, 0, maxx, v->canvas_height-1, highlight_color) ; } #ifdef TRUNCATE_OLD if(v->truncate_head > 0) { gint maxx = sample_to_pixel(v, v->truncate_head) ; if(maxx > 0) { gint minx = sample_to_pixel(v, 0) ; if(minx < 0) minx = 0 ; draw_a_highlight_rect(MyGC, minx, 0, maxx, v->canvas_height-1, cut_highlight_color) ; } } if(v->truncate_tail < v->n_samples-1) { gint minx = sample_to_pixel(v, v->truncate_tail) ; if(minx < v->canvas_width) { gint maxx = sample_to_pixel(v, v->n_samples-1) ; if(maxx > v->canvas_width-1) maxx = v->canvas_width-1 ; draw_a_highlight_rect(MyGC, minx, 0, maxx, v->canvas_height-1, cut_highlight_color) ; } } #endif /* TRUNCATE_OLD */ if(cursor_flag == TRUE) { /* draw_a_cursor_line(MyGC, x-4, y1+4, x-4, y2-4, yellow_color, 0) ; */ /* draw_a_cursor_line(MyGC, x-3, y1+3, x-3, y2-3, yellow_color, 0) ; */ /* draw_a_cursor_line(MyGC, x-2, y1+2, x-2, y2-2, yellow_color, 0) ; */ /* draw_a_cursor_line(MyGC, x-1, y1+1, x-1, y2-1, yellow_color, 0) ; */ /* draw_a_cursor_line(MyGC, x+0, y1+0, x+0, y2+0, yellow_color, 0) ; */ last_cursor_x = x; /**************** This is also in redraw *******************/ gdk_draw_pixmap(cursor_pixmap, da->style->fg_gc[GTK_WIDGET_STATE (da)], highlight_pixmap, x,0, 0,0, 1, v->canvas_height); draw_a_cursor_line(MyGC, x+0, 0, x+0, v->canvas_height-1, yellow_color, 0) ; /* draw_a_cursor_line(MyGC, x+1, y1+1, x+1, y2-1, yellow_color, 0) ; */ /* draw_a_cursor_line(MyGC, x+2, y1+2, x+2, y2-2, yellow_color, 0) ; */ /* draw_a_cursor_line(MyGC, x+3, y1+3, x+3, y2-3, yellow_color, 0) ; */ /* draw_a_cursor_line(MyGC, x+4, y1+4, x+4, y2-4, yellow_color, 0) ; */ } else { last_cursor_x = -1; } gdk_draw_pixmap(da->window, da->style->fg_gc[GTK_WIDGET_STATE (da)], highlight_pixmap, 0,0, 0,0, v->canvas_width, v->canvas_height); gdk_gc_unref(MyGC) ; } void redraw(struct view *v, struct sound_prefs *p, GtkWidget *da, int cursor_flag, int redraw_data, int sonogram_flag) { /* double left[MAX_BUF], right[MAX_BUF] ; */ fftw_real left[MAX_BUF], right[MAX_BUF] ; long i, n ; int pixels_per_sample = v->canvas_width / (v->last_sample - v->first_sample + 1) ; double samples_per_pixel = (double)(v->last_sample - v->first_sample + 1) / (double)v->canvas_width ; int draw_flag = 0 ; int zero_left, zero_right ; int y1 = v->canvas_height/2.0 - 4; int y2 = y1 + 8 ; static int first_time = 1 ; static GdkColormap *my_map ; GdkGC *MyGC ; zero_left = AtoS(0,1.0,0,v->canvas_height) ; zero_right = AtoS(0,1.0,1,v->canvas_height) ; if(v->selection_region == FALSE) { region_select_min_x = -1 ; region_select_max_x = -1 ; } else { if(v->selection_region == TRUE) { region_select_min_x = sample_to_pixel(v, v->selected_first_sample) ; region_select_max_x = sample_to_pixel(v, v->selected_last_sample) ; } } if(cursor_flag != TRUE) { MyGC = gdk_gc_new(da->window) ; } else { if(v->cursor_position >= v->first_sample && v->cursor_position <= v->last_sample) { int prev_x = sample_to_pixel(v, v->prev_cursor_position) ; int x = sample_to_pixel(v, v->cursor_position) ; if(x != prev_x) { MyGC = gdk_gc_new(da->window) ; if (last_cursor_x == -1) { paint_screen_with_highlight(v, da, y1, y2, cursor_flag) ; } else { int x = sample_to_pixel(v, v->cursor_position) ; /****** This is also in paint_screen_with_highlight *******/ gdk_draw_pixmap(highlight_pixmap, da->style->fg_gc[GTK_WIDGET_STATE (da)], cursor_pixmap, 0,0, last_cursor_x,0, 1, v->canvas_height); gdk_draw_pixmap(da->window, da->style->fg_gc[GTK_WIDGET_STATE (da)], cursor_pixmap, 0,0, last_cursor_x,0, 1, v->canvas_height); gdk_draw_pixmap(cursor_pixmap, da->style->fg_gc[GTK_WIDGET_STATE (da)], highlight_pixmap, x,0, 0,0, 1, v->canvas_height); draw_a_cursor_line(MyGC, x+0, 0, x+0, v->canvas_height-1, yellow_color, 0) ; gdk_draw_pixmap(da->window, da->style->fg_gc[GTK_WIDGET_STATE (da)], highlight_pixmap, x,0, x,0, 1, v->canvas_height); last_cursor_x = x; } gdk_gc_unref(MyGC) ; } else { } v->prev_cursor_position = v->cursor_position ; } return ; } if(first_time == 1) { int i ; first_time = 0 ; /* my_visual = gdk_visual_get_best() ; */ /* my_map = gdk_colormap_new(my_visual, FALSE) ; */ my_map = gdk_colormap_get_system() ; gdk_colormap_alloc_color(my_map, black_color, FALSE, TRUE) ; gdk_colormap_alloc_color(my_map, white_color, FALSE, TRUE) ; gdk_colormap_alloc_color(my_map, grey_color, FALSE, TRUE) ; gdk_colormap_alloc_color(my_map, red_color, FALSE, TRUE) ; gdk_colormap_alloc_color(my_map, green_color, FALSE, TRUE) ; gdk_colormap_alloc_color(my_map, blue_color, FALSE, TRUE) ; gdk_colormap_alloc_color(my_map, yellow_color, FALSE, TRUE) ; gdk_colormap_alloc_color(my_map, orange_color, FALSE, TRUE) ; #define JJW_CMAP_NOT #ifdef JJW_CMAP for(i = 0 ; i < 256 ; i++) { double d = i ; double p_red = (d-105.0)/150.0 ; double p_green = (d-200.0)/55.0 ; double p_blue = d/255.0 ; if(i > 100) p_blue = 1.0 - (d-100.0)/20.0 ; /* if(i > 128 && i < 192) p_blue = 1.0 - (d-128.0)/64.0 ; */ /* if(i > 192) p_blue = (d-192.0)/64.0 ; */ if(0){ double c[5][3] = { {0.0,0.0,0.0}, {0.0,0.0,0.5}, {0.5,0.0,1.0}, {1.0,0.5,1.0}, {1.0,1.0,1.0} } ; double p0, p1,d ; int ilow ; int breakpt[5] = {0,51,102,204,255} ; for(ilow = 0 ; ilow < 4 ; ilow++) if(breakpt[ilow+1] > i) break ; d = breakpt[ilow+1] - breakpt[ilow] ; p1 = (double)(i-breakpt[ilow])/d ; p0 = 1.0 - p1 ; p_red = c[ilow][0]*p0 + c[ilow+1][0]*p1 ; p_green = c[ilow][1]*p0 + c[ilow+1][1]*p1 ; p_blue = c[ilow][2]*p0 + c[ilow+1][2]*p1 ; } p_red = MIN(1.0, p_red) ; p_green = MIN(1.0, p_green) ; p_blue = MIN(1.0, p_blue) ; p_red = MAX(0.0, p_red) ; p_green = MAX(0.0, p_green) ; p_blue = MAX(0.0, p_blue) ; sonogram_color[i].red = 65535*p_red/2.0 ; sonogram_color[i].green = 65535*p_green/2.0 ; sonogram_color[i].blue = 65535*p_blue/2.0 ; gdk_colormap_alloc_color(my_map, &sonogram_color[i], FALSE, TRUE) ; } #else #define PASTEL #define WHITE_HOT for(i = 0 ; i < 256 ; i++) { double d = i ; double p_red = 0.0; double p_green = 0.0; double p_blue = 0.0; double gamma_fact = 1/1.5; p_blue = d / 85.0; if (i > 85) { p_red = (d - 85.0) / (85.0) ; p_blue = (170.0 - d) / 85.0; } if (i > 170) { p_red = (255.0 - d) / 85.0 ; p_green = (d - 170.0) / (50.0) ; #ifdef WHITE_HOT p_red = MAX(p_red, p_green) ; #endif } #ifdef WHITE_HOT if (i > 220) { p_blue = (d-220.0) / 35.0 ; } #endif p_red = MIN(1.0, p_red) ; p_green = MIN(1.0, p_green) ; p_blue = MIN(1.0, p_blue) ; p_red = MAX(0.0, p_red) ; p_green = MAX(0.0, p_green) ; p_blue = MAX(0.0, p_blue) ; #ifdef PASTEL /* desaturate the colors a bit... */ { double max_v = MAX(p_red, MAX(p_green, p_blue)) ; double sum_v = p_red + p_green + p_blue ; if(sum_v < 1.0) { double ds = (1.0-sum_v)*max_v ; p_red += ds ; p_green += ds ; /* p_blue += ds ; */ } } p_red = MIN(1.0, p_red) ; p_green = MIN(1.0, p_green) ; p_blue = MIN(1.0, p_blue) ; #endif sonogram_color[i].red = 65535*pow(p_red, gamma_fact) ; sonogram_color[i].green = 65535*pow(p_green, gamma_fact) ; sonogram_color[i].blue = 65535*pow(p_blue, gamma_fact) ; #ifdef INVERT_SONOGRAM sonogram_color[i].red = 65535 - sonogram_color[i].red ; sonogram_color[i].green = 65535 - sonogram_color[i].green ; sonogram_color[i].blue = 65535 - sonogram_color[i].blue ; #endif gdk_colormap_alloc_color(my_map, &sonogram_color[i], FALSE, TRUE) ; } #endif /* Some 8 bit displays use 0 for white so XOR doesn't highlight * selection */ if (highlight_color->pixel == 0) highlight_color = black_color; } if(sonogram_flag == TRUE) { if (redraw_data) draw_sonogram(v, p, da, samples_per_pixel, cursor_flag) ; gdk_draw_rectangle(audio_pixmap, MyGC, TRUE, 0, y1, v->canvas_width-1, 8) ; paint_screen_with_highlight(v, da, y1, y2, cursor_flag) ; } else if (redraw_data) { /* clear the background to grey */ draw_a_rect(MyGC, 0, 0, v->canvas_width-1, v->canvas_height-1, grey_color) ; draw_a_rect(MyGC, 0, y1, v->canvas_width-1, y2, black_color) ; for(i = 0 ; i < clicks->n_clicks ; i++) { int x1 = sample_to_pixel(v, clicks->start[i]) ; int x2 = sample_to_pixel(v, clicks->end[i]) ; int y1 = AtoS(-1.0,1.0,clicks->channel[i],v->canvas_height) ; int y2 = AtoS(1.0,1.0,clicks->channel[i],v->canvas_height) ; /* g_print("Click %s, %ld to %ld\n", clicks->channel[i] ? "R" : "L", clicks->start[i], clicks->end[i]) ; */ draw_a_rect(MyGC, x1, y1, x2, y2, red_color) ; } p->max_value = 0.0 ; if(pixels_per_sample >= 1) { double samp_width = 1./samples_per_pixel ; if(pixels_per_sample > 8) draw_flag = GWC_POINT_HANDLE ; n = read_fft_real_wavefile_data(left, right, v->first_sample, v->last_sample) ; for(i = 0 ; i < n-1 ; i++) { int x1, x2, ly1, ly2, ry1, ry2 ; if(ABS(left[i]) > p->max_value) p->max_value = ABS(left[i]) ; if(ABS(right[i]) > p->max_value) p->max_value = ABS(right[i]) ; ly1 = AtoS(left[i],1.0,0,v->canvas_height) ; ly2 = AtoS(left[i+1],1.0,0,v->canvas_height) ; ry1 = AtoS(right[i],1.0,1,v->canvas_height) ; ry2 = AtoS(right[i+1],1.0,1,v->canvas_height) ; x1 = (int)((double)i*samp_width+0.5) + point_handle_width/2 ; x2 = x1 + pixels_per_sample ; draw_a_line(MyGC, x1, ly1, x2, ly2, black_color, draw_flag) ; draw_a_line(MyGC, x1, ry1, x2, ry2, black_color, draw_flag) ; } /* d_print("MAX VALUE is %ld.\n", p->max_value) ; */ } else { draw_compressed_audio_image(v, p, da) ; } draw_a_line(MyGC, 0, zero_left, v->canvas_width-1, zero_left, blue_color, 0) ; draw_a_line(MyGC, 0, zero_right, v->canvas_width-1, zero_right, blue_color, 0) ; int n_view_samples = v->last_sample-v->first_sample+1 ; if(n_view_samples < 20000) { int x ; /* draw the RMSE of samples in a green line */ double last_left_rmse = -1.0 ; double last_right_rmse = -1.0 ; double left_rmse = -1 ; double right_rmse = -1 ; double samp_width = 1./samples_per_pixel ; for(x = 0 ; x < v->canvas_width ; x++) { int s_at_x = (double)x / (double)(v->canvas_width-1) * n_view_samples + v->first_sample ; int first = MAX(s_at_x-50, 0) ; int last = MIN(s_at_x+50, v->n_samples-1) ; n = read_fft_real_wavefile_data(left, right, first, last) ; left_rmse = 0 ; /* first use these for sums */ right_rmse = 0 ; for(i = 0 ; i < n-1 ; i++) { left_rmse += left[i] * left[i] ; right_rmse += right[i] * right[i] ; } left_rmse = sqrt(left_rmse/((double)n+1.e-30)) ; right_rmse = sqrt(right_rmse/((double)n+1.e-30)) ; if(last_left_rmse > -1.0) { int x1, x2, ly1, ly2, ry1, ry2 ; ly1 = AtoS(-last_left_rmse,1.0,0,v->canvas_height) ; ly2 = AtoS(-left_rmse,1.0,0,v->canvas_height) ; ry1 = AtoS(-last_right_rmse,1.0,1,v->canvas_height) ; ry2 = AtoS(-right_rmse,1.0,1,v->canvas_height) ; x1 = x ; x2 = x1 + 1 ; draw_a_line(MyGC, x1, ly1, x2, ly2, green_color, draw_flag) ; draw_a_line(MyGC, x1, ry1, x2, ry2, green_color, draw_flag) ; } last_left_rmse = left_rmse ; last_right_rmse = right_rmse ; } } } draw_a_rect(MyGC, 0, y1, v->canvas_width-1, y1+8, black_color) ; for(i = 0 ; i < n_markers ; i++) { if(markers[i] >= v->first_sample && markers[i] <= v->last_sample) { int x = sample_to_pixel(v, markers[i]) ; draw_a_line(MyGC, x, 0, x, v->canvas_height-1, blue_color, 0) ; } } { for (i = 0; i < num_song_markers; i++) { if(song_markers[i] >= v->first_sample && song_markers[i] <= v->last_sample) { gint x = sample_to_pixel(v, song_markers[i]) ; draw_a_line(MyGC, x, 0, x, v->canvas_height-1, orange_color, 0) ; } } } /* if(v->selection_region == TRUE) { */ paint_screen_with_highlight(v, da, y1, y2, cursor_flag) ; /* } else { */ /* rect.x = 0 ; */ /* rect.y = 0 ; */ /* rect.width = v->canvas_width ; */ /* rect.height = v->canvas_height ; */ /* gtk_widget_draw(da, &rect) ; */ /* } */ gdk_gc_set_foreground(da->style->white_gc, white_color) ; gdk_gc_set_foreground(da->style->black_gc, black_color) ; gdk_gc_unref(MyGC) ; } gtk-wave-cleaner-0.22-04/encode.c0000777000175000017500000006112113120075106017606 0ustar00alisteralister00000000000000/**************************************************************************** * Gnome Wave Cleaner Version 0.01 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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 #include #include #include #include #include #include #include #include #include #include #include /* for basename() */ #include "gwc.h" #include "encoding.h" /* sound files for in and out streams */ SNDFILE *in_fd; SNDFILE *out_fd; char *options[255]; char pipe_name[256] ; SF_INFO insfinfo, outsfinfo; /* sound file format descriptions for input and output */ extern struct encoding_prefs encoding_prefs; struct stat filestat; int build_options(int fmt, char *newfilename, char *trackname) { int i, optcnt = 0; sprintf(pipe_name, ".gwc_pipe%d\n", (int)getpid()) ; /* remove any old options */ for (i = 0; i < 255; i++) options[i] = (char *)NULL; if (insfinfo.channels > 2) { warning("We only support mono and stereo encodings"); return (1); } if (fmt == OGG_FMT) { /* Check if defined encoder location and it exists */ if ((strlen(encoding_prefs.oggloc) == 0) || (stat(encoding_prefs.oggloc, &filestat) == -1)) { // We should probably just set it to /usr/bin/ogg by default, or `which ogg` warning("Encoder for Ogg is not defined correctly - check the Settings menu\n"); return 1; } /* Required Settings */ options[optcnt] = (char *) basename(encoding_prefs.oggloc); /* argv[0] is the excutable */ optcnt++; options[optcnt] = "-"; /* read from stdin */ // Alister: need to comment this out if use_sox=1. options[optcnt] = pipe_name ; /* named pipe */ optcnt++; options[optcnt] = "-o"; /* Output to newfilename */ optcnt++; options[optcnt] = newfilename; optcnt++; options[optcnt] = "-r"; /* Raw input */ optcnt++; options[optcnt] = "-C"; /* Channels */ optcnt++; if (insfinfo.channels == 2) { options[optcnt] = "2"; } else { options[optcnt] = "1"; } optcnt++; options[optcnt] = "-R"; /* Sample Rate */ optcnt++; // Alister: I think we could get rid of the warning below and possibly allow the user to choose the samplerate instead of getting it from the input file. switch (insfinfo.samplerate) { case 48000: options[optcnt] = "48000"; break; case 44100: options[optcnt] = "44100"; break; case 32000: options[optcnt] = "32000"; break; case 24000: options[optcnt] = "24000"; break; case 22050: options[optcnt] = "22050"; break; case 16000: options[optcnt] = "16000"; break; case 12000: options[optcnt] = "12000"; break; case 11025: options[optcnt] = "11025"; break; case 8000: options[optcnt] = "8000"; break; default: warning ("Please resample audio file to standard 8/11.025/12/16/22.05/24/32/44.1/48 kHz\n"); return (1); break; } optcnt++; options[optcnt] = "-B"; /* Bit Width */ optcnt++; options[optcnt] = "16"; /* Output format is 16 bit PCM */ optcnt++; /* check for downmix */ if (encoding_prefs.ogg_downmix == 1) { options[optcnt] = "--downmix"; optcnt++; } /* check for resample */ if (encoding_prefs.ogg_useresample == 1) { options[optcnt] = "--resample"; options[optcnt + 1] = encoding_prefs.ogg_resample; optcnt = optcnt + 2; } /* check for adv low pass */ if (encoding_prefs.ogg_useadvlowpass == 1) { options[optcnt] = "--advanced_encode_option"; options[optcnt + 1] = strcat("lowpass_frequency=", encoding_prefs.ogg_lowpass_frequency); optcnt = optcnt + 2; } /* check for adv Bitrate Avg Window */ if (encoding_prefs.ogg_useadvbravgwindow == 1) { options[optcnt] = "--advanced_encode_option"; options[optcnt + 1] = strcat("bitrate_average_window=", encoding_prefs.ogg_bitrate_average_window); optcnt = optcnt + 2; } if ((strlen(trackname) > 0)) { options[optcnt] = "-t"; options[optcnt + 1] = trackname ; optcnt += 2; } /* check Encoding Mode options */ switch (encoding_prefs.ogg_encopt) { case 0: break; /* We want to use the default options */ case 1: options[optcnt] = "--managed"; options[optcnt + 1] = "-M"; options[optcnt + 2] = encoding_prefs.ogg_maxbitrate; options[optcnt + 3] = "-m"; options[optcnt + 4] = encoding_prefs.ogg_minbitrate; optcnt = optcnt + 5; break; case 2: options[optcnt] = "-b"; options[optcnt + 1] = encoding_prefs.ogg_bitrate; optcnt = optcnt + 2; break; case 3: options[optcnt] = "-q"; options[optcnt + 1] = encoding_prefs.ogg_quality_level; break; default: warning("Unrecognized encoding options selected\n"); return (1); break; /* should not be here unknown value */ } } else if(fmt == MP3_FMT) { /* Check if defined encoder location and it exists */ if ((strlen(encoding_prefs.mp3loc) == 0) || (stat(encoding_prefs.mp3loc, &filestat) == -1)) { // We should probably just set it to /usr/bin/lame by default, or `which lame` warning("Encoder for MP3 is not defined correctly - check the Settings menu\n"); return 1; } /* Required Settings */ options[optcnt] = (char *) basename(encoding_prefs.mp3loc); /* argv[0] is the executable */ optcnt++; options[optcnt] = "-r"; /* read raw */ optcnt++; options[optcnt] = "--bitwidth"; optcnt++; options[optcnt] = "16"; optcnt++; options[optcnt] = "-s"; /* Sample Rate */ optcnt++; // Alister: I think we could get rid of the warning below and possibly allow the user to choose the samplerate instead of getting it from the input file. switch (insfinfo.samplerate) { case 48000: options[optcnt] = "48"; break; case 44100: options[optcnt] = "44.1"; break; case 32000: options[optcnt] = "32"; break; case 24000: options[optcnt] = "24"; break; case 22050: options[optcnt] = "22.05"; break; case 16000: options[optcnt] = "16"; break; case 12000: options[optcnt] = "12"; break; case 11025: options[optcnt] = "11.025"; break; case 8000: options[optcnt] = "8"; break; default: warning ("Please resample audio file to standard 8/11.025/12/16/22.05/24/32/44.1/48 kHz\n"); return (1); break; } optcnt++; options[optcnt] = "-m"; /* Mode */ optcnt++; if (insfinfo.channels == 2) { options[optcnt] = "s"; /* stereo */ } else { options[optcnt] = "m"; /* mono */ } optcnt++; // Alister: this creates a file that is just a loud hiss for at least me and John Cirillo (see mailing list) // options[optcnt] = "-x"; /* Swap bytes */ // optcnt++; /* asm options only for MMX enabled version of lame */ if (encoding_prefs.mp3_lame_mmx_enabled) { if (!encoding_prefs.mp3_sse) { options[optcnt] = "--noasm"; options[optcnt + 1] = "sse"; optcnt = optcnt + 2; } if (!encoding_prefs.mp3_mmx) { options[optcnt] = "--noasm"; options[optcnt + 1] = "mmx"; optcnt = optcnt + 2; } if (!encoding_prefs.mp3_threednow) { options[optcnt] = "--noasm"; options[optcnt + 1] = "3dnow"; optcnt = optcnt + 2; } } if (encoding_prefs.mp3_copyrighted) { options[optcnt] = "-c"; optcnt++; } if (encoding_prefs.mp3_nofilters) { options[optcnt] = "-k"; optcnt++; } if (encoding_prefs.mp3_add_crc) { options[optcnt] = "-p"; optcnt++; } if (encoding_prefs.mp3_strict_iso) { options[optcnt] = "--strictly-enforce-ISO"; optcnt++; } if (encoding_prefs.mp3_use_lowpass) { options[optcnt] = "--lowpass"; options[optcnt + 1] = encoding_prefs.mp3_lowpass_freq; optcnt = optcnt + 2; } if (encoding_prefs.mp3_use_highpass) { options[optcnt] = "--highpass"; options[optcnt + 1] = encoding_prefs.mp3_highpass_freq; optcnt = optcnt + 2; } { int qval = atoi(encoding_prefs.mp3_quality_level); if (qval < 0 || qval > 9) { warning ("Quality level for MP3 encoder should be between 0 and 9\n"); return (1); } else { /* Set quality level */ options[optcnt] = "-q"; options[optcnt + 1] = encoding_prefs.mp3_quality_level; optcnt = optcnt + 2; } } /* check if preset is enabled */ if (encoding_prefs.mp3presets == 0) { /* check for alternate settings */ if (encoding_prefs.mp3_br_mode == 1) { /* ABR */ options[optcnt] = "--abr"; options[optcnt + 1] = encoding_prefs.mp3_bitrate; optcnt = optcnt + 2; } else if (encoding_prefs.mp3_br_mode == 2) { int bval = atoi(encoding_prefs.mp3_bitrate); /* CBR */ options[optcnt] = "--cbr"; options[optcnt + 1] = "-b"; switch (bval) { case 320: case 256: case 224: case 192: case 160: case 128: case 112: case 96: case 80: case 64: case 48: case 40: case 32: break; /* all these values are okay */ default: warning ("Please choose bitrate of 320/256/224/192/160/128/112/96/80/64/48/40 or 32"); return (1); /* Bad value */ break; } options[optcnt + 2] = encoding_prefs.mp3_bitrate; optcnt = optcnt + 3; } else if (encoding_prefs.mp3_br_mode == 3) { /* VBR */ options[optcnt] = "-V"; options[optcnt + 1] = encoding_prefs.mp3_quality_level; optcnt = optcnt + 2; } } else { printf("MP3 preset is %d\n", encoding_prefs.mp3presets); switch (encoding_prefs.mp3presets) { case 1: options[optcnt] = "--r3mix"; optcnt = optcnt + 1; break; case 2: options[optcnt] = "--preset"; options[optcnt + 1] = "standard"; optcnt = optcnt + 2; break; case 3: options[optcnt] = "--preset"; options[optcnt + 1] = "medium"; optcnt = optcnt + 2; break; case 4: options[optcnt] = "--preset"; options[optcnt + 1] = "extreme"; optcnt = optcnt + 2; break; case 5: options[optcnt] = "--preset"; options[optcnt + 1] = "insane"; optcnt = optcnt + 2; break; case 6: options[optcnt] = "--preset"; options[optcnt + 1] = "fast"; options[optcnt + 2] = "standard"; optcnt = optcnt + 3; break; case 7: options[optcnt] = "--preset"; options[optcnt + 1] = "fast"; options[optcnt + 2] = "medium"; optcnt = optcnt + 3; break; case 8: options[optcnt] = "--preset"; options[optcnt + 1] = "fast"; options[optcnt + 2] = "extreme"; optcnt = optcnt + 3; break; default: warning ("Failed to interpret which mp3 encoding preset you selected"); return (1); break; } } if ((strlen(trackname) > 0)) { options[optcnt] = "--tt"; options[optcnt + 1] = trackname ; optcnt += 2; } /* All other options come before the input and output filenames */ options[optcnt] = "-"; /* Stdin */ // Alister: need to comment this out if use_sox=1. options[optcnt] = pipe_name ; /* named pipe */ options[optcnt + 1] = newfilename; } else { /* fmt == MP3_SIMPLE_FMT */ /* Check if defined encoder location and it exists */ if ((strlen(encoding_prefs.mp3loc) == 0) || (stat(encoding_prefs.mp3loc, &filestat) == -1)) { // We should probably just set it to /usr/bin/lame by default, or `which lame` warning("Encoder for MP3 is not defined correctly - check the Settings menu\n"); return 1; } /* Required Settings */ options[optcnt] = (char *) basename(encoding_prefs.mp3loc); /* argv[0] is the executable */ optcnt++; options[optcnt] = "-h"; /* use recommended quality setting from lame */ optcnt++; options[optcnt] = "-r"; /* read raw */ optcnt++; options[optcnt] = "--bitwidth"; optcnt++; options[optcnt] = "16"; optcnt++; options[optcnt] = "-V"; optcnt++; options[optcnt] = encoding_prefs.mp3_quality_level ; optcnt++; options[optcnt] = "-s"; /* Sample Rate */ optcnt++; // Alister: I think we could get rid of the warning below. switch (insfinfo.samplerate) { case 48000: options[optcnt] = "48"; break; case 44100: options[optcnt] = "44.1"; break; case 32000: options[optcnt] = "32"; break; case 24000: options[optcnt] = "24"; break; case 22050: options[optcnt] = "22.05"; break; case 16000: options[optcnt] = "16"; break; case 12000: options[optcnt] = "12"; break; case 11025: options[optcnt] = "11.025"; break; case 8000: options[optcnt] = "8"; break; default: warning ("Please resample audio file to standard 8/11.025/12/16/22.05/24/32/44.1/48 kHz\n"); return (1); break; } optcnt++; options[optcnt] = "-m"; /* Mode */ optcnt++; if (insfinfo.channels == 2) { options[optcnt] = "s"; /* stereo */ } else { options[optcnt] = "m"; /* mono */ } optcnt++; if ((strlen(encoding_prefs.artist) > 0)) { options[optcnt] = "--ta"; options[optcnt + 1] = encoding_prefs.artist; optcnt += 2; } if ((strlen(encoding_prefs.album) > 0)) { options[optcnt] = "--tl"; options[optcnt + 1] = encoding_prefs.album; optcnt += 2; } if ((strlen(trackname) > 0)) { options[optcnt] = "--tt"; options[optcnt + 1] = trackname ; optcnt += 2; } /* All other options come before the input and output filenames */ options[optcnt] = "-"; /* Stdin */ // Alister: need to comment this out if use_sox=1. options[optcnt] = pipe_name ; /* named pipe */ options[optcnt + 1] = newfilename; } return (0); } int encode(int mode, char *origfilename, char *newfilename, long start, long length, char *trackname) { int ret; signal(SIGCHLD, SIG_IGN); /* Make sure we dont create a zombie */ signal(SIGPIPE, SIG_IGN); /* Make sure broken pipe doesnt make us exit */ /* open file to get paramters needed for rate etc.. */ /* Open a sound file */ insfinfo.format = 0; /* before open set format to 0 */ in_fd = sf_open(origfilename, SFM_READ, &insfinfo); if (in_fd == NULL) { fprintf(stderr, "Failed to open %s", origfilename); return (1); } if (start + length > insfinfo.frames) { warning("Selection is outside of soundfile\n"); sf_close(in_fd); return (1); } outsfinfo = insfinfo; /* skip to position in sound file */ if (!sf_seek(in_fd, start, SEEK_SET) == start) { warning("Failed to seek to position in sound file\n"); sf_close(in_fd); return (1); } ret = build_options(mode, newfilename, trackname); /* create options based on encoder chosen */ if (ret != 0) { sf_close(in_fd); return (ret); } /* set format for output */ outsfinfo.format = (SF_FORMAT_RAW | SF_FORMAT_PCM_16); ret = start_encode(mode, newfilename, start, length, origfilename); return ret; } void create_progress_window(void) ; gint encode_progress (gfloat pvalue) ; void destroy_progress_window(void) ; gint stop_encoding = FALSE ; int start_encode_old(int mode, char *newfilename, long start, long length, char *origfilename) { long samples_read; long ctr; long numframes = 0; int f_des[2], child_pid; int i=0 ; int use_sox = 1 ; char cmd[2048] ; char *exec_loc ; if (mode == OGG_FMT) { /* execute ogg encoder using prebuilt options */ exec_loc = encoding_prefs.oggloc ; } else if (mode == MP3_FMT) { /* execute mp3 encoder using prebuilt options */ exec_loc = encoding_prefs.mp3loc ; } else if (mode == MP3_SIMPLE_FMT) { /* execute mp3 encoder using prebuilt options */ exec_loc = encoding_prefs.mp3loc ; } printf("Encoding using %s\n", exec_loc) ; printf(" ") ; for(i = 0 ; options[i] != (char *)NULL ; i++) printf("\'%s\'", options[i]) ; printf("\n") ; if(use_sox) { sprintf(cmd, "sox %s -t raw - trim %ld\s %ld\s |", origfilename, start, length) ; for(i = 0 ; options[i] != (char *)NULL ; i++) { int j ; strcat(cmd, " ") ; for(j = 0 ; j < strlen(options[i]) ; j++) { char buf[10] ; int need_esc=0 ; if(options[i][j] == ' ') need_esc = 1 ; if(options[i][j] == '\'') need_esc = 1 ; if(options[i][j] == '\"') need_esc = 1 ; if(need_esc) sprintf(buf, "\\%c", options[i][j]) ; else sprintf(buf, "%c", options[i][j]) ; strcat(cmd, buf) ; } } printf("CMD:\n'%s\'\n", cmd) ; system(cmd) ; return 0 ; } /* Create a pipe to send data through - must do first */ if (pipe(f_des) != 0) { warning("Unable to process file now \n"); return (1); } /* fork to allow us to create a child process for processing data */ if ((child_pid = fork()) == 0) { /* Child (or proc 2) */ close(0); /* redirecting stdin fd=0 */ dup(f_des[0]); /* duplicate pipe read with stdin i.e. 0=3 */ close(f_des[1]); /* child proc does not need stdout of pipe */ if (execvp(exec_loc, options) == -1) { warning("Failed to process audio file\n"); return (1); } } else { double *framebuf = NULL ; FILE *fp ; /* Parent */ fprintf(stderr, "encoding child pid is %d\n", child_pid) ; close(1); /* redirecting stdout fd=1 */ dup(f_des[1]); /* duplicate pipe write with stdout i.e. 1=4 */ close(f_des[0]); /* closing stdin of pipe for this process not used */ /* open output to standard out */ out_fd = sf_open("/dev/stdout", SFM_WRITE, &outsfinfo); if (out_fd == NULL) { warning("Failed to open output file\n"); sf_close(in_fd); return (1); } /* put out raw data */ /* Make sure frame buffer size is multiple of # channels */ numframes = 44100; framebuf = (double*)calloc(numframes * insfinfo.channels, sizeof(double)); if (framebuf == NULL) { warning( "failed to allocate intermediate buffer\n"); sf_close(in_fd); return (1); } create_progress_window() ; /* read in blocks of size buffer and send out converted to new sound format */ for (ctr = 0; ctr < length; ctr += samples_read) { if(stop_encoding == TRUE) { stop_encoding = FALSE ; break ; } samples_read = sf_readf_double(in_fd, framebuf, numframes); sf_writef_double(out_fd, framebuf, samples_read); encode_progress ((double)ctr/(double)length) ; } destroy_progress_window() ; close(1); /* close stdout on parent */ /* Main Parent (proc 1) */ sf_close(in_fd); /* done reading/writing from program */ sf_close(out_fd); close(f_des[0]); /* overall parent closes pipes so that */ close(f_des[1]); /* processes terminate on time */ fp = freopen("/dev/tty", "w", stdout); /* reopen tty for writing on stdout */ if(fp == NULL) { fprintf(stderr, "FAILED to reopen stdout!\n") ; } else { stdout = fp ; fprintf(stderr, "SUCCEEDED to reopen stdout!\n") ; printf("Finished encoding using %s\n", encoding_prefs.mp3loc) ; } } return (0); } // Alister: if using this, need to uncomment the line noted above so the pipe name is inserted for the "simple encode..." function int start_encode(int mode, char *newfilename, long start, long length, char *origfilename) { long samples_read; long ctr; long numframes = 0; int f_des[2], child_pid; int i=0 ; int use_sox = 0 ; char cmd[2048] ; char *exec_loc ; if (mode == OGG_FMT) { /* execute ogg encoder using prebuilt options */ exec_loc = encoding_prefs.oggloc ; } else if (mode == MP3_FMT) { /* execute mp3 encoder using prebuilt options */ exec_loc = encoding_prefs.mp3loc ; } else if (mode == MP3_SIMPLE_FMT) { /* execute mp3 encoder using prebuilt options */ exec_loc = encoding_prefs.mp3loc ; } printf("Encoding using %s\n", exec_loc) ; printf(" ") ; for(i = 0 ; options[i] != (char *)NULL ; i++) printf("\'%s\'", options[i]) ; printf("\n") ; if(use_sox) { sprintf(cmd, "sox %s -t raw - trim %ld\s %ld\s |", origfilename, start, length) ; for(i = 0 ; options[i] != (char *)NULL ; i++) { int j ; strcat(cmd, " ") ; for(j = 0 ; j < strlen(options[i]) ; j++) { char buf[10] ; int need_esc=0 ; if(options[i][j] == ' ') need_esc = 1 ; if(options[i][j] == '\'') need_esc = 1 ; if(options[i][j] == '\"') need_esc = 1 ; if(need_esc) sprintf(buf, "\\%c", options[i][j]) ; else sprintf(buf, "%c", options[i][j]) ; strcat(cmd, buf) ; } } printf("CMD:\n'%s\'\n", cmd) ; system(cmd) ; return 0 ; } /* Create a pipe to send data through - must do first */ /* now using a named pipe */ if(mkfifo(pipe_name, S_IRWXU)) { static char buf[254] ; snprintf(buf,255,"Failed to open named pipe to transfer data to %s, cannot proceed", exec_loc) ; warning(buf) ; return 1 ; } /* fork to allow us to create a child process for processing data */ if ((child_pid = fork()) == 0) { /* Child (or proc 2) */ if (execvp(exec_loc, options) == -1) { warning("Failed to process audio file\n"); return (1); } } else { double *framebuf = NULL ; FILE *fp ; /* Parent */ fprintf(stderr, "encoding child pid is %d\n", child_pid) ; //close(1); /* redirecting stdout fd=1 */ //dup(f_des[1]); /* duplicate pipe write with stdout i.e. 1=4 */ //close(f_des[0]); /* closing stdin of pipe for this process not used */ /* open output to named_pipe */ out_fd = sf_open(pipe_name, SFM_WRITE, &outsfinfo); if (out_fd == NULL) { warning("Failed to open output file\n"); sf_close(in_fd); unlink(pipe_name) ; return (1); } /* put out raw data */ /* Make sure frame buffer size is multiple of # channels */ numframes = 44100; framebuf = (double*)calloc(numframes * insfinfo.channels, sizeof(double)); if (framebuf == NULL) { warning( "failed to allocate intermediate buffer\n"); sf_close(in_fd); unlink(pipe_name) ; return (1); } create_progress_window() ; /* read in blocks of size buffer and send out converted to new sound format */ for (ctr = 0; ctr < length; ctr += samples_read) { if(stop_encoding == TRUE) { stop_encoding = FALSE ; break ; } samples_read = sf_readf_double(in_fd, framebuf, numframes); sf_writef_double(out_fd, framebuf, samples_read); encode_progress ((double)ctr/(double)length) ; } destroy_progress_window() ; /* Main Parent (proc 1) */ sf_close(in_fd); /* done reading/writing from program */ sf_close(out_fd); unlink(pipe_name) ; } return (0); } static GtkWidget *progress_dialog; static GtkWidget *button; static GtkWidget *label; static GtkWidget *table; static GtkWidget *pbar; /* This function increments and updates the progress bar, it also resets the progress bar if pstat is FALSE */ gint encode_progress (gfloat pvalue) { gtk_progress_bar_update (GTK_PROGRESS_BAR (pbar), pvalue); while(gtk_events_pending()) gtk_main_iteration() ; return TRUE; } void cancel_encoding(GtkWidget *w) { stop_encoding = TRUE ; } void destroy_progress_window(void) { gtk_widget_destroy(pbar) ; gtk_widget_destroy(button) ; gtk_widget_destroy(label) ; gtk_widget_destroy(table) ; gtk_widget_destroy(progress_dialog) ; } void create_progress_window(void) { //progress_dialog = gtk_dialog_new("Encoding progress window", NULL); progress_dialog = gtk_dialog_new(); gtk_window_set_modal (GTK_WINDOW(progress_dialog), TRUE); gtk_window_set_transient_for(GTK_WINDOW(progress_dialog), GTK_WINDOW(main_window)); gtk_container_border_width (GTK_CONTAINER (progress_dialog), 10); table = gtk_table_new(3,1,TRUE); label = gtk_label_new ("Encoding progress"); gtk_table_attach_defaults(GTK_TABLE(table), label, 0,1,0,1); gtk_widget_show(label); /* Create a new progress bar, pack it into the table, and show it */ pbar = gtk_progress_bar_new (); gtk_table_attach_defaults(GTK_TABLE(table), pbar, 0,1,1,2); gtk_widget_show (pbar); button = gtk_button_new_with_label ("Cancel"); /* gtk_signal_connect_object(GTK_OBJECT(button), "clicked", */ /* GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) progress_dialog); */ gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(cancel_encoding), NULL); gtk_table_attach_defaults(GTK_TABLE(table), button, 0,1,2,3); gtk_widget_show (button); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(progress_dialog)->vbox), table, TRUE, TRUE, 0); gtk_widget_show(table); gtk_widget_show(progress_dialog); while(gtk_events_pending()) gtk_main_iteration() ; } gtk-wave-cleaner-0.22-04/encoding.h0000777000175000017500000000227513120075106020151 0ustar00alisteralister00000000000000#define OGG_FMT 1000 #define MP3_FMT 2000 #define MP3_SIMPLE_FMT 3000 struct encoding_prefs { /* MP3 */ int mp3_br_mode; char mp3_bitrate[6]; char mp3_quality_level[2]; int mp3presets; /* Lame is mmx enabled? */ int mp3_lame_mmx_enabled; /* Advanced MP3 settings */ int mp3_mmx; int mp3_sse; int mp3_threednow; int mp3_copyrighted; int mp3_add_crc; int mp3_strict_iso; int mp3_nofilters; int mp3_use_lowpass; int mp3_use_highpass; char mp3_lowpass_freq[6]; char mp3_highpass_freq[6]; char mp3loc[256]; /* Full path and executable for mp3 encoder */ char artist[256]; char album[256]; /* OGG Vorbis */ char ogg_quality_level[7]; /* 6 characters */ char oggloc[256]; /* Full path and executable for ogg encoder */ int ogg_downmix; char ogg_bitrate[6]; char ogg_maxbitrate[6]; char ogg_minbitrate[6]; int ogg_encopt; /* use Managed, nominal Bitrate, or Quality Level , or none */ char ogg_resample[6]; /* Resample at new rate */ /* Advanced ogg options */ char ogg_lowpass_frequency[6]; char ogg_bitrate_average_window[6]; int ogg_useresample; int ogg_useadvlowpass; int ogg_useadvbravgwindow; }; gtk-wave-cleaner-0.22-04/fmtheaders.h0000777000175000017500000000616513120075106020507 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.01 * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* fmtheaders.h */ /* This is not an original file, it was copied from the gramofile application */ #ifndef _FMTHEADERS_H #define _FMTHEADERS_H 1 #include /* Definitions for .VOC files */ #define VOC_MAGIC "Creative Voice File\032" #define DATALEN(bp) ((u_long)(bp.BlockLen[0]) | \ ((u_long)(bp.BlockLen[1]) << 8) | \ ((u_long)(bp.BlockLen[2]) << 16) ) # ifndef MAC_OS_X # ifndef __u_char_defined typedef __u_char u_char; typedef __u_short u_short; typedef __u_int u_int; typedef __u_long u_long; typedef __quad_t quad_t; typedef __u_quad_t u_quad_t; typedef __fsid_t fsid_t; # define __u_char_defined # endif # endif /* MAC_OS_X*/ typedef struct vochead { u_char Magic[20]; /* must be VOC_MAGIC */ u_short BlockOffset; /* Offset to first block from top of file */ u_short Version; /* VOC-file version */ u_short IDCode; /* complement of version + 0x1234 */ } vochead; typedef struct blockTC { u_char BlockID; u_char BlockLen[3]; /* low, mid, high byte of length of rest of block */ } blockTC; typedef struct blockT1 { u_char TimeConstant; u_char PackMethod; } blockT1; typedef struct blockT8 { u_short TimeConstant; u_char PackMethod; u_char VoiceMode; } blockT8; typedef struct blockT9 { u_int SamplesPerSec; u_char BitsPerSample; u_char Channels; u_short Format; u_char reserved[4]; } blockT9; /* Definitions for Microsoft WAVE format */ /* it's in chunks like .voc and AMIGA iff, but my source say there are in only in this combination, so I combined them in one header; it works on all WAVE-file I have */ typedef struct wavhead { u_long main_chunk; /* 'RIFF' */ u_long length; /* Length of rest of file */ u_long chunk_type; /* 'WAVE' */ u_long sub_chunk; /* 'fmt ' */ u_long sc_len; /* length of sub_chunk, =16 (rest of chunk) */ u_short format; /* should be 1 for PCM-code */ u_short modus; /* 1 Mono, 2 Stereo */ u_long sample_fq; /* frequence of sample */ u_long byte_p_sec; u_short byte_p_spl; /* samplesize; 1 or 2 bytes */ u_short bit_p_spl; /* 8, 12 or 16 bit */ u_long data_chunk; /* 'data' */ u_long data_length; /* samplecount (length of rest of block?)*/ } wavhead; #endif gtk-wave-cleaner-0.22-04/gtkled.c0000777000175000017500000001473513120075106017634 0ustar00alisteralister00000000000000/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * GtkLed: Emulate a simple LED (light emitting diode) * Copyright (C) 1997 Tim Janik * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* #include */ #include #include "gtkled.h" #define LED_WIDTH (10) #define LED_HEIGHT (5) #define BOTTOM_SPACE (2) static void gtk_led_class_init (GtkLedClass *klass); static void gtk_led_init (GtkLed *led); static void gtk_led_destroy (GtkObject *object); static void gtk_led_size_request (GtkWidget *widget, GtkRequisition *requisition); static gint gtk_led_expose (GtkWidget *widget, GdkEventExpose *event); static void gtk_led_realize (GtkWidget *widget); static GtkMiscClass *parent_class = NULL; enum { LED_COLOR_ON, LED_COLOR_OFF }; GtkType gtk_led_get_type () { static GtkType led_type = 0; if (!led_type) { GtkTypeInfo led_info = { "GtkLed", sizeof (GtkLed), sizeof (GtkLedClass), (GtkClassInitFunc) gtk_led_class_init, (GtkObjectInitFunc) gtk_led_init, /* reserved */ NULL, /* reserved */ NULL, (GtkClassInitFunc) NULL, }; led_type = gtk_type_unique (gtk_misc_get_type (), &led_info); } return led_type; } void gtk_led_class_init (GtkLedClass *class) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; parent_class = gtk_type_class (gtk_misc_get_type ()); object_class->destroy = gtk_led_destroy; widget_class->size_request = gtk_led_size_request; widget_class->expose_event = gtk_led_expose; widget_class->realize = gtk_led_realize; } void gtk_led_init (GtkLed *led) { GtkMisc *misc; misc = GTK_MISC (led); GTK_WIDGET_SET_FLAGS (led, GTK_NO_WINDOW); led->is_on = FALSE; led->gc = NULL; } GtkWidget* gtk_led_new () { GtkLed *led; led = gtk_type_new (gtk_led_get_type ()); return GTK_WIDGET (led); } void gtk_led_set_colors (GtkLed *led, GdkColor *active, GdkColor *inactive) { g_return_if_fail (led != NULL); g_return_if_fail (GTK_IS_LED (led)); led->fg[LED_COLOR_ON] = *(active); led->fg[LED_COLOR_OFF] = *(inactive); } void gtk_led_set_state (GtkLed *led, GtkStateType widget_state, gboolean on_off) { g_return_if_fail (led != NULL); g_return_if_fail (GTK_IS_LED (led)); gtk_widget_set_state (GTK_WIDGET (led), widget_state); gtk_led_switch (led, on_off); } void gtk_led_switch (GtkLed *led, gboolean on_off) { g_return_if_fail (led != NULL); g_return_if_fail (GTK_IS_LED (led)); led->is_on = on_off != FALSE; gtk_widget_draw (GTK_WIDGET (led), NULL); } gboolean gtk_led_is_on (GtkLed *led) { g_return_val_if_fail (led != NULL, FALSE); g_return_val_if_fail (GTK_IS_LED (led), FALSE); return led->is_on; } static void gtk_led_destroy (GtkObject *object) { GtkLed *led; g_return_if_fail (object != NULL); g_return_if_fail (GTK_IS_LED (object)); led = GTK_LED (object); if (GTK_WIDGET (object)->parent && GTK_WIDGET_MAPPED (object)) gtk_widget_unmap (GTK_WIDGET (object)); if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } static void gtk_led_size_request (GtkWidget *widget, GtkRequisition *requisition) { GtkLed *led; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LED (widget)); g_return_if_fail (requisition != NULL); led = GTK_LED (widget); requisition->width = LED_WIDTH + led->misc.xpad * 2; requisition->height = LED_HEIGHT + led->misc.ypad * 2 + BOTTOM_SPACE; } static void gtk_led_realize (GtkWidget *widget) { GtkLed *led; GdkColormap *cmap; g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_LED (widget)); GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); led = GTK_LED (widget); widget->window = gtk_widget_get_parent_window (widget); gdk_window_ref (widget->window); widget->style = gtk_style_attach (widget->style, widget->window); if (!led->gc) { cmap = gtk_widget_get_colormap (widget); if (!(&(led->fg[LED_COLOR_ON]))) gdk_color_parse ("#00F100", &(led->fg[LED_COLOR_ON])); gdk_color_alloc (cmap, &(led->fg[LED_COLOR_ON])); if (!(&(led->fg[LED_COLOR_OFF]))) gdk_color_parse ("#008C00", &(led->fg[LED_COLOR_OFF])); gdk_color_alloc (cmap, &(led->fg[LED_COLOR_OFF])); led->gc = gdk_gc_new (widget->window); gdk_gc_copy (led->gc, widget->style->white_gc); } } static gint gtk_led_expose (GtkWidget *widget, GdkEventExpose *event) { GtkLed *led; GtkMisc *misc; GdkColor *win_bg; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_LED (widget), FALSE); g_return_val_if_fail (event != NULL, FALSE); led = GTK_LED (widget); misc = GTK_MISC (widget); if (GTK_WIDGET_DRAWABLE (widget)) { if ((widget->allocation.width >= widget->requisition.width) && (widget->allocation.height >= widget->requisition.height)) { guint x, y; win_bg = (led->is_on) ? &(led->fg[LED_COLOR_ON]) : &(led->fg[LED_COLOR_OFF]); gdk_gc_set_foreground (led->gc, win_bg); x = widget->allocation.x + misc->xpad + (widget->allocation.width - widget->requisition.width) * misc->xalign + 0.5; y = widget->allocation.y + misc->ypad + LED_HEIGHT + (widget->allocation.height - widget->requisition.height) * misc->xalign + 0.5 - BOTTOM_SPACE; gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, x, y, LED_WIDTH, LED_HEIGHT); gdk_draw_rectangle (widget->window, led->gc, TRUE, x + 1, y + 1, LED_WIDTH - 2, LED_HEIGHT - 2); } } return TRUE; } /* EOF */ gtk-wave-cleaner-0.22-04/gtkled.h0000777000175000017500000000405313120075106017631 0ustar00alisteralister00000000000000/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * GtkLed: Emulate a simple LED (light emitting diode) * Copyright (C) 1997 Tim Janik * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __GTK_LED_H__ #define __GTK_LED_H__ #include #include #ifdef __cplusplus extern "C" { #pragma } #endif /* __cplusplus */ #define GTK_LED(obj) (GTK_CHECK_CAST (obj, gtk_led_get_type (), GtkLed)) #define GTK_LED_CLASS(klass) (GTK_CHECK_CLASS_CAST (klass, gtk_led_get_type (), GtkLedClass)) #define GTK_IS_LED(obj) (GTK_CHECK_TYPE (obj, gtk_led_get_type ())) typedef struct _GtkLed GtkLed; typedef struct _GtkLedClass GtkLedClass; struct _GtkLed { GtkMisc misc; GdkColor fg[2]; GdkColor bg[2]; GdkGC *gc; guint is_on; }; struct _GtkLedClass { GtkMiscClass parent_class; }; GtkType gtk_led_get_type (void); GtkWidget* gtk_led_new (void); void gtk_led_set_state (GtkLed *led, GtkStateType widget_state, gboolean on_off); void gtk_led_switch (GtkLed *led, gboolean on_off); gboolean gtk_led_is_on (GtkLed *led); void gtk_led_set_colors (GtkLed *led, GdkColor *active, GdkColor *inactive); #ifdef __cplusplus #pragma { } #endif /* __cplusplus */ #endif /* __GTK_LED_H__ */ gtk-wave-cleaner-0.22-04/gtkledbar.c0000777000175000017500000001530313120075106020311 0ustar00alisteralister00000000000000/* * $Id: gtkledbar.c,v 1.1.1.1 2002/09/08 04:03:51 welty Exp $ * GTKEXT - Extensions to The GIMP Toolkit * Copyright (C) 1998 Gregory McLean * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA * 02139, USA. * * Eye candy! */ #include #include "gtkledbar.h" static void led_bar_class_init (LedBarClass *klass); static void led_bar_init (LedBar *led_bar); GtkType led_bar_get_type () { static GtkType led_bar_type = 0; if (!led_bar_type) { GtkTypeInfo led_bar_info = { "LedBar", sizeof (LedBar), sizeof (LedBarClass), (GtkClassInitFunc) led_bar_class_init, (GtkObjectInitFunc) led_bar_init, /* reserved_1 */ NULL, /* reserved_1 */ NULL, (GtkClassInitFunc) NULL, }; led_bar_type = gtk_type_unique (gtk_vbox_get_type (), &led_bar_info); } return led_bar_type; } static void led_bar_class_init (LedBarClass *class) { GtkObjectClass *object_class; object_class = (GtkObjectClass *) class; } static void led_bar_init (LedBar *led_bar) { led_bar->num_segments = 0; led_bar->lit_segments = 0; led_bar->seq_segment = 0; led_bar->seq_dir = 1; } GtkWidget * led_bar_new (gint segments, gint orientation ) { LedBar *led_bar; GtkWidget *table; gint i; GdkColor active; GdkColor inactive; gint half, full; led_bar = gtk_type_new (led_bar_get_type ()); if (segments > MAX_SEGMENTS) segments = MAX_SEGMENTS; led_bar->num_segments = segments; led_bar->orientation = orientation; if ( !orientation ) /* horiz */ table = gtk_table_new (1, segments, FALSE); else /* vert */ table = gtk_table_new (segments, 1, FALSE); gtk_container_add (GTK_CONTAINER (led_bar), table); gtk_widget_show (table); half = .50 * segments; full = .75 * segments; gdk_color_parse ("#00F100", &active); gdk_color_parse ("#008C00", &inactive); for (i = 0; i < segments; i++) { if (i >= half && i <= full) { gdk_color_parse ("#F1EE00", &active); gdk_color_parse ("#8CAA00", &inactive); } else if (i >= full) { gdk_color_parse ("#F10000", &active); gdk_color_parse ("#8C0000", &inactive); } led_bar->segments[i] = gtk_led_new (); gtk_led_set_colors (GTK_LED (led_bar->segments[i]), &active, &inactive); if ( !orientation ) /* horiz */ gtk_table_attach (GTK_TABLE (table), led_bar->segments[i], i, (i + 1), 0, 1, 0, 0, 0, 0); else /* vert */ gtk_table_attach (GTK_TABLE (table), led_bar->segments[i], 0, 1, (segments - i - 1), (segments - i), 0, 0, 0, 0 ); gtk_widget_show (led_bar->segments[i]); } return GTK_WIDGET (led_bar); } gint led_bar_get_num_segments (GtkWidget *bar) { g_return_val_if_fail (bar != NULL, 0); g_return_val_if_fail (IS_LEDBAR (bar), 0); return (LEDBAR (bar)->num_segments); } void led_bar_light_segments (GtkWidget *bar, gint num) { LedBar *led_bar; int i; g_return_if_fail (bar != NULL); g_return_if_fail (IS_LEDBAR (bar)); led_bar = LEDBAR (bar); if (num == 0 && led_bar->lit_segments == 0) return; if (num < led_bar->lit_segments) { for (i = 0; i < num; i++) { gtk_led_set_state (GTK_LED (led_bar->segments[i]), GTK_STATE_SELECTED, TRUE); } } else { for (i = led_bar->lit_segments; i < num; i++) gtk_led_set_state (GTK_LED (led_bar->segments[i]), GTK_STATE_SELECTED, TRUE); } led_bar->lit_segments = i; } void led_bar_unlight_segments (GtkWidget *bar, gint num) { LedBar *led_bar; int i; g_return_if_fail (bar != NULL); g_return_if_fail (IS_LEDBAR (bar)); led_bar = LEDBAR (bar); if (led_bar->lit_segments == 0) return; for (i = 0; i < num; i++) { gtk_led_set_state (GTK_LED (led_bar->segments[i]), GTK_STATE_SELECTED, FALSE); } led_bar->lit_segments -= num; if (led_bar->lit_segments < 0) led_bar->lit_segments = 0; } void led_bar_light_segment (GtkWidget *bar, gint segment) { LedBar *led_bar; g_return_if_fail (bar != NULL); g_return_if_fail (IS_LEDBAR (bar)); led_bar = LEDBAR (bar); gtk_led_set_state (GTK_LED (led_bar->segments[segment]), GTK_STATE_SELECTED, TRUE); } void led_bar_unlight_segment (GtkWidget *bar, gint segment) { LedBar *led_bar; g_return_if_fail (bar != NULL); g_return_if_fail (IS_LEDBAR (bar)); led_bar = LEDBAR (bar); gtk_led_set_state (GTK_LED (led_bar->segments[segment]), GTK_STATE_SELECTED, FALSE); } void led_bar_light_percent (GtkWidget *bar, gfloat percent) { LedBar *led_bar; gint num, i; g_return_if_fail (bar != NULL); g_return_if_fail (IS_LEDBAR (bar)); led_bar = LEDBAR (bar); num = percent * led_bar->num_segments; led_bar->lit_segments = num; for (i = 0; i < led_bar->num_segments; i++) { if (num > 0 ) { if (! (GTK_LED (led_bar->segments[i])->is_on)) gtk_led_set_state (GTK_LED (led_bar->segments[i]), GTK_STATE_SELECTED, TRUE); num--; } else { if (GTK_LED (led_bar->segments[i])->is_on) gtk_led_set_state (GTK_LED (led_bar->segments[i]), GTK_STATE_SELECTED, FALSE); } } } void led_bar_clear (GtkWidget *bar) { LedBar *led_bar; int i; g_return_if_fail (bar != NULL); g_return_if_fail (IS_LEDBAR (bar)); led_bar = LEDBAR (bar); for (i = 0; i < led_bar->num_segments; i++) { if (GTK_LED (led_bar->segments[i])->is_on) gtk_led_set_state (GTK_LED (led_bar->segments[i]), GTK_STATE_SELECTED, FALSE); } } void led_bar_sequence_step (GtkWidget *bar) { LedBar *led_bar; g_return_if_fail (bar != NULL); g_return_if_fail (IS_LEDBAR (bar)); led_bar = LEDBAR (bar); if (led_bar->seq_segment >= (led_bar->num_segments - 1)) led_bar->seq_dir = -1; else if (led_bar->seq_segment <= 0) led_bar->seq_dir = 1; led_bar_unlight_segment (GTK_WIDGET(led_bar), led_bar->seq_segment); led_bar->seq_segment += led_bar->seq_dir; led_bar_light_segment (GTK_WIDGET(led_bar), led_bar->seq_segment); } /* EOF */ gtk-wave-cleaner-0.22-04/gtkledbar.h0000777000175000017500000000517013120075106020317 0ustar00alisteralister00000000000000/* * $Id: gtkledbar.h,v 1.1.1.1 2002/09/08 04:03:51 welty Exp $ * GTKEXT - Extensions to The GIMP Toolkit * Copyright (C) 1998 Gregory McLean * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA * 02139, USA. * * Eye candy! */ #ifndef __GTKLEDBAR_H__ #define __GTKLEDBAR_H__ #include #include "gtkled.h" #ifdef __cplusplus extern "C" { #endif #define LEDBAR(obj) GTK_CHECK_CAST (obj, led_bar_get_type (), LedBar) #define LEDBAR_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, led_bar_get_type (), LedBarClass) #define IS_LEDBAR(obj) GTK_CHECK_TYPE (obj, led_bar_get_type ()) #define MAX_SEGMENTS 40 typedef struct _LedBar LedBar; typedef struct _LedBarClass LedBarClass; struct _LedBar { GtkVBox vbox; GtkWidget *segments[MAX_SEGMENTS]; gint num_segments; /* How many segmanets in this bar */ gint lit_segments; /* last segment that is lit */ gint seq_segment; /* which led in the sequence we are at */ gint seq_dir; /* direction */ gint orientation; /* horizontal (0), or vertical (1) */ }; struct _LedBarClass { GtkVBoxClass parent_class; }; GtkType led_bar_get_type (void); GtkWidget* led_bar_new (gint segments, gint orientation); gint led_bar_get_num_segments (GtkWidget *bar); void led_bar_light_segments (GtkWidget *bar, gint num); void led_bar_unlight_segments (GtkWidget *bar, gint num); void led_bar_light_segment (GtkWidget *bar, gint segment); void led_bar_unlight_segment (GtkWidget *bar, gint segment); void led_bar_light_percent (GtkWidget *bar, gfloat percent); void led_bar_sequence_step (GtkWidget *bar); void led_bar_clear (GtkWidget *bar); #ifdef __cplusplus } #endif #endif /* EOF */ gtk-wave-cleaner-0.22-04/gwc.c0000666000175000017500000036521013455263703017151 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.21 * Copyright (C) 2001,2002,2003,2004,2005,2006 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* gwc.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include "gwc.h" #include #include #include #include "gtkledbar.h" #include "encoding.h" #include "soundfile.h" #include "audio_edit.h" #include #include "icons/amplify.xpm" #include "icons/pinknoise.xpm" #include "icons/declick.xpm" #include "icons/gtk-wave-cleaner.xpm" #include "icons/declick_w.xpm" #include "icons/declick_m.xpm" #include "icons/decrackle.xpm" #include "icons/estimate.xpm" #include "icons/filter.xpm" #include "icons/noise_sample.xpm" #include "icons/remove_noise.xpm" #include "icons/start.xpm" #include "icons/stop.xpm" #include "icons/zoom_sel.xpm" #include "icons/zoom_in.xpm" #include "icons/zoom_out.xpm" #include "icons/view_all.xpm" #include "icons/select_all.xpm" #include "icons/spectral.xpm" #ifndef TRUNCATE_OLD #include "icons/silence.xpm" #endif #ifdef MAC_OS_X // Note that we only tested if we are building on OSX, and are just assuming we are building with the GDK QUARTZ backend. // We should really check that, as we could be building with the X11 backend. #include //#import #endif char pathname[PATH_MAX+1] = "./"; GtkWidget *dial[2]; GtkWidget *audio_canvas_w; GtkWidget *audio_drawing_area; GdkPixmap *audio_pixmap = NULL; GdkPixmap *highlight_pixmap = NULL; GdkPixmap *cursor_pixmap = NULL; GtkObject *scroll_pos; GtkWidget *hscrollbar; GtkWidget *detect_only_widget; GtkWidget *leave_click_marks_widget; GtkWidget *l_file_time; GtkWidget *l_file_samples; GtkWidget *l_first_time; GtkWidget *l_selected_time; GtkWidget *l_last_time; GtkWidget *l_samples; struct sound_prefs prefs; struct denoise_prefs denoise_prefs; struct encoding_prefs encoding_prefs; struct view audio_view; struct click_data click_data; int audio_playback = FALSE; int audio_is_looping = FALSE; int cursor_playback = FALSE; int batch_mode = 0 ; long cursor_samples_per_playback_block; gint playback_timer = -1 ; gint cursor_timer; gint spectral_view_flag = FALSE; gint repair_clicks = 1; double view_scale = 1.0; double declick_sensitivity = 0.75; double weak_declick_sensitivity = 1.00; double strong_declick_sensitivity = 0.75; double weak_fft_declick_sensitivity = 3.0 ; double strong_fft_declick_sensitivity = 5.0 ; int declick_detector_type = FFT_DETECT ; double stop_key_highlight_interval = 0.5; double song_key_highlight_interval = 15; double song_mark_silence = 2.0; int sonogram_log = 0; gint declick_iterate_flag = 0; double decrackle_level = 0.2; gint decrackle_window = 2000; gint decrackle_average = 3; gint encoding_type = GWC_OGG; extern double spectral_amp; #ifdef HAVE_ALSA char audio_device[256]="default"; #else char audio_device[256]="/dev/dsp"; #endif gint window_x; gint window_y; gint window_width = 800; gint window_height = 580; gboolean window_maximised; gint doing_progressbar_update = FALSE; DENOISE_DATA denoise_data = { 0, 0, 0, 0, FALSE }; gint debug = 0; gchar save_selection_filename[PATH_MAX+1]; gchar wave_filename[PATH_MAX+1]; gchar last_filename[PATH_MAX+1]; gchar *file_extension; long markers[MAX_MARKERS]; long n_markers = 0; long num_song_markers = 0; long song_markers[MAX_MARKERS]; /* The file selection widget and the string to store the chosen filename */ GtkWidget *file_selector; gchar *selected_filename; gint file_is_open = FALSE; gint file_processing = FALSE; int stop_playback_force = 1 ; void d_print(char *fmt, ...) { if (debug) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); } } static int audio_debug = 0 ; void usage(char *prog) { fprintf(stderr, "Usages:\n\ %s\n\ %s [file]\n\ %s \n\ %s \n\ %s \n\ %s \n\ %s \n\ %s \n\ %s \n\ %s \n\ Position are in hh:mm:ss for batch or in samples for batchs. Stop_position can \ also be end to denote the stop_position being the end of file.\n", prog, prog, prog, prog, prog, prog, prog, prog, prog, prog); exit(EXIT_FAILURE); } void audio_debug_print(char *fmt, ...) { if (audio_debug) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); } } char *sample_to_time_text(long i, int rate, char *prefix, char *buf) { int m, s, ms; m = i / (rate * 60); i -= m * rate * 60; s = i / rate; i -= s * rate; ms = 1000 * i / rate; sprintf(buf, "%s%d:%02d:%03d", prefix, m, s, ms); return buf; } void shellsort_long(long a[], int n) { int gap, i, j; long tmp; for (gap = n / 2; gap > 0; gap /= 2) { for (i = gap; i < n; i++) { for (j = i - gap; j >= 0 && a[j] > a[j + gap]; j -= gap) { tmp = a[j]; a[j] = a[j + gap]; a[j + gap] = tmp; } } } } #ifndef TRUNCATE_OLD static int is_region_selected(void) { if (!audio_view.selection_region) { info("Please select a region of audio data."); return 0; } return 1; } #endif /* !TRUNCATE_OLD */ void append_cdrdao(struct view *v) { FILE *fp = fopen("cdrdao.toc", "a"); long first, last ; if (fp == NULL) { fp = fopen("cdrdao.toc", "w"); } get_region_of_interest(&first, &last, v) ; fprintf(fp, "TRACK AUDIO\n"); fprintf(fp, "FILE \"%s\" %ld %ld\n", wave_filename, first, last - first + 1); fclose(fp); } void display_times(void) { char buf[50]; long first, last; get_region_of_interest(&first, &last, &audio_view); #ifndef OLD gtk_label_set_text(GTK_LABEL(l_file_time), sample_to_time_text(prefs.n_samples, prefs.rate, "Total ", buf)); gtk_label_set_text(GTK_LABEL(l_first_time), sample_to_time_text(first, prefs.rate, "First ", buf)); gtk_label_set_text(GTK_LABEL(l_last_time), sample_to_time_text(last, prefs.rate, "Last ", buf)); gtk_label_set_text(GTK_LABEL(l_selected_time), sample_to_time_text(last-first-1, prefs.rate, "Selected ", buf)); sprintf(buf, "Samples: %ld", last - first + 1); gtk_label_set_text(GTK_LABEL(l_samples), buf); sprintf(buf, "Track samples: %ld", audio_view.n_samples); gtk_label_set_text(GTK_LABEL(l_file_samples), buf); #else gtk_label_set_text(GTK_LABEL(l_file_time), sample_to_time_text(prefs.n_samples, prefs.rate, "", buf)); gtk_label_set_text(GTK_LABEL(l_first_time), sample_to_time_text(first, prefs.rate, "", buf)); gtk_label_set_text(GTK_LABEL(l_last_time), sample_to_time_text(last, prefs.rate, "", buf)); sprintf(buf, " %ld", last - first + 1); gtk_label_set_text(GTK_LABEL(l_samples), buf); #endif } void set_scroll_bar(long n, long first, long last) { GtkAdjustment *a = (GtkAdjustment *) scroll_pos; double dn = n; double df = first; double dl = last; double ps = dl - df; a->lower = 0; a->upper = dn; a->value = df; a->page_size = ps; a->step_increment = ps / 8.0; a->page_increment = ps * 0.95; /* scroll_pos = gtk_adjustment_new(1.0, 0.0, 100.0, 10.0, 20.0, 20.0) ; */ /* a->lower = 0 ; */ /* a->upper = 100.0 ; */ /* a->value = 10.0 ; */ /* a->step_increment = 10.0 ; */ /* a->page_increment = 20.0 ; */ /* a->page_size = 20.0 ; */ gtk_adjustment_changed(a); } void scroll_bar_changed(GtkWidget * widget, gpointer data) { GtkAdjustment *a = (GtkAdjustment *) scroll_pos; audio_view.first_sample = MAX(0, MIN(prefs.n_samples - 1, a->value)); audio_view.last_sample = MAX(0, MIN(prefs.n_samples - 1, a->value + a->page_size)); main_redraw(FALSE, TRUE); /* pause 1/3 second to allow the user to release the mouse button */ usleep(333); } void get_region_of_interest(long *first, long *last, struct view *v) { *first = v->selected_first_sample; *last = v->selected_last_sample; if (v->selection_region == FALSE) { *first = v->first_sample; *last = v->last_sample; } } GKeyFile* read_config(void) { gchar *config_file; GKeyFile *key_file = NULL; GError *error = NULL; config_file = g_build_filename (g_get_user_config_dir (), APPNAME, SETTINGS_FILE, NULL); //fprintf(stderr, "%s \n", config_file); key_file = g_key_file_new (); if (! g_key_file_load_from_file (key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, &error)) { if (error->code != G_IO_ERROR_NOT_FOUND) // this is expected when running for the first time // therefore don't use g_warning, which will error if G_DEBUG environment variable is set to "fatal-warnings" g_message ("Could not load options file: %s\n", error->message); g_clear_error (&error); } g_free (config_file); return(key_file); } void write_config(GKeyFile *key_file) { gchar *file_data; gchar *config_file; file_data = g_key_file_to_data (key_file, NULL, NULL); if (g_mkdir_with_parents (g_build_filename (g_get_user_config_dir (), APPNAME, NULL), 0755) != -1) { config_file = g_build_filename (g_get_user_config_dir (), APPNAME, SETTINGS_FILE, NULL); g_file_set_contents (config_file, file_data, -1, NULL); g_free (config_file); } else g_printerr ("Could not write settings file: %s\n", strerror (errno)); g_free (file_data); g_key_file_free (key_file); } void load_preferences(void) { GKeyFile *key_file = read_config(); // We should probably have a separate test for each preference... if (g_key_file_has_group(key_file, "config") == TRUE) { strcpy(pathname, g_key_file_get_string(key_file, "config", "pathname", NULL)); strcpy(last_filename, g_key_file_get_string(key_file, "config", "last_filename", NULL)); audio_view.first_sample = g_key_file_get_integer(key_file, "config", "first_sample_viewed", NULL); audio_view.last_sample = g_key_file_get_integer(key_file, "config", "last_sample_viewed", NULL); // What's going on here with num_song_markers? num_song_markers = 0; weak_declick_sensitivity = g_key_file_get_double(key_file, "config", "weak_declick_sensitivity", NULL); strong_declick_sensitivity = g_key_file_get_double(key_file, "config", "strong_declick_sensitivity", NULL); declick_iterate_flag = g_key_file_get_integer(key_file, "config", "declick_iterate", NULL); weak_fft_declick_sensitivity = g_key_file_get_double(key_file, "config", "weak_fft_declick_sensitivity", NULL); strong_fft_declick_sensitivity = g_key_file_get_double(key_file, "config", "strong_fft_declick_sensitivity", NULL); declick_detector_type = g_key_file_get_integer(key_file, "config", "declick_detector_type", NULL); decrackle_level = g_key_file_get_double(key_file, "config", "decrackle_level", NULL); decrackle_window = g_key_file_get_integer(key_file, "config", "decrackle_window", NULL); decrackle_average = g_key_file_get_integer(key_file, "config", "decrackle_average", NULL); stop_key_highlight_interval = g_key_file_get_double(key_file, "config", "stop_key_highlight_interval", NULL); song_key_highlight_interval = g_key_file_get_double(key_file, "config", "song_key_highlight_interval", NULL); song_mark_silence = g_key_file_get_double(key_file, "config", "song_mark_silence", NULL); sonogram_log = g_key_file_get_double(key_file, "config", "sonogram_log", NULL); /* audio_view.truncate_tail = g_key_file_get_integer(key_file, "config", "truncate_tail", NULL) ; */ /* audio_view.truncate_head = g_key_file_get_integer(key_file, "config", "truncate_head", NULL) ; */ strcpy(audio_device, g_key_file_get_string(key_file, "config", "audio_device", NULL)); } if (g_key_file_has_group(key_file, "window") == TRUE) { window_width = g_key_file_get_integer(key_file, "window", "width", NULL); window_height = g_key_file_get_integer(key_file, "window", "height", NULL); window_x = g_key_file_get_integer(key_file, "window", "x", NULL); window_y = g_key_file_get_integer(key_file, "window", "y", NULL); window_maximised = g_key_file_get_boolean(key_file, "window", "maximised", NULL); } g_key_file_free (key_file); } void save_preferences(void) { GKeyFile *key_file = read_config(); g_key_file_set_string(key_file, "config", "pathname", pathname); g_key_file_set_string(key_file, "config", "last_filename", last_filename); g_key_file_set_integer(key_file, "config", "first_sample_viewed", audio_view.first_sample); g_key_file_set_integer(key_file, "config", "last_sample_viewed", audio_view.last_sample); g_key_file_set_double(key_file, "config", "weak_declick_sensitivity", weak_declick_sensitivity); g_key_file_set_double(key_file, "config", "strong_declick_sensitivity", strong_declick_sensitivity); g_key_file_set_integer(key_file, "config", "declick_iterate", declick_iterate_flag); g_key_file_set_double(key_file, "config", "weak_fft_declick_sensitivity", weak_fft_declick_sensitivity); g_key_file_set_double(key_file, "config", "strong_fft_declick_sensitivity", strong_fft_declick_sensitivity); g_key_file_set_integer(key_file, "config", "declick_detector_type", declick_detector_type); g_key_file_set_double(key_file, "config", "decrackle_level", decrackle_level); g_key_file_set_integer(key_file, "config", "decrackle_window", decrackle_window); g_key_file_set_integer(key_file, "config", "decrackle_average", decrackle_average); g_key_file_set_double(key_file, "config", "stop_key_highlight_interval", stop_key_highlight_interval); g_key_file_set_double(key_file, "config", "song_key_highlight_interval", song_key_highlight_interval); g_key_file_set_double(key_file, "config", "song_mark_silence", song_mark_silence); g_key_file_set_integer(key_file, "config", "sonogram_log", sonogram_log); g_key_file_set_string(key_file, "config", "audio_device", audio_device); g_key_file_set_integer(key_file, "window", "width", window_width); g_key_file_set_integer(key_file, "window", "height", window_height); g_key_file_set_integer(key_file, "window", "x", window_x); g_key_file_set_integer(key_file, "window", "y", window_y); g_key_file_set_boolean(key_file, "window", "maximised", window_maximised); /* g_key_file_set_integer(key_file, "config", "truncate_head", audio_view.truncate_head) ; */ /* g_key_file_set_integer(key_file, "config", "truncate_tail", audio_view.truncate_tail) ; */ write_config(key_file); } /* void main_set_preferences(GtkWidget * widget, gpointer data) */ /* { */ /* preferences_dialog(prefs); */ /* } */ void display_message(char *msg, char *title) { GtkWidget *dlg, *txt; dlg = gtk_dialog_new_with_buttons(title, GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK, GTK_RESPONSE_NONE, NULL); txt = gtk_label_new(msg); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), txt, TRUE, TRUE, 0) ; /* Alister: disable since we have the file_selector closing even if opening fails // Also for the matching code in other functions // Alister: doing this (and for the other dialogs?) means that if the user raises // another window above gwc, then clicks on the dialog, the main_window // isn't raised, only the two dialogs. // But that is better than if we don't do this, in which case the user can raise the // file_selector dialog above the display_message dialog. if (GTK_WIDGET_VISIBLE(file_selector)) { gtk_window_set_transient_for((GtkWindow*) dlg, (GtkWindow*) file_selector); }*/ gtk_widget_show_all(dlg) ; gtk_dialog_run(GTK_DIALOG(dlg)) ; gtk_widget_destroy(txt) ; gtk_widget_destroy(dlg) ; main_redraw(FALSE, TRUE); } void warning(char *msg) { display_message(msg, "WARNING"); } void info(char *msg) { display_message(msg, ""); } int yesnocancel(char *msg) { GtkWidget *dlg, *text; gint dres; dlg = gtk_dialog_new_with_buttons("Question", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_NO, GTK_RESPONSE_NO, GTK_STOCK_YES, GTK_RESPONSE_YES, NULL); // This is right for the save changes dialog, but not for the truncation dialog #ifdef TRUNCATE_OLD // But it is probably time to remove that... I didn't cater to it when migrating from GnomeUIInfo to GtkUIManager and GtkAction gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_YES); text = gtk_label_new(msg); gtk_widget_show(text); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), text, TRUE, TRUE, 0); gtk_widget_show_all(dlg) ; /* if (GTK_WIDGET_VISIBLE(file_selector)) { gtk_window_set_transient_for((GtkWindow*) dlg, (GtkWindow*) file_selector); }*/ dres = gtk_dialog_run(GTK_DIALOG(dlg)); gtk_widget_destroy(dlg) ; if (dres == GTK_RESPONSE_NONE || dres == GTK_RESPONSE_CANCEL) { dres = 2 ; /* return we clicked cancel */ } else if (dres == GTK_RESPONSE_YES) { dres = 0 ; /* return we clicked yes */ } else { dres = 1 ; } main_redraw(FALSE, TRUE); return dres; } int yesno(char *msg) { GtkWidget *dlg, *text; int dres; dlg = gtk_dialog_new_with_buttons("Question", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_NO, GTK_RESPONSE_NO, GTK_STOCK_YES, GTK_RESPONSE_YES, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_NO); text = gtk_label_new(msg); gtk_widget_show(text); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), text, TRUE, TRUE, 0); /* if (GTK_WIDGET_VISIBLE(file_selector)) { gtk_window_set_transient_for((GtkWindow*) dlg, (GtkWindow*) file_selector); }*/ gtk_widget_show_all(dlg) ; dres = gtk_dialog_run(GTK_DIALOG(dlg)); gtk_widget_destroy(dlg) ; if (dres == GTK_RESPONSE_NONE || dres == GTK_RESPONSE_NO) { dres = 1 ; /* return we clicked no */ } else { dres = 0 ; /* return we clicked yes */ } main_redraw(FALSE, TRUE); return dres; } int prompt_user(char *msg, char *s, int maxlen) { GtkWidget *dlg, *text, *entry ; int dres; dlg = gtk_dialog_new_with_buttons("Input Requested", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); text = gtk_label_new(msg); gtk_widget_show(text); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), text, TRUE, TRUE, 0); entry = gtk_entry_new_with_max_length(maxlen); gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); if(strlen(s) > 0) gtk_entry_set_text(GTK_ENTRY(entry), s); gtk_widget_show(entry); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), entry, TRUE, TRUE, 0); /* if (GTK_WIDGET_VISIBLE(file_selector)) { gtk_window_set_transient_for((GtkWindow*) dlg, (GtkWindow*) file_selector); }*/ gtk_widget_show_all(dlg) ; dres = gtk_dialog_run(GTK_DIALOG(dlg)); if (dres == GTK_RESPONSE_NONE || dres == GTK_RESPONSE_NO) { dres = 1 ; /* return we clicked cancel */ } else { dres = 0 ; /* return we clicked yes */ strcpy(s, gtk_entry_get_text(GTK_ENTRY(entry))); } gtk_widget_destroy(dlg) ; main_redraw(FALSE, TRUE); return dres; } void help(GtkWidget * widget, gpointer data) { /* This shows the help in yelp and requires /usr/share/gnome/help/gwc/C/gwc.html (or similar, if not using html documentation) #if GTK_CHECK_VERSION(2,14,0) // GdkScreen *screen; // Need some more includes or something for this display stuff // DDisplay *ddisp; // ddisp = ddisplay_active(); // screen = gtk_widget_get_screen (GTK_WIDGET(ddisp->menu_bar)); // opens /usr/share/gnome/help/gwc/gwc.html (or similar, if not using html documentation) // if (gtk_show_uri(screen, "ghelp:gwc", gtk_get_current_event_time (), NULL)) if (gtk_show_uri(NULL, "ghelp:gwc", gtk_get_current_event_time (), NULL)) return; #endif */ // We prefer to show the help in a browser than yelp. // We should probably modify this so that it works if running GWC from the build directory without installing, and/or // so that it shows a warning message if the help file does not exist. But should figure out test for gvfs first. char *uri = g_strconcat ("file://", HELPDIR, "/", APPNAME, "/", APPNAME, ".html", NULL); #ifdef MAC_OS_X if ( gtkosx_application_get_bundle_id() ) uri = g_strconcat ("file://", g_uri_escape_string(gtkosx_application_get_resource_path(), "/", TRUE), HELPDIR, "/", APPNAME, "/", APPNAME, ".html", NULL); //g_message("testing %s", uri); char *command = g_strdup_printf("%s %s &", "open", uri); system(command); g_free(command); // I had compile problems trying to do it using this method! /* NSURL *ns_url; gboolean retval; //neither work //NSAutoreleasePool *pool [[NSAutoreleasePool alloc] init]; @autoreleasepool { ns_url = NSURL URLWithString: [NSString stringWithUTF8String: "file:///users/alister/gwc/doc/gtk-wave-cleaner.html"]; retval = [[NSWorkspace sharedWorkspace] openURL: ns_url]; } return retval; */ # else /* // This is infuriating as it silently fails if gvfs is not installed, and it will freeze gwc // if gvfs is installed but broken (e.g. because the dbus session isn't working correctly)! if GTK_CHECK_VERSION(2,14,0) { // not sure if this does what I want GdkScreen *screen = gtk_widget_get_screen (main_window); // First try gtk_show_uri(), which fails if gvfs is not installed // Then use xdg-open, which should work in almost all cases. // If we were keen we could copy pragha's src/utils.c, which then tries firefox, mozilla, opera... if ( !gtk_show_uri(screen, uri, gtk_get_current_event_time (), NULL) ) { char *command = g_strdup_printf("%s %s &", command ? command : "xdg-open", uri); system(command); g_free(command); } } else { */ // I used to think that xdg-open was inferior because it used a hard-coded list of browsers, // but it actually uses the $BROWSER environment variable if set char *command = g_strdup_printf("%s %s &", "xdg-open", uri); system(command); g_free(command); // } #endif g_free(uri); } void declick_with_sensitivity(double sensitivity) { long first, last; char *result_msg; gint leave_click_marks ; repair_clicks = gtk_toggle_button_get_active((GtkToggleButton *)detect_only_widget) == TRUE ? FALSE : TRUE; leave_click_marks = gtk_toggle_button_get_active((GtkToggleButton *)leave_click_marks_widget) == TRUE ? TRUE : FALSE ; if (repair_clicks == TRUE) start_save_undo("Undo declick", &audio_view); get_region_of_interest(&first, &last, &audio_view); push_status_text(repair_clicks == TRUE ? "Declicking selection" : "Detecting clicks"); click_data.max_clicks = MAX_CLICKS; result_msg = do_declick(&prefs, first, last, audio_view.channel_selection_mask, sensitivity, repair_clicks, &click_data, declick_iterate_flag,leave_click_marks); if (repair_clicks == TRUE) { resample_audio_data(&prefs, first, last); save_sample_block_data(&prefs); } pop_status_text(); set_status_text(result_msg); if (repair_clicks == TRUE) { close_undo(); } main_redraw(FALSE, TRUE); } void declick(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; if(declick_detector_type == HPF_DETECT) declick_with_sensitivity(strong_declick_sensitivity); else declick_with_sensitivity(strong_fft_declick_sensitivity); file_processing = FALSE; } } void declick_weak(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; if(declick_detector_type == HPF_DETECT) declick_with_sensitivity(weak_declick_sensitivity); else declick_with_sensitivity(weak_fft_declick_sensitivity); file_processing = FALSE; } } void estimate(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { long first, last; file_processing = TRUE; get_region_of_interest(&first, &last, &audio_view); dethunk(&prefs, first, last, audio_view.channel_selection_mask); main_redraw(FALSE, TRUE); set_status_text("Estimate done."); file_processing = FALSE; } } void manual_declick(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { int doit = TRUE; long first, last; file_processing = TRUE; get_region_of_interest(&first, &last, &audio_view); if (last - first > 299) { char msg_buf[1000] ; double n = last-first+1 ; double a = 100 ; double elements = ( n + (n-a) * n + (n-a) * n + (n-a) * n + (n-a) * (n-a) + (n-a) * (n-a) + n * n ) ; double bytes = elements * sizeof(double) / (double) (1 << 20) ; char *units = "Megabytes" ; if(bytes > 1000) { bytes /= (double) 1024 ; units = "Gigabytes" ; } if(bytes > 1000) { bytes /= (double) 1024 ; units = "Terabytes" ; } sprintf(msg_buf, "Repairing > 300 samples may cause a crash\nYou have selected %lg samples, which will require about %8.0lf %s of memory and a long time.", n, bytes, units ) ; doit = FALSE; if (!yesno(msg_buf)) doit = TRUE; } if (doit == TRUE) { start_save_undo("Undo declick", &audio_view); push_status_text("Declicking selection"); declick_a_click(&prefs, first, last, audio_view.channel_selection_mask); resample_audio_data(&prefs, first, last); save_sample_block_data(&prefs); pop_status_text(); set_status_text("Manual declick done."); close_undo(); main_redraw(FALSE, TRUE); } file_processing = FALSE; } } void decrackle(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { int cancel; long first, last; file_processing = TRUE; push_status_text("Saving undo information"); start_save_undo("Undo decrackle", &audio_view); get_region_of_interest(&first, &last, &audio_view); cancel = save_undo_data(first, last, &prefs, TRUE); close_undo(); pop_status_text(); if (cancel != 1) { push_status_text("Decrackling selection"); do_decrackle(&prefs, first, last, audio_view.channel_selection_mask, decrackle_level, decrackle_window, decrackle_average); resample_audio_data(&prefs, first, last); save_sample_block_data(&prefs); pop_status_text(); set_status_text("Decrackle done."); } main_redraw(FALSE, TRUE); file_processing = FALSE; } } void noise_sample(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; get_region_of_interest(&denoise_data.noise_start, &denoise_data.noise_end, &audio_view); denoise_data.ready = TRUE; load_denoise_preferences() ; //print_noise_sample(&prefs, &denoise_prefs, denoise_data.noise_start, denoise_data.noise_end) ; file_processing = FALSE; } } void remove_noise(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; if (denoise_data.ready == FALSE) { warning("Please select the noise sample first"); } else { get_region_of_interest(&denoise_data.denoise_start, &denoise_data.denoise_end, &audio_view); load_denoise_preferences(); print_denoise("remove_noise", &denoise_prefs); { int cancel; if (denoise_prefs.FFT_SIZE > (denoise_data.noise_end - denoise_data.noise_start + 1)) { warning ("FFT_SIZE must be <= # samples in noise sample!"); main_redraw(FALSE, TRUE); file_processing = FALSE ; return; } push_status_text("Saving undo information"); start_save_undo("Undo denoise", &audio_view); cancel = save_undo_data(denoise_data.denoise_start, denoise_data.denoise_end, &prefs, TRUE); close_undo(); pop_status_text(); if (cancel != 1) { push_status_text("Denoising selection"); denoise(&prefs, &denoise_prefs, denoise_data.noise_start, denoise_data.noise_end, denoise_data.denoise_start, denoise_data.denoise_end, audio_view.channel_selection_mask); resample_audio_data(&prefs, denoise_data.denoise_start, denoise_data.denoise_end); save_sample_block_data(&prefs); pop_status_text(); } set_status_text("Denoise done."); main_redraw(FALSE, TRUE); } } file_processing = FALSE; } } void undo_callback(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; undo(&audio_view, &prefs); main_redraw(FALSE, TRUE); file_processing = FALSE; } else { if (file_is_open == FALSE) { warning("Nothing to Undo Yet."); } else warning ("Please try Undo when processing or Audio Playback has stopped"); } } void scale_up_callback(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; view_scale *= 1.25; main_redraw(FALSE, TRUE); file_processing = FALSE; } } void cut_callback(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { #ifdef TRUNCATE_OLD long start, end; file_processing = TRUE; get_region_of_interest(&start, &end, &audio_view); if (start < prefs.n_samples - end) { audio_view.truncate_head = end + 1; } else { audio_view.truncate_tail = start - 1; } main_redraw(FALSE, TRUE); file_processing = FALSE; #else /* !TRUNCATE_OLD */ if (is_region_selected()) { long first, last; get_region_of_interest(&first, &last, &audio_view); if (first == 0 && last == prefs.n_samples - 1) { info("Can't cut ALL audio data from file."); } else { file_processing = TRUE; audioedit_cut_selection(&audio_view); set_status_text("Cut done."); main_redraw(FALSE, TRUE); file_processing = FALSE; } } #endif /* !TRUNCATE_OLD */ } } #ifndef TRUNCATE_OLD void copy_callback(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { if (is_region_selected()) { file_processing = TRUE; audioedit_copy_selection(&audio_view); file_processing = FALSE; } } } void paste_callback(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { if (is_region_selected()) { if (audioedit_has_clipdata()) { file_processing = TRUE; audioedit_paste_selection(&audio_view); set_status_text("Paste done."); main_redraw(FALSE, TRUE); file_processing = FALSE; } else { info("No audio data in internal clipboard."); } } } } void delete_callback(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { if (is_region_selected()) { long first, last; get_region_of_interest(&first, &last, &audio_view); if (first == 0 && last == prefs.n_samples - 1) { info("Can't delete ALL audio data from file."); } else { file_processing = TRUE; audioedit_delete_selection(&audio_view); set_status_text("Delete done."); main_redraw(FALSE, TRUE); file_processing = FALSE; } } } } void silence_callback(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { if (is_region_selected()) { if(!yesno("Insert silence can take a long time, continue?")) { file_processing = TRUE; audioedit_insert_silence(&audio_view); set_status_text("Silence done."); main_redraw(FALSE, TRUE); file_processing = FALSE; } } } } #endif /* !TRUNCATE_OLD */ void scale_reset_callback(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; view_scale = 1.00; spectral_amp = 1.00; main_redraw(FALSE, TRUE); file_processing = FALSE; } } void scale_down_callback(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; view_scale /= 1.25; main_redraw(FALSE, TRUE); file_processing = FALSE; } } int count = 0; long prev_cursor_millisec = -1; /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void stop_all_playback_functions(GtkWidget * widget, gpointer data) { if (playback_timer != -1) { gtk_timeout_remove(playback_timer); playback_timer = -1 ; } if (cursor_playback == TRUE) gtk_timeout_remove(cursor_timer); stop_playback(stop_playback_force); cursor_playback = FALSE; audio_playback = FALSE; led_bar_light_percent(dial[0], 0.0); led_bar_light_percent(dial[1], 0.0); } /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void record(GtkWidget * widget, gpointer data) { /* stop_recording() ; */ } void gnome_flush(void) { while (gtk_events_pending()) gtk_main_iteration(); } long playback_samples_per_block; gint play_a_block(gpointer data) { gfloat l, r; long first, last, bytes_left; get_region_of_interest(&first, &last, &audio_view); if (audio_playback == TRUE) { if (process_audio(&l, &r) == 0) { led_bar_light_percent(dial[0], l); led_bar_light_percent(dial[1], r); } else { d_print("process_audio returns nonzero.\n"); } } bytes_left = set_playback_cursor_position(&audio_view, prev_cursor_millisec); /* fprintf(stderr, "bytes_left:%ld\n", bytes_left) ; */ if (bytes_left < 10 && !audio_is_looping) { /* the "10" is to allow some error in the audio driver */ audio_debug_print("play_a_block is stopping the playback_timer.\n") ; stop_playback_force = 0 ; stop_all_playback_functions(NULL, NULL) ; stop_playback_force = 1 ; } return (TRUE); } gint update_cursor(gpointer data) { long cursor_samples_per_pixel; long cursor_millisec; audio_debug_print("update_cursor with audio_playback:%d\n", audio_playback) ; if (audio_playback == TRUE) { cursor_samples_per_pixel = (audio_view.last_sample - audio_view.first_sample) / audio_view.canvas_width; cursor_millisec = (cursor_samples_per_pixel * 1000) / prefs.rate; /* lower limit of 1/20th second on screen redraws */ if (cursor_millisec < 50) cursor_millisec = 50; if (cursor_millisec != prev_cursor_millisec) { gtk_timeout_remove(cursor_timer); cursor_timer = gtk_timeout_add(cursor_millisec, update_cursor, NULL); prev_cursor_millisec = cursor_millisec; } set_playback_cursor_position(&audio_view, prev_cursor_millisec); main_redraw(TRUE, TRUE); audio_debug_print(".\n") ; } else { long last, first; get_region_of_interest(&first, &last, &audio_view); if (audio_view.cursor_position < last) { set_playback_cursor_position(&audio_view, prev_cursor_millisec); main_redraw(TRUE, TRUE); audio_debug_print("?\n") ; } else { audio_debug_print("\nupdate_cursor is stopping cursor_timer\n") ; cursor_playback = FALSE; gtk_timeout_remove(cursor_timer); stop_playback_force = 0 ; stop_all_playback_functions(NULL, NULL); stop_playback_force = 1 ; prev_cursor_millisec = -1; /* this will redraw the whole sonogram view at the end of a "full view" playback ...frank 31.08.03 */ /* main_redraw(FALSE, TRUE); */ } } return (TRUE); } /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void start_gwc_playback(GtkWidget * widget, gpointer data) { /* Play audio */ long millisec_per_block; audio_debug_print("entering start_gwc_playback with audio_playback=%d\n", audio_playback) ; if (file_is_open == TRUE && file_processing == FALSE && audio_playback == FALSE && cursor_playback == FALSE) { playback_samples_per_block = start_playback(audio_device, &audio_view, &prefs, 0.10, 0.25); if(playback_samples_per_block < 1) return ; // an error occurred audio_playback = TRUE; audio_debug_print("playback_samples_per_block=%ld\n", playback_samples_per_block) ; if (audio_playback == TRUE) { millisec_per_block = playback_samples_per_block * 1000 / prefs.rate; cursor_samples_per_playback_block = (millisec_per_block - 5) * prefs.rate / 1000; { long margin = 50; if (millisec_per_block < 100) margin = millisec_per_block / 2; audio_debug_print("start_gwc_playback starting playback timers\n") ; playback_timer = gtk_timeout_add(millisec_per_block - margin, play_a_block, NULL); cursor_playback = TRUE; prev_cursor_millisec = millisec_per_block - margin; cursor_timer = gtk_timeout_add(50, update_cursor, NULL); } play_a_block(NULL); } else { /* not enough samples played to get more than 1 block in the buffer, no point in drawing cursor now, the audio data is not available to dump to the audio device now! */ } } audio_debug_print("leaving start_gwc_playback with audio_playback=%d\n", audio_playback) ; audio_is_looping = FALSE ; } void detect_only_func(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; repair_clicks = gtk_toggle_button_get_active((GtkToggleButton *) widget) == TRUE ? FALSE : TRUE; g_print("detect_only_func called: %s\n", (char *) data); file_processing = FALSE; } } /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void amplify(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; if (amplify_dialog(prefs, &audio_view)) { long first, last; int cancel; get_region_of_interest(&first, &last, &audio_view); push_status_text("Saving undo information"); start_save_undo("Undo amplify", &audio_view); cancel = save_undo_data(first, last, &prefs, TRUE); close_undo(); pop_status_text(); if (cancel != 1) { amplify_audio(&prefs, first, last, audio_view.channel_selection_mask); save_sample_block_data(&prefs); set_status_text("Amplify done."); } main_redraw(FALSE, TRUE); } file_processing = FALSE; } } /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void reverb(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; if (reverb_dialog(prefs, &audio_view)) { long first, last; int cancel; get_region_of_interest(&first, &last, &audio_view); push_status_text("Saving undo information"); start_save_undo("Undo reverb", &audio_view); cancel = save_undo_data(first, last, &prefs, TRUE); close_undo(); pop_status_text(); if (cancel != 1) { reverb_audio(&prefs, first, last, audio_view.channel_selection_mask); save_sample_block_data(&prefs); set_status_text("Reverb done."); } main_redraw(FALSE, TRUE); } file_processing = FALSE; } } /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void pinknoise_cb(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; if (pinknoise_dialog(prefs, &audio_view)) { long first, last; int cancel; get_region_of_interest(&first, &last, &audio_view); push_status_text("Saving undo information"); start_save_undo("Undo pinknoise", &audio_view); cancel = save_undo_data(first, last, &prefs, TRUE); close_undo(); pop_status_text(); if (cancel != 1) { pinknoise(&prefs, first, last, audio_view.channel_selection_mask); save_sample_block_data(&prefs); set_status_text("Pink Noise done."); } main_redraw(FALSE, TRUE); } file_processing = FALSE; } } /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void filter_cb(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; if (filter_dialog(prefs, &audio_view)) { long first, last; int cancel; get_region_of_interest(&first, &last, &audio_view); push_status_text("Saving undo information"); start_save_undo("Undo filter", &audio_view); cancel = save_undo_data(first, last, &prefs, TRUE); close_undo(); pop_status_text(); if (cancel != 1) { filter_audio(&prefs, first, last, audio_view.channel_selection_mask); save_sample_block_data(&prefs); set_status_text("Filter done."); } main_redraw(FALSE, TRUE); } file_processing = FALSE; } } void zoom_select(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; if(audio_view.selected_first_sample == audio_view.selected_last_sample) { audio_view.first_sample = audio_view.selected_first_sample - prefs.rate+1 ; audio_view.last_sample = audio_view.selected_last_sample + prefs.rate ; } else { audio_view.first_sample = audio_view.selected_first_sample; audio_view.last_sample = audio_view.selected_last_sample; } if(audio_view.selected_first_sample < 0) audio_view.selected_first_sample = 0 ; if(audio_view.selected_last_sample > prefs.n_samples-1) audio_view.selected_last_sample = prefs.n_samples-1 ; set_scroll_bar(prefs.n_samples - 1, audio_view.first_sample, audio_view.last_sample); /* set_scroll_bar redraws */ /*main_redraw(FALSE, TRUE) ; */ file_processing = FALSE; } } void select_all(GtkWidget * widget, gpointer data) { audio_view.selected_first_sample = audio_view.first_sample; audio_view.selected_last_sample = audio_view.last_sample; audio_view.selection_region = TRUE; main_redraw(FALSE, TRUE); } void select_none(GtkWidget * widget, gpointer data) { audio_view.selection_region = FALSE; audio_view.channel_selection_mask = 3 ; main_redraw(FALSE, TRUE); } void select_markers(GtkWidget * widget, gpointer data) { int i ; long new_first = -1 ; long new_last = -1 ; for (i = 0; i < n_markers; i++) { if(markers[i] < audio_view.selected_first_sample) { if(new_first == -1) new_first = markers[i] ; else new_first = MAX(new_first, markers[i]) ; } if(markers[i] > audio_view.selected_last_sample) { if(new_last == -1) new_last = markers[i] ; else new_last = MIN(new_last, markers[i]) ; } } if(new_first != -1) audio_view.selected_first_sample = new_first ; if(new_last != -1) audio_view.selected_last_sample = new_last ; main_redraw(FALSE, TRUE); } void toggle_marker_at(long sample) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { int i; int j; file_processing = TRUE; for (i = 0; i < n_markers; i++) { if (markers[i] == sample) { n_markers--; for (j = i; j < n_markers; j++) markers[j] = markers[j + 1]; file_processing = FALSE; return; } } if (n_markers < MAX_MARKERS) { markers[n_markers] = sample; n_markers++; } else { warning("Maximum number of markers already set"); } file_processing = FALSE; } } void split_audio_on_markers(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { int i = 0 ; int first = -1 ; int trackno = 1 ; long first_sample = 0 ; long last_sample = song_markers[0] ; /* for(i = 0 ; i < num_song_markers ; i++) { */ /* printf("marker %2d at sample %d\n", i, song_markers[i]) ; */ /* } */ /* */ /* i=0 ; */ while(last_sample < 10000 && i < num_song_markers) { first_sample = last_sample ; i++ ; last_sample = song_markers[i] ; } file_processing = TRUE; while(last_sample <= prefs.n_samples-1 && i <= num_song_markers) { char filename[100] ; // Alister: I'm sure this could be much tidier // Not that the first case is really needed if (file_extension=="") { if(trackno < 10) { //Alister: don't just output as xxx.cdda.wav //we aren't necessarily working with a .wav file //and why would we need the .cdda? snprintf(filename,99,"track0%d",trackno) ; } else { snprintf(filename,99,"track%d",trackno) ; } } else { if(trackno < 10) { //Alister: don't just output as xxx.cdda.wav //we aren't necessarily working with a .wav file //and why would we need the .cdda? snprintf(filename,99,"track0%d.%s",trackno,file_extension) ; } else { snprintf(filename,99,"track%d.%s",trackno,file_extension) ; } } if(last_sample-first_sample >= 10000) { save_as_wavfile(filename, first_sample, last_sample) ; printf("Save as wavfile %s %d->%d\n", filename, first_sample, last_sample) ; trackno++ ; } first_sample=last_sample+1 ; i++ ; if(i < num_song_markers) { last_sample = song_markers[i] ; } else { last_sample = prefs.n_samples-1 ; } } file_processing = FALSE; } } void adjust_marker_positions(long pos, long delta) { int i,j; i = 0; while (i < n_markers) { if (markers[i] >= pos) { markers[i] += delta; if (markers[i] <= pos || markers[i] >= prefs.n_samples) { for (j = i; j < n_markers - 1; j++) { markers[j] = markers[j+1]; } n_markers--; } else { i++; } } else { i++; } } } /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void view_all(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; audio_view.first_sample = 0; audio_view.last_sample = prefs.n_samples - 1; set_scroll_bar(prefs.n_samples - 1, audio_view.first_sample, audio_view.last_sample); /* set_scroll_bar redraws */ /*main_redraw(FALSE, TRUE) ; */ file_processing = FALSE; } } /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void zoom_out(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { long w = audio_view.last_sample - audio_view.first_sample; file_processing = TRUE; w *= 2; audio_view.first_sample -= w / 4; if (audio_view.first_sample < 0) audio_view.first_sample = 0; audio_view.last_sample = audio_view.first_sample + w; if (audio_view.last_sample > prefs.n_samples - 1) audio_view.last_sample = prefs.n_samples - 1; set_scroll_bar(prefs.n_samples - 1, audio_view.first_sample, audio_view.last_sample); /* set_scroll_bar redraws */ /*main_redraw(FALSE, TRUE) ; */ file_processing = FALSE; } } /* This is a callback function. The data arguments are ignored * in this example. More on callbacks below. */ void zoom_in(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { long w = audio_view.last_sample - audio_view.first_sample; file_processing = TRUE; w /= 2; audio_view.first_sample += w / 2; if (audio_view.first_sample < 0) audio_view.first_sample = 0; audio_view.last_sample = audio_view.first_sample + w; if (audio_view.last_sample > prefs.n_samples - 1) audio_view.last_sample = prefs.n_samples - 1; set_scroll_bar(prefs.n_samples - 1, audio_view.first_sample, audio_view.last_sample); /* set_scroll_bar redraws */ /*main_redraw(FALSE, TRUE) ; */ file_processing = FALSE; } } void toggle_start_marker(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { long first, last; get_region_of_interest(&first, &last, &audio_view); toggle_marker_at(first); main_redraw(FALSE, TRUE); } } void toggle_end_marker(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { long first, last; get_region_of_interest(&first, &last, &audio_view); toggle_marker_at(last); main_redraw(FALSE, TRUE); } } void clear_markers_in_view(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { long first, last; int i; get_region_of_interest(&first, &last, &audio_view); for (i = 0; i < n_markers; i++) { if (markers[i] >= first && markers[i] <= last) { toggle_marker_at(markers[i]); i--; /* current marker deleted, next marker dropped into position i */ } } main_redraw(FALSE, TRUE); } } gboolean key_press_cb(GtkWidget * widget, GdkEventKey * event, gpointer data) { extern double spectral_amp; gboolean handled = TRUE ; /* g_print("key_press_cb\n") ; */ /* GDK_b, GDK_c, GDK_e, GDK_n, GDK_z used through menus */ switch (event->keyval) { case GDK_space: if (cursor_playback == FALSE) start_gwc_playback(widget, data); else { stop_all_playback_functions(widget, data); } break; case GDK_l: if (cursor_playback == FALSE) { start_gwc_playback(widget, data); audio_is_looping = TRUE ; } else { audio_is_looping = FALSE ; stop_all_playback_functions(widget, data); } break; case GDK_s: if (audio_playback == TRUE) { set_playback_cursor_position(&audio_view, prev_cursor_millisec); gtk_timeout_remove(cursor_timer); stop_all_playback_functions(widget, data); audio_view.selected_last_sample = audio_view.cursor_position; audio_view.selected_first_sample = audio_view.selected_last_sample - prefs.rate * stop_key_highlight_interval; if (audio_view.selected_first_sample < 0) audio_view.selected_first_sample = 0; audio_view.selection_region = TRUE; main_redraw(FALSE, TRUE); } break; case GDK_3: if (audio_playback == FALSE) { /* go foward by one revolution of a 33 1/3 rpm record */ int sample_shift = prefs.rate * 60.0 / 33.333333333 ; //printf("shift is %d samples\n", sample_shift) ; if ( sample_shift + audio_view.last_sample < prefs.n_samples - 1) { audio_view.last_sample += sample_shift ; audio_view.first_sample += sample_shift ; set_scroll_bar(prefs.n_samples - 1, audio_view.first_sample, audio_view.last_sample); } } break; case GDK_2: if (audio_playback == FALSE) { /* go backward by one revolution of a 33 1/3 rpm record */ int sample_shift = prefs.rate * 60.0 / 33.333333333 ; if (sample_shift < audio_view.first_sample) { audio_view.last_sample -= sample_shift ; audio_view.first_sample -= sample_shift ; set_scroll_bar(prefs.n_samples - 1, audio_view.first_sample, audio_view.last_sample); } } break; case GDK_d: scale_down_callback(widget, data); break; case GDK_j: spectral_amp *= 1.7; main_redraw(FALSE, TRUE); break; case GDK_k: spectral_amp /= 1.7; main_redraw(FALSE, TRUE); break; case GDK_r: scale_reset_callback(widget, data); break; case GDK_u: scale_up_callback(widget, data); break; case GDK_a: if (event->state & GDK_MOD1_MASK) /* Alt-a */ manual_declick(NULL, NULL); else append_cdrdao(&audio_view); break; default: handled = FALSE ; break ; } return handled ; } int cleanup_and_close(struct view *v, struct sound_prefs *p) { stop_playback(1); if(batch_mode == 0 && file_is_open && get_undo_levels() > 0) { int r = yesnocancel("Save changes to the audio file?") ; if(r == 2) return 0 ; if(r == 1) { fprintf(stderr, "Undoing all changes\n") ; int _p = get_undo_levels() ; while(undo(v, p) > 0) { if ( get_undo_levels() == _p ) return 0 ; _p -- ; } ; } } if (file_is_open) save_sample_block_data(&prefs); if (close_wavefile(&audio_view)) { window_maximised = gdk_window_get_state(gtk_widget_get_window(main_window)) & GDK_WINDOW_STATE_MAXIMIZED; if(window_maximised == FALSE) { gtk_window_get_position(GTK_WINDOW(main_window), &window_x, &window_y); gtk_window_get_size(GTK_WINDOW(main_window), &window_width, &window_height); } save_preferences(); gtk_accel_map_save( g_build_filename (g_get_user_config_dir (), APPNAME, ACCELERATORS_FILE, NULL) ); undo_purge(); } return 1 ; } gint delete_event(GtkWidget * widget, GdkEvent * event, gpointer data) { if( file_processing == TRUE ) { warning("Can't quit while file is being processed."); return TRUE; } if( batch_mode == TRUE ) { warning("Can't quit while in batch mode. (Will automatically close.)"); return TRUE; } if(!cleanup_and_close(&audio_view, &prefs)) return TRUE; rmdir(tmpdir); gtk_main_quit(); return FALSE; } /* I believe I have fixed the crash when clicking outside the about dialog. I'm guessing opening the website link requires gvfs and a working dbus session. */ void about(GtkWidget *window) { const gchar *authors[] = { "Jeffrey J. Welty", "James Tappin", "Ian Leonard", "Bill Jetzer", "Charles Morgon", "Frank Freudenberg", "Thiemo Gehrke", "Rob Frohne", "Alister Hood", NULL }; const gchar* LICENSE="This program is free software; you can redistribute it and/or " "modify it under the terms of the GNU General Public License " "as published by the Free Software Foundation; either version 2 " "of the License, or (at your option) any later version.\n\n" "This program is distributed in the hope that it will be useful, " "but WITHOUT ANY WARRANTY; without even the implied warranty of " "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the " "GNU General Public License for more details.\n" "You 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."; gtk_show_about_dialog(GTK_WINDOW( NULL ), "version", VERSION, "copyright", "Copyright 2001, 2002, 2003, 2004, 2005 Redhawk.org", "license", LICENSE, "wrap-license", TRUE, "website", "http://gwc.sourceforge.net/", "comments", "Removes noise (hiss, pops and clicks) from audio files in WAV and similar formats.\ne.g recordings of scratchy vinyl records.", "authors", authors, "logo-icon-name", APPNAME, NULL); // Note I think we'd have to refactor a bit to make this dialog modal in GTK2 } void main_redraw(int cursor_flag, int redraw_data) { if (doing_progressbar_update == TRUE) return; if (file_is_open == TRUE) redraw(&audio_view, &prefs, audio_drawing_area, cursor_flag, redraw_data, spectral_view_flag); if (file_is_open == TRUE && cursor_flag == FALSE) display_times(); } void display_sonogram(GtkWidget * widget, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { file_processing = TRUE; spectral_view_flag = !spectral_view_flag; main_redraw(FALSE, TRUE); file_processing = FALSE; } } void open_wave_filename(void) { char tmp[PATH_MAX+1]; int l; struct sound_prefs tmp_prefs; gnome_flush(); /* Close writes to wave_filename so put back the name of the current open file */ // Note that the current file is closed (but still visible) even if opening the new file fails! strcpy(tmp,wave_filename); strcpy(wave_filename, last_filename); if(!cleanup_and_close(&audio_view, &prefs)) return ; strcpy(wave_filename,tmp); /* all this to store the last directory where a file was opened */ // Eh? It was storing the full path, but mangling it if the file was in / /* strcpy(tmp, wave_filename); strcpy(pathname, dirname(tmp)); strcat(pathname, "/"); strcpy(tmp, wave_filename); strcat(pathname, basename(tmp)); */ // This seems to do the job // But note that it still stores the file location even if it isn't able to be opened (e.g. because it isn't a wav file). Is this intended? strcpy(pathname, tmp); l = strlen(wave_filename); // Should also really reject wav files that we can't work with, or fix it so they do work! if (is_valid_audio_file(wave_filename)) { tmp_prefs = open_wavefile((char *) wave_filename, &audio_view); if (tmp_prefs.successful_open) { prefs = tmp_prefs; spectral_view_flag = FALSE; if (prefs.wavefile_fd != -1) { #ifdef TRUNCATE_OLD audio_view.truncate_head = 0; audio_view.truncate_tail = (prefs.n_samples - 1); #endif /* TRUNCATE_OLD */ audio_view.n_samples = prefs.n_samples; if (audio_view.first_sample == -1) { audio_view.first_sample = 0; audio_view.last_sample = (prefs.n_samples - 1); } else { audio_view.first_sample = MIN(prefs.n_samples - 1, audio_view.first_sample); audio_view.first_sample = MAX(0, audio_view.first_sample); audio_view.last_sample = MIN(prefs.n_samples - 1, audio_view.last_sample); audio_view.last_sample = MAX(0, audio_view.last_sample); } audio_view.selection_region = FALSE; // If we don't do this and we had another file open with just left or right channel selected, only that channel will be cleaned // But that is very unexpected! audio_view.channel_selection_mask = 3 ; file_is_open = TRUE; fill_sample_buffer(&prefs); /* display entire file data if this file changed since last edit session */ if (strcmp(wave_filename, last_filename)) { audio_view.first_sample = 0; audio_view.last_sample = prefs.n_samples - 1; strcpy(last_filename, wave_filename); num_song_markers = 0; } set_scroll_bar(prefs.n_samples - 1, audio_view.first_sample, audio_view.last_sample); main_redraw(FALSE, TRUE); // get the file extension, so we know what to call files we export // note that for a hidden file with no extension e.g. ~/.name // name will be used as the extension. // this is obviously wrong, but actually kind of cool as it allows you to // split more than one file into tracks without overwriting outputs or restarting gwc from a different working directory. // i.e. track01.name1, track02.name1, then track01.name2, track02.name2 gchar *name = basename(wave_filename) ; file_extension = ""; while (*name) { if (*name++ == '.') file_extension = name; } } else { file_is_open = FALSE; warning("failed to open audio file"); } } else { strcpy(wave_filename, last_filename); } } else { file_is_open = FALSE; warning("No file selected, or file format not recognized"); } } void old_open_wave_filename(void) { char tmp[PATH_MAX+1]; gnome_flush(); /* all this to store the last directory where a file was opened */ strcpy(tmp, wave_filename); strcpy(pathname, dirname(tmp)); strcat(pathname, "/"); strcpy(tmp, wave_filename); strcat(pathname, basename(tmp)); { int l; struct sound_prefs tmp_prefs; cleanup_and_close(&audio_view, &prefs); l = strlen(wave_filename); if (is_valid_audio_file(wave_filename)) { tmp_prefs = open_wavefile((char *) wave_filename, &audio_view); if (tmp_prefs.successful_open) { prefs = tmp_prefs; spectral_view_flag = FALSE; if (prefs.wavefile_fd != -1) { #ifdef TRUNCATE_OLD audio_view.truncate_head = 0; audio_view.truncate_tail = (prefs.n_samples - 1); #endif /* TRUNCATE_OLD */ audio_view.n_samples = prefs.n_samples; if (audio_view.first_sample == -1) { audio_view.first_sample = 0; audio_view.last_sample = (prefs.n_samples - 1); } else { audio_view.first_sample = MIN(prefs.n_samples - 1, audio_view.first_sample); audio_view.first_sample = MAX(0, audio_view.first_sample); audio_view.last_sample = MIN(prefs.n_samples - 1, audio_view.last_sample); audio_view.last_sample = MAX(0, audio_view.last_sample); } audio_view.selection_region = FALSE; file_is_open = TRUE; fill_sample_buffer(&prefs); /* display entire file data if this file changed since last edit session */ if (strcmp(wave_filename, last_filename)) { audio_view.first_sample = 0; audio_view.last_sample = prefs.n_samples - 1; strcpy(last_filename, wave_filename); num_song_markers = 0; } set_scroll_bar(prefs.n_samples - 1, audio_view.first_sample, audio_view.last_sample); main_redraw(FALSE, TRUE); } else { file_is_open = FALSE; warning("failed to open audio file"); } } else { strcpy(wave_filename, last_filename); } } else { file_is_open = FALSE; warning("No file selected, or file format not recognized"); } } } #ifdef MAC_OS_X void app_open_file_cb (GtkosxApplication *theApp, gchar *path, gpointer p) { strcpy(wave_filename, path); open_wave_filename(); } #endif void store_selection_filename(gpointer user_data) { if (strcmp(save_selection_filename, wave_filename)) { int l; l = strlen(save_selection_filename); save_selection_as_wavfile(save_selection_filename, &audio_view); } else { warning("Cannot save selection over the currently open file!"); } } void open_file_selection(GtkWidget * widget, gpointer data) { GtkFileFilter * ff, * ffa; if ((file_processing == FALSE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { /* Create the selector */ file_selector = gtk_file_chooser_dialog_new("Please select a file for editing.", GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(file_selector), pathname); ff = gtk_file_filter_new(); gtk_file_filter_set_name(ff,"Known extensions"); // I think we could borrow code from mhwaveedit which gets the list of formats from libsndfile, // but I don't think it would tell us all the extensions, and we'd need to make it only tell us // formats which support rdwr // // We could also borrow the dialog from mhwaveedit which allows you to open a raw audio file, // And it would also be good to be able to load raw audio specifying its format from the command line gtk_file_filter_add_pattern(ff,"*.wav"); gtk_file_filter_add_pattern(ff,"*.wavpcm"); gtk_file_filter_add_pattern(ff,"*.aiff"); gtk_file_filter_add_pattern(ff,"*.aif"); // when I try to create this format it actually seems the same as aiff, so not sure if we really do support it. gtk_file_filter_add_pattern(ff,"*.aiffc"); gtk_file_filter_add_pattern(ff,"*.aifc"); gtk_file_filter_add_pattern(ff,"*.au"); gtk_file_filter_add_pattern(ff,"*.snd"); gtk_file_filter_add_pattern(ff,"*.avr"); gtk_file_filter_add_pattern(ff,"*.caf"); gtk_file_filter_add_pattern(ff,"*.htk"); gtk_file_filter_add_pattern(ff,"*.iff"); gtk_file_filter_add_pattern(ff,"*.mat"); gtk_file_filter_add_pattern(ff,"*.mat4"); gtk_file_filter_add_pattern(ff,"*.mat5"); gtk_file_filter_add_pattern(ff,"*.mpc"); gtk_file_filter_add_pattern(ff,"*.paf"); gtk_file_filter_add_pattern(ff,"*.pvf"); gtk_file_filter_add_pattern(ff,"*.rf64"); gtk_file_filter_add_pattern(ff,"*.sd2"); gtk_file_filter_add_pattern(ff,"*.sds"); gtk_file_filter_add_pattern(ff,"*.sf"); gtk_file_filter_add_pattern(ff,"*.voc"); gtk_file_filter_add_pattern(ff,"*.w64"); gtk_file_filter_add_pattern(ff,"*.wve"); gtk_file_filter_add_pattern(ff,"*.WAV"); gtk_file_filter_add_pattern(ff,"*.WAVPCM"); gtk_file_filter_add_pattern(ff,"*.AIFF"); gtk_file_filter_add_pattern(ff,"*.AIF"); gtk_file_filter_add_pattern(ff,"*.AIFFC"); gtk_file_filter_add_pattern(ff,"*.AIFC"); gtk_file_filter_add_pattern(ff,"*.AU"); gtk_file_filter_add_pattern(ff,"*.SND"); gtk_file_filter_add_pattern(ff,"*.AVR"); gtk_file_filter_add_pattern(ff,"*.CAF"); gtk_file_filter_add_pattern(ff,"*.HTK"); gtk_file_filter_add_pattern(ff,"*.IFF"); gtk_file_filter_add_pattern(ff,"*.MAT"); gtk_file_filter_add_pattern(ff,"*.MAT4"); gtk_file_filter_add_pattern(ff,"*.MAT5"); gtk_file_filter_add_pattern(ff,"*.MPC"); // note that this format seems to be broken when written by ffmpeg, but mhwaveedit is OK gtk_file_filter_add_pattern(ff,"*.PAF"); gtk_file_filter_add_pattern(ff,"*.PVF"); gtk_file_filter_add_pattern(ff,"*.RF64"); gtk_file_filter_add_pattern(ff,"*.SD2"); gtk_file_filter_add_pattern(ff,"*.SDS"); gtk_file_filter_add_pattern(ff,"*.SF"); // note that this format seems to be broken when written by ffmpeg, but mhwaveedit is OK gtk_file_filter_add_pattern(ff,"*.VOC"); gtk_file_filter_add_pattern(ff,"*.W64"); // note that this format seems to be broken when written by mhwaveedit, but sox is OK gtk_file_filter_add_pattern(ff,"*.WVE"); // note libsndfile also supports reading and writing FLAC & ALAC, but does not support opening them in RDWR mode // and it supports reading and writing OGG, but I wasn't able to generate an OGG that it supported! gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_selector),ff); // Not sure why, but after switching to show all files, when next opened the dialog doesn't // show which filter is selected ??? // But if we put this code first it is ALWAYS selected // ??? ffa = gtk_file_filter_new(); gtk_file_filter_set_name(ffa,"All files"); gtk_file_filter_add_pattern(ffa,"*"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_selector),ffa); /* Display the dialog */ if (gtk_dialog_run (GTK_DIALOG (file_selector)) == GTK_RESPONSE_ACCEPT) { strncpy(wave_filename, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (file_selector)), PATH_MAX); gtk_widget_destroy (GTK_WIDGET (file_selector)); open_wave_filename(); } else { gtk_widget_destroy (GTK_WIDGET (file_selector)); } } } void save_selection_as_encoded(int fmt, char *filename, char *filename_new, struct view *v, char *trackname) { long total_samples; total_samples = v->selected_last_sample - v->selected_first_sample + 1; if (total_samples < 0 || total_samples > v->n_samples) { warning("Invalid selection"); return; } /* save part of file as encoded fmt - fmt,old file, new file, start sample, number of samples */ encode(fmt, filename, filename_new, v->selected_first_sample, total_samples, trackname); } void store_selected_filename_as_encoded(gpointer user_data) { int enc_format = NULL ; int l; char trackname[1024] = "" ; if (encoding_type == GWC_OGG) enc_format = OGG_FMT ; if (encoding_type == GWC_MP3) enc_format = MP3_FMT ; if (encoding_type == GWC_MP3_SIMPLE) enc_format = MP3_SIMPLE_FMT ; if(!prompt_user("Enter the trackname:", trackname, 1023)) { l = strlen(save_selection_filename); file_processing = TRUE; save_selection_as_encoded(enc_format, wave_filename, save_selection_filename, &audio_view, trackname); file_processing = FALSE; } } void remove_extension(char* s) { char* dot = 0; while (*s) { if (*s == '.') dot = s; // last dot else if (*s == '/' || *s == '\\') dot = 0; // ignore dots before path separators s++; } if (dot) *dot = '\0'; } void save_as_encoded() { GtkFileFilter * ff, * ffa; if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { char tmppath[PATH_MAX+6]; if (audio_view.selection_region == TRUE) { strcpy(tmppath, pathname); /* Create the selector */ file_selector = gtk_file_chooser_dialog_new("Encode to filename:", GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); ff = gtk_file_filter_new(); ffa = gtk_file_filter_new(); gtk_file_filter_set_name(ffa,"All files"); gtk_file_filter_add_pattern(ffa,"*"); if (encoding_type == GWC_OGG) { /* make it a .ogg extension */ //The corner case where this code might produce unexpected results is if you are working on hidden files without extensions e.g. "~/.recording1" //But since we are choosing a name in the dialog that is ok. remove_extension(tmppath) ; strcat(tmppath, ".ogg"); gtk_file_filter_set_name(ff,"OGG files"); gtk_file_filter_add_pattern(ff,"*.ogg"); gtk_file_filter_add_pattern(ff,"*.OGG"); } else { /* make it a .mp3 extension */ //The corner case where this code might produce unexpected results is if you are working on hidden files without extensions e.g. "~/.recording1" //But since we are choosing a name in the dialog that is ok. remove_extension(tmppath) ; strcat(tmppath, ".mp3"); gtk_file_filter_set_name(ff,"MP3 files"); gtk_file_filter_add_pattern(ff,"*.mp3"); gtk_file_filter_add_pattern(ff,"*.MP3"); } gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_selector),ff); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_selector),ffa); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (file_selector), basename(tmppath)); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_selector), dirname(tmppath)); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER(file_selector), TRUE); /* Display the dialog */ if (gtk_dialog_run (GTK_DIALOG (file_selector)) == GTK_RESPONSE_ACCEPT) { strncpy(save_selection_filename, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (file_selector)), PATH_MAX); gtk_widget_destroy (GTK_WIDGET (file_selector)); store_selected_filename_as_encoded(wave_filename); } else { gtk_widget_destroy (GTK_WIDGET (file_selector)); } } else { info("Please highlight a region to save first"); } } } void save_as_ogg_selection(GtkWidget * widget, gpointer data) { encoding_type = GWC_OGG; save_as_encoded(); } void save_as_mp3_selection(GtkWidget * widget, gpointer data) { encoding_type = GWC_MP3; save_as_encoded(); } void save_as_mp3_simple_selection(GtkWidget * widget, gpointer data) { encoding_type = GWC_MP3_SIMPLE; save_as_encoded(); } void save_as_selection(GtkWidget * widget, gpointer data) { /* Alister - disable, because we aren't necessarily saving a wav file GtkFileFilter * ff, * ffa;*/ if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { if (audio_view.selection_region == TRUE) { /* Create the selector */ file_selector = gtk_file_chooser_dialog_new("Filename to save selection to:", GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (file_selector), pathname); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER(file_selector), TRUE); /* Alister - disable, because we aren't necessarily saving a wav file ff = gtk_file_filter_new(); gtk_file_filter_set_name(ff,"Wave files"); gtk_file_filter_add_pattern(ff,"*.wav"); gtk_file_filter_add_pattern(ff,"*.WAV"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_selector),ff); ffa = gtk_file_filter_new(); gtk_file_filter_set_name(ffa,"All files"); gtk_file_filter_add_pattern(ffa,"*"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_selector),ffa);*/ if (gtk_dialog_run (GTK_DIALOG (file_selector)) == GTK_RESPONSE_ACCEPT) { strncpy(save_selection_filename, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (file_selector)), PATH_MAX); gtk_widget_destroy (GTK_WIDGET (file_selector)); store_selection_filename(wave_filename); } else { gtk_widget_destroy (GTK_WIDGET (file_selector)); } } else { info("Please highlight a region to save first"); } } } static struct { gchar *stockid; const char **icon_xpm; } stock_icons[] = { {"filter_icon", filter_xpm }, {"pinknoise_icon", pinknoise_xpm }, {"amplify_icon", amplify_xpm }, {"declick_icon", declick_xpm }, {"gwc_icon", gtk_wave_cleaner_xpm }, {"declick_w_icon", declick_w_xpm }, {"declick_m_icon", declick_m_xpm }, {"decrackle_icon", decrackle_xpm }, {"estimate_icon", estimate_xpm }, {"noise_sample_icon", noise_sample_xpm }, {"remove_noise_icon", remove_noise_xpm }, {"silence_icon", silence_xpm }, {"zoom_sel_icon", zoom_sel_xpm }, {"zoom_in_icon", zoom_in_xpm }, {"zoom_out_icon", zoom_out_xpm }, {"view_all_icon", view_all_xpm }, {"select_all_icon", select_all_xpm }, {"spectral_icon", spectral_xpm }, {"start_icon", start_xpm }, {"stop_icon", stop_xpm } }; static gint n_stock_icons = G_N_ELEMENTS (stock_icons); static void register_stock_icons (void) { GtkIconFactory *icon_factory; GtkIconSet *icon_set; GdkPixbuf *pixbuf; gint i; icon_factory = gtk_icon_factory_new (); for (i = 0; i < n_stock_icons; i++) { pixbuf = gdk_pixbuf_new_from_xpm_data(stock_icons[i].icon_xpm); icon_set = gtk_icon_set_new_from_pixbuf (pixbuf); g_object_unref(pixbuf); gtk_icon_factory_add (icon_factory, stock_icons[i].stockid, icon_set); gtk_icon_set_unref (icon_set); } gtk_icon_factory_add_default(icon_factory); g_object_unref(icon_factory); } /* Normal items */ static const GtkActionEntry entries[] = { { "FileMenu", NULL, "_File" }, { "Open", GTK_STOCK_OPEN, "_Open...", "O", "Open a file", G_CALLBACK(open_file_selection) }, { "SaveSelection", NULL, "Save selection as...", "S", "Save the current selection to a new wavfile", G_CALLBACK(save_as_selection) }, { "SaveSimple", NULL, "Simple encode selection as MP3...", NULL, "Save the current selection to an MP3 encoded file, simple options", G_CALLBACK(save_as_mp3_simple_selection) }, { "SaveMP3", NULL, "Encode selection as MP3...", NULL, "Save the current selection to an MP3 encoded file", G_CALLBACK(save_as_mp3_selection) }, { "SaveOGG", NULL, "Encode selection as OGG/Vorbis...", NULL, "Save the current selection to an OGG Vorbis encoded file", G_CALLBACK(save_as_ogg_selection) }, { "SaveCDRDAO", NULL, "Create cdrdao TOC file...", NULL, "Create a cdrdao table of contents file for marked songs", G_CALLBACK(save_cdrdao_tocs) }, { "SaveMarkers", NULL, "Create cdrdao TOC file, using marker pairs...", NULL, "Create a cdrtao table of contents file for marked songs, using pairs of song markers", G_CALLBACK(save_cdrdao_tocp) }, { "SaveSplit", NULL, "Split audio on song markers", NULL, "Create individual track files", G_CALLBACK(split_audio_on_markers) }, { "Quit", GTK_STOCK_QUIT, "Q_uit", "Q", "Close GWC", G_CALLBACK(delete_event) }, { "EditMenu", NULL, "_Edit" }, { "Undo", GTK_STOCK_UNDO, "Undo", "Z", "Undo the last edit", G_CALLBACK(undo_callback) }, { "Filter", "filter_icon", "Apply DSP Frequency Filters", NULL, "lowpass, highpass, notch or bandpass biquad filtering", G_CALLBACK(filter_cb) }, { "PinkNoise", "pinknoise_icon", "Generate Pink Noise", NULL, "Replace current view or selection with pink noise", G_CALLBACK(pinknoise_cb) }, { "Amplify", "amplify_icon", "Amplify", NULL, "Amplify or attenuate the current view or selection", G_CALLBACK(amplify) }, { "DeclickStrong", "declick_icon", "Declick Strong", NULL, "Automatically find and repair pops/clicks in current view or selection", G_CALLBACK(declick) }, { "DeclickWeak", "declick_w_icon", "Declick Weak", NULL, "Automatically find and repair weaker pops/clicks in current view or selection", G_CALLBACK(declick_weak) }, { "DeclickManual", "declick_m_icon", "Declick Manual", NULL, "Apply LSAR signal estimation to repair a single selected/viewed click", G_CALLBACK(manual_declick) }, { "Decrackle", "decrackle_icon", "Decrackle", "C", "Remove crackle from old, deteriorated vinyl", G_CALLBACK(decrackle) }, { "Estimate", "estimate_icon", "Estimate", NULL, "Estimate signal (> 300 samples) in current view or selection", G_CALLBACK(estimate) }, { "Sample", "noise_sample_icon", "Sample", NULL, "Use current view or selection as a noise sample", G_CALLBACK(noise_sample) }, { "Denoise", "remove_noise_icon", "Denoise", NULL, "Remove noise from current view or selection", G_CALLBACK(remove_noise) }, { "Silence", "silence_icon", "Silence", NULL, "Insert silence with size of current selection", G_CALLBACK(silence_callback) }, { "Reverb", NULL, "Reverb", NULL, "Apply reverberation to the current view or selection", G_CALLBACK(reverb) }, { "Cut", GTK_STOCK_CUT, "Cut", NULL, "Cut current selection to internal clipboard", G_CALLBACK(cut_callback) }, { "Copy", GTK_STOCK_COPY, "Copy", NULL, "Copy current selection to internal clipboard", G_CALLBACK(copy_callback) }, { "Paste", GTK_STOCK_PASTE, "Paste", NULL, "Insert internal clipboard before current selection", G_CALLBACK(paste_callback) }, { "Delete", GTK_STOCK_DELETE, "Delete", NULL, "Delete current selection from audio data", G_CALLBACK(delete_callback) }, { "ViewMenu", NULL, "_View" }, { "ZoomSelect", "zoom_sel_icon", "Zoom to selection", NULL, "Zoom in on selected portion", G_CALLBACK(zoom_select) }, { "ZoomIn", "zoom_in_icon", "Zoom in", NULL, "Zoom in", G_CALLBACK(zoom_in) }, { "ZoomOut", "zoom_out_icon", "Zoom out", NULL, "Zoom out", G_CALLBACK(zoom_out) }, { "ViewAll", "view_all_icon", "View all", NULL, "View entire audio file", G_CALLBACK(view_all) }, { "SelectAll", "select_all_icon", "Select current view", "A", "Select everything visible in the window", G_CALLBACK(select_all) }, { "SelectNone", NULL, "Select none", "Escape", "Clear the selection", G_CALLBACK(select_none) }, { "Spectral", "spectral_icon", "Spectral view", NULL, "Toggle between waveform view and spectrogram", G_CALLBACK(display_sonogram) }, { "MarkersMenu", NULL, "_Markers" }, { "ToggleBegin", NULL, "Toggle beginning marker", "B", "Add or remove an edit marker at the beginning of the highlighted selection (or current view)", G_CALLBACK(toggle_start_marker) }, { "ToggleEnd", NULL, "Toggle ending marker", "E", "Add or remove an edit marker at the end of the highlighted selection (or current view)", G_CALLBACK(toggle_end_marker) }, { "ClearMarkers", NULL, "Clear markers", NULL, "Remove all edit markers in the highlighted selection (or current view)", G_CALLBACK(clear_markers_in_view) }, { "ExpandSelection", NULL, "Expand selection to nearest markers", "M", "Select the region between two edit markers", G_CALLBACK(select_markers) }, { "MarkSongs", NULL, "Detect songs", NULL, "Mark all songs in the file using silence detection", G_CALLBACK(mark_songs) }, { "MoveMarker", NULL, "Move song marker", NULL, "Move the closest song marker to the beginning of the current (or most recent) selection", G_CALLBACK(move_song_marker) }, { "AddMarker", NULL, "Add song marker", NULL, "Add a song marker at the beginning of the current (or most recent) selection", G_CALLBACK(add_song_marker) }, { "AddMarkerPair", NULL, "Add song marker pair", NULL, "Add a song marker at the beginning AND end of the current (or most recent) selection", G_CALLBACK(add_song_marker_pair) }, { "DeleteMarker", NULL, "Clear song markers", NULL, "Remove all song markers in the current (or most recent) selection", G_CALLBACK(delete_song_marker) }, { "NextMarker", NULL, "Next song marker", "N", "Select 15 seconds of audio around the next song marker", G_CALLBACK(select_song_marker) }, { "SettingsMenu", NULL, "_Settings" }, { "DeclickPrefs", NULL, "Declick", NULL, "Set declick sensitivity, iteration", G_CALLBACK(declick_set_preferences) }, { "DecracklePrefs", NULL, "Decrackle", NULL, "Set decrackle sensitivity", G_CALLBACK(decrackle_set_preferences) }, { "DenoisePrefs", NULL, "Denoise", NULL, "Set denoise parameters", G_CALLBACK(denoise_set_preferences) }, { "MP3SimplePrefs", NULL, "MP3 simple encoding", NULL, "Set MP3 Simple Encoding parameters", G_CALLBACK(set_mp3_simple_encoding_preferences) }, { "MP3Prefs", NULL, "MP3 encoding", NULL, "Set MP3 Encoding parameters", G_CALLBACK(set_mp3_encoding_preferences) }, { "OggPrefs", NULL, "Ogg encoding", NULL, "Set Ogg Encoding parameters", G_CALLBACK(set_ogg_encoding_preferences) }, { "MiscPrefs", NULL, "Miscellaneous", NULL, "Miscellaneous parameters", G_CALLBACK(set_misc_preferences) }, { "HelpMenu", NULL, "_Help" }, { "Help", GTK_STOCK_HELP, "User Guide", NULL, "Instructions for using GWC", G_CALLBACK(help) }, { "About", GTK_STOCK_ABOUT, "About", NULL, "About GWC", G_CALLBACK(about) }, { "PlayAudio", "start_icon", "Start audio playback", NULL, "Playback the selected or current view of audio", G_CALLBACK(start_gwc_playback) }, { "StopAudio", "stop_icon", "Stop", NULL, "Stop audio playback", G_CALLBACK(stop_all_playback_functions) } }; static const char *ui_description = "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; /* Toggle items */ // todo /*static const GtkToggleActionEntry toggle_entries[] = { { "FullScreen", NULL, "_Full Screen", "F11", "Switch between full screen and windowed mode", full_screen_action_callback, FALSE } };*/ GtkStatusbar *status_bar; GtkWidget *progress_bar; guint status_message, push_message; void update_progress_bar(gfloat percentage, gfloat min_delta, gboolean init_flag) { #ifdef BY_DATA_LENGTH static gfloat last_percentage_displayed = -1.0; if (percentage - last_percentage_displayed > min_delta || init_flag == TRUE) { doing_progressbar_update = TRUE; gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress_bar), percentage); gnome_flush(); doing_progressbar_update = FALSE; last_percentage_displayed = percentage; } #else static struct timeval last_displayed = { 0, 0 }; static struct timezone tz = { 0, 0 }; static struct timeval this; long delta_ms; gettimeofday(&this, &tz); delta_ms = (this.tv_sec - last_displayed.tv_sec) * 1000 + (this.tv_usec - last_displayed. tv_usec) / 1000; if (delta_ms > 1000 * min_delta || init_flag == TRUE) { doing_progressbar_update = TRUE; gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(progress_bar), percentage); gnome_flush(); doing_progressbar_update = FALSE; last_displayed = this; } #endif } // Show "tooltips" in the statusbar for menu items static void on_menu_item_selected(GtkItem *item) { guint id = gtk_statusbar_get_context_id(status_bar, "MenuItemHints"); gchar *hint; g_object_get(gtk_widget_get_action(GTK_WIDGET(item)), "tooltip", &hint, NULL); if (hint) { gtk_statusbar_push(status_bar, id, hint); g_free(hint); } } static void on_menu_item_deselected(GtkItem *item) { guint id = gtk_statusbar_get_context_id(status_bar, "MenuItemHints"); gchar *hint; // gtk_action_get_label requires at least GTK 2.16! I guess we could use gtk_action_get_name for lower versions if we care... g_object_get(gtk_widget_get_action(GTK_WIDGET(item)), "tooltip", &hint, NULL); if (hint) { gtk_statusbar_pop(status_bar, id); g_free(hint); } } // Also show "labels" in statusbar for toolbar items static gboolean on_tool_item_enter_event (GtkAction *action) { guint id = gtk_statusbar_get_context_id(status_bar, "ToolItemHints"); // gtk_action_get_label requires at least GTK 2.16! I guess we could use gtk_action_get_name for lower versions if we care... const gchar *tooltip = gtk_action_get_label (action); gtk_statusbar_push (status_bar, id, tooltip); // don't prevent the normal gtk handlers from being invoked for the event. return FALSE; } static gboolean on_tool_item_leave_event (GtkWidget *tool_item) { guint id = gtk_statusbar_get_context_id(status_bar, "ToolItemHints"); gtk_statusbar_pop (status_bar, id); // don't prevent the normal gtk handlers from being invoked for the event. return FALSE; } // Set up callback functions to do the menu hints in the statusbar // Code adapted from mousepad static void ui_manager_connect_proxy ( GtkUIManager *ui_manager, GtkAction *action, GtkWidget *proxy ) { g_return_if_fail (GTK_IS_ACTION (action)); g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager)); if (GTK_IS_MENU_ITEM (proxy)) { /* menu item's don't work with gdk window events */ g_signal_connect (proxy, "select", G_CALLBACK (on_menu_item_selected), NULL); g_signal_connect (proxy, "deselect", G_CALLBACK (on_menu_item_deselected), NULL); } else if (GTK_IS_TOOL_ITEM (proxy)) { GtkWidget *child; /* tool items will have GtkButton or other widgets in them, we want the child */ child = gtk_bin_get_child (GTK_BIN (proxy)); /* get events for mouse enter/leave and focus in/out */ gtk_widget_add_events (child, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); /* connect to signals for the events */ g_signal_connect_swapped (child, "enter-notify-event", G_CALLBACK (on_tool_item_enter_event), action); g_signal_connect (child, "leave-notify-event", G_CALLBACK (on_tool_item_leave_event), NULL); } } // Do we actually need this? static void ui_manager_disconnect_proxy ( GtkUIManager *ui_manager, GtkAction *action, GtkWidget *proxy ) { g_return_if_fail (GTK_IS_ACTION (action)); g_return_if_fail (GTK_IS_MENU_ITEM (proxy) || GTK_IS_TOOL_ITEM (proxy)); g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager)); if (GTK_IS_MENU_ITEM (proxy)) { /* disconnect from the select/deselect signals */ g_signal_handlers_disconnect_by_func (proxy, on_menu_item_selected, NULL); g_signal_handlers_disconnect_by_func (proxy, on_menu_item_deselected, NULL); } else if (GTK_IS_TOOL_ITEM (proxy)) { GtkWidget *child; /* tool items will have GtkButton or other widgets in them, we want the child */ child = gtk_bin_get_child (GTK_BIN (proxy)); /* disconnect from the gdk window event signals */ g_signal_handlers_disconnect_by_func (child, on_tool_item_enter_event, NULL); g_signal_handlers_disconnect_by_func (child, on_tool_item_leave_event, NULL); } } void set_status_text(gchar * msg) { gtk_statusbar_pop (status_bar, status_message); gtk_statusbar_push (status_bar, status_message, msg); } void push_status_text(gchar * msg) { gtk_statusbar_push (status_bar, push_message, msg); // push_values = g_list_prepend (push_values, GUINT_TO_POINTER (value)); } void pop_status_text(void) { gtk_statusbar_pop (status_bar, push_message); // push_values = g_list_remove_link (push_values, push_values); } /* Create a new backing pixmap of the appropriate size */ static gint audio_area_configure_event(GtkWidget * widget, GdkEventConfigure * event) { if (audio_pixmap) gdk_pixmap_unref(audio_pixmap); audio_pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); if (highlight_pixmap) gdk_pixmap_unref(highlight_pixmap); highlight_pixmap = gdk_pixmap_new(widget->window, widget->allocation.width, widget->allocation.height, -1); if (cursor_pixmap) gdk_pixmap_unref(cursor_pixmap); cursor_pixmap = gdk_pixmap_new(widget->window, 1, widget->allocation.height, -1); gdk_draw_rectangle(audio_pixmap, widget->style->white_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); gdk_draw_rectangle(highlight_pixmap, widget->style->white_gc, TRUE, 0, 0, widget->allocation.width, widget->allocation.height); audio_view.canvas_width = widget->allocation.width; audio_view.canvas_height = widget->allocation.height; main_redraw(FALSE, TRUE); return TRUE; } int audio_area_button_event(GtkWidget *c, GdkEventButton *event, gpointer data) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { return _audio_area_button_event(c, event); } return FALSE; } int audio_area_motion_event(GtkWidget *c, GdkEventMotion *event) { if ((file_processing == FALSE) && (file_is_open == TRUE) && (audio_playback == FALSE) && (cursor_playback == FALSE)) { return _audio_area_motion_event(c, event); } return FALSE; } /* Redraw the screen from the backing pixmap */ gint audio_expose_event(GtkWidget * widget, GdkEventExpose * event) { gdk_draw_pixmap(widget->window, widget->style->fg_gc[GTK_WIDGET_STATE(widget)], highlight_pixmap, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height); /* g_print("expose x:%d y:%d width:%d height:%d\n", */ /* event->area.x, event->area.y, */ /* event->area.width, event->area.height); */ return FALSE; } void gwc_window_set_title(char *title) { char buf[255]; snprintf(buf, sizeof(buf), "%s - Gtk Wave Cleaner", title); gtk_window_set_title(GTK_WINDOW(main_window), buf); } GtkWidget *mk_label_and_pack(GtkBox * box, char *text) { GtkWidget *w = gtk_label_new(text); gtk_box_pack_start(box, w, TRUE, TRUE, 0); return w; } void gwc_signal_handler(int sig) { if (close_wavefile(&audio_view)) { save_preferences(); undo_purge(); } switch (sig) { case SIGSEGV: display_message("Segmentation Fault", "Fatal"); break; case SIGBUS: display_message("Bus Error", "Fatal"); break; } exit(1); } long time_to_sample(char *time, struct sound_prefs *p) { int nf; int h, m; double s; long position = 0; nf = sscanf(time, "%d:%d:%lf", &h, &m, &s); if (nf == 3) { position = (h * 3600 + m * 60) * p->rate + s * p->rate; } else if (nf == 2) { nf = sscanf(time, "%d:%lf", &m, &s); position = (m * 60) * p->rate + s * p->rate; } else if (nf == 1) { nf = sscanf(time, "%lf", &s); position = s * p->rate; } return position; } long batch_atol(char *time) { if( strcmp(time,"end") == 0 ) return prefs.n_samples; else return atol(time); } long batch_time_to_sample(char *time, struct sound_prefs *p) { if( strcmp(time,"end") == 0 ) return p->n_samples; else return time_to_sample(time, p); } /* bj Sep 2003 re-write batch declick, add batch denoise, batch truncate */ void batch(int argc, char **argv) { #define BYTIME 0 #define BYSAMPLE 1 int type = BYTIME ; batch_mode = 1 ; if( argv[3] == NULL ) usage(argv[0]); if(!strcmp(argv[2], "batchs")) { type = BYSAMPLE ; } if(!strcasecmp(argv[3], "declick")) { if(argc < 7) { fprintf(stderr, "Usage: gwc \n") ; } else { declick_detector_type = FFT_DETECT; double sens = atof(argv[4]) ; if(type == BYTIME) { audio_view.selected_first_sample = time_to_sample(argv[5],&prefs) ; audio_view.selected_last_sample = batch_time_to_sample(argv[6],&prefs) ; } else { audio_view.selected_first_sample = atol(argv[5]) ; audio_view.selected_last_sample = batch_atol(argv[6]) ; } audio_view.selection_region = TRUE; audio_view.channel_selection_mask = 0x03; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(detect_only_widget), FALSE); click_data.max_clicks = MAX_CLICKS ; click_data.n_clicks = 0 ; g_print("Declick from %ld to %ld\n", audio_view.selected_first_sample, audio_view.selected_last_sample) ; declick_with_sensitivity(sens); } } else if(!strcasecmp(argv[3], "declick-hpf")) { if(argc < 7) { fprintf(stderr, "Usage: gwc \n") ; } else { declick_detector_type = HPF_DETECT; double sens = atof(argv[4]) ; if(type == BYTIME) { audio_view.selected_first_sample = time_to_sample(argv[5],&prefs) ; audio_view.selected_last_sample = batch_time_to_sample(argv[6],&prefs) ; } else { audio_view.selected_first_sample = atol(argv[5]) ; audio_view.selected_last_sample = batch_atol(argv[6]) ; } audio_view.selection_region = TRUE; audio_view.channel_selection_mask = 0x03; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(detect_only_widget), FALSE); click_data.max_clicks = MAX_CLICKS ; click_data.n_clicks = 0 ; g_print("Declick from %ld to %ld\n", audio_view.selected_first_sample, audio_view.selected_last_sample) ; declick_with_sensitivity(sens); } } else if(!strcasecmp(argv[3], "amplify")) { if(argc < 7) { fprintf(stderr, "Usage: gwc \n") ; } else { double amount = atof(argv[4]) ; long first, last ; if(type == BYTIME) { audio_view.selected_first_sample = time_to_sample(argv[5],&prefs) ; audio_view.selected_last_sample = batch_time_to_sample(argv[6],&prefs) ; } else { audio_view.selected_first_sample = atol(argv[5]) ; audio_view.selected_last_sample = batch_atol(argv[6]) ; } first = audio_view.selected_first_sample ; last = audio_view.selected_last_sample ; audio_view.selection_region = TRUE; audio_view.channel_selection_mask = 0x03; g_print("amplify from %ld to %ld\n", audio_view.selected_first_sample, audio_view.selected_last_sample) ; simple_amplify_audio(&prefs, first, last, audio_view.channel_selection_mask, amount) ; } } else if(!strcasecmp(argv[3], "denoise")) { if(argc < 8) { fprintf(stderr, "Usage: gwc \n") ; } else { if(type == BYTIME) { denoise_data.noise_start = time_to_sample(argv[4],&prefs); denoise_data.noise_end = batch_time_to_sample(argv[5],&prefs); audio_view.selected_first_sample = time_to_sample(argv[6],&prefs); audio_view.selected_last_sample = batch_time_to_sample(argv[7],&prefs); } else { denoise_data.noise_start = atol(argv[4]); denoise_data.noise_end = batch_atol(argv[5]); audio_view.selected_first_sample = atol(argv[6]); audio_view.selected_last_sample = batch_atol(argv[7]); } audio_view.selection_region = TRUE; audio_view.channel_selection_mask = 0x03; get_region_of_interest(&denoise_data.denoise_start, &denoise_data.denoise_end, &audio_view) ; denoise_data.ready = TRUE ; load_denoise_preferences() ; print_denoise("batch remove_noise",&denoise_prefs) ; if(denoise_prefs.FFT_SIZE > (denoise_data.noise_end-denoise_data.noise_start+1)) { fprintf(stderr, "FFT_SIZE must be <= # samples in noise sample!") ; return; } g_print("Denoise from %ld to %ld using noise sample from %ld to %ld\n", denoise_data.denoise_start, denoise_data.denoise_end, denoise_data.noise_start, denoise_data.noise_end) ; push_status_text("Denoising selection") ; denoise(&prefs, &denoise_prefs, denoise_data.noise_start, denoise_data.noise_end, denoise_data.denoise_start, denoise_data.denoise_end, audio_view.channel_selection_mask) ; resample_audio_data(&prefs, denoise_data.denoise_start, denoise_data.denoise_end) ; save_sample_block_data(&prefs) ; pop_status_text() ; } } else if(!strcasecmp(argv[3], "normalize") || !strcasecmp(argv[3], "normalise")) { g_print("Normalize audiofile\n"); batch_normalize(&prefs,0,prefs.n_samples-1,prefs.n_channels > 1 ? 0x03 : 0x01); } else if(!strcasecmp(argv[3], "dsp")) { if(argc < 6) { fprintf(stderr, "Usage: gwc \n") ; } else { long first, last ; if(type == BYTIME) { audio_view.selected_first_sample = time_to_sample(argv[4],&prefs) ; audio_view.selected_last_sample = batch_time_to_sample(argv[5],&prefs) ; } else { audio_view.selected_first_sample = atol(argv[4]) ; audio_view.selected_last_sample = batch_atol(argv[5]) ; } first = audio_view.selected_first_sample ; last = audio_view.selected_last_sample ; audio_view.selection_region = TRUE; audio_view.channel_selection_mask = 0x03; get_region_of_interest(&first, &last, &audio_view); filter_audio(&prefs, first, last, audio_view.channel_selection_mask); save_sample_block_data(&prefs); } } else if(!strcasecmp(argv[3], "reverb")) { if(argc < 6) { fprintf(stderr, "Usage: gwc \n") ; } else { long first, last ; if(type == BYTIME) { audio_view.selected_first_sample = time_to_sample(argv[4],&prefs) ; audio_view.selected_last_sample = batch_time_to_sample(argv[5],&prefs) ; } else { audio_view.selected_first_sample = atol(argv[4]) ; audio_view.selected_last_sample = batch_atol(argv[5]) ; } first = audio_view.selected_first_sample ; last = audio_view.selected_last_sample ; audio_view.selection_region = TRUE; audio_view.channel_selection_mask = 0x03; get_region_of_interest(&first, &last, &audio_view); reverb_audio(&prefs, first, last, audio_view.channel_selection_mask); save_sample_block_data(&prefs); } } else if(!strcasecmp(argv[3], "truncate")) { if(argc < 6) { fprintf(stderr, "Usage: gwc \n") ; } else { long first, last ; #ifdef TRUNCATE_OLD if(type == BYTIME) { audio_view.truncate_head = time_to_sample(argv[4],&prefs) ; audio_view.truncate_tail = batch_time_to_sample(argv[5],&prefs) ; } else { audio_view.truncate_head = atol(argv[4]) ; audio_view.truncate_tail = batch_atol(argv[5]) ; } g_print("Truncating. Keeping samples %ld to %ld\n", audio_view.truncate_head, audio_view.truncate_tail) ; truncate_wavfile(&audio_view); audio_view.truncate_head = 0; audio_view.truncate_tail = audio_view.n_samples; #else if(type == BYTIME) { audio_view.selected_first_sample = time_to_sample(argv[4],&prefs) ; audio_view.selected_last_sample = batch_time_to_sample(argv[5],&prefs) ; } else { audio_view.selected_first_sample = atol(argv[4]) ; audio_view.selected_last_sample = batch_atol(argv[5]) ; } audio_view.selection_region = TRUE; first = audio_view.selected_first_sample ; last = audio_view.selected_last_sample ; g_print("Truncating. Keeping samples %ld to %ld\n", first, last); if(first == 0) { long total_samples = last-first+1 ; sndfile_truncate(total_samples) ; } else { truncate_wavfile(&audio_view, 0); /* 0 == don't save undo data */ } #endif } } else usage(argv[0]); cleanup_and_close(&audio_view, &prefs); batch_mode = 0 ; return ; } int main(int argc, char *argv[]) { GtkWidget *main_vbox, *menubar, *toolbar, *led_vbox, *track_times_vbox, *times_vbox, *bottom_hbox, *detect_only_box, *leave_click_marks_box; GtkActionGroup *action_group; GtkUIManager *ui_manager; GError *error; int i; /* *************************************************************** */ /* Lindsay Harris addition for SMP operations */ /* * On SMP systems, the stack size does not grow, for reasons beyond * my understanding. So, set an increase in size now. For my * SuSE 8.2 system, the initial size is 2MB, whereas the "denoise" * operation requires about 3.5MB, so I picked an arbitrary 4MB * stack size. This might not be sufficient for some other operations. */ { struct rlimit rl; #define GWC_STACK_LIM (6 * 1024 *1024) if( getrlimit( RLIMIT_STACK, &rl ) == -1 ) { perror( "getrlimit for RLIMIT_STACK:" ); exit( 1 ); } printf("Current stack limit: %d bytes\n", (int)rl.rlim_cur) ; /* Only change the size if it's too small. */ if( rl.rlim_cur < GWC_STACK_LIM ) { rl.rlim_cur = GWC_STACK_LIM ; if( setrlimit( RLIMIT_STACK, &rl ) == -1 ) { perror( "setrlimit for RLIMIT_STACK:" ); exit( 1 ); } printf("New stack limit: %d bytes\n", (int)rl.rlim_cur) ; } } #define PREFIX "." #define SYSCONFDIR "." load_preferences(); /* load all encoding preferences on start */ // Why load these but not the filter and reverb preferences? load_ogg_encoding_preferences(); load_mp3_encoding_preferences(); load_mp3_simple_encoding_preferences(); /* load ~/.config/gtk-wave-cleaner/gtkrc if it exists */ gtk_rc_add_default_file ( g_build_filename (g_get_user_config_dir (), APPNAME, "gtkrc", NULL) ); /* This is called in all GTK applications. Arguments are parsed * from the command line and are returned to the application. */ gtk_init(&argc, &argv); g_set_application_name("Gtk Wave Cleaner"); register_stock_icons (); main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); if (gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), APPNAME) == FALSE) { GdkPixbuf *icon = gtk_widget_render_icon(main_window, "gwc_icon", 6, NULL); gtk_icon_theme_add_builtin_icon(APPNAME, 48, icon); } gtk_window_set_default_icon_name(APPNAME); //gtk_window_set_default_icon_from_file(pixmapdir "/gwc-logo.png", NULL); gtk_window_set_title(GTK_WINDOW(main_window), "Gtk Wave Cleaner: Dehiss, declick audio files"); // Remember the window geometry from the last time GWC was used, but check for sanity // Looks like we don't actually need to get this information - see comments below. GdkDisplay *display = gdk_display_get_default(); GdkScreen *screen = gdk_display_get_default_screen(display); gint screen_width = gdk_screen_get_width(screen); gint screen_height = gdk_screen_get_height(screen); // Looks like we could just set it to window_width and window_height - perhaps because I have a helpful window manager? gtk_window_set_default_size(GTK_WINDOW(main_window), MIN( window_width, screen_width), MIN(window_height, screen_height) ); // Looks like we could just set it to window_x and window_y - perhaps because I have a helpful window manager? gtk_window_move(GTK_WINDOW(main_window), MIN( window_x, screen_width - 20), MIN( window_y, screen_height - 20 ) ); if(window_maximised == TRUE) { gtk_window_maximize(GTK_WINDOW(main_window)); } /* When the window is given the "delete_event" signal (this is given * by the window manager, usually by the "close" option, or on the * titlebar), we ask it to call the delete_event () function * as defined above. The data passed to the callback * function is NULL and is ignored in the callback function. */ gtk_signal_connect(GTK_OBJECT(main_window), "delete_event", GTK_SIGNAL_FUNC(delete_event), NULL); g_signal_connect(GTK_OBJECT(main_window), "key_press_event", GTK_SIGNAL_FUNC(key_press_cb), NULL); /* Sets the border width of the window. */ gtk_container_set_border_width(GTK_CONTAINER(main_window), 1); /* Creates a new button with the label "Stop Recording". */ /* When the button receives the "clicked" signal, it will call the * function stop() passing it NULL as its argument. The stop() * function is defined above. */ /* g_signal_connect (GTK_OBJECT (stop_button), "clicked", */ /* GTK_SIGNAL_FUNC (stop), NULL); */ main_vbox = gtk_vbox_new(FALSE, 0); track_times_vbox = gtk_vbox_new(FALSE, 1); times_vbox = gtk_vbox_new(FALSE, 1); led_vbox = gtk_vbox_new(FALSE, 1); bottom_hbox = gtk_hbox_new(FALSE, 1); gtk_container_add (GTK_CONTAINER (main_window), main_vbox); ui_manager = gtk_ui_manager_new (); // Set up the signals to do the menu hints in the statusbar g_signal_connect (ui_manager, "connect-proxy", G_CALLBACK (ui_manager_connect_proxy), NULL); // Do we actually need this? g_signal_connect (ui_manager, "disconnect-proxy", G_CALLBACK (ui_manager_disconnect_proxy), NULL); action_group = gtk_action_group_new ("MenuActions"); gtk_action_group_add_actions (action_group, entries, G_N_ELEMENTS (entries), main_window); /*gtk_action_group_add_toggle_actions (action_group, toggle_entries, G_N_ELEMENTS (toggle_entries), main_window); gtk_action_group_add_radio_actions (action_group, radio_entries, G_N_ELEMENTS (radio_entries), 0, radio_action_callback, main_window);*/ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); gtk_accel_map_load( g_build_filename (g_get_user_config_dir (), APPNAME, ACCELERATORS_FILE, NULL) ); gtk_window_add_accel_group (GTK_WINDOW (main_window), gtk_ui_manager_get_accel_group (ui_manager)); error = NULL; if (!gtk_ui_manager_add_ui_from_string (ui_manager, ui_description, -1, &error)) { g_message ("building menus failed: %s", error->message); g_error_free (error); exit (EXIT_FAILURE); } menubar = gtk_ui_manager_get_widget (ui_manager, "/MainMenu"); gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0); toolbar = gtk_ui_manager_get_widget (ui_manager, "/MainToolbar"); gtk_toolbar_set_style (GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS); gtk_box_pack_start (GTK_BOX (main_vbox), toolbar, FALSE, FALSE, 0); /*// Need to do stuff like this if we want handles so we can rearrange things. // https://developer.gnome.org/gtk2/stable/GtkHandleBox.html // GtkHandleBox is deprecated since GTK+ 3.4 // Maybe GDL is an alternative? // https://developer.gnome.org/gdl/ edit_toolbar = gtk_ui_manager_get_widget (ui_manager, "/EditToolbar"); gtk_toolbar_set_style (edit_toolbar, GTK_TOOLBAR_ICONS); GtkWidget* handlebox1; handlebox1 = gtk_handle_box_new (); gtk_container_add (handlebox1, edit_toolbar); gtk_box_pack_start (GTK_BOX (main_vbox), handlebox1, FALSE, FALSE, 0); transport_toolbar = gtk_ui_manager_get_widget (ui_manager, "/TransportToolbar"); gtk_toolbar_set_style (transport_toolbar, GTK_TOOLBAR_ICONS); GtkWidget* handlebox2; handlebox2 = gtk_handle_box_new (); gtk_container_add (handlebox2, transport_toolbar); gtk_box_pack_start (GTK_BOX (main_vbox), handlebox2, FALSE, FALSE, 0); */ { /* setup status bar at bottom of window including a progress display) */ progress_bar = gtk_progress_bar_new (); status_bar = GTK_STATUSBAR(gtk_statusbar_new ()); status_message = gtk_statusbar_get_context_id ( status_bar, "status-message"); push_message = gtk_statusbar_get_context_id ( status_bar, "push-message"); /* create a new canvas */ audio_drawing_area = gtk_drawing_area_new(); gtk_signal_connect(GTK_OBJECT(audio_drawing_area), "expose_event", (GCallback) audio_expose_event, NULL); gtk_signal_connect(GTK_OBJECT(audio_drawing_area), "configure_event", (GCallback) audio_area_configure_event, NULL); gtk_signal_connect(GTK_OBJECT(audio_drawing_area), "button_press_event", (GCallback) audio_area_button_event, NULL); gtk_signal_connect(GTK_OBJECT(audio_drawing_area), "motion_notify_event", (GCallback) audio_area_motion_event, NULL); /* gtk_signal_connect (GTK_OBJECT(audio_drawing_area),"event", */ /* (GCallback) audio_area_event, NULL); */ gtk_widget_set_events(audio_drawing_area, GDK_EXPOSURE_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); audio_view.canvas_width = 600; audio_view.canvas_height = 400; gtk_box_pack_start(GTK_BOX(main_vbox), audio_drawing_area, TRUE, TRUE, 0); } scroll_pos = gtk_adjustment_new(1.0, 0.0, 100.0, 5.0, 5.0, 0.0); hscrollbar = gtk_hscrollbar_new(GTK_ADJUSTMENT(scroll_pos)); gtk_signal_connect(GTK_OBJECT(GTK_ADJUSTMENT(scroll_pos)), "changed", (GCallback) scroll_bar_changed, NULL); gtk_signal_connect(GTK_OBJECT(GTK_ADJUSTMENT(scroll_pos)), "value_changed", (GCallback) scroll_bar_changed, NULL); gtk_box_pack_start(GTK_BOX(main_vbox), hscrollbar, FALSE, TRUE, 0); l_file_time = mk_label_and_pack(GTK_BOX(track_times_vbox), "Track 0:00:000"); l_file_samples = mk_label_and_pack(GTK_BOX(track_times_vbox), "Track samples: 0"); l_first_time = mk_label_and_pack(GTK_BOX(times_vbox), "First 0:00:000"); l_last_time = mk_label_and_pack(GTK_BOX(times_vbox), "Last 0:00:000"); l_selected_time = mk_label_and_pack(GTK_BOX(times_vbox), "Selected 0:00:000"); l_samples = mk_label_and_pack(GTK_BOX(times_vbox), "Samples: 0"); for (i = 0; i < 2; i++) { dial[i] = led_bar_new(20, 0); gtk_box_pack_start(GTK_BOX(led_vbox), dial[i], TRUE, TRUE, 0); } led_bar_light_percent(dial[0], (0.0)); led_bar_light_percent(dial[1], (0.0)); gtk_box_pack_start(GTK_BOX(bottom_hbox), led_vbox, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(bottom_hbox), track_times_vbox, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(bottom_hbox), times_vbox, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(main_vbox), bottom_hbox, FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(status_bar), GTK_WIDGET(progress_bar), FALSE, TRUE, 0); gtk_box_pack_start(GTK_BOX(main_vbox), GTK_WIDGET(status_bar), FALSE, TRUE, 0); { detect_only_box = gtk_hbox_new(FALSE, 10); detect_only_widget = gtk_check_button_new_with_label ("Detect, do not repair clicks"); GTK_WIDGET_UNSET_FLAGS(detect_only_widget, GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(detect_only_box), detect_only_widget, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(led_vbox), detect_only_box, FALSE, FALSE, 0); leave_click_marks_box = gtk_hbox_new(FALSE, 11); leave_click_marks_widget = gtk_check_button_new_with_label ("Leave click marks after repairing"); GTK_WIDGET_UNSET_FLAGS(leave_click_marks_widget, GTK_CAN_FOCUS); gtk_box_pack_start(GTK_BOX(leave_click_marks_box), leave_click_marks_widget, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(led_vbox), leave_click_marks_box, FALSE, FALSE, 0); } gchar *newdir = g_build_filename (g_get_user_cache_dir (), "gwcXXXXXX", NULL) ; gchar *_CLIPBOARD_FILE = "gwc_intclip.dat" ; // note that g_mkdtemp rather than mkdtemp is required for portability e.g. to Solaris (not OpenSolaris) // unfortunately it pushes the minimum GLIB required to 2.30, so is it really more or less portable...? if (!g_mkdtemp (newdir)) { // this is expected if $XDG_CACHE_HOME is not set // therefore don't use g_warning, which will error if G_DEBUG environment variable is set to "fatal-warnings" warning ("Could not create directory for temporary files in $XDG_CACHE_HOME\nFalling back to current working directory."); // note: assume if we can't create a folder for our undo files we probably can't create a clipboard file there either. // It would be best to move this to the file open routine and if we can't use $XDG_CACHE_HOME to save the temp files // in the same location as the file we are working on. https://github.com/AlisterH/gwc/issues/9 //*newdir = g_build_filename (g_path_get_dirname ( TODO filename), "gwcXXXXXX", NULL) ; // should be able to avoid this nonsense - need to study pointers again I think newdir = g_build_filename (g_get_current_dir(), "gwcXXXXXX", NULL) ; // might not need to test this - is it actually possible for it to fail but us still be able to write to the audio file we are working on itself? if (!g_mkdtemp (newdir)) { warning ("Could not create directory for temporary files in current working directory.\n" "If you run more than one instance of GWC in this directory their undo files will conflict.\n"); warning ("Is the current working directory read-only?\n" "If so we won't be able to save undo files!\n" "Strongly recommend you exit and create ~/.cache/, or restart in a writable directory!"); } else tmpdir = newdir; } else { tmpdir = newdir; // don't put the clipboard in tmpdir - this way we can share it between multiple instances of gwc // note there are problems if we try to paste incompatible audio e.g. mono vs stereo // and should we have some sort of locking so multiple instances don't try to write it at the same time? // also note there is a problem with undo (perhaps only with mono?) _CLIPBOARD_FILE = g_build_filename (g_get_user_cache_dir (), "gwc_intclip.dat", NULL) ; } CLIPBOARD_FILE = _CLIPBOARD_FILE ; //printf("CLIPBOARD_FILE: %s\n", CLIPBOARD_FILE) ; /* and the window */ gtk_widget_show_all(main_window); #ifdef MAC_OS_X // Note that we only tested if we are building on OSX, and are assuming we are building with the GDK QUARZ backend. // We should really check that, as we could be building with the X11 backend. // Supposedly just doing this first line makes closing from the dock work, etc. (#1) GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL); //We actually need this otherwise it just quits without asking about saving! g_signal_connect (theApp, "NSApplicationBlockTermination", G_CALLBACK (delete_event), NULL ); g_signal_connect (theApp, "NSApplicationOpenFile", G_CALLBACK(app_open_file_cb), NULL); // integrate the menus into the osx menu bar // N.B. osx adds a "special characters" entry to the edit menu, which is bizarre // but I guess useful for inserting symbols into the mp3 and ogg export metadata dialogs gtk_widget_hide (menubar); gtkosx_application_set_menu_bar(theApp, GTK_MENU_SHELL(menubar)); GtkWidget *about_item, *preferences_menu, *close_item, *help_menu; // move the about item to the main (program name) menu about_item = gtk_ui_manager_get_widget(ui_manager, "/MainMenu/HelpMenu/About"); gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET (about_item), 0); // move the preferences item to the main menu preferences_menu = gtk_ui_manager_get_widget(ui_manager, "/MainMenu/SettingsMenu"); gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET (preferences_menu), 1); // hide the close item in the file menu close_item = gtk_ui_manager_get_widget(ui_manager, "/MainMenu/FileMenu/Quit"); gtk_widget_hide (close_item); // only need to do this so that the "window" menu is positioned correctly! help_menu = gtk_ui_manager_get_widget(ui_manager, "/MainMenu/HelpMenu"); gtkosx_application_set_help_menu (theApp, GTK_MENU_ITEM (help_menu)); // this adds a "window" menu, which doesn't really seem useful in my test environment // except that it enables the ⌘M keyboard shortcut to minimise! gtkosx_application_set_window_menu (theApp, NULL); // N.B. Setting the icon like this is unnecessary when running as a .app application bundle // And we need to do that to get osx to use the icon when the application isn't running. // We need the test so we don't override it when we are in an application bundle! if (gtkosx_application_get_bundle_id() == NULL) { GdkPixbuf *icon = gtk_widget_render_icon(main_window, "gwc_icon", 6, NULL); gtkosx_application_set_dock_icon_pixbuf(theApp, icon); } // Possible todo: // implement native file dialogs using nativefiledialog library or tinyfiledialogs or something #endif /* and the idle function */ /* gtk_idle_add(idle_func, NULL); */ /* start_monitor("/dev/dsp") ; */ /* config_audio_input(44100, 16, 1) ; */ /* config_audio_input(prefs.rate, prefs.bits, prefs.stereo) ; */ /* All GTK applications must have a gtk_main(). Control ends here * and waits for an event to occur (like a key press or * mouse event). */ push_status_text("Ready"); signal(SIGSEGV, gwc_signal_handler); signal(SIGBUS, gwc_signal_handler); { char buf[100]; int v1, v2, v3, i; sf_command(NULL, SFC_GET_LIB_VERSION, buf, sizeof(buf)); /* printf("sfversion: %s \n", buf) ; */ for (i = 0; i < strlen(buf); i++) { if (buf[i] == '-') { i++; break; } } sscanf(&buf[i], "%d.%d.%d", &v1, &v2, &v3); printf("libsndfile Version: %s %d %d %d\n", buf, v1, v2, v3) ; if (v1 < 1 || v2 < 0 || v3 < 0) { warning("libsndfile 1.0.0 or greater is required"); exit(1); } } if (argc > 1) { strcpy(wave_filename, argv[1]); open_wave_filename(); if (argc > 2) { if ((!strcasecmp(argv[2], "batch")) || (!strcasecmp(argv[2], "batchs"))) { batch(argc, argv); return EXIT_SUCCESS; } } } #ifdef MAC_OS_X // Re #1 above - we actually need this, otherwise nothing happens at all. // It has has to be down here after e.g. open_wave_filename, otherwise running `gwc somefile` crashes on osx. // But the rest of the gtkosx_application stuff needs to be before that otherwise it freezes when // clicking the icon after running `gwc somefile` gtkosx_application_ready (theApp); #endif gtk_main(); return (0); } gtk-wave-cleaner-0.22-04/gwc.h0000777000175000017500000003272513455316730017162 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.21 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* gwc.h */ #define _ISOC9X_SOURCE 1 #define _ISOC99_SOURCE 1 #define __USE_ISOC9X 1 #define __USE_ISOC99 1 #include #include #ifdef HAVE_FFTW3 #include #if (FFTWPREC == 1) typedef float fftw_real ; # define FFTW(func) fftwf_ ## func #else /* FFTWPREC == 1 */ typedef double fftw_real ; # define FFTW(func) fftw_ ## func #endif /* FFTWPREC == 0 */ #else #ifdef HAVE_FFTW #include #else #include #endif #endif #include #ifndef PATH_MAX #define PATH_MAX 1024 #endif #define GWC_VERSION_MAJOR 0 #define GWC_VERSION_MINOR 22 #define VERSION "0.22-04" #define GWC_POINT_HANDLE 0x01 #define SBW 128 /* Sample Block Width, the number of audio samples summarized in one block */ #define PROGRESS_UPDATE_INTERVAL 0.5 /* update status bar every 1/2 second on long edit operations */ #define MAX_AUDIO_BUFSIZE 32768 /* defs for declicking results */ #define SINGULAR_MATRIX 0 #define REPAIR_SUCCESS 1 #define REPAIR_CLIPPED 2 #define REPAIR_FAILURE 3 #define DETECT_ONLY 4 #define REPAIR_OOB 5 /* defs for declick detection method */ #define FFT_DETECT 0 #define HPF_DETECT 1 /* defs for denoise */ #define DENOISE_MAX_FFT 32768 #define DENOISE_WINDOW_BLACKMAN 0 #define DENOISE_WINDOW_BLACKMAN_HYBRID 1 #define DENOISE_WINDOW_HANNING_OVERLAP_ADD 2 #ifdef DENOISE_TRY_ONE_SAMPLE #define DENOISE_WINDOW_ONE_SAMPLE 3 #define DENOISE_WINDOW_WELTY 4 #else #define DENOISE_WINDOW_WELTY 3 #endif #define DENOISE_WEINER 0 #define DENOISE_POWER_SPECTRAL_SUBTRACT 1 #define DENOISE_EM 2 #define DENOISE_LORBER 3 #define DENOISE_WOLFE_GODSILL 4 #define DENOISE_EXPERIMENTAL 5 //#define DENOISE_MAGNITUDE_SPECTRAL_SUBTRACT -1 /* defs for markers */ #define MAX_MARKERS 200 #define MARKER_RESET_VALUE -1000000000 /* (large negative long) markers to be completely off the screen when they are reset */ /* defs for encoding */ #define GWC_OGG 1 #define GWC_MP3 2 #define GWC_MP3_SIMPLE 3 #define SETTINGS_FILE "gwc.conf" #define ACCELERATORS_FILE "accels" struct sound_prefs { int playback_bits ; int bits ; int rate ; int stereo ; long n_samples ; int n_channels ; int wavefile_fd ; double max_value ; long max_allowed ; int sample_buffer_exists ; long data_length ; size_t mmap_size ; void *mmap_file ; size_t data_offset ; unsigned long data_size ; void *data ; int successful_open ; } ; struct denoise_prefs { int noise_suppression_method ; int window_type ; int smoothness ; int FFT_SIZE ; int n_noise_samples ; double amount ; double dn_gamma ; double randomness ; double min_sample_freq ; double max_sample_freq ; int freq_filter ; int estimate_power_floor ; int rate ; } ; struct view { int canvas_width ; int canvas_height ; long first_sample ; long last_sample ; long selected_first_sample ; long selected_last_sample ; long cursor_position ; long prev_cursor_position ; int selection_region ; int channel_selection_mask ; long n_samples ; #ifdef TRUNCATE_OLD long truncate_head, truncate_tail ; #endif /* TRUNCATE_OLD */ } ; struct sample_block { int n_samples ; double rms[2] ; double max_value[2] ; } ; struct sample_display_block { int n_samples ; double rms[2] ; double max_value[2] ; } ; #define MAX_CLICKS 1000 struct click_data { int n_clicks ; int max_clicks ; char channel[MAX_CLICKS] ; long start[MAX_CLICKS], end[MAX_CLICKS] ; } ; typedef struct { long noise_start ; long noise_end ; long denoise_start ; long denoise_end ; int ready ; } DENOISE_DATA ; gchar *tmpdir; gchar *CLIPBOARD_FILE ; void print_denoise(char *header, struct denoise_prefs *pDnprefs) ; GtkWidget *main_window; GtkWidget *add_number_entry_with_label(char *entry_text, char *label_text, GtkWidget *table, int row) ; GtkWidget *add_number_entry_with_label_int(int value, char *label_text, GtkWidget *table, int row) ; GtkWidget *add_number_entry_with_label_double(double value, char *label_text, GtkWidget *table, int row) ; void add_song_marker(void) ; void add_song_marker_pair(void) ; void amplify_audio(struct sound_prefs *p, long first, long last, int channel_mask) ; int amplify_dialog(struct sound_prefs current, struct view *) ; int audio_area_button_event(GtkWidget *c, GdkEventButton *event, gpointer data) ; int audio_area_motion_event(GtkWidget *c, GdkEventMotion *event) ; int _audio_area_button_event(GtkWidget *c, GdkEventButton *event) ; int _audio_area_motion_event(GtkWidget *c, GdkEventMotion *event) ; double blackman(int k, int N) ; double blackman_hybrid(int k, int n_flat, int N) ; int close_undo(void) ; int close_wavefile(struct view *v) ; void config_audio_device(int speed, int bits, int stereo) ; void d_print(char *, ...) ; int declick_a_click(struct sound_prefs *p, long first_sample, long last_sample, int channel_mask) ; void declick_set_preferences(GtkWidget * widget, gpointer data) ; void decrackle_set_preferences(GtkWidget * widget, gpointer data) ; void denoise_set_preferences(GtkWidget * widget, gpointer data) ; int denoise(struct sound_prefs *pPrefs, struct denoise_prefs *pDnprefs, long noise_start, long noise_end, long first_sample, long last_sample, int channel_mask) ; int denoise_dialog(struct sound_prefs current, struct view *) ; int dethunk(struct sound_prefs *pPrefs, long first_sample, long last_sample, int channel_mask) ; void audio_normalize(int flag); void set_scroll_bar(long n, long first, long last); void display_times(void) ; char *do_declick(struct sound_prefs *p, long noise_start, long noise_end, int channel_selection_mask, double sensitivity, int repair, struct click_data *, int iterate_flag, int leave_click_marks) ; char *do_declick_fft(struct sound_prefs *p, long noise_start, long noise_end, int channel_selection_mask, double sensitivity, int repair, struct click_data *, int iterate_flag, int leave_click_marks) ; char *do_declick_hpf(struct sound_prefs *p, long noise_start, long noise_end, int channel_selection_mask, double sensitivity, int repair, struct click_data *, int iterate_flag, int leave_click_marks) ; int do_decrackle(struct sound_prefs *p, long noise_start, long noise_end, int channel_selection_mask, double level, gint nmax, gint width) ; void estimate_region(fftw_real data[], int firstbad, int lastbad, int siglen) ; #ifndef TRUNCATE_OLD void resize_sample_buffer(struct sound_prefs *p); #endif void fill_sample_buffer(struct sound_prefs *p) ; void filter_audio(struct sound_prefs *p, long first, long last, int channel_mask) ; int filter_dialog(struct sound_prefs current, struct view *) ; void flush_wavefile_data(void) ; void get_region_of_interest(long *first, long *last, struct view *v) ; int get_sample_buffer(struct sample_block **result) ; void get_sample_stats(struct sample_display_block *result, long first, long last, double blocks_per_pixel) ; char *get_undo_msg(void) ; int get_undo_levels(void) ; int gwc_dialog_run(GtkDialog *); void gwc_window_set_title(char *title) ; double high_pass_filter(fftw_real x[], int N) ; void info(char *msg) ; int is_valid_audio_file(char *filename) ; void load_denoise_preferences(void) ; void load_mp3_encoding_preferences(void); void load_mp3_simple_encoding_preferences(void); void load_ogg_encoding_preferences(void); int load_sample_block_data(struct sound_prefs *p) ; void main_redraw(int cursor_flag, int redraw_data) ; void mark_songs(GtkWidget * widget, gpointer data) ; /* void move_delete_song_marker(int delete) ; */ void adjust_song_marker_positions(long start, long delta); void adjust_marker_positions(long start, long delta); void move_song_marker(void) ; void delete_song_marker(void) ; void select_song_marker(void) ; // do we need these two? GKeyFile* read_config(void) ; void write_config(GKeyFile *key_file) ; struct sound_prefs open_wavefile(char *filename, struct view *v) ; void pinknoise(struct sound_prefs *p, long first, long last, int channel_mask) ; int pinknoise_dialog(struct sound_prefs current, struct view *) ; int play_wavefile_data(long first, long last) ; void pop_status_text(void) ; int print_noise_sample(struct sound_prefs *pPrefs, struct denoise_prefs *pDnprefs, long noise_start, long noise_end) ; int process_audio(gfloat *pL, gfloat *pR) ; void push_status_text(gchar *msg) ; int read_fft_real_wavefile_data(fftw_real left[], fftw_real right[], long first, long last) ; int read_float_wavefile_data(float left[], float right[], long first, long last) ; int read_raw_wavefile_data(char buf[], long first, long last) ; void read_sample_block(struct sample_block *sb, struct sound_prefs *p, long block_number) ; int read_wavefile_data(long left[], long right[], long first, long last) ; void redraw(struct view *v, struct sound_prefs *p, GtkWidget *canvas, int cursor_flag, int redraw_data, int sonogram_flag) ; void rescan_sample_buffer(struct sound_prefs *p) ; void reverb_audio(struct sound_prefs *p, long first, long last, int channel_mask) ; int reverb_dialog(struct sound_prefs current, struct view *) ; int sample_to_pixel(struct view *v, long sample) ; void save_cdrdao_tocs(GtkWidget * widget, gpointer data) ; void save_cdrdao_tocp(GtkWidget * widget, gpointer data) ; void save_denoise_preferences(void) ; void save_ogg_encoding_preferences(void); void save_mp3_encoding_preferences(void); void save_mp3_simple_encoding_preferences(void); int partial_save_encoding_mp3(char *filename,char *filename_new,long first_sample,long total_samples); int save_encoding_ogg(char *filename,char *filename_new); void save_preferences(void); void save_sample_block_data(struct sound_prefs *p) ; void save_as_wavfile(char *filename_new, long first_sample, long last_sample) ; void save_selection_as_wavfile(char *filename_new, struct view *v) ; void save_selection_as_encoded(int fmt,char *oldname,char *filename_new, struct view *v, char *trackname) ; int encode(int fmt,char *origname, char *newname,long start,long length, char *trackname); int start_encode( int mode,char *newfilename,long start,long length, char *origfilename); int save_undo_data(long first_sample, long last_sample, struct sound_prefs *p, int progress_update_flag) ; #ifndef TRUNCATE_OLD int save_undo_data_remove(long first_sample, long last_sample, int progress_update_flag); int save_undo_data_insert(long first_sample, long last_sample, int progress_update_flag); #endif void seek_to_audio_position(long playback_position) ; void set_misc_preferences(GtkWidget * widget, gpointer data) ; void set_mp3_simple_encoding_preferences(GtkWidget * widget, gpointer data); void set_mp3_encoding_preferences(GtkWidget * widget, gpointer data); void set_ogg_encoding_preferences(GtkWidget * widget, gpointer data); long set_playback_cursor_position(struct view *v, long msec_per_visual_frame) ; void set_status_text(gchar *msg) ; void simple_amplify_audio(struct sound_prefs *p, long first, long last, int channel_mask, double amount) ; void sndfile_truncate(long total_samples) ; struct sound_prefs sound_pref_dialog(struct sound_prefs current) ; void stats(double x[], int n, double *pMean, double *pStderr, double *pVar, double *pCv, double *pStddev) ; void resample_audio_data(struct sound_prefs *p, long first, long last) ; int start_recording(char *input_device, char *filename) ; long start_playback(char *output_device, struct view *v, struct sound_prefs *p, double seconds_per_block, double seconds_to_preload) ; int start_monitor(char *input_device) ; void stop_playback(int force) ; void stop_recording(void) ; int start_save_undo(char *undo_msg, struct view *v) ; /* void sum_sample_block(struct sample_block *sb, double left[], double right[], long n) ; */ void sum_sample_block(struct sample_block *sb, fftw_real left[], fftw_real right[], long n) ; int undo(struct view *v, struct sound_prefs *p) ; void undo_purge(void) ; void update_progress_bar(gfloat percentage, gfloat min_delta, gboolean init_flag) ; int yesno(char *) ; int yesnocancel(char *) ; void warning(char *) ; int write_fft_real_wavefile_data(fftw_real left[], fftw_real right[], long first, long last) ; int write_float_wavefile_data(float left[], float right[], long first, long last) ; int write_raw_wavefile_data(char buf[], long first, long last) ; int write_wavefile_data(long left[], long right[], long first, long last) ; int write_wavefile_data_to_fd(long left[], long right[], long first, long last, int fd) ; /* bj 9/6/03 added */ #ifdef TRUNCATE_OLD void truncate_wavfile(struct view *v); #endif void start_timer(void); void stop_timer(char *message); void batch_normalize(struct sound_prefs *p, long first , long last, int channel_mask); gtk-wave-cleaner-0.22-04/gwcbatch0000777000175000017500000000764213124110551017720 0ustar00alisteralister00000000000000#!/usr/bin/perl # for usage instructions see below or run `perldoc gwcbatch` sub time2sec { my @tm = split(/:/,shift); my $sec = 0; while (@tm) { $sec *= 60; $sec += shift @tm; } return $sec; } # #------ # Main my ( $file ,$archive ,@keep ,$sens ,@noise ); while (@ARGV) { @keep = @noise = (); $file = shift; ($archive = $file) =~ s/\.wav$/_orig$&/; push @keep, (shift, shift); $sens = shift; push @noise, (shift,shift); #convert time to seconds @keep = map {&time2sec($_)} @keep; @noise = map {&time2sec($_)} @noise; # back up the file first. print `cp $file $archive`; # Now declick and remove noise print `gtk-wave-cleaner $file batch declick $sens $keep[0] $keep[1]`; # Add extra declicking runs if you want them #print `gtk-wave-cleaner $file batch declick $sens $keep[0] $keep[1]`; print `gtk-wave-cleaner $file batch denoise $noise[0] $noise[1] $keep[0] $keep[1]`; # truncate after cleaning in case the noise sample is from the region to truncate # for some reason, it *sometimes* hangs when truncating # both front and back, so do back first, then front print `gtk-wave-cleaner $file batch truncate 0 $keep[1]`; print `gtk-wave-cleaner $file batch truncate $keep[0] $keep[1]`; # normalize last so it isn't affected by anything we are discarding print `gtk-wave-cleaner $file batch normalize`; } 1; # Documentation follows =pod =head1 NAME gwcbatch - quick & dirty helper script for gwc's quick & dirty batch mode =head1 SYNOPSIS Usage is as follows: gwcbatch wavfile musicStart musicEnd declickSens noiseStart noiseEnd \ [wavfile2 musicStart2 ... \] [... \] [wavfileN musicStartN ...] =over =item B sound file to process (wav format) =item B portion of the wav file to keep. Time format is hh:mm:ss.xxx or just ss.xxx if desired. =item B sensitivity to use for the declick process. =item B noise sample to use for the denoise process. Time format is same as for musicStart & musicEnd =back =head1 DESCRIPTION There's no doubt about it. Ripping vinyl + cleaning the sound is a time-consuming process. gwc has some facilities for batch processing, and this perl script helps complete the automation. I typically record 2-4 album sides, inspect each file with gwc, then run this script to do the declicking & denoising while I sleep. That can take tens of minutes to several hours depending on the condition of the vinyl, length of recordings processed, and the power of your CPU. Here's the process: =over =item * record the album side. I do this via ecasound like this: ecasound -i /dev/dsp -ezf -ev -t 1800 -o sideX.wav the "-t 1800" means it'll record for 30 minutes and then stop so there's always something at the end to chop off, and usually something at the beginning too. But recording in this fashion means I don't have to babysit the process. =item * Set up your denoise preferences =item * If you like to iterate for declicking, mark that checkbox in the declick setup =item * load the wav file into gwc. Write down the times (to as many decimal places as you like) for musicStart, musicEnd, noiseStart, and noiseEnd =item * run this script as described above =back This script will do the following: =over =item * copy the file for archival purposes =item * declick using declickSens for the sensitivity =item * denoise using the noise sample specified in noiseStart- noiseEnd =item * truncate the wav file, keeping only musicStart - musicEnd =item * normalize the audio; amplify as much as possible without clipping. =back Feel free to modify this script for your own purposes. I sometimes add another declick after the first one just to catch the majority of the straglers. =head1 BUGS It'd be even better if this thing could mark songs and create a minimal but functional cdrdao toc file. That'll require a bit more coding in gwc. =head1 AUTHOR Bill Jetzer (created July 2003) =cut gtk-wave-cleaner-0.22-04/i0.c0000777000175000017500000002267413120075106016673 0ustar00alisteralister00000000000000/* i0.c * * Modified Bessel function of order zero * * * * SYNOPSIS: * * double x, y, i0(); * * y = i0( x ); * * * * DESCRIPTION: * * Returns modified Bessel function of order zero of the * argument. * * The function is defined as i0(x) = j0( ix ). * * The range is partitioned into the two intervals [0,8] and * (8, infinity). Chebyshev polynomial expansions are employed * in each interval. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC 0,30 6000 8.2e-17 1.9e-17 * IEEE 0,30 30000 5.8e-16 1.4e-16 * */ /* i0e.c * * Modified Bessel function of order zero, * exponentially scaled * * * * SYNOPSIS: * * double x, y, i0e(); * * y = i0e( x ); * * * * DESCRIPTION: * * Returns exponentially scaled modified Bessel function * of order zero of the argument. * * The function is defined as i0e(x) = exp(-|x|) j0( ix ). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE 0,30 30000 5.4e-16 1.2e-16 * See i0(). * */ /* i0.c */ /* Cephes Math Library Release 2.8: June, 2000 Copyright 1984, 1987, 2000 by Stephen L. Moshier Some software in this archive may be from the book _Methods and Programs for Mathematical Functions_ (Prentice-Hall, 1989) or from the Cephes Mathematical Library, a commercial product. In either event, it is copyrighted by the author. What you see here may be used freely but it comes with no support or guarantee. The two known misprints in the book are repaired here in the source listings for the gamma function and the incomplete beta integral. Stephen L. Moshier moshier@world.std.com */ #include "mconf.h" /* Chebyshev coefficients for exp(-x) I0(x) * in the interval [0,8]. * * lim(x->0){ exp(-x) I0(x) } = 1. */ #ifdef UNK static double A[] = { -4.41534164647933937950E-18, 3.33079451882223809783E-17, -2.43127984654795469359E-16, 1.71539128555513303061E-15, -1.16853328779934516808E-14, 7.67618549860493561688E-14, -4.85644678311192946090E-13, 2.95505266312963983461E-12, -1.72682629144155570723E-11, 9.67580903537323691224E-11, -5.18979560163526290666E-10, 2.65982372468238665035E-9, -1.30002500998624804212E-8, 6.04699502254191894932E-8, -2.67079385394061173391E-7, 1.11738753912010371815E-6, -4.41673835845875056359E-6, 1.64484480707288970893E-5, -5.75419501008210370398E-5, 1.88502885095841655729E-4, -5.76375574538582365885E-4, 1.63947561694133579842E-3, -4.32430999505057594430E-3, 1.05464603945949983183E-2, -2.37374148058994688156E-2, 4.93052842396707084878E-2, -9.49010970480476444210E-2, 1.71620901522208775349E-1, -3.04682672343198398683E-1, 6.76795274409476084995E-1 }; #endif #ifdef DEC static unsigned short A[] = { 0121642,0162671,0004646,0103567, 0022431,0115424,0135755,0026104, 0123214,0023533,0110365,0156635, 0023767,0033304,0117662,0172716, 0124522,0100426,0012277,0157531, 0025254,0155062,0054461,0030465, 0126010,0131143,0013560,0153604, 0026517,0170577,0006336,0114437, 0127227,0162253,0152243,0052734, 0027724,0142766,0061641,0160200, 0130416,0123760,0116564,0125262, 0031066,0144035,0021246,0054641, 0131537,0053664,0060131,0102530, 0032201,0155664,0165153,0020652, 0132617,0061434,0074423,0176145, 0033225,0174444,0136147,0122542, 0133624,0031576,0056453,0020470, 0034211,0175305,0172321,0041314, 0134561,0054462,0147040,0165315, 0035105,0124333,0120203,0162532, 0135427,0013750,0174257,0055221, 0035726,0161654,0050220,0100162, 0136215,0131361,0000325,0041110, 0036454,0145417,0117357,0017352, 0136702,0072367,0104415,0133574, 0037111,0172126,0072505,0014544, 0137302,0055601,0120550,0033523, 0037457,0136543,0136544,0043002, 0137633,0177536,0001276,0066150, 0040055,0041164,0100655,0010521 }; #endif #ifdef IBMPC static unsigned short A[] = { 0xd0ef,0x2134,0x5cb7,0xbc54, 0xa589,0x977d,0x3362,0x3c83, 0xbbb4,0x721e,0x84eb,0xbcb1, 0x5eba,0x93f6,0xe6d8,0x3cde, 0xfbeb,0xc297,0x5022,0xbd0a, 0x2627,0x4b26,0x9b46,0x3d35, 0x1af0,0x62ee,0x164c,0xbd61, 0xd324,0xe19b,0xfe2f,0x3d89, 0x6abc,0x7a94,0xfc95,0xbdb2, 0x3c10,0xcc74,0x98be,0x3dda, 0x9556,0x13ae,0xd4fe,0xbe01, 0xcb34,0xa454,0xd903,0x3e26, 0x30ab,0x8c0b,0xeaf6,0xbe4b, 0x6435,0x9d4d,0x3b76,0x3e70, 0x7f8d,0x8f22,0xec63,0xbe91, 0xf4ac,0x978c,0xbf24,0x3eb2, 0x6427,0xcba5,0x866f,0xbed2, 0x2859,0xbe9a,0x3f58,0x3ef1, 0x1d5a,0x59c4,0x2b26,0xbf0e, 0x7cab,0x7410,0xb51b,0x3f28, 0xeb52,0x1f15,0xe2fd,0xbf42, 0x100e,0x8a12,0xdc75,0x3f5a, 0xa849,0x201a,0xb65e,0xbf71, 0xe3dd,0xf3dd,0x9961,0x3f85, 0xb6f0,0xf121,0x4e9e,0xbf98, 0xa32d,0xcea8,0x3e8a,0x3fa9, 0x06ea,0x342d,0x4b70,0xbfb8, 0x88c0,0x77ac,0xf7ac,0x3fc5, 0xcd8d,0xc057,0x7feb,0xbfd3, 0xa22a,0x9035,0xa84e,0x3fe5, }; #endif #ifdef MIEEE static unsigned short A[] = { 0xbc54,0x5cb7,0x2134,0xd0ef, 0x3c83,0x3362,0x977d,0xa589, 0xbcb1,0x84eb,0x721e,0xbbb4, 0x3cde,0xe6d8,0x93f6,0x5eba, 0xbd0a,0x5022,0xc297,0xfbeb, 0x3d35,0x9b46,0x4b26,0x2627, 0xbd61,0x164c,0x62ee,0x1af0, 0x3d89,0xfe2f,0xe19b,0xd324, 0xbdb2,0xfc95,0x7a94,0x6abc, 0x3dda,0x98be,0xcc74,0x3c10, 0xbe01,0xd4fe,0x13ae,0x9556, 0x3e26,0xd903,0xa454,0xcb34, 0xbe4b,0xeaf6,0x8c0b,0x30ab, 0x3e70,0x3b76,0x9d4d,0x6435, 0xbe91,0xec63,0x8f22,0x7f8d, 0x3eb2,0xbf24,0x978c,0xf4ac, 0xbed2,0x866f,0xcba5,0x6427, 0x3ef1,0x3f58,0xbe9a,0x2859, 0xbf0e,0x2b26,0x59c4,0x1d5a, 0x3f28,0xb51b,0x7410,0x7cab, 0xbf42,0xe2fd,0x1f15,0xeb52, 0x3f5a,0xdc75,0x8a12,0x100e, 0xbf71,0xb65e,0x201a,0xa849, 0x3f85,0x9961,0xf3dd,0xe3dd, 0xbf98,0x4e9e,0xf121,0xb6f0, 0x3fa9,0x3e8a,0xcea8,0xa32d, 0xbfb8,0x4b70,0x342d,0x06ea, 0x3fc5,0xf7ac,0x77ac,0x88c0, 0xbfd3,0x7feb,0xc057,0xcd8d, 0x3fe5,0xa84e,0x9035,0xa22a }; #endif /* Chebyshev coefficients for exp(-x) sqrt(x) I0(x) * in the inverted interval [8,infinity]. * * lim(x->inf){ exp(-x) sqrt(x) I0(x) } = 1/sqrt(2pi). */ #ifdef UNK static double B[] = { -7.23318048787475395456E-18, -4.83050448594418207126E-18, 4.46562142029675999901E-17, 3.46122286769746109310E-17, -2.82762398051658348494E-16, -3.42548561967721913462E-16, 1.77256013305652638360E-15, 3.81168066935262242075E-15, -9.55484669882830764870E-15, -4.15056934728722208663E-14, 1.54008621752140982691E-14, 3.85277838274214270114E-13, 7.18012445138366623367E-13, -1.79417853150680611778E-12, -1.32158118404477131188E-11, -3.14991652796324136454E-11, 1.18891471078464383424E-11, 4.94060238822496958910E-10, 3.39623202570838634515E-9, 2.26666899049817806459E-8, 2.04891858946906374183E-7, 2.89137052083475648297E-6, 6.88975834691682398426E-5, 3.36911647825569408990E-3, 8.04490411014108831608E-1 }; #endif #ifdef DEC static unsigned short B[] = { 0122005,0066672,0123124,0054311, 0121662,0033323,0030214,0104602, 0022515,0170300,0113314,0020413, 0022437,0117350,0035402,0007146, 0123243,0000135,0057220,0177435, 0123305,0073476,0144106,0170702, 0023777,0071755,0017527,0154373, 0024211,0052214,0102247,0033270, 0124454,0017763,0171453,0012322, 0125072,0166316,0075505,0154616, 0024612,0133770,0065376,0025045, 0025730,0162143,0056036,0001632, 0026112,0015077,0150464,0063542, 0126374,0101030,0014274,0065457, 0127150,0077271,0125763,0157617, 0127412,0104350,0040713,0120445, 0027121,0023765,0057500,0001165, 0030407,0147146,0003643,0075644, 0031151,0061445,0044422,0156065, 0031702,0132224,0003266,0125551, 0032534,0000076,0147153,0005555, 0033502,0004536,0004016,0026055, 0034620,0076433,0142314,0171215, 0036134,0146145,0013454,0101104, 0040115,0171425,0062500,0047133 }; #endif #ifdef IBMPC static unsigned short B[] = { 0x8b19,0x54ca,0xadb7,0xbc60, 0x9130,0x6611,0x46da,0xbc56, 0x8421,0x12d9,0xbe18,0x3c89, 0x41cd,0x0760,0xf3dd,0x3c83, 0x1fe4,0xabd2,0x600b,0xbcb4, 0xde38,0xd908,0xaee7,0xbcb8, 0xfb1f,0xa3ea,0xee7d,0x3cdf, 0xe6d7,0x9094,0x2a91,0x3cf1, 0x629a,0x7e65,0x83fe,0xbd05, 0xbb32,0xcf68,0x5d99,0xbd27, 0xc545,0x0d5f,0x56ff,0x3d11, 0xc073,0x6b83,0x1c8c,0x3d5b, 0x8cec,0xfa26,0x4347,0x3d69, 0x8d66,0x0317,0x9043,0xbd7f, 0x7bf2,0x357e,0x0fd7,0xbdad, 0x7425,0x0839,0x511d,0xbdc1, 0x004f,0xabe8,0x24fe,0x3daa, 0x6f75,0xc0f4,0xf9cc,0x3e00, 0x5b87,0xa922,0x2c64,0x3e2d, 0xd56d,0x80d6,0x5692,0x3e58, 0x616e,0xd9cd,0x8007,0x3e8b, 0xc586,0xc101,0x412b,0x3ec8, 0x9e52,0x7899,0x0fa3,0x3f12, 0x9049,0xa2e5,0x998c,0x3f6b, 0x09cb,0xaca8,0xbe62,0x3fe9 }; #endif #ifdef MIEEE static unsigned short B[] = { 0xbc60,0xadb7,0x54ca,0x8b19, 0xbc56,0x46da,0x6611,0x9130, 0x3c89,0xbe18,0x12d9,0x8421, 0x3c83,0xf3dd,0x0760,0x41cd, 0xbcb4,0x600b,0xabd2,0x1fe4, 0xbcb8,0xaee7,0xd908,0xde38, 0x3cdf,0xee7d,0xa3ea,0xfb1f, 0x3cf1,0x2a91,0x9094,0xe6d7, 0xbd05,0x83fe,0x7e65,0x629a, 0xbd27,0x5d99,0xcf68,0xbb32, 0x3d11,0x56ff,0x0d5f,0xc545, 0x3d5b,0x1c8c,0x6b83,0xc073, 0x3d69,0x4347,0xfa26,0x8cec, 0xbd7f,0x9043,0x0317,0x8d66, 0xbdad,0x0fd7,0x357e,0x7bf2, 0xbdc1,0x511d,0x0839,0x7425, 0x3daa,0x24fe,0xabe8,0x004f, 0x3e00,0xf9cc,0xc0f4,0x6f75, 0x3e2d,0x2c64,0xa922,0x5b87, 0x3e58,0x5692,0x80d6,0xd56d, 0x3e8b,0x8007,0xd9cd,0x616e, 0x3ec8,0x412b,0xc101,0xc586, 0x3f12,0x0fa3,0x7899,0x9e52, 0x3f6b,0x998c,0xa2e5,0x9049, 0x3fe9,0xbe62,0xaca8,0x09cb }; #endif #ifdef ANSIPROT extern double chbevl ( double, void *, int ); extern double exp ( double ); extern double sqrt ( double ); #else double chbevl(), exp(), sqrt(); #endif double i0(x) double x; { double y; if( x < 0 ) x = -x; if( x <= 8.0 ) { y = (x/2.0) - 2.0; return( exp(x) * chbevl( y, A, 30 ) ); } return( exp(x) * chbevl( 32.0/x - 2.0, B, 25 ) / sqrt(x) ); } double i0e( x ) double x; { double y; if( x < 0 ) x = -x; if( x <= 8.0 ) { y = (x/2.0) - 2.0; return( chbevl( y, A, 30 ) ); } return( chbevl( 32.0/x - 2.0, B, 25 ) / sqrt(x) ); } gtk-wave-cleaner-0.22-04/i1.c0000777000175000017500000002276213120075106016672 0ustar00alisteralister00000000000000/* i1.c * * Modified Bessel function of order one * * * * SYNOPSIS: * * double x, y, i1(); * * y = i1( x ); * * * * DESCRIPTION: * * Returns modified Bessel function of order one of the * argument. * * The function is defined as i1(x) = -i j1( ix ). * * The range is partitioned into the two intervals [0,8] and * (8, infinity). Chebyshev polynomial expansions are employed * in each interval. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * DEC 0, 30 3400 1.2e-16 2.3e-17 * IEEE 0, 30 30000 1.9e-15 2.1e-16 * * */ /* i1e.c * * Modified Bessel function of order one, * exponentially scaled * * * * SYNOPSIS: * * double x, y, i1e(); * * y = i1e( x ); * * * * DESCRIPTION: * * Returns exponentially scaled modified Bessel function * of order one of the argument. * * The function is defined as i1(x) = -i exp(-|x|) j1( ix ). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE 0, 30 30000 2.0e-15 2.0e-16 * See i1(). * */ /* i1.c 2 */ /* Cephes Math Library Release 2.8: June, 2000 Copyright 1985, 1987, 2000 by Stephen L. Moshier Some software in this archive may be from the book _Methods and Programs for Mathematical Functions_ (Prentice-Hall, 1989) or from the Cephes Mathematical Library, a commercial product. In either event, it is copyrighted by the author. What you see here may be used freely but it comes with no support or guarantee. The two known misprints in the book are repaired here in the source listings for the gamma function and the incomplete beta integral. Stephen L. Moshier moshier@world.std.com */ #include "mconf.h" /* Chebyshev coefficients for exp(-x) I1(x) / x * in the interval [0,8]. * * lim(x->0){ exp(-x) I1(x) / x } = 1/2. */ #ifdef UNK static double A[] = { 2.77791411276104639959E-18, -2.11142121435816608115E-17, 1.55363195773620046921E-16, -1.10559694773538630805E-15, 7.60068429473540693410E-15, -5.04218550472791168711E-14, 3.22379336594557470981E-13, -1.98397439776494371520E-12, 1.17361862988909016308E-11, -6.66348972350202774223E-11, 3.62559028155211703701E-10, -1.88724975172282928790E-9, 9.38153738649577178388E-9, -4.44505912879632808065E-8, 2.00329475355213526229E-7, -8.56872026469545474066E-7, 3.47025130813767847674E-6, -1.32731636560394358279E-5, 4.78156510755005422638E-5, -1.61760815825896745588E-4, 5.12285956168575772895E-4, -1.51357245063125314899E-3, 4.15642294431288815669E-3, -1.05640848946261981558E-2, 2.47264490306265168283E-2, -5.29459812080949914269E-2, 1.02643658689847095384E-1, -1.76416518357834055153E-1, 2.52587186443633654823E-1 }; #endif #ifdef DEC static unsigned short A[] = { 0021514,0174520,0060742,0000241, 0122302,0137206,0016120,0025663, 0023063,0017437,0026235,0176536, 0123637,0052523,0170150,0125632, 0024410,0165770,0030251,0044134, 0125143,0012160,0162170,0054727, 0025665,0075702,0035716,0145247, 0126413,0116032,0176670,0015462, 0027116,0073425,0110351,0105242, 0127622,0104034,0137530,0037364, 0030307,0050645,0120776,0175535, 0131001,0130331,0043523,0037455, 0031441,0026160,0010712,0100174, 0132076,0164761,0022706,0017500, 0032527,0015045,0115076,0104076, 0133146,0001714,0015434,0144520, 0033550,0161166,0124215,0077050, 0134136,0127715,0143365,0157170, 0034510,0106652,0013070,0064130, 0135051,0117126,0117264,0123761, 0035406,0045355,0133066,0175751, 0135706,0061420,0054746,0122440, 0036210,0031232,0047235,0006640, 0136455,0012373,0144235,0011523, 0036712,0107437,0036731,0015111, 0137130,0156742,0115744,0172743, 0037322,0033326,0124667,0124740, 0137464,0123210,0021510,0144556, 0037601,0051433,0111123,0177721 }; #endif #ifdef IBMPC static unsigned short A[] = { 0x4014,0x0c3c,0x9f2a,0x3c49, 0x0576,0xc38a,0x57d0,0xbc78, 0xbfac,0xe593,0x63e3,0x3ca6, 0x1573,0x7e0d,0xeaaa,0xbcd3, 0x290c,0x0615,0x1d7f,0x3d01, 0x0b3b,0x1c8f,0x628e,0xbd2c, 0xd955,0x4779,0xaf78,0x3d56, 0x0366,0x5fb7,0x7383,0xbd81, 0x3154,0xb21d,0xcee2,0x3da9, 0x07de,0x97eb,0x5103,0xbdd2, 0xdf6c,0xb43f,0xea34,0x3df8, 0x67e6,0x28ea,0x361b,0xbe20, 0x5010,0x0239,0x258e,0x3e44, 0xc3e8,0x24b8,0xdd3e,0xbe67, 0xd108,0xb347,0xe344,0x3e8a, 0x992a,0x8363,0xc079,0xbeac, 0xafc5,0xd511,0x1c4e,0x3ecd, 0xbbcf,0xb8de,0xd5f9,0xbeeb, 0x0d0b,0x42c7,0x11b5,0x3f09, 0x94fe,0xd3d6,0x33ca,0xbf25, 0xdf7d,0xb6c6,0xc95d,0x3f40, 0xd4a4,0x0b3c,0xcc62,0xbf58, 0xa1b4,0x49d3,0x0653,0x3f71, 0xa26a,0x7913,0xa29f,0xbf85, 0x2349,0xe7bb,0x51e3,0x3f99, 0x9ebc,0x537c,0x1bbc,0xbfab, 0xf53c,0xd536,0x46da,0x3fba, 0x192e,0x0469,0x94d1,0xbfc6, 0x7ffa,0x724a,0x2a63,0x3fd0 }; #endif #ifdef MIEEE static unsigned short A[] = { 0x3c49,0x9f2a,0x0c3c,0x4014, 0xbc78,0x57d0,0xc38a,0x0576, 0x3ca6,0x63e3,0xe593,0xbfac, 0xbcd3,0xeaaa,0x7e0d,0x1573, 0x3d01,0x1d7f,0x0615,0x290c, 0xbd2c,0x628e,0x1c8f,0x0b3b, 0x3d56,0xaf78,0x4779,0xd955, 0xbd81,0x7383,0x5fb7,0x0366, 0x3da9,0xcee2,0xb21d,0x3154, 0xbdd2,0x5103,0x97eb,0x07de, 0x3df8,0xea34,0xb43f,0xdf6c, 0xbe20,0x361b,0x28ea,0x67e6, 0x3e44,0x258e,0x0239,0x5010, 0xbe67,0xdd3e,0x24b8,0xc3e8, 0x3e8a,0xe344,0xb347,0xd108, 0xbeac,0xc079,0x8363,0x992a, 0x3ecd,0x1c4e,0xd511,0xafc5, 0xbeeb,0xd5f9,0xb8de,0xbbcf, 0x3f09,0x11b5,0x42c7,0x0d0b, 0xbf25,0x33ca,0xd3d6,0x94fe, 0x3f40,0xc95d,0xb6c6,0xdf7d, 0xbf58,0xcc62,0x0b3c,0xd4a4, 0x3f71,0x0653,0x49d3,0xa1b4, 0xbf85,0xa29f,0x7913,0xa26a, 0x3f99,0x51e3,0xe7bb,0x2349, 0xbfab,0x1bbc,0x537c,0x9ebc, 0x3fba,0x46da,0xd536,0xf53c, 0xbfc6,0x94d1,0x0469,0x192e, 0x3fd0,0x2a63,0x724a,0x7ffa }; #endif /* i1.c */ /* Chebyshev coefficients for exp(-x) sqrt(x) I1(x) * in the inverted interval [8,infinity]. * * lim(x->inf){ exp(-x) sqrt(x) I1(x) } = 1/sqrt(2pi). */ #ifdef UNK static double B[] = { 7.51729631084210481353E-18, 4.41434832307170791151E-18, -4.65030536848935832153E-17, -3.20952592199342395980E-17, 2.96262899764595013876E-16, 3.30820231092092828324E-16, -1.88035477551078244854E-15, -3.81440307243700780478E-15, 1.04202769841288027642E-14, 4.27244001671195135429E-14, -2.10154184277266431302E-14, -4.08355111109219731823E-13, -7.19855177624590851209E-13, 2.03562854414708950722E-12, 1.41258074366137813316E-11, 3.25260358301548823856E-11, -1.89749581235054123450E-11, -5.58974346219658380687E-10, -3.83538038596423702205E-9, -2.63146884688951950684E-8, -2.51223623787020892529E-7, -3.88256480887769039346E-6, -1.10588938762623716291E-4, -9.76109749136146840777E-3, 7.78576235018280120474E-1 }; #endif #ifdef DEC static unsigned short B[] = { 0022012,0125555,0115227,0043456, 0021642,0156127,0052075,0145203, 0122526,0072435,0111231,0011664, 0122424,0001544,0161671,0114403, 0023252,0144257,0163532,0142121, 0023276,0132162,0174045,0013204, 0124007,0077154,0057046,0110517, 0124211,0066650,0116127,0157073, 0024473,0133413,0130551,0107504, 0025100,0064741,0032631,0040364, 0124675,0045101,0071551,0012400, 0125745,0161054,0071637,0011247, 0126112,0117410,0035525,0122231, 0026417,0037237,0131034,0176427, 0027170,0100373,0024742,0025725, 0027417,0006417,0105303,0141446, 0127246,0163716,0121202,0060137, 0130431,0123122,0120436,0166000, 0131203,0144134,0153251,0124500, 0131742,0005234,0122732,0033006, 0132606,0157751,0072362,0121031, 0133602,0043372,0047120,0015626, 0134747,0165774,0001125,0046462, 0136437,0166402,0117746,0155137, 0040107,0050305,0125330,0124241 }; #endif #ifdef IBMPC static unsigned short B[] = { 0xe8e6,0xb352,0x556d,0x3c61, 0xb950,0xea87,0x5b8a,0x3c54, 0x2277,0xb253,0xcea3,0xbc8a, 0x3320,0x9c77,0x806c,0xbc82, 0x588a,0xfceb,0x5915,0x3cb5, 0xa2d1,0x5f04,0xd68e,0x3cb7, 0xd22a,0x8bc4,0xefcd,0xbce0, 0xfbc7,0x138a,0x2db5,0xbcf1, 0x31e8,0x762d,0x76e1,0x3d07, 0x281e,0x26b3,0x0d3c,0x3d28, 0x22a0,0x2e6d,0xa948,0xbd17, 0xe255,0x8e73,0xbc45,0xbd5c, 0xb493,0x076a,0x53e1,0xbd69, 0x9fa3,0xf643,0xe7d3,0x3d81, 0x457b,0x653c,0x101f,0x3daf, 0x7865,0xf158,0xe1a1,0x3dc1, 0x4c0c,0xd450,0xdcf9,0xbdb4, 0xdd80,0x5423,0x34ca,0xbe03, 0x3528,0x9ad5,0x790b,0xbe30, 0x46c1,0x94bb,0x4153,0xbe5c, 0x5443,0x2e9e,0xdbfd,0xbe90, 0x0373,0x49ca,0x48df,0xbed0, 0xa9a6,0x804a,0xfd7f,0xbf1c, 0xdb4c,0x53fc,0xfda0,0xbf83, 0x1514,0xb55b,0xea18,0x3fe8 }; #endif #ifdef MIEEE static unsigned short B[] = { 0x3c61,0x556d,0xb352,0xe8e6, 0x3c54,0x5b8a,0xea87,0xb950, 0xbc8a,0xcea3,0xb253,0x2277, 0xbc82,0x806c,0x9c77,0x3320, 0x3cb5,0x5915,0xfceb,0x588a, 0x3cb7,0xd68e,0x5f04,0xa2d1, 0xbce0,0xefcd,0x8bc4,0xd22a, 0xbcf1,0x2db5,0x138a,0xfbc7, 0x3d07,0x76e1,0x762d,0x31e8, 0x3d28,0x0d3c,0x26b3,0x281e, 0xbd17,0xa948,0x2e6d,0x22a0, 0xbd5c,0xbc45,0x8e73,0xe255, 0xbd69,0x53e1,0x076a,0xb493, 0x3d81,0xe7d3,0xf643,0x9fa3, 0x3daf,0x101f,0x653c,0x457b, 0x3dc1,0xe1a1,0xf158,0x7865, 0xbdb4,0xdcf9,0xd450,0x4c0c, 0xbe03,0x34ca,0x5423,0xdd80, 0xbe30,0x790b,0x9ad5,0x3528, 0xbe5c,0x4153,0x94bb,0x46c1, 0xbe90,0xdbfd,0x2e9e,0x5443, 0xbed0,0x48df,0x49ca,0x0373, 0xbf1c,0xfd7f,0x804a,0xa9a6, 0xbf83,0xfda0,0x53fc,0xdb4c, 0x3fe8,0xea18,0xb55b,0x1514 }; #endif /* i1.c */ #ifdef ANSIPROT extern double chbevl ( double, void *, int ); extern double exp ( double ); extern double sqrt ( double ); extern double fabs ( double ); #else double chbevl(), exp(), sqrt(), fabs(); #endif double i1(x) double x; { double y, z; z = fabs(x); if( z <= 8.0 ) { y = (z/2.0) - 2.0; z = chbevl( y, A, 29 ) * z * exp(z); } else { z = exp(z) * chbevl( 32.0/z - 2.0, B, 25 ) / sqrt(z); } if( x < 0.0 ) z = -z; return( z ); } /* i1e() */ double i1e( x ) double x; { double y, z; z = fabs(x); if( z <= 8.0 ) { y = (z/2.0) - 2.0; z = chbevl( y, A, 29 ) * z; } else { z = chbevl( 32.0/z - 2.0, B, 25 ) / sqrt(z); } if( x < 0.0 ) z = -z; return( z ); } gtk-wave-cleaner-0.22-04/icons/0000755000175000017500000000000013450764342017325 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/icons/amplify.xcf0000777000175000017500000000337613120075106021473 0ustar00alisteralister00000000000000gimp xcf file00BB cð00 Gfig Layer 0ÿ      00 000”þwþwþwþwþwþwþwþwþwþwþwþw üwwüwwµ”þwþwþwþwþwþwþwþwþwþwþwþw üwwüwwµ”þwþwþwþwþwþwþwþwþwþwþwþw üwwüwwµ2ÿÿ ÿ ÿÿÿþÿÿþÿÿþÿþÿþÿþÿþÿÿþÿþÿþÿÿþÿþÿþÿþÿ þÿþÿþÿûÿÿþÿÿúÿÿÿÿúÿÿÿÿúÿÿÿÿúÿÿÿÿÿ ÿÿ¶00Colorÿ     š00®00¾Nÿÿÿÿ ÿÿ ÿÿwÿÿwÿþÿwþÿþÿwþÿþÿwþÿþÿwþÿþÿwþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÿÿÿ ÿÿ ÿÿ ÿÿÿÿNNÿÿÿÿ ÿÿ ÿÿwÿÿwÿþÿwþÿþÿwþÿþÿwþÿþÿwþÿþÿwþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿþÿÿÿÿ ÿÿ ÿÿ ÿÿÿÿNNÿÿÿÿ ÿÿ ÿÿÿwÿÿÿÿwÿÿþÿÿwÿþÿþÿÿwÿþÿüÿÿÿwÿþÿüÿÿÿwÿþÿüÿÿÿwÿþÿüÿÿ ÿþÿüÿÿ ÿþÿüÿÿ ÿþÿþÿ ÿþÿþÿ ÿþÿÿÿÿÿÿÿÿ ÿÿ ÿÿÿÿNÿ& ÿ$ ÿ" ÿ ÿÿÿÿÿÿÿÿ ÿ" ÿ$ ÿ&ÿ˜þÿ-þÿ-þÿÿÿ+þÿ-þÿ-þÿZgtk-wave-cleaner-0.22-04/icons/amplify.xpm0000777000175000017500000000200613120075106021504 0ustar00alisteralister00000000000000/* XPM */ static const char * amplify_xpm[] = { "28 28 5 1", " c None", ". c #EA8585", "+ c #050202", "@ c #000000", "# c #BCB8B8", " ", " . ", " . ", " . . ", " . . ", " + . . ", " @@ . . .. ", " @@@ . . . ", " @@@@ . . . ", " @@@@@ . .. .. ", " @@@@ @@@@@@ . . . ", " @@@@ @@@@@@ . . . ", " @@@@ @@@@@@ . . . ", " @@@@ @@@@@@ . . . ", " @@@@ @@@@@@ . . . ", " #@#@ #@@@@@ . . . ", " @#@# @#@@@@ . .. . ", " @#@@@ . . .. ", " @#@@ . . . ", " @#@ . . . ", " @# . . . ", " @ . .. ", " . . ", " . . ", " . ", " . ", " . ", " "}; gtk-wave-cleaner-0.22-04/icons/cut.gfig0000777000175000017500000000063413120075106020753 0ustar00alisteralister00000000000000GFIG Version 0.1 Name: Scissors Version: 0.000000 ObjCount: 4 GridSpacing: 30 GridType: RECT_GRID DrawGrid: FALSE Snap2Grid: FALSE LockOnGrid: FALSE ShowControl: TRUE 128 23 73 144 66 25 120 142 120 142 136 146 146 135 135 114 119 114 108 112 4 73 144 60 148 56 134 61 117 71 112 88 113 4 gtk-wave-cleaner-0.22-04/icons/cut.xcf0000777000175000017500000000163013120075106020614 0ustar00alisteralister00000000000000gimp xcf file00BB / gimp-commentCreated with The GIMP–00 Gfig Layer 0ÿ      G00[00k   ý ü8ûU û:Ø[û ¨Äû•Õ&ûOç`û/Û‰ûº¹û†Û2úaæRû#Ð ûŬ ûnäD ûpãBûÄ­!û"Ρ û\çR"û€à6û¶¼#û/ÙŽûNåe#õŽÚ( ¦Ê%ö9ß}=ãt%÷ žÐ#—Ô&'øDän0ÚŠ'ù­Æ’Þ9)úPèëš)ûÎöM*ûÔõV)ù[çâ« (ù¸¼‚ãD%óPæc$Р ï$j}¤ÚȄ崙b#ìZÐíØÝö|.ÜåÜéÖŽ(ê[âÂU) Ô*ŽÛJR¯ìÌ9ö"ÎÄ&-ÛŠö9ß~ eéÇ ömò`Þ4õ ŸÐ#gíuö‘Ú!$Л ö@ãoǯ ÷¢ÒqâDö ­ÃÀ¬ ÷yëV#ĪöPãxRžð}ù7ÞèÃçOø„Ðèå›ù=œ¦f ú 2G2 ü ügtk-wave-cleaner-0.22-04/icons/cut.xpm0000777000175000017500000000207613120075106020645 0ustar00alisteralister00000000000000/* XPM */ static const char * cut_xpm[] = { "28 28 9 1", " c None", ". c #000000", "+ c #888889", "@ c #BABABC", "# c #D19C9C", "$ c #E86363", "% c #807C80", "& c #000005", "* c #788078", " ", " ", " ", " ", " ... ", " .... .+@. ", " .#$$$. .+@. ", " .# .$. .+@. ", " .$ .. .+@. ", " .## $. .+@. ", " .#.$#. .+@. ", " ....$. .+@. ", " %.+@ .+@. ", " .+&+@. ", " .++@. ", " .+&&+@. ", " ....$. *.+@. ", " .$.#$. .+@. ", " .$# #. .+@. ", " .# .. .+@. ", " .$ #$. .+@. ", " ..$#$. .+@. ", " .... .+@. ", " ... ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/declick.xcf0000777000175000017500000000367613120075106021433 0ustar00alisteralister00000000000000gimp xcf file00BBc|00 Gfig Layer 0ÿ     00(0083ÿÿÿÿÿüÿÿ ÿÿÿÿÿÿþÿÿÿþÿÿþÿÿÿÿÿÿÿþÿÿþÿþÿÿþÿÿÿ ÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿÿ þÿþÿÿþÿÿÿÿþÿÿþÿþÿÿþÿÿÿÿÿÿüÿÿþÿÿÿÿÿÿÿÿÿ ÿÿÿ#ÿÓþÿ,ÿ,ÿ+ÿ,ÿ)ÿ(ÿüÿÿ(ÿÿ  3ÿ#ÿÿÿ ÿÿÿÿþdÿÿûÓþ”ÿþÿüÑþdþÿÿüéþdÿÿüÓþ0ÿþÿüñþDþÿþÿüíúD þÿÿûöû0 ÿþÿ ûñû0 þÿþÿ ûöú þÿþÿ ûúõ0 ûÿÿ þÿ û0ùõ ûÿÿ þÿ û0úóþÿþÿüdúíþÿþÿûDþíþÿÿüDýÚÿþÿüdþèþÿþÿüdþÚþÿÿü~þÓÿÿùdÿ¯ÿÿþÿûœþ°ÿÿüœÿÿÿÿþDÿÿÿ ÿÿÿ#ÿ$00Colorÿ     00200Buÿ(ÿÿ#ÿÿ ÿ ÿÿÿÿÿþÿþÿÿÿÿÿúÿÿÿÿþÿÿþÿþÿÿÿþÿÿþÿþÿÿÿþÿÿþÿþÿþÿþÿ þÿ þÿþÿ þÿ þÿþÿ þÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿÿþÿþÿÿþÿÿÿþÿþÿþÿþÿÿÿþÿÿÿþÿÿÿýÿÿÿÿÿÿþÿÿ ÿ"ÿÿ'ÿP  8þÿ-þÿ-þÿ-þÿ-þÿ-þÿ-þÿ-þÿ-þÿ-ÿ!þÿÿÿüÿÿÿÿüÿÿÿÿ þÿüÿÿÿÿ þÿüÿÿ ÿÿ ÿüÿÿ þÿÿþÿüÿÿ ÿÿþÿüÿÿÿ þÿùÿÿÿÿÿ ÿÿþÿÿ þÿÿÿÿ&ÿÏgtk-wave-cleaner-0.22-04/icons/declick.xpm0000777000175000017500000000216013120075106021442 0ustar00alisteralister00000000000000/* XPM */ static const char * declick_xpm[] = { "28 28 12 1", " c None", ". c #F90707", "+ c #E88484", "@ c #000000", "# c #ADADB2", "$ c #0A0505", "% c #070709", "& c #000002", "* c #020000", "= c #060608", "- c #262628", "; c #000005", " ", " ", " .+ @ +. ", " +.+ @ +.+ ", " +.+@+.+ ", " +.@.+ ", " +.+ ", " +.@.+ ", " +.+@ .+ ", " +.+ @ +.+ ", " .+ @ +. ", " @ ", " @ ", " @ # ", " @ #$# ", " @ #%&*# # ", " #&# &&#*& #@# ", " =*# &&* #*# #&# @@@ ", " &# &#* &* &* #@#@ ", " -# #& & &# #* @@ # ", " ** ** * * *# #@# ", " #& *# &#& &@#@@ ", " &# #&# ;** #&@@# ", " &&#&&# #;# #### ", " #&@&# # # ", " ##&# ", " # ", " "}; gtk-wave-cleaner-0.22-04/icons/declick1.xpm0000777000175000017500000001514113120075106021526 0ustar00alisteralister00000000000000/* XPM */ static const char * declick_xpm[] = { "48 49 112 2", " c None", ". c #FF4A4A", "+ c #FF3B3B", "@ c #FF1C1C", "# c #FF0A0A", "$ c #FF0202", "% c #FF0808", "& c #FF1A1A", "* c #FF3737", "= c #FF5252", "- c #FF3939", "; c #FF1515", "> c #FF0000", ", c #FF0101", "' c #FF0505", ") c #FF0404", "! c #FF1111", "~ c #FF1B1B", "{ c #FF2121", "] c #FF3838", "^ c #FF4242", "/ c #FF1717", "( c #FF0B0B", "_ c #831F1F", ": c #FF2F2F", "< c #FF2B2B", "[ c #353333", "} c #FF2525", "| c #020000", "1 c #FF0C0C", "2 c #FF1616", "3 c #FF1010", "4 c #FF0303", "5 c #FF2828", "6 c #FF3434", "7 c #FF3030", "8 c #050000", "9 c #A5A4A4", "0 c #000002", "a c #3D0000", "b c #0C0C0E", "c c #1B0001", "d c #AA0000", "e c #FF5151", "f c #8A0203", "g c #FF4545", "h c #FF2626", "i c #010103", "j c #060608", "k c #040406", "l c #F60001", "m c #FF2222", "n c #1D1D1F", "o c #010002", "p c #827C7C", "q c #4F0305", "r c #0E0E10", "s c #262628", "t c #250103", "u c #0F0FC4", "v c #B90438", "w c #160EBD", "x c #130EC0", "y c #240EB3", "z c #0F0EC3", "A c #900659", "B c #FF0707", "C c #18181A", "D c #F90B0B", "E c #000001", "F c #000000", "G c #B2B0B0", "H c #FF4949", "I c #313133", "J c #08080A", "K c #783536", "L c #FB0B0B", "M c #232325", "N c #FD5555", "O c #050204", "P c #252526", "Q c #191919", "R c #0F0F11", "S c #9B0708", "T c #030305", "U c #F82324", "V c #F90505", "W c #070001", "X c #837A7A", "Y c #FF1E1E", "Z c #913232", "` c #F70000", " . c #180001", ".. c #0D0D0F", "+. c #FF3F3F", "@. c #957070", "#. c #E80000", "$. c #560001", "%. c #7C1011", "&. c #CF2E2E", "*. c #DD2D2E", "=. c #FF2424", "-. c #FF1313", ";. c #FF2727", ">. c #FF1F1F", ",. c #2E0001", "'. c #FF0F0F", "). c #FF0E0E", "!. c #FF0D0D", "~. c #FF0606", "{. c #FF1212", "]. c #340103", " ", " ", " ", " ", " . + @ # $ % & * = ", " - ; > , $ $ ' ' ' ' ) ! ~ { ] ", " ^ / ( > > > > _ > > > > ' @ : ", " < # > > [ > > % } ", " ' > > | 1 1 2 ", " > > > | 1 1 > > ", " , > | 1 1 1 > > ", " 3 , | 1 1 1 > # ", " ] 4 | 1 1 1 1 $ 5 ", " > $ | 1 1 1 1 > ' ", " : > | 1 1 1 > } ", " > > | 1 1 1 > > 6 ", " 7 > 8 | 1 1 1 > 5 ", " ) > 9 0 8 8 | 1 1 1 a > 4 ", " > > 0 0 0 b 0 1 1 1 1 0 0 c d > ", " e > > 9 0 0 9 0 9 0 0 1 1 1 0 0 0 0 0 0 f , g ", " h > > 9 i 0 9 j 0 0 0 1 1 1 1 k 0 0 0 l > m ", " 1 > > 9 n o p 9 j 0 o q 1 1 1 0 0 0 0 0 > > # ", " | , > > 0 0 9 r s o t 1 1 1 0 k 0 0 0 > > , ", " u % > v w u u u u u u u u u u u x y 1 1 1 u u u u u u u u u u u u u u u z A > B u ", " p { > > 9 0 0 C 0 D 1 1 0 0 0 0 0 E F > > @ [ ", " G G 9 H > > p 0 p I 0 0 1 1 1 0 0 J 0 0 F > > ^ ", " G 9 K > > 0 0 t o L 1 1 1 0 M 0 E F > > N ", " G O > > P Q R S 1 1 1 0 T 0 0 F > > ", " G p U V W X 1 1 1 0 0 E > Y ", " Z > ` . 1 1 1 .. 0 > > +. ", " @.m #.$. 1 1 1 0 > ~ ", " %.> &. 1 1 0 , > ; ", " *.> 1 1 1 0 > =. ", " -.> 1 1 1 0 > ( 6 ", " , > 1 1 1 0 > > ", " > 1 1 1 0 > > ", " ) 1 > 0 > > ) ", " ;.> > > 0 > > > >. ", " ^ # ' > > > ,. $ , , '.7 ", " @ m ).> > > , ) , > 4 ) , , !.} ). ", " { =.; ~.> ) {.5 7 ", " ]. ", " 0 ", " ", " ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/declick2.xpm0000777000175000017500000000601213120075106021524 0ustar00alisteralister00000000000000/* XPM */ static const char * declick2_xpm[] = { "50 49 25 1", " c None", ". c #F40909", "+ c #000002", "@ c #0C0C0E", "# c #010103", "$ c #060608", "% c #040406", "& c #1D1D1F", "* c #0E0E10", "= c #262628", "- c #0F0FC4", "; c #18181A", "> c #000001", ", c #000000", "' c #020000", ") c #313133", "! c #08080A", "~ c #232325", "{ c #252526", "] c #191919", "^ c #0F0F11", "/ c #030305", "( c #070709", "_ c #0D0D0F", ": c #111114", " ", " ", " ", " ", " ", " ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " +++ +. ", " +++@ +. +++ +++ ", " ++ + ++ +++++ ++++ ", " #+ $+ ++ ++ %+ ++ + ", " &+ $+ ++ ++ ++ ++ ++ ", " + ++ *= ++++ + %+ ++ + ", " ---------------------------------------- ", " + ++ ;+ ++ +++ ++ >, ' ", " + + )++ ++ ++ !+ +, ", " ++ ++ ++ ++ . ~+ >, ", " ++ {] ^+ ++ . /++, ", " + + +++ . +> ", " +] + (_ . ", " ++++ . ", " +: . ", " + . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " ", " ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/declick3.xpm0000777000175000017500000000717213120075106021535 0ustar00alisteralister00000000000000/* XPM */ static const char * declick3_xpm[] = { "50 50 63 1", " c None", ". c #F9094D", "+ c #070002", "@ c #020000", "# c #010508", "$ c #020609", "% c #010608", "& c #030501", "* c #030401", "= c #040601", "- c #010300", "; c #010200", "> c #030603", ", c #050703", "' c #010301", ") c #050203", "! c #040103", "~ c #040104", "{ c #070307", "] c #050104", "^ c #070407", "/ c #090508", "( c #0D0A0D", "_ c #060305", ": c #080408", "< c #03050F", "[ c #020410", "} c #00010D", "| c #02040F", "1 c #01020E", "2 c #02030F", "3 c #02030E", "4 c #030611", "5 c #050611", "6 c #030410", "7 c #02020E", "8 c #01030E", "9 c #00020E", "0 c #2909E2", "a c #08080C", "b c #09090E", "c c #030308", "d c #05050A", "e c #07070C", "f c #010107", "g c #020208", "h c #040409", "i c #030309", "j c #05050B", "k c #08070D", "l c #08080E", "m c #04040A", "n c #020207", "o c #020202", "p c #090909", "q c #050505", "r c #0A0A0A", "s c #060606", "t c #040404", "u c #030303", "v c #030403", "w c #010302", "x c #010201", " ", " ", " ", " ", " ", " ", " ", " ", " ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " + . + ", " + . @ + ", " + . @ + @ + ", " + . @ + + @ + ", " @ # ++ #+ @ $ + %@ + + ", " @ @ @ &*++ =+ -;=>+ +& ,@ ++ +' ", " @ )@ @ +++@!!@~!!~~!!+{+]@^++/(!_^: ", " @<@@@@@@@@@@@+[@@@}}@}}}}}}}+[|1@234567889 ", " 00000000000000000000000000000000000000000000 ", " @@a@@@@@@+@@@@bcdcefgh@di@g@@j+h@klmijg+ng ", " @ @@ @@ @+ @op+qors@@qt+ u@+ u@ ut +q ", " @@ + @ @+ ++ v+ @ @ @ w@ + ++ ", " @ + + x @ @ @ @ + ", " + + . @ @ @ + ", " + + . @ @ + ", " + . @ + + ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " . ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/declick4.xpm0000777000175000017500000001756513120075106021545 0ustar00alisteralister00000000000000/* XPM */ static const char * declick_xpm[] = { "50 49 181 2", " c None", ". c #000000", "+ c #040404", "@ c #080808", "# c #111111", "$ c #121212", "% c #101010", "& c #0D0D0D", "* c #070707", "= c #060606", "- c #131313", "; c #202020", "> c #525151", ", c #898888", "' c #B5B4B4", ") c #D6D5D5", "! c #E7E5E5", "~ c #E7E2E2", "{ c #E8E3E3", "] c #EAE5E5", "^ c #C8C5C5", "/ c #949393", "( c #6A6969", "_ c #6D6B6B", ": c #0E0E0E", "< c #0A0A0A", "[ c #212121", "} c #535252", "| c #9D9C9C", "1 c #E3E2E2", "2 c #E8E5E5", "3 c #B1AFAF", "4 c #626161", "5 c #272727", "6 c #050505", "7 c #5E5D5D", "8 c #B2B0B0", "9 c #E2DEDE", "0 c #F40909", "a c #C8C6C6", "b c #706F6F", "c c #2A2A2A", "d c #0F0F0F", "e c #434242", "f c #9A9898", "g c #DBD7D7", "h c #B2B1B1", "i c #545353", "j c #181818", "k c #161616", "l c #646464", "m c #C0BCBC", "n c #E9E4E4", "o c #D3CFCF", "p c #7E7D7D", "q c #252525", "r c #737272", "s c #CDC9C9", "t c #DCD7D7", "u c #918F8F", "v c #2B2B2B", "w c #151515", "x c #767575", "y c #D3D0D0", "z c #DDD8D8", "A c #959393", "B c #686767", "C c #D2CFCF", "D c #8B8989", "E c #484747", "F c #CECACA", "G c #D8D4D4", "H c #716F6F", "I c #B3B2B2", "J c #C6C3C3", "K c #424242", "L c #6D6C6C", "M c #E5E1E1", "N c #E6E2E2", "O c #919090", "P c #1E1E1E", "Q c #D9D8D8", "R c #DEDDDD", "S c #484848", "T c #6A6A6A", "U c #8E8D8D", "V c #1A1A1A", "W c #010101", "X c #C5C4C4", "Y c #040406", "Z c #000002", "` c #DCD7D8", " . c #D0CECE", ".. c #343434", "+. c #9E9B9C", "@. c #393839", "#. c #09080A", "$. c #5A5959", "%. c #6C6C6C", "&. c #E6E1E1", "*. c #ADA9AA", "=. c #CFCACB", "-. c #E1DCDC", ";. c #0F0F11", ">. c #E2DDDD", ",. c #1C1B1D", "'. c #A5A5A5", "). c #939091", "!. c #010103", "~. c #3A393A", "{. c #060608", "]. c #3E3D3E", "^. c #C7C2C3", "/. c #C8C4C4", "(. c #E0DCDC", "_. c #B9B7B7", ":. c #D0D0D0", "<. c #202022", "[. c #CCC8C8", "}. c #070709", "|. c #E1DDDD", "1. c #C6C1C2", "2. c #A29E9F", "3. c #585657", "4. c #D9D4D4", "5. c #DBD9D9", "6. c #E4E2E2", "7. c #ABA9AA", "8. c #131315", "9. c #262628", "0. c #918E8F", "a. c #E3DEDE", "b. c #BBB7B7", "c. c #2E2D2F", "d. c #E6E3E3", "e. c #2D2D2D", "f. c #9F9BD7", "g. c #0F0FC4", "h. c #2D2C2C", "i. c #4E4C4D", "j. c #5B595B", "k. c #18181A", "l. c #3E3D3D", "m. c #585656", "n. c #020000", "o. c #CAC6C6", "p. c #161618", "q. c #636163", "r. c #747273", "s. c #E5E0E0", "t. c #878485", "u. c #E4DFE0", "v. c #08080A", "w. c #020204", "x. c #424141", "y. c #E5E2E2", "z. c #D3CECF", "A. c #E4DFDF", "B. c #3D3C3E", "C. c #2B2A2B", "D. c #6B6969", "E. c #D7D6D6", "F. c #252526", "G. c #191919", "H. c #646264", "I. c #030305", "J. c #494747", "K. c #B7B6B6", "L. c #D2CDCD", "M. c #090809", "N. c #0D0D0F", "O. c #111114", "P. c #E8E6E6", "Q. c #B0AFAF", "R. c #DFDADB", "S. c #DCDBDB", "T. c #BCBCBC", "U. c #5F5F5F", "V. c #090909", "W. c #0C0C0C", "X. c #100F0F", " ", " ", " ", " . + @ # $ $ % % % % & & * . ", " = - ; > , ' ) ! ~ { ~ ] ^ / ( _ ; : ", " < [ } | 1 ] ] ] ] ] ] ] ] ] ] ] ] 2 3 4 5 $ ", " 6 ; 7 8 9 ] ] ] ] ] ] 0 ] ] ] ] ] ] ] ] ] ] a b c < ", " d e f g ] ] ] ] ] ] ] ] 0 ] ] ] ] ] ] ] ] ] ] ] ~ h i j ", " . k l m ~ ] ] ] ] ] ] ] ] ] 0 ] ] ] ] ] ] ] ] ] ] ] ] n o p q . ", " j r s ] ] ] ] ] ] ] ] ] ] ] 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] t u v . ", " w x y ] ] ] ] ] ] ] ] ] ] ~ ] 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] z A c . ", " : B C ] ] ] ] ] ] ] ] ] ] ] ~ ] 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] t D [ ", " 6 E F ] ] ] ] ] ] ] ] ] ] ] ] ~ ] 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] G H % ", " k I ] ] ] ] ] ] ] ] ] ] ] ] ] ~ ] 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] J K . ", " = L M ] ] ] ] ] ] ] ] ] ] ] ] ] { ] 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] N O P ", " : Q ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] R S . ", " . T n ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 0 n ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] U V ", " W X ] ] ] ] ] ] Y Z Z ` ] ] ] ] ] ] Z 0 n ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] .... ", " 5 ] ] ] ] ] ] +.Z Z Z @.] ] ] ] ] ] Z 0 ] ] ] n Z Z #.] ] ] ] ] ] ] ] Z Z Z n ] ] $.@ ", " %.] ] ] ] ] &.Z Z *.=.Z { { ] ] { ] Z Z ] ] -.Z Z Z Z ;.] ] ] ] ] ] >.Z Z Z ,.] ] U k ", " . '.] n ] ] ] ).!.~.] ] {.].] ] ] { ] Z Z n ] Z Z ^./.Y Z ] ] ] ] ] ] Z Z n (.Z ] ] _.[ ", " . :.] n ] ] &.<.Z [.] ] }.Z |.] ] ] 1.Z Z 2.n Z 3.] >.Z Z 4.] ] ] ] (.Z Z ] n Z Y ] 5.c ", " . 6.Z ] ] ] 7.Z Z t ] { 8.9.0.] ] ] ~.Z Z Z a.Z z ] ~ z Y !.] ] ] ] !.!.(.n n b.c.] d.e.. ", " . f.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.g.&.h.. ", " . &.i.] ] ] ~ Z j.] ] ] |.k.Z -.] ] Z ~.] Z Z Z ] ] ] ] Z Z ] ] ] ] l.m.a.] ] n ] n.~ h.. ", " . 6.Z o.] n t p.] ] ] n ] q.Z Z ] ] Z r.s.~.Z t.] ] ] ] u.v.Y ] ] w.x.a.] ] ] ] ] ] y.h.. ", " . :.!.Z ] ~ Z p.] ] ] ] ~ z.Z Z A.!.Z n ] n 0 ] ] ] ] ] ] B.Z ] ] C.D.] ] ] ] ] ~ ] E.c . ", " . '.Z Z ] ~ F.G.] ] ] ] n ] H.Z { Z Z ] ] ] 0 ] ] ] ] ] ] &.I.Y w.J.>.] ] ] ] ] ] ] K.[ ", " . %.(.Z ] { Z a.n ] ] ] ] ] ] Z ;.Z L.] ] ] 0 ] ] ] ] ] ] ] n Z M.~ ] ] ] ] ] ] ] ] U k ", " 5 ] Z G.t Z n s.] ] ] { ] ] >.}.N.] ] ] ] 0 ] ] ] ] ] ] ] ] &.] ] ] ] ] ] ] ] ] ] $.@ ", " W X Z Z ~.Z &.] ] ] ] ] ] ] ] n &.] ] ] ] 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] .... ", " . T >.Z O.&.] ] ] ] ] ] ] ] ] ] ] ] n ] ] 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] U V . ", " : Q { Z n ] ] ] ] ] ] n ] ] ] ] ] ] ] n 0 ] ] ] ] ] n ] ] ] ] ] ] ] ] ] ] ] R S . ", " = L M ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] n 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] N O P . ", " k I ] ] ] ] ] ] ] ] ] n n ] ] ] ] ] n 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] J K . ", " = E F ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] n 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] G H % ", " : B C ] ] ] ] ] ] ] ] ] ] ] ] ] ] ] 0 ] ] ] ] ] ] ] ] ] ] ] ] ] ] t D [ . ", " w x y ] ] ] ] ] ] ] ] ] ] ] ] ] n 0 ] ] ] ] ] ] ] ] ] ] ] ] ] z A c . ", " . j r s ] ] ] ] ] ] ] ] ] ] ] ] n 0 ] ] ] ] ] ] ] ] ] ] ] ] t u v . ", " . k l m ~ ] ] ] ] ] ] ] ] ] ] ~ 0 ] ] ] ] ] ] ] ] ] ] n o p q . ", " . d e f g ] ] ] ] ] ] ] ] ] s.0 ] ] ] ] ] ] ] ] ] ~ h i j . ", " 6 ; 7 8 9 ] ] ] ] ] ] ] &.0 ] ] ] ] ] ] ] ] a b c * . ", " . < [ } | 1 ] ] ] ] ] { 0 ] ] ] ] ] P.Q.4 5 : . . ", " . = - ; > , ' ) n ~ R.d.S.T./ U.c k V.. . ", " . . + @ W.: X.% % % d & V.6 W . . ", " . . . . . . . . ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/declick5.xpm0000777000175000017500000002024613120075106021534 0ustar00alisteralister00000000000000/* XPM */ static const char * declick5_xpm[] = { "50 49 200 2", " c None", ". c #414141", "+ c #424242", "@ c #444444", "# c #5C5C5C", "$ c #515151", "% c #4C4C4C", "& c #484848", "* c #5F5F5F", "= c #747474", "- c #464646", "; c #494949", "> c #4B4B4B", ", c #4D4D4D", "' c #4E4E4E", ") c #4F4F4F", "! c #505050", "~ c #6B6B6B", "{ c #474747", "] c #525252", "^ c #545454", "/ c #555555", "( c #565656", "_ c #575757", ": c #585858", "< c #535353", "[ c #646464", "} c #9E9E9E", "| c #595959", "1 c #5B5B5B", "2 c #F40909", "3 c #5E5E5E", "4 c #5D5D5D", "5 c #5A5A5A", "6 c #717171", "7 c #616161", "8 c #636363", "9 c #666666", "0 c #676767", "a c #656565", "b c #626262", "c c #606060", "d c #9C9C9C", "e c #696969", "f c #6A6A6A", "g c #6C6C6C", "h c #6E6E6E", "i c #6F6F6F", "j c #6D6D6D", "k c #686868", "l c #8E8E8E", "m c #727272", "n c #767676", "o c #777777", "p c #757575", "q c #707070", "r c #787878", "s c #7C7C7C", "t c #7E7E7E", "u c #7F7F7F", "v c #7D7D7D", "w c #7B7B7B", "x c #7A7A7A", "y c #797979", "z c #999999", "A c #808080", "B c #838383", "C c #858585", "D c #868686", "E c #878787", "F c #848484", "G c #828282", "H c #818181", "I c #AEAEAE", "J c #8B8B8B", "K c #8D8D8D", "L c #8F8F8F", "M c #8C8C8C", "N c #8A8A8A", "O c #898989", "P c #888888", "Q c #D1D1D1", "R c #FFFFFF", "S c #929292", "T c #949494", "U c #959595", "V c #969696", "W c #939393", "X c #919191", "Y c #909090", "Z c #9B9B9B", "` c #9D9D9D", " . c #9A9A9A", ".. c #989898", "+. c #979797", "@. c #C0C0C0", "#. c #9F9F9F", "$. c #A2A2A2", "%. c #A3A3A3", "&. c #A4A4A4", "*. c #A1A1A1", "=. c #A0A0A0", "-. c #A5A5A5", ";. c #A7A7A7", ">. c #A9A9A9", ",. c #AAAAAA", "'. c #A8A8A8", "). c #A6A6A6", "!. c #CDCDCD", "~. c #020204", "{. c #000002", "]. c #ADADAD", "^. c #AFAFAF", "/. c #B0B0B0", "(. c #ACACAC", "_. c #ABABAB", ":. c #B4B4B4", "<. c #E5E5E5", "[. c #666667", "}. c #2A2A2B", "|. c #B2B2B2", "1. c #B3B3B3", "2. c #070709", "3. c #B1B1B1", "4. c #F0F0F0", "5. c #BFBFBF", "6. c #767677", "7. c #B7B7B7", "8. c #B8B8B8", "9. c #0C0C0E", "0. c #B6B6B6", "a. c #B5B5B5", "b. c #151517", "c. c #D8D8D8", "d. c #010103", "e. c #282829", "f. c #060608", "g. c #2D2D2F", "h. c #B9B9B9", "i. c #BBBBBB", "j. c #A0A0A1", "k. c #040406", "l. c #BCBCBC", "m. c #BABABA", "n. c #E4E4E4", "o. c #1F1F20", "p. c #9C9C9D", "q. c #BDBDBD", "r. c #474749", "s. c #BEBEBE", "t. c #030305", "u. c #D7D7D7", "v. c #838384", "w. c #111113", "x. c #262628", "y. c #6E6E6F", "z. c #2E2E30", "A. c #C1C1C1", "B. c #949495", "C. c #252526", "D. c #FDFDFE", "E. c #6868A4", "F. c #0F0FC4", "G. c #B8B8B9", "H. c #323233", "I. c #404041", "J. c #18181A", "K. c #2F2F31", "L. c #C3C3C3", "M. c #C2C2C2", "N. c #020000", "O. c #0F0F11", "P. c #535355", "Q. c #5E5E5F", "R. c #303031", "S. c #707071", "T. c #08080A", "U. c #363636", "V. c #373739", "W. c #232323", "X. c #C4C4C4", "Y. c #191919", "Z. c #4E4E4F", "`. c #3A3A3A", " + c #DDDDDD", ".+ c #0B0B0D", "++ c #070708", "@+ c #FCFCFC", "#+ c #969697", "$+ c #0D0D0F", "%+ c #D6D6D6", "&+ c #232324", "*+ c #111114", "=+ c #F1F1F1", "-+ c #737373", ";+ c #F6F6F6", ">+ c #DBDBDB", ",+ c #CACACA", "'+ c #4A4A4A", ")+ c #525253", " ", " ", " ", " . + @ # $ % & & & & & * = $ - ", " @ - & ; > % , ' ) ) ! ! ! ) ) ' , ~ ", " { ; > , ) $ ] ^ / ( _ _ _ : _ _ _ ( / ^ < [ } ", " ; > ' ! ] ^ ( : | 1 # 2 3 * * * * * 3 3 4 # 1 5 | 6 ", " ' ! ] / _ | 1 4 * 7 8 [ 2 9 9 0 0 0 0 9 9 a [ 8 b 7 c * d ", " ! < / _ 5 # * 7 8 a 0 e f g 2 h i i i i i i h j g ~ f e k 0 9 l ", " _ 5 # * 7 8 9 k ~ j i 6 m = 2 n o o o o o o n p = = m 6 q i h j l ", " 4 * 7 [ 9 e ~ h q m = o r r s 2 t u u u u u u t v v s w x y r n p p z ", " 7 8 9 k ~ j q m p o x s t A A B 2 C D E E E E E D D C F B G H A u t v s I ", " 9 k ~ j i m = o y s u H B C E E J 2 K l l L L L l l K M M J N O P E D C F B Q R R R R R R ", " j i 6 = n y w t H B D P N K L l S 2 T U V V V V V V U T W S X Y L l K K M J z R R R R R R ", " m = n r w v A G C E N M L X W U U z 2 Z d ` ` ` ` ` ` d Z Z .z ..+.V U T W W S @.R R R R R ", " r x s u H B D O J l Y W U .. .d } #.2 $.%.%.&.&.&.&.%.%.$.*.=.=.#.} ` d Z . .z #.R R R R R ", " v t A B C E N M L X T +.z d } =.$.&.-.2 ;.>.,.,.,.,.,.,.>.>.'.;.).-.&.%.%.$.*.=.=.#.!.R R R R ", " R W F D P N M L S ~.{.{.W #.*.%.).'.>.{.2 ].^.^./././././.^.I I ].(._.,.,.>.'.;.;.).-.:.R R R R ", "R R <.E O J K L S T [.{.{.{.}.%.).'.,.(.I {.2 |.1.:.:.{.{.2.:.:.1.1.|.3./.^.{.{.{._.(._.,.,.4.R R R ", "R R 5.J K L X W V U {.{.6.Y {.).>.(.^.^.|.{.{.7.8.3.{.{.{.{.9.8.8.7.0.0.a.I {.{.{.b././.^.^.c.R R R ", "R R _.l Y S U +.z [.d.e.%.).f.g.I /.|.|.0.{.{.h.i.{.{.j.$.k.{.l.l.i.m.h.h.{.{.a.I {.:.:.1.|.n.R R R ", "R R #.X W U +. . .o.{.L ).>.2.{.,.1.a.7.p.{.{.B q.{.r.5.i.{.{.3.s.s.q.l.:.{.{.h.7.{.t.0.0.a.u.R R R ", "R R ..W {.+. .d v.{.{.d '.>.w.x.y.a.7.h.z.{.{.{.m.{.0.A.@.8.k.d.@.@.5.s.d.d.:.m.h.B.C.8.8.7.8.R R R ", "D.R W E.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.F.G.h.8.R R R ", "R R W U H.z Z ` } {.I.;.,.(.,.J.{.^.8.m.{.K.5.{.{.{.L.L.L.L.{.{.M.A.A.@.H.{ 8.q.l.m.i.N.h.h.M.R R R ", "R R S T {.v. .d +.O.&.;.>._.I P.{.{.8.m.{.Q.i.R.{.S.M.M.L.L.s.T.t.A.@.~.U.8.q.l.i.i.m.h.h.8.h.R R R ", "R R V S d.{.z z {.O.%.-.'.,._.j.{.{.|.d.{.i.q.s.2 @.A.A.A.A.A.V.{.5.5.W.( l.i.m.m.h.a.8.7.0.X.R R R ", "R R ` Y {.{.V +.C.Y.=.%.).'.,.].Z.{.|.{.{.m.i.l.2 s.5.5.5.5.5.i.t.t.~.`.a.m.h.8.7.7.0.a.:.:. +R R R ", "R R >.K O {.W U {.V d =.%.-.'._.].{..+{.$.7.h.m.2 i.l.l.l.l.l.i.m.{.++0.8.7.0.a.:.1.1.|.3.3.@+R R R ", "R R s.O J {.Y.O {.V #+d #.$.%.;.>.).2.$+|.1.a.0.2 8.8.8.8.8.8.7.7.1.a.:.1.|.3.3./.^.I ].].(.%+R R R ", "R R n.F E {.{.&+{.L U ..Z ` =.$.-.;.>.>.I ^.3.|.2 1.:.:.:.:.1.1.|.3.3./.^.I ].(._.,.>.'.'.;.R R R R ", " Y H A {.*+P K Y W U ..Z } =.$.-.;.>.>.(.].2 I ^.^.^.^.I I ].(._.,.>.'.;.).).-.&.%.$./.R R R R ", " |.s t u {.F P N K Y W U +. .` #.*.%.-.).).2 >.>.>.>.>.;.'.;.).-.&.%.$.*.=.#.} ` d Z =+R R R R ", " v r x s u G F E N M L S T +.z Z ` } =.=.2 $.%.%.%.$.$.*.*.=.#.} ` Z .z ..+.V U %.R R R R R ", " %.6 -+n r w v A B D P J K L S T V ..z z 2 d d d d d Z . .z ..+.U T W S X Y L ).;+R R R R R ", " y j i 6 = o x s u G F E O J l L X S S 2 U U U U U T W S X Y L l K M N O P E 4.R R R R R R ", " l.a k f j q m p r x v A G F D P N J M 2 K K l K K M M J N O E D C F B H A S ", " S 7 8 9 e ~ h 6 -+n r w v u H G B B 2 D D D D C C F B G H A t v s w x r ", " t # * 7 [ 0 e g h 6 -+p o y x s s 2 t t t t v s s w x r o n p -+m 6 >+ ", " p : 5 4 * b a 0 e g h q 6 -+= -+2 n n n n p p = -+m q i h j ~ f ,+ ", " o < / : 5 4 * b [ 9 k e ~ g f 2 h h h h j g g ~ f k 0 9 a 8 ", " O ' $ < ( : 5 # 3 c 7 8 [ 8 2 9 9 9 a a [ 8 b 7 c * 4 # ", " 7 % ' $ < / _ : 5 1 # # 2 3 3 3 4 4 # 1 5 | : _ i ", " | '+% ' ! $ < ^ / ( )+( ( ( ( / / ^ < ] b d ", " b % & '+> % , ' ' ) ) ) ' ' , $ e ", " t ! - { { { % ] [ ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/declick6.xpm0000777000175000017500000001706713120075106021544 0ustar00alisteralister00000000000000/* XPM */ static const char * declick_xpm[] = { "51 49 155 2", " c None", ". c #373636", "+ c #AAA7A7", "@ c #9C9999", "# c #727070", "$ c #F40909", "% c #A8A5A5", "& c #A9A6A6", "* c #A7A4A4", "= c #848282", "- c #5F5D5D", "; c #817F7F", "> c #9F9C9C", ", c #9A9797", "' c #969393", ") c #030303", "! c #000000", "~ c #8E8B8B", "{ c #000002", "] c #8A8888", "^ c #4D4B4B", "/ c #959292", "( c #797777", "_ c #444343", ": c #9E9B9B", "< c #908D8D", "[ c #343333", "} c #201F21", "| c #8B8888", "1 c #060606", "2 c #A19E9E", "3 c #9D9A9A", "4 c #626060", "5 c #7E7B7C", "6 c #928F8F", "7 c #656363", "8 c #A19F9F", "9 c #A09D9D", "0 c #7D7B7B", "a c #000001", "b c #0B0B0D", "c c #686666", "d c #0D0D0D", "e c #868484", "f c #1C1C1C", "g c #292829", "h c #010103", "i c #1E1D1D", "j c #8A8787", "k c #A4A1A1", "l c #7F7D7D", "m c #8C8A8A", "n c #8D8A8A", "o c #030305", "p c #989595", "q c #A29F9F", "r c #7B7979", "s c #908E8E", "t c #5A5959", "u c #999696", "v c #A6A3A3", "w c #636161", "x c #0C0C0D", "y c #949292", "z c #050507", "A c #858282", "B c #868383", "C c #4E4D4D", "D c #7A7777", "E c #363535", "F c #A5A2A2", "G c #7E7B7B", "H c #615F5F", "I c #010101", "J c #838181", "K c #737273", "L c #0F0F11", "M c #252527", "N c #5C5A5A", "O c #2A292B", "P c #8D8B8B", "Q c #A3A0A0", "R c #6C6A6A", "S c #0E0E0E", "T c #706EA6", "U c #0E0EBF", "V c #0F0FC4", "W c #0D0DBE", "X c #0E0EBD", "Y c #0E0EC3", "Z c #0E0EC0", "` c #0C0CBD", " . c #0C0CB2", ".. c #0E0EBE", "+. c #0E0EBB", "@. c #0C0CAD", "#. c #0D0DB3", "$. c #0B0BA5", "%. c #070764", "&. c #0D0DBB", "*. c #0B0B9F", "=. c #050556", "-. c #090986", ";. c #949192", ">. c #2F2E2F", ",. c #878585", "'. c #3C3B3B", "). c #161618", "!. c #898686", "~. c #757373", "{. c #181818", "]. c #383737", "^. c #6B6969", "/. c #828080", "(. c #4F4D4D", "_. c #939091", ":. c #6D6B6B", "<. c #0C0B0B", "[. c #888686", "}. c #979494", "|. c #3E3E3E", "1. c #545354", "2. c #626061", "3. c #040406", "4. c #020202", "5. c #121212", "6. c #777575", "7. c #595757", "8. c #0B0B0B", "9. c #737172", "0. c #6E6C6C", "a. c #232224", "b. c #787575", "c. c #414040", "d. c #060505", "e. c #161616", "f. c #8E8C8C", "g. c #989696", "h. c #161617", "i. c #2E2D2E", "j. c #424141", "k. c #131212", "l. c #747171", "m. c #888585", "n. c #949191", "o. c #706E6E", "p. c #646262", "q. c #040404", "r. c #767474", "s. c #939191", "t. c #918E8E", "u. c #939090", "v. c #191818", "w. c #827F7F", "x. c #585757", " ", " ", " ", " . + + + + + + + + + + + + @ # ", " + + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + $ + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + % + $ + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + % + $ + + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + + % + $ + + + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + + % + $ + + + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + + + % + $ + + + + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + & * + + + + + + + + $ + + + + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + = - ; * + + + + + + + $ & + + + + + + + + + + + + + + > , + + + + + ", " + + + + + + + & ' ) ! ! ~ + + + + + + { $ & + + + ] ^ / + + + + + + + + ( _ : + + + + ", " + + + + + + + + < [ ! ! ! } , + + + + + { $ + + * | ! ! 1 + + + + + + + 2 ! ! ! 3 + + + + ", " + + + + + + + % 4 ! ! 5 6 ! 7 8 + + % : ! ! 9 & 0 ! ! a a b + + + + + + c ! ! ! d e + + + ", " + + + + + + + : f a g + ' h i j % + k = ! ! l 3 ! ! m n o a p + + + + q ! a r s ! t k + + ", " + + u v + + + w x ! y + q z a A q + k B { a C D ! E + F ! ! G + + + + H ! a v % ! I J + + ", " + + J ! + + + K a { 9 + : L M N & + + O { { ! ; ! y + % P h I v + + q ! a Q & & R S 7 * + ", " + + T U V V V V V V V V V W V X Y V V V V V Z ` ...V V X +.@.#.V V $.%.&.V V V *.=.-.;.+ ", " + + ( >.+ + + ,.! '.+ + * ~ ).! @ + * a O + { { { + + + * ! ! !.+ + ~.{.].F + + * ^.! /.v ", " + : (.! _.+ & :.<.[.+ + & }.|.! ! : y a 1.v O { 2.+ + + q ] 3.4.y 0 ! 5.6.+ + + + [.] ; u ", " + @ 7.! ! + u ! 8.}.+ + + * 9.! ! 0.I a 3 + & $ + + + + + ' a.! b.c.d.e.f.+ + + + F : 9 q ", " + + r ! ! Q g.h.S F + + + & < i.! j.! ! ~ + + $ + + + + + & e ! 4.I k.l.+ + + + + + + + + ", " + + Q [ ! m.n.a o.& + + + + v = ! 8.! p.k + + $ + + + + + + v < ! q.r.+ + + + + + + + + + ", " + + + 0.! d ; ! n v + + + & + F s.! a % + + + $ + + + + + + + + t.u.& + + + + + + + + + + ", " + + + u ! ! v.! v + + + + + + + + w.^.+ + + + $ + + + + + + + + + + + + + + + + + + + + ", " + + * D ! o x.+ + + + + + + + + + + + & + + $ + + + + + + + + + + + + + + + + + + + + ", " + + + % | ! p + + + + + + & + + + + + + + & $ + + + + + & + + + + + + + + + + + + + + ", " + + + % !.+ + + + + + + + + + + + + + + & $ + + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + & & + + + + + & $ + + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + + + + + & $ + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + + + + + + $ + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + + + + & $ + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + + + & $ + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + + % $ + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + + v $ + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + + * $ + + + + + + + + + + + + + ", " + + + + + + + + + + + + + % $ + + + + + + + + + + + + ", " + + + + + + + + + + + + k + + + + + + + + + + ", " + + + + + + + + + + + + + + + + + + + ", " + + + + + + + + + + + + + ", " + ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/declick_m.xcf0000777000175000017500000000504713120075106021741 0ustar00alisteralister00000000000000gimp xcf file00BBkBD •" Pasted Layerÿ      "("8 ÿÿÿÿ ÿüÿÿ ÿ ÿÿ ÿÿ ÿþÿÿÿþÿÿþÿÿÿÿÿÿÿþÿÿþÿþÿÿþÿÿÿ ÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿÿ þÿþÿÿþÿÿÿÿþÿÿþÿþÿÿþÿÿÿÿÿÿüÿÿþÿÿÿÿ ÿÿ ÿÿÿ ÿÿÿÿ  ÿÿÿÿ ÿÿÿ ÿþdÿ ÿûÓþ”ÿþÿüÑþdþÿÿüéþdÿÿüÓþ0ÿþÿüñþDþÿþÿüíúD þÿÿûöû0 ÿþÿ ûñû0 þÿþÿ ûöú þÿþÿ ûúõ0 úÿÿÿ û0ùõ úÿÿÿ û0úóþÿþÿüdúíþÿþÿûDþíþÿÿüDýÚÿþÿüdþèþÿþÿüdþÚþÿÿü~þÓÿÿùdÿ¯ÿÿþÿûœþ°ÿÿüœÿÿÿÿþD ÿÿÿ ÿÿÿÿ 00 New Layerÿ      ð0000èÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ+ÿ*ÿ(ÿ'ÿ'ÿ'ÿ'ÿ'ÿ(ÿ2  èû%ee%*û¢üü¢*ûãÿÿã*ûêÿÿê*ûçÿÿç*ûçÿÿç*ûèÿÿè*ûêÿÿê*ûëÿÿë*ûéÿÿé*ûäÿÿä*ûäÿÿä*ûëÿÿë*ûìÿÿì*ûéÿÿé*ûäÿÿä*ûäÿÿä*ûëÿÿë*ûêÿÿê*ûäÿÿä*ûäÿÿä*ûêÿÿê*ûéÿÿé*ûâÿÿâ*ûâÿÿâ*ûëÿÿë*ûîÿÿî*ûîÿÿî*ûêÿÿê*ûâÿÿâ*ûâÿÿâ*ûæÿÿæ*ûÍÿÿÍ*ûmääm*û(()ù .. '÷ K¯íí¯K &ý=¼þþý¼=&ýníþþýín&ý{úþþýú{&ý_ÞþþýÞ_&÷(˜ëúúë˜('ù(}»»}(100Colorÿ     æ00ú00 …ÿ)ÿÿ$ÿÿ"þÿ ÿ ÿ ÿ.þÿþÿ ÿþÿ ÿþÿþÿ ÿüÿÿþÿÿþÿþÿüÿÿþÿþÿüÿÿþÿþÿþÿ þÿÿ+þÿþÿþÿ ÿÿ ÿ ÿ ÿ"ÿÿ%þÿÿ'ÿÿ)ÿ‡   ÿ)ÿ%ÿÿÿÿÿÿÿ ÿþÿÿÿ ÿü–»´ ÿÿþÿüüÿ ÿÿþÿüÿÿÿ þÿÿüÿÿÿ ÿÿýÿÿ þÿÿÿÿ&ÿÏ00Selection Mask ÿ00 00 # ÿgtk-wave-cleaner-0.22-04/icons/declick_m.xpm0000777000175000017500000000212413120075106021756 0ustar00alisteralister00000000000000/* XPM */ static const char * declick_m_xpm[] = { "28 28 10 1", " c None", ". c #000000", "+ c #ADADB2", "@ c #0A0505", "# c #070709", "$ c #000002", "% c #020000", "& c #060608", "* c #262628", "= c #000005", " ", " ", " ", " ", " ............... ", " . ", " . . . ... ", " .. . . . . ", " . . . ... . ", " . . . . . . ", " .. . . ... ", " ", " ", " + ", " +@+ ", " +#$%+ + ", " +$+ $$+%$ +.+ ", " &%+ $$% +%+ +$+ ... ", " $+ $+% $% $% +.+. ", " *+ +$ $ $+ +% .. + ", " %% %% % % %+ +.+ ", " +$ %+ $+$ $.+.. ", " $+ +$+ =%% +$..+ ", " $$+$$+ +=+ ++++ ", " +$.$+ + + ", " ++$+ ", " + ", " "}; gtk-wave-cleaner-0.22-04/icons/declick_w.xcf0000777000175000017500000000345113120075106021750 0ustar00alisteralister00000000000000gimp xcf file00BBg>—" Pasted Layerÿ      "$"4 ÿÿÿÿ ÿüÿÿ ÿ ÿÿ ÿÿ ÿþÿÿÿþÿÿþÿÿÿÿÿÿÿþÿÿþÿþÿÿþÿÿÿ ÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿÿ þÿþÿÿþÿÿÿÿþÿÿþÿþÿÿþÿÿÿÿÿÿüÿÿþÿÿÿÿ ÿÿ ÿÿÿ ÿÿÿÿ  ÿÿÿÿ ÿÿÿ ÿþdÿ ÿûÓþ”ÿþÿüÑþdþÿÿüéþdÿÿüÓþ0ÿþÿüñþDþÿþÿüíúD þÿÿûöû0 ÿþÿ ûñû0 þÿþÿ ûöú þÿþÿ ûúõ0 úÿÿÿ û0ùõ úÿÿÿ û0úóþÿþÿüdúíþÿþÿûDþíþÿÿüDýÚÿþÿüdþèþÿþÿüdþÚþÿÿü~þÓÿÿùdÿ¯ÿÿþÿûœþ°ÿÿüœÿÿÿÿþD ÿÿÿ ÿÿÿÿ 00Colorÿ     è00ü00 …ÿ)ÿÿ$ÿÿ"þÿ ÿ ÿ ÿ.þÿþÿ ÿþÿ ÿþÿþÿ ÿüÿÿþÿÿþÿþÿüÿÿþÿþÿüÿÿþÿþÿþÿ þÿÿ+þÿþÿþÿ ÿÿ ÿ ÿ ÿ"ÿÿ%þÿÿ'ÿÿ)ÿ‡   ÿ)ÿ%ÿÿÿÿÿÿÿ ÿþÿÿÿ ÿü–»´ ÿÿþÿüüÿ ÿÿþÿüÿÿÿ þÿÿüÿÿÿ ÿÿýÿÿ þÿÿÿÿ&ÿÏ00Selection Mask0000% ÿgtk-wave-cleaner-0.22-04/icons/declick_w.xpm0000777000175000017500000000210413120075106021766 0ustar00alisteralister00000000000000/* XPM */ static const char * declick_w_xpm[] = { "28 28 9 1", " c None", ". c #000000", "+ c #F90707", "@ c #E88484", "# c #ADADB2", "$ c #070709", "% c #000002", "& c #020000", "* c #000005", " ", " ", " ", " ", " ", " ", " . ", " +@ . @+ ", " . @+@.@+@ ", " +@ . @+ @+.+@ ", " @+@.@+@ @+@ ", " @+.+@ @+.+@ ", " @+@ @+@. +@ ", " @+.+@ +@ . @+ ", " @+@. +@ #.# ", " +@ . @+ #$%&# ", " . # # %%#&% ", " . %%& #&# #%# ", " ..#... %#& %& %& ", " #.#.#. #% % %# #& .# ", " .#. . && & & &# #.# ", " ... . &# %#% %.#.. ", " #.# . #%# *&& #%..# ", " # %#%%# #*# #### ", " #%.%# # # ", " #### ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/decrackle.xcf0000777000175000017500000000347213120075106021744 0ustar00alisteralister00000000000000gimp xcf file00BB c:" Pasted Layerÿ       " "0 ÿÿÿÿ ÿüÿÿ ÿ ÿÿ ÿÿ ÿþÿÿÿþÿÿþÿÿÿÿÿÿÿþÿÿþÿþÿÿþÿÿÿ ÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿ ÿ þÿþÿÿ þÿþÿÿþÿÿÿÿþÿÿþÿþÿÿþÿÿÿÿÿÿüÿÿþÿÿÿÿ ÿÿ ÿÿÿ ÿÿÿÿ  ÿÿÿÿ ÿÿÿ ÿþdÿ ÿûÓþ”ÿþÿüÑþdþÿÿüéþdÿÿüÓþ0ÿþÿüñþDþÿþÿüíúD þÿÿûöû0 ÿþÿ ûñû0 þÿþÿ ûöú þÿþÿ ûúõ0 úÿÿÿ û0ùõ úÿÿÿ û0úóþÿþÿüdúíþÿþÿûDþíþÿÿüDýÚÿþÿüdþèþÿþÿüdþÚþÿÿü~þÓÿÿùdÿ¯ÿÿþÿûœþ°ÿÿüœÿÿÿÿþD ÿÿÿ ÿÿÿÿ 00Colorÿ     ä00ø00…ÿ)ÿÿ$ÿÿ"þÿ ÿ ÿ ÿ.þÿþÿ ÿþÿ ÿþÿþÿ ÿüÿÿþÿÿþÿþÿüÿÿ"þÿüÿÿ$þÿþÿ)ÿ+þÿ-þÿ þÿÿ þÿ ÿ ÿ"ÿÿ%þÿÿ'ÿÿ)ÿ‡  yþÿ,ÿ,üÿÿ+üÿÿþÿÿûÿÿÿþÿ ÿøÿÿÿÿþÿÿÿÿùÿÿÿþÿÿÿÿÿþÿ úÿåýÿÿÿÿü–»´ ûÿýÿÿÿþÿüüÿ úûýûÂÿÿþÿþÿüÿÿöÿÿÿPÿÿþÿÿüÿÿûÿ«ÿÿÿÿÿýÿüÿßÿýýÿþÿÿÿúýÿ‹þÿ÷ÿÖÿ®ÿþÿ÷þÿÿÿÿþÿøÿÀþÿÿã'ùÿÞÿÿ-þÿgtk-wave-cleaner-0.22-04/icons/decrackle.xpm0000777000175000017500000000212413120075106021761 0ustar00alisteralister00000000000000/* XPM */ static const char * decrackle_xpm[] = { "28 28 10 1", " c None", ". c #FF0519", "+ c #000000", "@ c #ADADB2", "# c #0A0505", "$ c #070709", "% c #000002", "& c #020000", "* c #060608", "= c #262628", " ", " ", " ", " ", " ", " ", " . . + . . ", " . + . . . . . . . ", " .+. + . . . .+. ", " + + .+. .+. .+. + ", " + + + @#@ + + ", " + + + @$%&@ + + ", " + + @%@ %%+&% + @+@ ", " +*&@ + %%& +&@+@%@ + +++ ", " + %@ + %@& + + %& + @+@+ ", " + =@ + @% % %@ + @& + ++ + ", " + && + && & & + &@+@+@ + ", " + @% + &@ %@% + %++++ + ", " + %@+@%@ +&& + @%++@ + ", " + %%+%%@ + @ + @+@@ .+.", ".+. @%+%@ + .+. + . ", " . @@%@ .+. . .+. . .", ". . .+. . . . . ", " . . . . . ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/estimate.xpm0000777000175000017500000000214213120075106021657 0ustar00alisteralister00000000000000/* XPM */ static const char * estimate_xpm[] = { "28 28 11 1", " c None", ". c #F90404", "+ c #ADADB2", "@ c #0A0505", "# c #070709", "$ c #000002", "% c #020000", "& c #000000", "* c #060608", "= c #262628", "- c #000005", " ", " ", " ", " ..... ", " . . ", " . ", " . ", " .. ", " . ", " . ", " ", " . ", " ", " + ", " +@+ ", " +#$%+ + ", " +$+ $$+%$ +&+ ", " *%+ $$% +%+ +$+ &&& ", " $+ $+% $% $% +&+& ", " =+ +$ $ $+ +% && + ", " %% %% % % %+ +&+ ", " +$ %+ $+$ $&+&& ", " $+ +$+ -%% +$&&+ ", " $$+$$+ +-+ ++++ ", " +$&$+ + + ", " ++$+ ", " + ", " "}; gtk-wave-cleaner-0.22-04/icons/filter.xpm0000777000175000017500000000173013120075106021333 0ustar00alisteralister00000000000000/* XPM */ static const char * filter_xpm[] = { "28 28 2 1", " c None", ". c #000000", " ", " ", " ", " ", " .....", " ..........", " ....... ", " .... ", " ... ", " ... ", " .. ", " .. ", " .. ", " .. ", " .. ", " .. ", " .. ", " . ..... ", "......... ", "... . ", " ", " ", " ", " ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/gtk-wave-cleaner.xpm0000777000175000017500000002073613120462625023217 0ustar00alisteralister00000000000000/* XPM */ static const char * gtk_wave_cleaner_xpm[] = { /* columns rows colors chars-per-pixel */ "48 48 239 2 ", " c black", ". c #010101", "X c #000002", "o c #020202", "O c gray1", "+ c #000006", "@ c #040404", "# c gray2", "$ c #060606", "% c #03030A", "& c gray3", "* c #090909", "= c gray4", "- c #0C0C0C", "; c gray5", ": c #0E0E0E", "> c gray6", ", c #100000", "< c #170707", "1 c #000010", "2 c #030312", "3 c #000017", "4 c #030317", "5 c #000018", "6 c #000019", "7 c #00001D", "8 c #101010", "9 c #111111", "0 c #131313", "q c gray8", "w c #151515", "e c #161616", "r c gray9", "t c #181818", "y c gray10", "u c #1B1B1B", "i c #19191C", "p c gray11", "a c #1E1E1E", "s c gray12", "d c #2E1E1E", "f c #000027", "g c #090922", "h c #00002C", "j c #0B0B28", "k c #07073A", "l c gray13", "z c #222222", "x c #232327", "c c gray14", "v c #252525", "b c gray15", "n c #272727", "m c #282828", "M c #2A2A2A", "N c gray17", "B c #2C2C2C", "V c gray18", "C c #2F2F2F", "Z c #313131", "A c #353535", "S c gray21", "D c #373737", "F c #35353B", "G c #393939", "H c #3A3A3A", "J c gray23", "K c #3F3F3F", "L c #4A0D0D", "P c #4A0F0F", "I c #630909", "U c #630C0C", "Y c #7D0B0B", "T c #7D0F0F", "R c #181842", "E c #000059", "W c #000075", "Q c #0E0E75", "! c #000079", "~ c gray25", "^ c #414141", "/ c gray26", "( c #434343", ") c #444444", "_ c gray27", "` c #464646", "' c gray28", "] c #43434A", "[ c #484848", "{ c #494949", "} c gray29", "| c gray30", " . c #4E4E4E", ".. c gray31", "X. c #505050", "o. c gray32", "O. c #515157", "+. c gray33", "@. c #565656", "#. c gray34", "$. c #585858", "%. c #5B5B5B", "&. c gray36", "*. c #5D5D5D", "=. c #5F5F5F", "-. c #606060", ";. c gray38", ":. c #626262", ">. c gray39", ",. c #656565", "<. c #60606A", "1. c #686868", "2. c DimGray", "3. c #6C6C6C", "4. c #6F6F6F", "5. c #736363", "6. c gray44", "7. c #717171", "8. c #727272", "9. c #767676", "0. c #7C7575", "q. c gray47", "w. c #797979", "e. c #7C7C7C", "r. c gray49", "t. c #E80000", "y. c #E90101", "u. c red", "i. c #F30B0B", "p. c #E80017", "a. c #EB0317", "s. c #F81010", "d. c #FD1517", "f. c #FF1717", "g. c #000096", "h. c #0000A4", "j. c #0000B0", "k. c #1717BD", "l. c #1818C4", "z. c #0000DD", "x. c #0000EB", "c. c #1000EF", "v. c #1B1BE0", "b. c #1C1CE9", "n. c #1D1DEB", "m. c #0000F8", "M. c #0000FA", "N. c #0000FB", "B. c blue", "V. c #1E1EF4", "C. c #1F1FFF", "Z. c #2D1DEF", "A. c gray52", "S. c gray53", "D. c #898989", "F. c gray55", "G. c #8E8E8E", "H. c gray56", "J. c #909090", "K. c #9B9B9B", "L. c gray62", "P. c #9797A7", "I. c #9A9AAA", "U. c gray64", "Y. c #A4A4A4", "T. c gray65", "R. c #A7A7A7", "E. c gray66", "W. c #A9A9A9", "Q. c #AAAAAA", "!. c #ACACAC", "~. c #AEAEAE", "^. c #AFAFAF", "/. c #B1B1B1", "(. c gray70", "). c #B4B4B4", "_. c gray71", "`. c #B9B9B9", "'. c #BBBBBB", "]. c gray", "[. c gray75", "{. c #CCBCBC", "}. c #B0B0C2", "|. c #B1B1C3", " X c #C0C0C0", ".X c #C1C1C1", "XX c #C3C3C3", "oX c gray77", "OX c #C5C5C5", "+X c #C6C6C6", "@X c gray78", "#X c #C8C8C8", "$X c gray79", "%X c #CBCBCB", "&X c gray80", "*X c #CECECE", "=X c gray81", "-X c #DECECE", ";X c #C6C6DB", ":X c #C7C7DC", ">X c #D0D0D0", ",X c gray82", ".0.T U L V ; # MXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMX", "MXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMX # @ @ MXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMXMX" }; gtk-wave-cleaner-0.22-04/icons/noise_sample.xpm0000777000175000017500000000207013120075106022522 0ustar00alisteralister00000000000000/* XPM */ static const char * noise_sample_xpm[] = { "28 28 8 1", " c None", ". c #000000", "+ c #FFFFFF", "@ c #ADADB2", "# c #0A0505", "$ c #070709", "% c #000002", "& c #020000", " ", " ", " ... ", " ..... ", " ..... ", " ..... ", " ....+... ", " .... ", " .+... ", " .+++.. ", " .+++. . ", " .+++. ", " .+++. ", " .+.+. ", " .++. ", " ... @ ", " @#@ ", " @ @$%&@ @ ", " @..@ %%@&% @.@ ", " .@ . @&@ @%@ ... ", " . .@ .& %& @.@. ", " @. @.@ .@ @& .. @ ", " @@. .. .. &@ @.@ ", " ..@ @% @ %.@.. ", " @ @%..@ ", " @@@@ ", " @ ", " "}; gtk-wave-cleaner-0.22-04/icons/pinknoise.xpm0000777000175000017500000000223713120075106022050 0ustar00alisteralister00000000000000/* XPM */ static const char * pinknoise_xpm[] = { "28 28 15 1", " c None", ". c #000000", "+ c #050DFC", "@ c #0466F9", "# c #E900FF", "$ c #CF05FC", "% c #FF0000", "& c #F90F07", "* c #FF1000", "= c #FC7005", "- c #FFBE00", "; c #FCA505", "> c #F7BB07", ", c #FFFA00", "' c #FCEB05", ".+..+.....+.................", "..+..+.@.@.+..+..@.@.+...+..", ".+..+..+..+..@.++@.@..+@..+.", "..@+.@.@+..@..+..@...+.@@+..", ".+..+.@+..+.@@..+@.@.+.@@...", "@@..@@....@+.@+..@..@.+@@@+.", ".+@.+..@+.+..@@.@@+@.+.@...+", "...@.+...+..@.@..+@...+...+.", ".@..@.@@+..+..+.@..+...@.+..", "..+..+.@.@..+..+.@..+@+...+.", "...++......+..+....+...+.+..", "..+..#..$..@...@.$..#$+.$.#.", ".#$.#.#..$..$##...$...$..$..", "...$%$..$#$..$.#.$$.#$.%$%#.", ".#$...$%#..$$%#$.%.$..$.$...", "..$.&$....$.#...$.$..$.$.$..", ".&.$.&&..&.*..&$&.&.*.*.&.&.", "..&.&..&..&.*..&.&.&..&*.&.&", ".*.*&.=.*&=.*=&=&.&=.*.=&.&.", "..=.=&.-=.*=*.=*;...=.;.==..", ".=;.-;=..==..;;=.;.=;;.=;.=.", "...;=.;.=;..;..>;.>..>-..;..", ".>->.-...>->..-.-..>;->.>.>.", "..>.>.>>.,>->>.>>.>>.>.>.>.>", ".>.',>.'>>''.>>'.>'>>'>.>'>.", "..>.'..>',.''>..'.>',>'>.>'.", ".,.',.,'..''.,.',.'.,'.,.',.", "............................"}; gtk-wave-cleaner-0.22-04/icons/remove_noise.xpm0000777000175000017500000000273513120075106022546 0ustar00alisteralister00000000000000/* XPM */ static const char * remove_noise_xpm[] = { "28 28 36 1", " c None", ". c #F90404", "+ c #F71F1F", "@ c #F81616", "# c #E82C2C", "$ c #F37272", "% c #F74343", "& c #EF0404", "* c #F80404", "= c #F90707", "- c #F83838", "; c #F82323", "> c #F90505", ", c #F90808", "' c #F5AAAA", ") c #F47F7F", "! c #F62323", "~ c #EFA9A9", "{ c #F5D7D7", "] c #F6E2E2", "^ c #F6D5D5", "/ c #F6C2C2", "( c #F6CCCC", "_ c #F6CECE", ": c #F6BFBF", "< c #F6ADAD", "[ c #F79A9A", "} c #F79393", "| c #F91414", "1 c #F6D8D8", "2 c #F7D3D3", "3 c #F81010", "4 c #F7C7C7", "5 c #F91111", "6 c #F90A0A", "7 c #000000", " ", " ", " ", " . ", " .. ", " +@. ", " #$%& ", " **..=-;>,')!. ", " .~{]^/(_:<[}.. ", " ......=|.12*. ", " 345. ", " .6. ", " .. ", " . ", " ", " 7 7 ", " 777 777 7 ", " 7 7 7 7 77 7 7 ", " 7 7 7 7 7 7 7 777 777 77 ", " 7 7 7 7 7 7 7 7 7 7 7 7 ", " 777 7 7 777 777 777 777 ", " 7 7 7 7 7 7 7 ", " 777 ", " 7 ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/select_all.xpm0000777000175000017500000000201113120075106022146 0ustar00alisteralister00000000000000/* XPM */ static const char * select_all_xpm[] = { "28 28 5 1", " c None", ". c #000000", "+ c #5B5B5E", "@ c #A3A1A1", "# c #FFFFFF", " ", " ", " .++++++++++++++++++++++++. ", " .++++++++++++++++++++++++. ", " .++++++++++++++++++++++++. ", " .++++++++++++++++++++++++. ", " .++++++++++++++++++++++++. ", " .+++++++++++++@++++++++++. ", " .+++++++@++++@#@+++++++@+. ", " .++++++@@@++@###@+++++@@@. ", " .@+++++@#@+@##@##++++@@#@. ", " .#@++++###+@#@@@#@@++@###. ", " .#@+++@#@#+##@+@##@++@#@#. ", " .#@+++@#@#+#@@+@@#@+@##@+. ", " .##+++##@#+#@++@@#@@@#@++. ", " .@#++@#@@#@#@+++@##@##@++. ", " .+#@+@#@@###@+++@@###@+++. ", " .+##@##@+@#@@++++@@@@++++. ", " .+@###@+++@++++++++@+++++. ", " .+@@#@+++++++++++++++++++. ", " .++@@@+++++++++++++++++++. ", " .++++++++++++++++++++++++. ", " .++++++++++++++++++++++++. ", " .++++++++++++++++++++++++. ", " .++++++++++++++++++++++++. ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/silence.xpm0000777000175000017500000000176513120075106021500 0ustar00alisteralister00000000000000/* XPM */ static const char * silence_xpm[] = { "28 28 4 1", " c None", ". c #262628", "X c black", "o c #F90404", " ", " ", " ", " ", " ", " ", " ", " ", " .. .. ", " .. .. ", " .. .. ", " X .. ..X X ", " X XXX ..ooooo..XX XXX XX ", " X X X ..ooooo.. X X X X ", " XXX XX.. .. XXX XXX ", " X X.. .. X X ", " .. .. ", " .. .. ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/spectral.xpm0000777000175000017500000000223613120075106021665 0ustar00alisteralister00000000000000/* XPM */ static const char * spectral_xpm[] = { "28 28 15 1", " c None", ". c #A09D9D", "+ c #000000", "@ c #9B9898", "# c #0A0505", "$ c #070709", "% c #000002", "& c #020000", "* c #091DF7", "= c #262628", "- c #1909F7", "; c #F72D09", "> c #F72509", ", c #F7BB09", "' c #F7F709", " ", " ", " ", " . ++ ", " @#. +++ ", " . .$%&. +++++ ", " .%. %% &% ++++++ ", " & %%& .&. .% +++++++ ", " % % & %& ++*+++++ ", " =. .% % %. +++*+*+*+ ", " && && & & ++++-+-+-+ ", " .% & %.% +++++-+-+-+ ", " %. .% &&& ++++-+-+-+;+ ", " %% %% .&. +++++-+-+-+;+ ", " .%+%. . ++++-+-+-+;+;+ ", " % +++-+-+-+;+;+;+ ", " ++++-+;+-+;+;+;+ ", " +++++-+;+-+;+;+>+ ", " ++++-+*+;+;+;+;+>+ ", " +++-+-+*+;+;+;+>+,+ ", " ++>+>+;+>+>+>+>+,+,+ ", " +++,+,+>+,+,+,+,+,+,+ ", " ++,+,+,+,+,+'+,+,+,+'+ ", " +++'+,+'+,+'+'+,+,+'+'+ ", " ++,+'+'+'+'+'+'+,+'+'+'+ ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/start.xcf0000777000175000017500000000056113120075106021160 0ustar00alisteralister00000000000000gimp xcf fileBB_Colorÿ      -äääZþÿÿÿÿÿ ÿ ÿ ÿ ÿ ÿÿÿþÿ~gtk-wave-cleaner-0.22-04/icons/start.xpm0000777000175000017500000000653313120075106021211 0ustar00alisteralister00000000000000/* XPM */ static const char * start_xpm[] = { "28 28 105 2", " c None", ". c #000000", "+ c #302C2C", "@ c #181717", "# c #111111", "$ c #322E2E", "% c #393535", "& c #1D1D1D", "* c #121212", "= c #373333", "- c #5F5A5A", "; c #474343", "> c #2A2626", ", c #0F0E0E", "' c #363232", ") c #777070", "! c #635E5E", "~ c #272424", "{ c #040303", "] c #333030", "^ c #7D7575", "/ c #7F7777", "( c #605A5A", "_ c #484242", ": c #151515", "< c #030303", "[ c #312D2D", "} c #746D6D", "| c #6C6565", "1 c #575151", "2 c #433F3F", "3 c #0B0A0A", "4 c #2D2929", "5 c #655F5F", "6 c #6F6868", "7 c #6B6565", "8 c #5C5757", "9 c #4A4444", "0 c #242323", "a c #101010", "b c #010101", "c c #272323", "d c #524C4C", "e c #605B5B", "f c #686363", "g c #656060", "h c #595454", "i c #423D3D", "j c #0F0F0F", "k c #020202", "l c #1D1919", "m c #413C3C", "n c #544F4F", "o c #645F5F", "p c #4A4545", "q c #1A1717", "r c #342F2F", "s c #393434", "t c #433E3E", "u c #403C3C", "v c #3F3A3A", "w c #3D3838", "x c #312C2C", "y c #251F1F", "z c #171313", "A c #120F0F", "B c #1F1B1B", "C c #1E1A1A", "D c #211D1D", "E c #252020", "F c #231F1F", "G c #2E2A2A", "H c #0F0C0C", "I c #181414", "J c #141010", "K c #110D0D", "L c #130F0F", "M c #151212", "N c #1D1B1B", "O c #110E0E", "P c #151111", "Q c #0F0B0B", "R c #090707", "S c #0A0808", "T c #0B0909", "U c #131010", "V c #0B0808", "W c #060404", "X c #050303", "Y c #060303", "Z c #121010", "` c #100E0E", " . c #080505", ".. c #030101", "+. c #030202", "@. c #040202", "#. c #110F0F", "$. c #0D0C0C", "%. c #020101", "&. c #010000", "*. c #0A0909", "=. c #080707", "-. c #060606", ";. c #0C0A0A", ">. c #070707", " ", " ", " ", " ", " . . ", " + @ # ", " $ % & * ", " = - ; > , ", " ' ) ! ; ~ { ", " ] ^ / ( _ : < ", " [ } / | 1 2 * 3 ", " 4 5 6 7 8 9 0 a b ", " c d e f g h i 5 j k ", " l m n ! o ! 5 p 5 # . ", " q r s t _ u v w x y z ", " A B C D E D F G [ E ", " H I J K L L M q N ", " O P Q R R R S T ", " U J V W X Y W ", " Z ` ...+.@. ", " #.$.X %.&. ", " , *.{ k ", " $.=.-. ", " ;.>. ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/stop.xpm0000777000175000017500000000376113120075106021041 0ustar00alisteralister00000000000000/* XPM */ static const char * stop_xpm[] = { "28 28 72 1", " c None", ". c #000000", "+ c #020202", "@ c #1F1F1F", "# c #A1A1A1", "$ c #A0A0A0", "% c #939393", "& c #696869", "* c #0A0A08", "= c #313131", "- c #A3A3A3", "; c #0D0D0D", "> c #0F0F0F", ", c #BEBDBD", "' c #272727", ") c #9E9E9E", "! c #070707", "~ c #050505", "{ c #010101", "] c #2D2C2C", "^ c #0B0B0B", "/ c #080808", "( c #030303", "_ c #BBBABA", ": c #060606", "< c #C3C1C1", "[ c #302E2E", "} c #B8B7B7", "| c #312F2F", "1 c #B8B6B6", "2 c #2F2E2E", "3 c #302F2F", "4 c #C5C3C3", "5 c #C4C2C2", "6 c #1A1A1A", "7 c #BEBCBC", "8 c #090909", "9 c #B3B2B2", "0 c #AFADAD", "a c #313030", "b c #B4B3B3", "c c #2E2E2E", "d c #A8A7A7", "e c #252424", "f c #161616", "g c #0E0E0E", "h c #0C0C0C", "i c #141414", "j c #101010", "k c #B4B2B2", "l c #3A3939", "m c #292929", "n c #8F8F8F", "o c #BAB8B8", "p c #C8C7C7", "q c #CBC9C9", "r c #CAC9C9", "s c #C6C5C5", "t c #C4C3C3", "u c #C5C4C4", "v c #C2C1C1", "w c #C6C4C4", "x c #9F9C9C", "y c #100F0F", "z c #222121", "A c #262525", "B c #272626", "C c #292828", "D c #2B2A2A", "E c #262424", "F c #282727", "G c #292727", " ", " ", " ", " .................+ ", " @##############$%&* ", " =-;;;;;;;;;;;;;>+,' ", " =)..!~~~~{.....{+,] ", " =)..^////{...({{+_] ", " =)...........:{.+<[ ", " =)..!........:{.+}| ", " =)...........:{.+12 ", " =)...........:{{+,3 ", " =)...........:{.+43 ", " =)...........:;.+53 ", " =)......{{{{+!6.+7[ ", " =)...8.:^^^^^>@.+92 ", " =)..............+0a ", " =).............{+ba ", " cdefg;;;hhh;gigj+kl ", " mnopqqrstuv4wvwrkx+ ", " +yzABBBACDCeEFBFBG ", " ", " ", " ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/toolbar.xcf0000777000175000017500000003245213120075106021471 0ustar00alisteralister00000000000000gimp xcf fileBBÖ/ gimp-commentCreated with The GIMPº' ? °¸HÖ%~.Ü4S Zoom selectÿ      bv†IÉþÌþɺºþÉüɺ ‘‘ý Éûɺº ‘‘ü ºÉúÉɺ ‘‘û ººòÉ¿« ‘‘* ¯ºº òºËr ‘‘‘ fɺ òɺ©@ ‘9‘‘ ú òɺɑ ‘‘‘ ºÉºüŸ ‘‘ü ºûÉºÉ ‘‘ü ººüɺ ‘‘ý ÉþɺºþÉüɺÉ*þäþä ûääþä þÌ þÌþÌ  þÌ >IÊþÇþʼ¼þÊüʼ””ýÊûʼ¼””ü¼ÊúÊʼ””û¼¼òʾ©””*¯¼¼ ò¼Êq”””fʼ òʼ¨@”8””Á¼ òʼÊ”””¼Ê¼ü””ü¼ûʼÊ””ü¼¼üʼ””ýÊþʼ¼þÊüʼÊ*þâþâ ûââþâ þÇ þÇþÇ  þÇ >IØþÇþØÝÝþØüØÝùØØýùØûØÝÝùØØüùÝØúØØÝùØØûùÝÝòؾ©ùØØ*ù¯ÝÝ òÝÊqùØØØùfØÝ òØÝ¨@ùØ8ØØùÁÝ òØÝØùØØØùÝØÝüùØØüùÝûØÝØùØØüùÝÝüØÝùØØýùØþØÝÝþØüØÝØ*þâþâÖ ûââÖþâÖ þÇÖ þÇÖþÇ Ö þÇ ÖÖ>,ÿÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ýÿÿ ÿ ÿþÿÿ ÿÿÿÿþÿ ÿþÿ ÿÿ ÿ þÿþÿ“ Zoom outÿ      ÌàðIüÌåÌþÌååþÌþÌååäåþÌþÌååúÙ¿ÚåÌóÌÍÞââßÕ¥áÝòÌ¿«ÔÙ®*¯âÌ òåËr’´©¯fÒÜ òåÖ©@©9¾ÅÃã òÌäÓ‘“¶ËŒÖÌôáÔŸ`½Ë¹ÓôÌãÕÉÒÏÏßÕáÕþÌääúåàåäÌþÌååþÌüÌåÌ*þåþåþåþå þÌ þÌþÌþÌiIüÇãÇþÇããþÇþÇããâãþÇþÇããú×½ØãÇóËÌÜààÝÓ£ßÛòǾ©Ò׬*¯àÇ òãÊq²¨®fÐÚ òãÔ¨@§8¼ÄÁá òÇâÑ’µÊ‹ÔÇôßÒ_‹»É¸ÑôÇâÔÇÐÍÍÝÓßÔöÇãââãÞãâÇþÇããþÇüÇãÇ*þãþãþãþã þÇ þÇþÇþÇiIüÇãÇþÇããþÇþÇããâãþÇþÇããú×½ØãÇóËÌÜààÝÓ£ßÛòǾ©Ò׬*¯àÇ òãÊq²¨®fÐÚ òãÔ¨@§8¼ÄÁá òÇâÑ’µÊ‹ÔÇôßÒ_‹»É¸ÑôÇâÔÇÐÍÍÝÓßÔöÇãââãÞãâÇþÇããþÇüÇãÇ*þãþãþãþãÖ þÇÖ þÇÖþÇþÇi,ÿÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ýÿÿ ÿ ÿþÿÿ ÿÿÿÿÿÿÿý·ÿÿþ þ Zoom inÿ      ã ÷ IüÌåÌþÌååþÌþÌååäåþÌþÌååúÙ¿ÚåÌóÌÍÞââßÕ¥áÝòÌ¿«ÔÙ®*¯âÌ òåËr’´©¯fÒÜ òåÖ©@©9¾ÅÃã òÌäÓ‘“¶ËŒÖÌôáÔŸ`½Ë¹ÓôÌãÕÉÒÏÏßÕáÕþÌääúåàåäÌþÌååþÌüÌåÌ*þäþä þä þä þÌ þÌþÌ  þÌ >IüÇãÇþÇããþÇþÇããâãþÇþÇããú×½ØãÇóËÌÜààÝÓ£ßÛòǾ©Ò׬*¯àÇ òãÊq²¨®fÐÚ òãÔ¨@§8¼ÄÁá òÇâÑ’µÊ‹ÔÇôßÒ_‹»É¸ÑôÇâÔÇÐÍÍÝÓßÔöÇãââãÞãâÇþÇããþÇüÇãÇ*þâþâ þâ þâ þÇ þÇþÇ  þÇ >IüÇãÇþÇããþÇþÇããâãþÇþÇããú×½ØãÇóËÌÜààÝÓ£ßÛòǾ©Ò׬*¯àÇ òãÊq²¨®fÐÚ òãÔ¨@§8¼ÄÁá òÇâÑ’µÊ‹ÔÇôßÒ_‹»É¸ÑôÇâÔÇÐÍÍÝÓßÔöÇãââãÞãâÇþÇããþÇüÇãÇ*þâþâÖ þâ ÖþâÖ þÇÖ þÇÖþÇ Ö þÇ ÖÖ>,ÿÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ÿ ýÿÿ ÿ ÿþÿÿ ÿÿÿÿþÿ ÿþÿ ÿÿ üÿÿ þÿ þ þÿ%þþý3 View allÿ     Uiyþ‘‘þO‘‘þO‘‘ûOO‘‘ûOO‘‘ûOO‘‘ûOO‘ ‘þ­‘‘ûOO‘‘þk‘‘ü­ ­‘‘ûOO‘‘õW­k‘‘­­‘‘öW­kO¥Okk‘‘õ­­‘k­‘‘õk­­O­‘‘ò‘­­k­­k‘‘kùOO­‘‘ík­‘W‘Wk‘‘­­üO&­‘‘ì­k‘­W‘W­k‘Wk­üO‘‘Þk‘k‘‘Wk­W­­‘‘OO­‘‘k­k­k‘‘æk­k‘‘OrO‘­‘­­kk‘‘ýk­þ­‘‘ïOO‘­­‘­­k‘‘þk­­‘ùOO‘­þ­‘‘þ­‘‘þ­‘‘öOO‘­­­‘‘öO‘O‘‘k­k‘‘ûOO‘‘ûOO‘‘ûOO‘‘ûOO‘‘þOrNþ””þT””þT””ûTT””ûTT””ûTT””ûTT” ”þ­””ûTT””þq””ü­­””ûTT””õ\­q””­­””ö\­qT¤Tqq””õ­­”q­””õq­­T­””ó”­­q­­q””qùTT­””íq­”\”\q””­­üT&­””ì­q”­\”\­q”\q­üT””Þq”q””\q­\­­””TT­””q­q­q””êq­q””TrT”­”­­qþq””ýq­þ­””ïTT”­­”­­q””þq­­”ùTT”­þ­””þ­””þ­””öTT”­­­””öT”T””q­q””ûTT””ûTT””ûTT””ûTT””þTrNþØØþŒØØþŒØØûŒŒØØûŒŒØØûŒŒØØûŒŒØ Øþ²ØØûŒŒØØþ²ØØü²²ØØûŒŒØØõ“²²ØØ² ²ØØö“²²Œ¤Œ²²ØØõ²²Ø²²ØØ²÷²Œ²ØØûز²²ù²²ØØ²ùŒŒ²ØØæ²²Ø“Ø“²ØØ²²Œ(²ØØæ²²Ø²“Ø“²²Ø“²²ŒØØÞ²Ø²ØØ“²²“²²ØØŒŒ²ØØ²²²²²ØØæ²²²ØØŒuŒØ²Ø²²²²ØØ²û²ØØïŒŒØ²²Ø²²²ØØ²ØõŒŒØ²²ØØþ²ØØþ²ØØöŒŒØ²²²ØØùŒØŒØØ²²ØûŒŒØØûŒŒØØûŒŒØØûŒŒØØþŒuN©þÿûÿÿ þÿûÿÿ ÿûÿÿþÿúÿþþÿÿùÿÿ ÿÿúþÔÿáîÿÿÿþÿÿûÿÓÿÿÿÿüÿÿýùÿÿÿÿúÿÿÿÿÿúÿÿÿÿÿûÿÿÿþÿÿüÿÿÿÿþÿÿÿ÷ÿÿÿÿÿÿþÿÿýÿúÿÿúÿÿÿÿûýÿÿÿÿÿúÿÿÿÿýþÿþÿþÿöÿÿÿÿîÿûÿÿþÿûÿÿþÿ¨ Select allÿ      g{‹þ‘‘[[[[[ [þ£[[ý[[þ£[[ü£ÿ£[[ý£[[£[þ£ÿÿþ£[[£ü¥£[[õ£ÿ£[£ÿÿ£ÿÿ[[£ýÿ£ýÿ£[[ÿü[£ÿ££ùÿ££[[£ÿÿýÿ£[[ì£ÿ£ÿ[ÿÿ£[£ÿÿ£[[£ÿ£ÿýÿ£[[ì£ÿ£ÿ[ÿ££[££ÿ£[£ÿÿ£[ÿ[ÿõ£ÿ[ÿ£[[££ÿ££ûÿ£[[ó£ÿ[[£ÿ££ÿ£ÿ£[[ê£ÿÿ£ÿÿ£[[r[ÿ£[£ÿ££ÿÿþ£[[£ÿþ£[[ó[ÿÿ£ÿÿ£[£ÿ££[[£[ý[£ÿÿþ£[[þ£[[þ£[[ú[££ÿ£[[ù‘[[££[[[[[rNþ””[[[[[ [þ¡[[[þ¡[[ü¡ÿ¡[[ý¡[[¡[þ¡ÿÿþ¡[[¡ü¤¡[[õ¡ÿ¡[¡ÿÿ¡ÿÿ[[¡ýÿ¡ýÿ¡[[ÿü[¡ÿ¡¡ùÿ¡¡[[¡ÿÿýÿ¡[[ì¡ÿ¡ÿ[ÿÿ¡[¡ÿÿ¡[[¡ÿ¡ÿýÿ¡[[ì¡ÿ¡ÿ[ÿ¡¡[¡¡ÿ¡[¡ÿÿ¡[ÿ[ÿõ¡ÿ[ÿ¡[[¡¡ÿ¡¡ûÿ¡[[ó¡ÿ[[¡ÿ¡¡ÿ¡ÿ¡[[ê¡ÿÿ¡ÿÿ¡[[r[ÿ¡[¡ÿ¡¡ÿÿþ¡[[¡ÿþ¡[[ó[ÿÿ¡ÿÿ¡[¡ÿ¡¡[[¡[ý[¡ÿÿþ¡[[þ¡[[þ¡[[ú[¡¡ÿ¡[[ù”[[¡¡[[[[[rNþØØ^^^^^ ^þ¡^^^þ¡^^ü¡ÿ¡^^ù¡^^^¡^þ¡ÿÿþ¡^^¡ú¤¡^^õ¡ÿ¡^¡ÿÿ¡ÿÿ^^¡÷ÿ¡ÿ¡^^ÿü^¡ÿ¡¡ùÿ¡¡^^¡ÿÿùÿ¡^^æ¡ÿ¡ÿ^ÿÿ¡^¡ÿÿ¡^^¡ÿ¡ÿÿ¡^^æ¡ÿ¡ÿ^ÿ¡¡^¡¡ÿ¡^¡ÿÿ¡^ÿÿ^^ÿõ¡ÿ^ÿ¡^^¡¡ÿ¡¡ûÿ¡^^ó¡ÿ^^¡ÿ¡¡ÿ¡ÿ¡^^ê¡ÿÿ¡ÿÿ¡^^u^ÿ¡^¡ÿ¡¡ÿÿþ¡^^¡ÿþ¡^^ó^ÿÿ¡ÿÿ¡^¡ÿ¡¡^^¡^ý^¡ÿÿþ¡^^þ¡^^þ¡^^ú^¡¡ÿ¡^^ùØ^^¡¡^^^^^uN8ÿÿÿÿÿÿÿÿý ÿÿÿÿÿÿÿýÿÿÿÿÿÿÿÿÿÿN New Layer#2ÿ     †ð–ü0û29ú7_G*ù6wcG'ø3}`H÷1tlWC ö-eok\J$õ'R`heYBeõATcdceJeô49CH@?=1%õ!%!#.1%öü  ý ø ùú û ü ý ~–ü,û.5ú3ZC&ù2p^C$ø0uwZB÷-mweQ? ö)_heWD#õ#L[c`T=_õB<:8,õ *- ö  ü ý úùû û ü ý ~–ü,û.5ú3ZC&ù2p^C$ø0uwZB÷-mweQ? ö)_heWD#õ#L[c`T=_õB<:8,õ *- ö  ü ý úùû û ü ý ~yÿÿÿÿÿÿÿÿ ÿ ÿ ÿ ÿÿÿÿÿÿÿÿÿ€ New Layerÿ     q| QþTþþTþ¡ ¡ø “i Müÿ1£ ø¾' Tùÿ1žþø¾-[ùÿ1ž þö»-]üÿ1ž öÃ0]ùÿ1žö¸1üÿ1ž ö¸/ üÿ1ž ö¾0'üÿ1ž öÅ0-üÿ1ž ö Ä0-üÿ1žö¾00üÿ1žü   ÷³/1üÿ1ž ú¯1/üÿ1ž ù´100ùÿ.¨%   ô ´:K0èÿ)ºÈËËÊÆÄÅÂÅÆÂÆÊ´ŸS0úÿ"&''ð&)+)%&('(')K0úÿ"&''ð&)+)%&('('):S/èÿ)ºÈËËÊÆÄÅÂÅÆÂÆÊ´Ÿ7¯10úï"&''ð&)+)%&('(')A´1Kõ¼Ú.¨%   ö h´:Sè` )ºÈËËÊÆÄÅÂÅÆÂÆÊ´Ÿ1Mû"&''ò&)+)%&('(') QþRþþRþ¡ ¡ø “h Küÿ1£ ø½' Rùÿ1žþø½,Yùÿ1ž þöº,Züÿ1ž öÁ.Zùÿ1žö·/üÿ1ž ö¶. üÿ1ž ö½/'üÿ1ž öÃ/,üÿ1ž ö Â/,üÿ1žö¼..üÿ1žü   ÷²./üÿ1ž ú­0.üÿ1ž ù³0//ùÿ.§$   ô ²9J/úÿ)¸ÇÉÉðÅÃÄÁÃÄÁÄɲœQ/úÿ!%&&ð%(*($$'&'&'J.úÿ!%&&ð%(*($$'&'&'9Q.úÿ)¸ÇÉÉðÅÃÄÁÃÄÁÄɲœ7­0/úï!%&&ð%(*($$'&'&'A³0Jõ¼Ú.§$   ö h²9Qø] )¸ÇÉÉòÅÃÄÁÃÄÁÄɲœ/Kû!%&&ò%(*($$'&'&' QþRþþRþ¡ ¡ø “iKüÿ1£ ø½'Rùÿ1žþø½,Yùÿ1ž þöº,Züÿ1ž öÁ.Zùÿ1žö·/üÿ1ž ö¶.üÿ1ž ö½/'üÿ1ž öÃ/,üÿ1ž ö Â/,üÿ1žö¼..üÿ1žü   ÷²./üÿ1ž ú­0.üÿ1ž ù³0//ùÿ.§$   ô ²9J/úÿ)¸ÇÉÉðÅÃÄÁÃÄÁÄɲœQ/úÿ!%&&ð%(*($$'&'&'J.úÿ!%&&ð%(*($$'&'&'9Q.úÿ)¸ÇÉÉðÅÃÄÁÃÄÁÄɲœ7­0/úï!%&&ð%(*($$'&'&'A³0Jõ¼Ú.§$   ö h²9Qø] )¸ÇÉÉòÅÃÄÁÃÄÁÄɲœ/Kû!%&&ò%(*($$'&'&' Qþÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉ Switch viewÿ     E&&&:&J*þ ü›   þþ ú   û¥ mþ ü›   õ     û¥ mü  üü ö    ú  ö›rþ ú & õ    î r  õ h þû  ñ ro  ó÷h&ü  ò÷o ú  ñ÷÷÷ þé÷÷÷÷rr  rï÷÷÷÷÷hr î÷÷÷÷÷o þ ð ÷÷÷÷÷÷ è ÷÷÷÷÷÷r ì÷÷÷÷÷÷÷÷÷÷ì÷÷÷÷÷÷÷÷÷÷ç÷÷÷÷÷÷÷÷÷÷÷rê÷÷÷÷÷÷÷÷÷÷÷è÷÷÷÷÷÷÷÷÷÷÷÷æ÷÷÷÷÷÷÷÷÷÷÷÷÷æ÷÷÷÷÷÷÷÷÷÷÷÷÷ç÷÷÷÷÷÷÷÷÷÷÷÷÷*þü˜þúû¤mþü˜õû¤müüøü ý˜rþú&÷÷rü õ hûñ ro ó - h&üò - oþþñ --- é ----rrrï - ----hr î - --%%oþð ----%% è ---%»%rì%%-%%%%»»%ì»»%»»»»»»»ç»»»»»÷»»»÷»rê÷»÷»÷÷»»÷÷»è»÷÷÷÷÷÷»÷÷÷÷æ»÷÷÷÷÷÷÷÷÷÷÷÷æ÷÷÷÷÷÷÷÷÷÷÷÷÷ç÷÷÷÷÷÷÷÷÷÷÷÷÷%þþþü˜ö í¤p˜õ ó¤pý úøû÷þù˜uþ÷ú÷(ö î÷÷÷÷uõ÷÷÷÷kþûñ÷÷÷÷uró÷÷÷ ÷k(ûî÷÷÷ ÷rþñ÷÷÷ þè÷÷÷ uuuï÷ ÷ kuê÷ ÷ rð÷÷ è÷÷÷ u ì ì ç uê è æ æ ç þ þUþ%þþªÿ þüöÿÿû¬ÿÿþÿúÿþþÿÿÿû/ýÿÿúþÔáîÿþÿÿþÿÿúÿÎÿÿþÿôÿÿÿÿÿÿÿÿúÿÿÿÿÿÿûÿÿ ÿÿüÿÿÿ ÿÿúÿÿÿÿ ÿÿúýÿÿÿþÿ ÿÿýþÿýÿÿ ÿþîÿþüÿÿþÿ ÿÿÿÿÿÿÿ( Basic waveformÿ     /‡/›/«Óþ ü  ü›  ûþ ú  þ û¥ mü  þü  ýö    û  örü  ý& þ ù r? þ ûø    þ þþ þ þrü  ýE ý þhü   û  üo þ þ þ7þû  ùr  ý Sþrþr þr'rNÓþþ ü˜þúþû¤mü üþøû þrüý&þúr?þùþþþþrüýEþþhüûüoþþþ7ûùrýSþrþr þr'rNvþþ8þþþ þü˜ þþú ï¤pýøòúõuõ(üúuBüùüüüõuùHýkûûørþû: ûùu þ ýVþuþu þu'uNvþþ8þþÿþüöÿÿ þÿþÿúÿþþÿÿþÿ÷ ÿÿÿÿúþÔáîÿÿýÿÿþÿÿûÿÓÿÿÿôÿÿÿÿùÿÿÿÿúÿÿÿÿÿüÿÿÿÿûÿÿÿþÿÿÿüÿÿÿÿõÿÿÿÿÿÿýÿúÿÿöÿÿýÿÿÿÿýÿÿýþÿþÿþîþ<þþ þ'N Backgroundÿ     4ú55ÁÁÁgtk-wave-cleaner-0.22-04/icons/toolbar1.xcf0000777000175000017500000004120013120075106021541 0ustar00alisteralister00000000000000gimp xcf fileBBŠ/ gimp-commentCreated with The GIMPºG ~€Ž&Ø.½6m:µA© Scissorsÿ     _sƒ¢ýˆºþÑèè ýˆº þÑþèýˆº þè ýˆº Ñþèýˆº ûÑèÑýˆºþèýˆºöx€ˆºxˆºù€ˆˆºú€ˆˆºúˆˆºøèxˆºûèÑèûxˆº úèÑÑûxˆº þÑûxˆº úèÑèû€ˆº üèÑèûxˆºûxˆº¢ýˆºþœcc ýˆº þœþcýˆº þc ýˆº œþcýˆº ûœcœýˆºþcýˆºö€|ˆº€ˆºù|ˆˆºú|ˆˆºúˆˆºøc€ˆºûcœcû€ˆº úcœœû€ˆº þœû€ˆº úcœcû|ˆº ücœcû€ˆºû€ˆº¢ý‰¼þœcc ý‰¼ þœþcý‰¼ þc ý‰¼ œþcý‰¼ ûœcœý‰¼þcý‰¼öx€‰¼x‰¼ù€‰‰¼ú€‰‰¼ú‰‰¼øcx‰¼ûcœcûx‰¼ úcœœûx‰¼ þœûx‰¼ úcœcû€‰¼ ücœcûx‰¼ûx‰¼†ÿã þãÿÿþãÿÿþãþãÿÿøãÿãÿãþãÿÿ ýãÿýÿãþãÿÿ øãÿÿÿãþãÿÿ þãÿÿþãþãÿÿãúÿããÿÿùÿãÿÿãÿÿþãÿÿþãþãÿÿþãþãÿÿãúÿããÿÿþãÿÿþãþãÿÿ øãÿÿÿãþãÿÿ ýãÿýÿãþãÿÿ øãÿÿÿãþãÿÿ þãÿÿþãþãÿÿ ã ÿÿrDeclick - weekÿ     3ò=ýùèýèùüèùèüèùèøèùèèùèþOúèùùèþOüèùèþOñèùùèùèùè­ùèùþOðèùèùèùèùèèùèþ­ëùèùèùèù­èùèùèùùèç­­èùèùèèùèèùèùèùèçèùèùùèèùèùùè­­øOèùèùè­öèùèùèèùèþ­èèùèùùèùèùèùèù­­êèùèùèèùè­­­­­ßùèùè­ùèù­­­­­­OOú­­­ü­­­ý­ýþ­ø­­­­þ­ï­­­­ö­­­­­÷­­­­þ­þ­û÷­­­­ø­­­­þ­ü­­ø­­ü­­þ­ó­­­­­­­ü­­ú­­­ü­­­þ­/=ý„ý„ü„„ü„„ø„„„„þTú„„þTü„„þTñ„„„„­„þTð„„„„„„„þ­ë„„„­„„„„ñ­­„„„„„ø„„„„ø„„„ó„„„­­øT„„„­ö„„„„„þ­ø„„„ó„„„­­ê„„„„„­­­­­ö„„­„ì­­­­­­TTú­­­ü­­­ý­þþ­ø­­­­þ­ü­­ü­­ö­­­­­ø­­­­þ­þ­ ø­­­­ù­­­­þ­ü­­ü­­ü­­þ­ó­­­­­­­ü­­ú­­­ü­­­þ­/=ý„ý„ü„„ü„„ø„„„„þŒú„„þŒü„„þŒñ„„„„²„þŒð„„„„„„„þ²ë„„„²„„„„ñ²²„„„„„ø„„„„÷„„„ò„„„²²댄„„²„„„„„þ²ø„„„ó„„„²²ê„„„„„²²²²²Ö„„²„² ² ²²²²ŒŒ²²²ü²²²ý²ø²ø²²²²þ²î²²²²ì²²²²²²²²²þ²þ² ø²²²²ø²²²²ú²ô²²²²ø²²²ó²²²²²²²ô²²²²²ü²²²þ²/ºþÿÿúÿÿÿ þÿÿÿúÿÿÿÿ ÿÿ ÿÿ ÿÿüÿÿÿÿúÿÿÿÿüÿÿÿ ÿúÿÿÿúÿþþÿÿ üÿõÿÿþÔÿáî þÿÿþÿÿûÿÓÿÿÿüÿÿýùÿÿÿúÿÿÿÿÿÿõÿÿÿÿÿÿþÿÿÿøÿÿÿÿÿÿÿüÿÿÿþÿÿýÿúÿÿöÿÿÿýÿÿÿÿÿÿýþÿþÿþÿÿI Decrackleÿ     n,@P=ýùèýèùüèùèüèùèøèùèèùèþOúèùùèüÿÿüèùèþ­üÿÿýOÿíèÿÿèÿ ÿÿÿÿæÿÿèùèÿùè­ÿ­ÿÿÿþOëùèÿÿèùèÿÿÿÿ­­ùOÿèöù­ ­­üÿÿüO­ðÿÿ­­ÿÿ­üOÿ­ý­üü­­ü­ð­­­ÿÿüO­ó­­­­ü­­øO&­­­­÷­­üOû÷­­­ý­õ­­­­ õO­­­­þ­ü­­ýO&þ­­ð­­­­ÿÿÿÿ­ý­íÿÿ­­­ÿÿ­­ø­­ÿÿþÿßÿÿÿÿÿÿÿÿ­ÿÿÿ­ÿ­÷ÿ­ÿÿ­òÿÿ­ÿÿÿÿ­þ­ùÿÿðÿÿ­­­ÿÿþÿïÿÿÿÿÿÿÿÿûÿÿÿþÿ þÿüÿÿüÿÿ=ý„ý„ü„„ü„„ø„„„„þTú„„üü„„þ­üýTø„„ùæ„„„­­þTë„„„­­ùT„ù­­­üüT­ð­­­üT­ý­ ü­­ü­÷­­­üT­÷­­­­ü­­øT&­­­­ú­­ þTú­­­ý­ö­­­­ öT­­­­þ­ü­­ýT&þ­­ð­­­­­þ­ï­­­­­ø­­þë­ö­­÷­­ò­­þ­ù9ð­­­þïû99þ þüü=ý„ý„ü„„ü„„ø„„„„þŒú„„üü„„þ²üýŒí„„æ„„„² ²þŒë„„„²²÷Œ„ù²²²üüŒ²ð² ²²üŒ²ö²ü²²ü²÷²²²üŒ²õ²²²²ü²²ìŒ(²²²²² ²èŒ²²²í²²²²²öŒ²²²²÷²²²÷Œ(²²ì²²²²²²ï²²²²²Ý²²²ö²²÷²²î²²²ùÿð²²²þïûÿÿþ þüüªúÿÿÿüÿÿöÿÿÿÿôÿÿÿÿÿÿýÿþÿþÿüÿÿÿùÿÿÿÿÿÿþÿúÿÿþÿÿþÿþÿúÿÿþÿ÷ÿþþÿÿÿþÿøÿÿÿÿõþÔÿáîÿÿÿÿûÿÿÿþÿÿùÓÿÿÿÿ÷ÿÿÿÿÿÿôÿÿùÿÿÿÿÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñÿÿÿÿÿÿÿÿÿüÿÿÿùÿÿÿÿþÿÿúÿÿúÿÿùÿÿÿÿõýÿÿÿÿÿÿþÿÿþÿÿúþÿÿÿþÿóÿÿÿÿîÿÿÿþÿÿ÷ÿÿÿÿÿÿþÿüÿÿþÿ þÿüÿÿüÿÿsDeclick - strongÿ     C-AQ=ýùèýèùüèùèüèùèøèùèèùèþOúèùùèþOüèùèþ­ þOõèùùè­ ­ þOóèùèùè­­þ­þOóèùè­­èùè­ü­­ù­ùèöèù­­­üO­ûþü­­üO&­þ­þ­ý­þ­üOð­­­­ýO­õ­­­ ­þ­íO­­­­­­ü­­þOñ­­­­­­­ý­ü­ñ­­­­­­­òO­­­­þü­­øO&­­­þ­ý­þ­üOûù­­­þ­ú­­þ­ ö­­­þ­þ­÷­­­­­þ­þ­þ­þ­­ý­þ­/=ý„ý„ü„„ü„„ø„„„„þTú„„þTü„„þ­ þTõ„„­­ þTó„„„­­þ­þTô„„­­„„­ü­­ù­„ø„­­­üT­ü­­üT&­þ­þ­þ­þ­þT þ­ú­­­ýT­ö­­­­þ­÷T­­­ù­­­ü­­þTô­­­­­­ý­ü­þ­­÷­­­­öT­­­­ ü­­øT&­­­þ­þ­þ­þTú­­­þ­û­­þ­ ú­­­þ­þ­÷­­­­­þ­þ­þ­þ­­ý­þ­/=ý„ý„ü„„ü„„ø„„„„þŒú„„þŒü„„þ² þŒõ„„²² þŒó„„„² ²þ²þŒò„„²²„„²ü²²÷²„ø„²²²üŒ²þþþü²²üŒ(²ø²²þ²þ²þŒ þ²ú²²²üŒ²ò²²²²²çŒ²²²² ²²²²íŒ²²²²²²²ý²ë²²²²²²²²óŒ²²²²þü²²òŒ(²²²²þ²þ²þŒú²²²ý²ú²²ü²÷²²²ú²²÷²²²²²ú²²þ²þ²²ý²þ²/=ÿúÿÿÿÿüÿÿÿÿÿÿÿÿüÿÿÿüÿÿÿÿúÿÿÿþÿþÿþÿþÿ þþÿÿ þþÿúÿþþÿÿþÿþÿúþÔÿáîÿÿÿþÿÿûÿÓÿÿÿÿüÿÿýùÿÿÿÿúÿÿÿÿÿýÿÿÿûÿÿÿþÿÿÿÿþÿÿÿÿþÿÿþÿÿýÿúÿÿÿûýÿÿÿÿÿÿýþÿþÿþÿÿýîÿþÿ/ Remove noiseÿ     X 7 K [=ûùèùùùèùèùùùýèùýùùù þOûùèùùü÷øù þOùúèó÷ïþOøùøùûõôöùþOüùïõöö÷ùþ­þOùûö÷øùü­­ü­þùú­ø÷ùùüO­úùùùùþü­­üO&­þ­ù­ùù­þ­üOðù­­­ýO­õ­­­O­þ­íO­­­­O­ü­­þOþ­ù­­­þ­þ­ü­þ­ü­­ üO­þ­þ øO­­­þ­þþþþ­þ­ú­­ú­ú­­­­þ­þ­þ­þ­­ý­þ­/=û„ù„„ý„ý þTû„ü þTú,rCþTö8#ª#þTñ©×âÕÂÌο­š“þ­þTøØÓü­­ü­þú­ÇüT­÷ ü­­üT&­þ­ú­­þ­þT þú­­­ýT­ö­­­T­þ­÷T­­­ù­T­ü­­þTþ­ù­­­þ­þ­ü­þ­ü­­ üT­þ­øT­­­þ­!þ­þ­û­­þ­ú­­­­þ­þ­þ­þ­­ý­þ­/=û„ù„„ý„ý þŒû„ü þŒú,rCþŒö8#ª#þŒñ©×âÕÂÌο­š“þ²þŒøØÓü²²ü²þú²ÇüŒ²÷ ü²²üŒ(²ô²²²þ²þŒ þú²²²üŒ²ò²²²Œ²²猲²²² Œ²²²þŒþ²ø²²²þ²ý²ü²÷²²² úŒ²û²øŒ²²²ý²!þ²ý²ú²²þû²÷²²²²ú²²þ²þ²²ý²þ²/AýþÿÿüÝþÿûÞôþíþÿøþÿÿúúûÿ ûÿöûýþþÿ ÿþþÿÿÿþÿÿþÿ þþþüÿþÿþÿþÿÿü ÿõÿÿÿÿÿÿþÿþÿôÿÿÿÿÿÿýÿÿÿþÿÿïÿÿÿÿÿÿÿÿôÿÿÿÿÿÿÿúÿÿÿÿÿþÿÿþÿÿöÿÿÿÿþÿþÿþÿÿþÿQþn/Declick algorithum copyÿ     M'Œ' '°=ûùèùùùèùèùùùýèùýùùù þOûùèùù þOùýù þOýùùùý­ þOøùèùùùùþ­þ­þOõèùùùü­­ü­þùü­­ üO­ûùùþü­­üO&­þ­þ­ý­þ­üOð­­­­ýO­õ­­­ ­þ­íO­­­­­­ü­­þOñ­­­­­­­ý­ü­ñ­­­­­­­òO­­­­þü­­øO&­­­þ­ý­þ­üOûù­­­þ­ú­­þ­ ö­­­þ­þ­÷­­­­­þ­þ­þ­þ­­ý­þ­/=û„ù„„ý„ý þTû„ þTý þTýý­ þTø„þ­þ­þTø„ü­­ü­þü­­ üT­ûü­­üT&­þ­þ­þ­þ­þT þ­ú­­­ýT­ö­­­­þ­÷T­­­ù­­­ü­­þTô­­­­­­ý­ü­þ­­÷­­­­öT­­­­ ü­­øT&­­­þ­þ­þ­þTú­­­þ­û­­þ­ ú­­­þ­þ­÷­­­­­þ­þ­þ­þ­­ý­þ­/=û„ù„„ý„ý þŒû„ þŒý þŒýý² þŒø„þ²þ²þŒø„þü²²ü²þû²² üŒ²ûþü²²üŒ(²ø²²þ²þ²þŒ þ²ú²²²üŒ²ò²²²²²çŒ²²²² ²²²²íŒ²²²²²²²ý²ë²²²²²²²²óŒ²²²²þü²²òŒ(²²²²þ²þ²þŒú²²²ý²ú²²ü²÷²²²ú²²÷²²²²²ú²²þ²þ²²ý²þ²/Aýÿúÿÿýÿüÿýáÿþÿúÿ2ûÿ1þþÿ þþÿ þþ úÿþþÿÿþÿþõÿùªþÔÿáîÿÿÿþÿÿûÿÓÿÿÿÿüÿÿýùÿÿÿÿúÿÿÿÿÿýÿÿÿûÿÿÿþÿÿÿÿþÿÿÿÿþÿÿþÿÿýÿúÿÿÿûýÿÿÿÿÿÿýþÿþÿþÿÿýîÿþÿ/Declick algorithumÿ     -/l/€/=ýùèýèùüèùèýèùþOûùèþO þ­ þOþùþ­ þOýùèþ­þ­þOþèþü­­ü­þü­­ üO­ûþü­­üO&­þ­þ­ý­þ­üOð­­­­ýO­õ­­­ ­þ­íO­­­­­­ü­­þOñ­­­­­­­ý­ü­ñ­­­­­­­òO­­­­þü­­øO&­­­þ­ý­þ­üOûù­­­þ­ú­­þ­ ö­­­þ­þ­÷­­­­­þ­þ­þ­þ­­ý­þ­/=ý„ý„ü„„ý„þTû„þT þ­ þTþþ­ þTý„þ­þ­þTþ„ ü­­ü­ü­­ üT­ü­­üT&­þ­þ­þ­þ­þT þ­ú­­­ýT­ö­­­­þ­÷T­­­ù­­­ü­­þTô­­­­­­ý­ü­þ­­÷­­­­öT­­­­ ü­­øT&­­­þ­þ­þ­þTú­­­þ­û­­þ­ ú­­­þ­þ­÷­­­­­þ­þ­þ­þ­­ý­þ­/=ý„ý„ü„„ý„þŒû„þŒ þ² þŒþþ² þŒý„þ²þ²þŒþ„þü²²ü²û²² üŒ²þþü²²üŒ(²ø²²þ²þ²þŒ þ²ú²²²üŒ²ò²²²²²çŒ²²²² ²²²²íŒ²²²²²²²ý²ë²²²²²²²²óŒ²²²²þü²²òŒ(²²²²þ²þ²þŒú²²²ý²ú²²ü²÷²²²ú²²÷²²²²²ú²²þ²þ²²ý²þ²/Eþ ü ÿ þÿøÿÿ ÿÿ ÿùÿÿÿþÿþÿþÿûÿÿÿþÿ ïÿÿÿÿÿÿ ÿþÿúÿÿÿGþþÿ þþÿ þþ úÿþþÿÿþÿþõÿùªþÔÿáîÿÿÿþÿÿûÿÓÿÿÿÿüÿÿýùÿÿÿÿúÿÿÿÿÿýÿÿÿûÿÿÿþÿÿÿÿþÿÿÿÿþÿÿþÿÿýÿúÿÿÿûýÿÿÿÿÿÿýþÿþÿþÿÿýîÿþÿ/ New Layerÿ     77'77¸þÿ2þÿÿÿÿÿüÿÿÿ!þ­ü­ ­þ­ú­­þ­û­­ý­ü­­þ­ø­­­­þ­þþü­­þ­ü­­þ­ý­þ­­ú­­­ù­­­þ­þ­þ­þ­þ­þ­þ­­þ­ ¸þÿ2þÿÿÿÿÿüÿÿÿ!þ­ü­­þ­ú­­þ­û­­þ­ü­­þ­ø­­­­þ­ ü­­þ­ü­­þ­þ­þ­­ú­­­ ú­­­þ­þ­þ­þ­þ­þ­þ­­þ­ ¸þÿ2þÿÿÿÿÿüÿÿÿ!þ²ü²²þ²ú² ²þ²û²²ü²ü²²þ²ø²²²²þ²þü²²þ²ü²²þ²þ²þ²²ú²²² ú²²²þ²ú²²ü²þ²ú²²²þ² HÿÿÿÿÿÿÿÿÿýÿÿÿÿÿÿþÿÿþÿúÿþþÿÿþÿÿúþÔÿáîÿÿýÿÿûÿÓÿÿúÿÿÿÿýùÿÿÿÿÿÿÿýÿÿö!ÿÿÿÿÿþÿÿÿÿþÿÿþÿýÿúÿÿÿþÿ Volumeÿ     ;X;l;|+ûØêêØþØúØêêØ ØúØØúêØØêêØØúêØêêôØØêØØêêöêØØêØêêõØêØêØØêêöØêØêØØêêöØêØêêêê÷ØêØêØê÷ØêØêØê÷ØêØêØê÷ØêØêØê÷ØêØêØêù¼¼¼÷ØêØêØêù¼¼¼÷ØêêêØê þ¼öØêØêØêê þ¼öØêØêØØêê õ¼ØêØêØêêô¼êØØêØêêþØ ùØØêêêêþØ øØêØØêêþØØþêØØêØýØêêþØêêûØêêþØ+ûp…Îpþpúp…Îp púppú…pp…Îppú…p…Îôpp…pp…Îö…pp…p……õp…p…pp…Îöp…p…pp…Îöp…p…………÷p…p…p…÷p…p…p…÷p…p…p…÷p…p…p…÷p…p…p…ù¸¸¸÷p…p…p…ù¸¸¸÷p………p… þ¸öp…p…p…… þ¸öp…p…pp…Î ò¸p…p…pÎ…Îô¸…pp…pÎ…þp öpp……Î……þp øp…ppÎ…þppþ…ppýÎ…púpÎ…ÎûpÎ…Îûp…Îþp+ûp…Îpþpúp…Îp púppú…pp…Îppú…p…Îôpp…pp…Îö…pp…p……õp…p…pp…Îöp…p…pp…Îöp…p…………÷p…p…p…÷p…p…p…÷p…p…p…÷p…p…p…÷p…p…p…ù¸¸¸÷p…p…p…ù¸¸¸÷p………p… þ¸öp…p…p…… þ¸öp…p…pp…Î ò¸p…p…pÎ…Îô¸…pp…pÎ…þp öpp……Î……þp øp…ppÎ…þppþ…ppýÎ…púpÎ…ÎûpÎ…Îûp…Îþp+ýÿþü"ÿ ùûÿ"ÿõ%ÿ5ÿþÿý7ÿþÿÿõÿÿ;ÿÿ ÿûÿÿþÿ ÿøÿÿ"ÿ ÿö.ÿÿÿÿÿÿþÿÿøÿÿÿÿþÿÿøÿÿÿÿþÿÿøÿÿÿÿþÿÿøÿÿÿÿþÿÿ÷.ÿÿÿÿþÿÿøÿÿÿÿþÿÿøÿÿÿÿ ÿö.ÿÿÿÿ ÿøÿÿÿ ÿûÿÿþÿÿýÿþÿþÿþ þÿý7ÿÿþ ý%ÿþÿþþÿþÿý þÿþÿþÿþ1 Backgroundÿ     BPBdBt¨¦¦gtk-wave-cleaner-0.22-04/icons/undo.xpm0000777000175000017500000000225513120075106021016 0ustar00alisteralister00000000000000/* XPM */ static const char *undo_xpm[] = { /* columns rows colors chars-per-pixel */ "16 16 51 1", " c #000000", ". c #040b06", "X c #040b0b", "o c #090f10", "O c #051413", "+ c #081912", "@ c #0a1f18", "# c #0f2417", "$ c #0d2419", "% c #0b281e", "& c #10211f", "* c #14311f", "= c #0d3525", "- c #142724", "; c #162d26", ": c #153220", "> c #163923", ", c #143d29", "< c #1c442b", "1 c #1e4335", "2 c #214b30", "3 c #245135", "4 c #227d37", "5 c #38774e", "6 c #2a8f3d", "7 c #259039", "8 c #2f9645", "9 c #3e9951", "0 c #36a34d", "q c #3faf57", "w c #3bb057", "e c #468166", "r c #42b75b", "t c #43ba5c", "y c #55ae72", "u c #5aa77b", "i c #5ab975", "p c #7ba08a", "a c #88ab9c", "s c #90bd9f", "d c #afbeba", "f c #9dc6aa", "g c #b2d1bc", "h c #bdcec7", "j c #bfd0c8", "k c #c1cecc", "l c #c0d1c9", "z c #c2dbca", "x c #cfe0d4", "c c #dbeadf", "v c None", /* pixels */ "vvvvvvvvvvvvvvvv", "vvvvvvvvv vvvvv", "vvvvvvvv2<< vvv", "vvvvvv22kcg,< vv", "3vvvv2jc444sk* v", ">3v 2c44rw844h*v", ">p32c4rq,%%254: ", ">zaf40>Xvvvv+34#", ">x640=vvvvvvv@4.", ">g964OvvvvvvvX$+", ">euiy4+vvvvvvOX ", ": X vvvvX& v", " vvvvvvvvvvX;Xvv", "vvvvvvvvvvo-Xvvv", "vvvvvvvv X vvvvv", "vvvvvvvvvvvvvvvv" }; gtk-wave-cleaner-0.22-04/icons/view_all.xcf0000777000175000017500000000447113120075106021631 0ustar00alisteralister00000000000000gimp xcf file00BB / gimp-commentCreated with The GIMPš00 Gfig Layer 0ÿ      C00W00g   ø $ò0gŸ¼ÐËͰšIîY¾Ð˜`=5@x¹Ïù(³ÈZù/›Ðoú@Ð| ú4š ûKÏP ûž¥ üAÎ?û¡üÉTüÉbûüEÔ$ü$Ü/û–•û~—ü0Ðü»CüºNü(Öýr†ü>²üD®üd¤ü7Ì ýz{üÎýv…üÌüR±ü=½ü2Ä üZªü Ë&ü•oü¨nüÑ/üLÅü^ºü ºhüÄ\üDÖû|®û†­ üBÑ*û Ÿ– üAÙTû©£ ùaÎŽºú ”Óa ö/°¿9o¶ç;¿Ån$ @›Û¡j‘© è L¦É̯†x ¶Î½}#ÊD £Ž é6Lvwg@>Ë7¢”%õTË$¶o%õg¾ ¾i%öl¼%Í\&ö› <ÌB&ö ¬yBÓ:&ö!¿okÏ&ö!Égª &÷6ÙZÅZ'øIÜx|u(ù1Ú”C¾g)ú+ ®*üø00 Backgroundÿ     °00Ä00Ô-wýJw+wûRpw&w÷Jaw c #E2E0E0", ", c #DFDDDD", "' c #D5D3D3", ") c #A5A3A3", "! c #E1DFDF", "~ c #DDDBDB", "{ c #BFBEBE", "] c #ABA9A9", "^ c #D4D2D2", "/ c #AEACAC", "( c #2A2A2A", "_ c #AFAFAF", ": c #CBCACA", "< c #727171", "[ c #929090", "} c #B4B2B2", "| c #A9A8A8", "1 c #AFAEAE", "2 c #666666", "3 c #D2D0D0", "4 c #DCDADA", "5 c #D6D4D4", "6 c #404040", "7 c #A9A7A7", "8 c #393838", "9 c #BEBCBC", "0 c #C5C4C4", "a c #C3C1C1", "b c #E3E1E1", "c c #D3D1D1", "d c #918F8F", "e c #939292", "f c #B6B5B5", "g c #8C8B8B", "h c #9F9D9D", "i c #605F5F", "j c #8D8B8B", "k c #BDBBBB", "l c #CBC9C9", "m c #B9B8B8", "n c #E3E2E2", "o c #D5D4D4", "p c #C9C7C7", "q c #CFCDCD", "r c #E4E3E3", "s c #E0DEDE", "t c #1117D6", " ", " ..... ", " ...+@+... ", " ..+@@@@@+.. ", " ..+@@@##@@+.. ", " .+@@@@@$%&@+. ", " .*=-;>>,'.)!~.. ", " .+{.]^$/.(._>+. ", " .@:<.[}.|1.234. ", " .@5|6.7890..ab. ", " .+#cd.e.f:g.5+. ", " ..!^hi.jklm.c.. ", " .+nop3qq,'!o. ", " ..+r##@s@#+.. ", " . ..+@@@@@+.. ", " ... ...+@+... ", " ... ..... ", " #.. ", " ..# t ", " #.. t ", " ..# ttttt ", " .. t ", " t ", " ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/zoom_out.xpm0000777000175000017500000000346213120075106021725 0ustar00alisteralister00000000000000/* XPM */ static const char * zoom_out_xpm[] = { "28 28 59 1", " c None", ". c #000000", "+ c #CCC7C7", "@ c #E5E3E3", "# c #E4E2E2", "$ c #D9D7D7", "% c #BFBDBD", "& c #DAD8D8", "* c #141414", "= c #CCCBCB", "- c #CDCCCC", "; c #DEDCDC", "> c #E2E0E0", ", c #DFDDDD", "' c #D5D3D3", ") c #A5A3A3", "! c #E1DFDF", "~ c #DDDBDB", "{ c #BFBEBE", "] c #ABA9A9", "^ c #D4D2D2", "/ c #AEACAC", "( c #2A2A2A", "_ c #AFAFAF", ": c #CBCACA", "< c #727171", "[ c #929090", "} c #B4B2B2", "| c #A9A8A8", "1 c #AFAEAE", "2 c #666666", "3 c #D2D0D0", "4 c #DCDADA", "5 c #D6D4D4", "6 c #404040", "7 c #A9A7A7", "8 c #393838", "9 c #BEBCBC", "0 c #C5C4C4", "a c #C3C1C1", "b c #E3E1E1", "c c #D3D1D1", "d c #918F8F", "e c #939292", "f c #B6B5B5", "g c #8C8B8B", "h c #9F9D9D", "i c #605F5F", "j c #8D8B8B", "k c #BDBBBB", "l c #CBC9C9", "m c #B9B8B8", "n c #E3E2E2", "o c #D5D4D4", "p c #C9C7C7", "q c #CFCDCD", "r c #E4E3E3", "s c #E0DEDE", "t c #1117D6", " ", " ..... ", " ...+@+... ", " ..+@@@@@+.. ", " ..+@@@##@@+.. ", " .+@@@@@$%&@+. ", " .*=-;>>,'.)!~.. ", " .+{.]^$/.(._>+. ", " .@:<.[}.|1.234. ", " .@5|6.7890..ab. ", " .+#cd.e.f:g.5+. ", " ..!^hi.jklm.c.. ", " .+nop3qq,'!o. ", " ..+r##@s@#+.. ", " . ..+@@@@@+.. ", " ... ...+@+... ", " ... ..... ", " @.. ", " ..@ ", " @.. ", " ..@ ", " .. ttttt ", " ", " ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/zoom_sel.xpm0000777000175000017500000000242613120075106021700 0ustar00alisteralister00000000000000/* XPM */ static const char * zoom_sel_xpm[] = { "28 28 23 1", " c None", ". c #000000", "+ c #C9CAD8", "@ c #CCC7C7", "# c #BABCDD", "$ c #0915F9", "% c #9194D8", "& c #141414", "* c #BFBEBE", "= c #ABA9A9", "- c #2A2A2A", "; c #AFAFAF", "> c #CBCACA", ", c #727171", "' c #666666", ") c #A9A8A8", "! c #404040", "~ c #393838", "{ c #C3C1C1", "] c #918F8F", "^ c #9F9D9D", "/ c #E4E2E2", "( c #1117D6", " ", " ..... ", " ...++@... ", " ..+#####+.. ", " ..+#$%%%%$+.. ", " .+##$%%%%$#+. ", " .&++#$%%%.$##.. ", " .+*.=$%%.-$;##. ", " .#>,.$%.%%$'+#. ", " .+#)!$%~%%$.{#. ", " .+#+]$%.%%$.#+. ", " ..##^$.%%%$.#.. ", " .+#+$%%%%$##. ", " ..+#$%%%%$+.. ", " . ..+#####+.. ", " ... ...+#+... ", " ... ..... ", " /.. ", " ../ ( ", " /.. ( ", " ../ ((((( ", " .. ( ", " ( ", " ", " ", " ", " ", " "}; gtk-wave-cleaner-0.22-04/icons/zoomselect.png0000777000175000017500000000072313120075106022213 0ustar00alisteralister00000000000000‰PNG  IHDR00Wù‡*tEXtTitle/home/welty/gwc/icons/zoomselect.png›SttEXtSoftwareGNOME Icon Editorž* l>IDATxœí˜Ýà …aÙû¿²»Xè"ò#N›ð%»Y«œ#´RŠ¢x4m·#(]x‚Qã+c’¤ûCx É{S\ž±¾5Fh·ß ~ÂÃ1$4át€ÁÜÄTŒž.þZ©˜e„—LZ qñÙh à^ ^†â² ÍZ´»UB[•™0<&Á,XǸæ&æA“YÐÆºßH÷ ¬,ϪºL·ø@yb˜M„z!*£Ä}¡Æ@¸™s˜˜1©~¯Lu£†:ccŽMi§`dbéÞA)²ÞÇ àwñ³Ä+±ãÿiA#¸bKÝèΖÁuÐÐëFOèwÌ&x3w‚xÂdÂ{.ä1˜½É©qö†”a@ÕÆ›¹“¹Ì%ÍEK&þiΪI¼¸3.=§•͈“ÞEQEQEoNX"”8qIEND®B`‚gtk-wave-cleaner-0.22-04/install-sh0000777000175000017500000003325513120075106020215 0ustar00alisteralister00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # 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 # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: gtk-wave-cleaner-0.22-04/markers.c0000666000175000017500000005322213450764342020032 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* markers.c */ #include #include #include #include #include #include #include #include #include #include #include #include #include "gwc.h" long cdtext_length; char *cdtext_data = NULL; /* The file selection widget and the string to store the chosen filename */ GtkWidget *file_selector; gchar *selected_filename; gchar save_cdrdao_toc_filename[PATH_MAX+1]; extern long num_song_markers, song_markers[] ; extern gchar wave_filename[] ; extern struct sound_prefs prefs ; extern struct view audio_view; extern double song_key_highlight_interval ; extern double song_mark_silence ; char *find_text(long length,char *data, char *str) { char *ret = NULL; char *end = data + length; int len; while (data < end && ret == NULL) { len = strlen(data); if (strcmp(data, str) == 0) { ret = data + len + 1; } else { data = data + len + 1; /* Skip field value */ len = strlen(data); data = data + len + 1; } } return ret; } int only_blank(char *str) { while (*str != 0) { if (*str++ != ' ') return 0; } return 1; } static int use_song_marker_pairs ; /* song markers are positioned at start AND end of each song? */ #define ARRAYSIZE(x) (sizeof(x) / sizeof(x[0])) /* CD Tracks must be multiple of 588 or they will be padded with zeros */ #define SONG_BLOCK_LEN 588 void cdrdao_toc_info(char *filename) { GtkWidget *dlg ; GtkWidget *dialog_table ; GtkWidget *song_table ; int dres ; int row = 0; struct { char *title; char *fieldid; char *init; int always_write; GtkWidget *widget; } album_info[] = { {"Language", "LANGUAGE", "EN", 1, NULL}, /* This is special and must be first */ {"Title", "TITLE", "", 1, NULL}, {"Performer", "PERFORMER", "", 0, NULL}, {"Songwriter", "SONGWRITER", "", 0, NULL}, {"Arranger", "ARRANGER", "", 0, NULL}, {"Composer", "COMPOSER", "", 0, NULL}, {"Disc_ID", "DISC_ID", "", 0, NULL}, {"Message", "MESSAGE", "", 1, NULL} }; struct { char *title; char *fieldid; char *init; int always_write; } song_info[] = { {"Title", "TITLE", "", 1}, {"Message", "MESSAGE", "", 1} }; GtkWidget *song_widget[MAX_MARKERS+1][ARRAYSIZE(song_info)]; int i,j; GtkWidget *scrolled; int new_cdtext_length = 0; char *new_cdtext; int new_cdtext_loc; char buf[200], buf2[200]; dlg = gtk_dialog_new_with_buttons("Cdrdao CD Text Information", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); //Alister: I don't believe this does anything //gtk_window_set_policy(GTK_WINDOW(dlg), FALSE, TRUE, FALSE); dialog_table = gtk_table_new(5,2,0) ; gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 4) ; gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6) ; gtk_widget_show (dialog_table); for (i = 0; i < ARRAYSIZE(album_info); i++) { char *init; init = find_text(cdtext_length, cdtext_data, album_info[i].fieldid); if (init == NULL) { init = album_info[i].init; } album_info[i].widget = add_number_entry_with_label(init, album_info[i].title, dialog_table, row++) ; } song_table = gtk_table_new(5,2,0) ; gtk_table_set_row_spacings(GTK_TABLE(song_table), 4) ; gtk_table_set_col_spacings(GTK_TABLE(song_table), 6) ; scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), song_table); gtk_widget_set_usize(scrolled,300,300); gtk_widget_show (scrolled); gtk_widget_show (song_table); row = 0; for (j = 0; j < num_song_markers+1; j += 1+use_song_marker_pairs) { for (i = 0; i < ARRAYSIZE(song_info); i++) { char *init; snprintf(buf, sizeof(buf), "Song %2d %s", j+1, song_info[i].title); /* Duplicated below, and new_cdtext_length adjusted by 3 for %3d */ snprintf(buf2, sizeof(buf2), "%3d%s", j+1, song_info[i].fieldid); init = find_text(cdtext_length, cdtext_data, buf2); if (init == NULL) { init = song_info[i].init; } song_widget[j][i] = add_number_entry_with_label(init, buf, song_table, row++) ; } } gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), scrolled, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)) ; if(dres == 0) { FILE *toc; toc = fopen(filename,"w"); if (toc == NULL) { snprintf(buf, sizeof(buf), "Unable to open %s: %s", filename, strerror(errno)); warning(buf); } else { int found_text = 0; for (i = 0; i < ARRAYSIZE(album_info); i++) { char *str; str = (char *)gtk_entry_get_text(GTK_ENTRY(album_info[i].widget)); /* +2 for null at end of both strings*/ new_cdtext_length += strlen(str) + strlen(album_info[i].fieldid) + 2 ; if (strlen(album_info[i].init) == 0 && !only_blank(str)) found_text = 1;; } for (j = 0; j < num_song_markers+(1-use_song_marker_pairs); j += 1+use_song_marker_pairs) { for (i = 0; i < ARRAYSIZE(song_info); i++) { char *str; str = (char *)gtk_entry_get_text(GTK_ENTRY(song_widget[j][i])); /* We add 3 digit song # to fieldid when storing */ new_cdtext_length += strlen(str) + strlen(song_info[i].fieldid) + 3 + 2; if (!only_blank(str)) found_text = 1;; } } new_cdtext_loc = 0; if (found_text) { new_cdtext = calloc(new_cdtext_length, 1); fprintf(toc, "CD_TEXT {\n LANGUAGE_MAP {\n 0: %s\n }\n", gtk_entry_get_text(GTK_ENTRY(album_info[0].widget))); fprintf(toc, " LANGUAGE 0 {\n"); for (i = 0; i < ARRAYSIZE(album_info); i++) { char *str; str = (char *)gtk_entry_get_text(GTK_ENTRY(album_info[i].widget)); if (album_info[i].always_write || !only_blank(str)) { /* First entry, language added to file above */ if (i > 0) { fprintf(toc, " %s \"%s\"\n", album_info[i].fieldid, str); } strcat(&new_cdtext[new_cdtext_loc], album_info[i].fieldid); new_cdtext_loc += strlen(&new_cdtext[new_cdtext_loc]) + 1; strcat(&new_cdtext[new_cdtext_loc], str); new_cdtext_loc += strlen(&new_cdtext[new_cdtext_loc]) + 1; } } fprintf(toc, " }\n}\n"); } else { new_cdtext = NULL; } for (j = 0; j < num_song_markers+(1-use_song_marker_pairs); j += 1+use_song_marker_pairs) { long end; int j1 = j+1 ; long length ; long start ; if(use_song_marker_pairs) { start = song_markers[j] ; if(j1 < num_song_markers) { length = song_markers[j+1] - start + 1 ; } else { /* no last song marker in last pair, assume end of audio for end of last track */ length = (prefs.n_samples-1) - start + 1 ; } } else { if (j == 0) { start = 0 ; length = song_markers[j] - start + 1 ; } else if (j == num_song_markers) { start = song_markers[j-1] ; length = (prefs.n_samples-1) - start + 1 ; } else { start = song_markers[j-1] ; length = song_markers[j] - start + 1 ; } } #define AUDIO_BLOCK_LEN 588 length = ((length + AUDIO_BLOCK_LEN / 2) / AUDIO_BLOCK_LEN) * AUDIO_BLOCK_LEN ; end = start + length -1 ; while(end > (prefs.n_samples-1) && end > 2*AUDIO_BLOCK_LEN) { end -= AUDIO_BLOCK_LEN ; } length = end - start + 1 ; fprintf(toc, "TRACK AUDIO\n"); if (found_text) { fprintf(toc, " CD_TEXT {\n LANGUAGE 0 {\n"); for (i = 0; i < ARRAYSIZE(song_info); i++) { char *str; str = (char *)gtk_entry_get_text(GTK_ENTRY(song_widget[j][i])); if (song_info[i].always_write || !only_blank(str)) { fprintf(toc, " %s \"%s\"\n", song_info[i].fieldid, str); /* Duplicated above */ snprintf(buf, sizeof(buf), "%3d%s", j+1, song_info[i].fieldid); strcat(&new_cdtext[new_cdtext_loc], buf); new_cdtext_loc += strlen(&new_cdtext[new_cdtext_loc]) + 1; strcat(&new_cdtext[new_cdtext_loc], str); new_cdtext_loc += strlen(&new_cdtext[new_cdtext_loc]) + 1; } } fprintf(toc, " }\n }\n"); } fprintf(toc, " FILE \"%s\" %ld %ld\n", wave_filename, start, end - start + 1) ; } fclose(toc); if (cdtext_data != NULL) { free(cdtext_data); } cdtext_data = new_cdtext; /* Loc is the actual length we filled */ cdtext_length = new_cdtext_loc; } } gtk_widget_destroy(dlg) ; } void store_cdrdao_toc(gpointer user_data) { if(strcmp(save_cdrdao_toc_filename, wave_filename)) { int l ; l = strlen(save_cdrdao_toc_filename) ; d_print("Save cdrdao_toc to %s\n", save_cdrdao_toc_filename) ; cdrdao_toc_info(save_cdrdao_toc_filename) ; } else { warning("Cannot save selection over the currently open file!") ; } } void save_cdrdao_toc(GtkWidget * widget, gpointer data) { char tmppath[PATH_MAX+6]; GtkFileFilter * ff, * ffa; if (num_song_markers == 0) { info("No songs marked, Use Markers->Mark Songs"); } else { strcpy(tmppath, wave_filename); /* Create the selector */ file_selector = gtk_file_chooser_dialog_new("Filename to save cdrdao toc to:", GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); bcopy(".toc", strrchr(tmppath, '.'), 4); gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER (file_selector), basename(tmppath)); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_selector), dirname(tmppath)); gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER(file_selector), TRUE); ff = gtk_file_filter_new(); gtk_file_filter_set_name(ff,"TOC files"); gtk_file_filter_add_pattern(ff,"*.toc"); gtk_file_filter_add_pattern(ff,"*.TOC"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_selector),ff); ffa = gtk_file_filter_new(); gtk_file_filter_set_name(ffa,"All files"); gtk_file_filter_add_pattern(ffa,"*"); gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(file_selector),ffa); /* Display the dialog */ if (gtk_dialog_run (GTK_DIALOG (file_selector)) == GTK_RESPONSE_ACCEPT) { strncpy(save_cdrdao_toc_filename, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (file_selector)), PATH_MAX); gtk_widget_destroy (GTK_WIDGET (file_selector)); store_cdrdao_toc(wave_filename); } else { gtk_widget_destroy (GTK_WIDGET (file_selector)); } } } void save_cdrdao_tocs(GtkWidget * widget, gpointer data) { use_song_marker_pairs = 0 ; save_cdrdao_toc(widget, data) ; } void save_cdrdao_tocp(GtkWidget * widget, gpointer data) { use_song_marker_pairs = 1 ; save_cdrdao_toc(widget, data) ; } int _add_song_marker(long loc) { int i,j; if (num_song_markers >= MAX_MARKERS - 1) { // This should probably be shown in a dialog instead of the status bar set_status_text("No more song markers available"); return 0 ; } else { for (i = 0; i < num_song_markers; i++) { if (song_markers[i] > loc) { break; } } for (j = num_song_markers - 1; j >= i; j--) { song_markers[j+1] = song_markers[j]; } song_markers[i] = loc ; num_song_markers++; return 1 ; } } void add_song_marker(void) { long loc = audio_view.selected_first_sample; if(_add_song_marker(loc)) main_redraw(FALSE, TRUE); } void add_song_marker_pair(void) { int r ; long loc = audio_view.selected_first_sample; r = _add_song_marker(loc) ; loc = audio_view.selected_last_sample; r += _add_song_marker(loc) ; if(r > 0) main_redraw(FALSE, TRUE); } void delete_song_marker(void) { int i,j; i = 0; while (i < num_song_markers) { if (song_markers[i] >= audio_view.selected_first_sample && song_markers[i] <= audio_view.selected_last_sample) { for (j = i; j < num_song_markers - 1; j++) { song_markers[j] = song_markers[j+1]; } num_song_markers--; } else { i++; } } main_redraw(FALSE, TRUE); } void adjust_song_marker_positions(long pos, long delta) { int i,j; i = 0; while (i < num_song_markers) { if (song_markers[i] >= pos) { song_markers[i] += delta; if (song_markers[i] <= pos || song_markers[i] >= prefs.n_samples) { for (j = i; j < num_song_markers - 1; j++) { song_markers[j] = song_markers[j+1]; } num_song_markers--; } else { i++; } } else { i++; } } } void move_song_marker(void) { int i; long loc = audio_view.selected_first_sample; long err; int min_err_loc = 0; long min_err = LONG_MAX; if (num_song_markers == 0) { set_status_text("No song markers"); } else { for (i = 0; i < num_song_markers; i++) { err = abs(loc - song_markers[i]); if (err < min_err) { min_err = err; min_err_loc = i; } } song_markers[min_err_loc] = (loc / SONG_BLOCK_LEN) * SONG_BLOCK_LEN; main_redraw(FALSE, TRUE); } } void select_song_marker(void) { int i; long loc = audio_view.selected_last_sample; if (num_song_markers == 0) { set_status_text("No song markers"); } else { if (loc > song_markers[num_song_markers-1]) { loc = 0; } for (i = 0; i < num_song_markers && song_markers[i] < loc; i++); audio_view.selected_last_sample = MIN(prefs.n_samples - 1, song_markers[i] + prefs.rate * song_key_highlight_interval / 2) ; audio_view.selected_first_sample = MAX(0, song_markers[i] - prefs.rate * song_key_highlight_interval / 2) ; audio_view.selection_region = TRUE ; main_redraw(FALSE, TRUE); } } #define DETECT_GAPS_NOT #ifdef DETECT_GAPS double sample_rms(struct sample_block *sample_buffer, int i, int w) { int istart=i-w/2 ; if(istart < 0) istart=0 ; int iend=i+w/2 ; double sum=0 ; double n=iend-istart+1.0 ; for(i=istart ; i <= iend ; i++) { sum += (sample_buffer[i].rms[0]+sample_buffer[i].rms[1])/2.0 ; } return sum/n ; } #endif void mark_songs(GtkWidget * widget, gpointer data) { struct sample_block *sample_buffer ; int n_blocks ; int i; double max_song = 0.0, min_song = 999999999.0; double song_amp; double song_window_amp = 0.0; double *delay; /* These might be good as preferences */ double MIN_SONG_LEN = 35.0; long min_song_blocks; /* Length of sliding window in seconds to average audio over */ double AVG_LEN = song_mark_silence*.75; int avg_blocks; long min_silence_blocks; double SILENCE_EST = .3; double silence; double sec_per_block; double silence_scale; int found_short; int valid_delay; int delay_cntr; int last_silence; int silence_cntr; char buf[200]; int last_song_block; num_song_markers = 0; n_blocks = get_sample_buffer(&sample_buffer) ; if (n_blocks > 0) { sec_per_block = (double) sample_buffer[0].n_samples / prefs.rate; } else { sec_per_block = 0.0; } if (n_blocks * sec_per_block < MIN_SONG_LEN * 3) { snprintf(buf, sizeof(buf), "Must have at least %4.0f seconds of music", MIN_SONG_LEN*3); info(buf); return; } min_silence_blocks = MAX(.25,song_mark_silence) / sec_per_block; min_song_blocks = MIN_SONG_LEN / sec_per_block; avg_blocks = MAX(.25*.75,AVG_LEN) / sec_per_block; delay = malloc(avg_blocks * sizeof(delay[0])); /* First find minimum and maximum level in a sliding window */ valid_delay = 0; delay_cntr = 0; song_window_amp = 0.0; for (i = 0; i < avg_blocks; i++) delay[i] = 0.0; for (i = min_song_blocks; i < n_blocks - min_song_blocks; i++) { song_amp = (sample_buffer[i].max_value[0] + sample_buffer[i].max_value[1]); song_window_amp += song_amp - delay[delay_cntr]; delay[delay_cntr] = song_amp; delay_cntr = (delay_cntr + 1) % avg_blocks; if (delay_cntr == 0) valid_delay = 1; if (valid_delay) { if (song_window_amp > max_song) max_song = song_window_amp; if (song_window_amp < min_song) min_song = song_window_amp; } } /* Now step the threshold up until we find something too short to be a */ /* song. */ found_short = 0; for (silence_scale = 2.0; silence_scale < 32.0 && !found_short; ) { last_silence = -min_song_blocks; valid_delay = 0; delay_cntr = 0; song_window_amp = 0.0; silence_cntr = 0; for (i = 0; i < avg_blocks; i++) delay[i] = 0.0; for (i = min_song_blocks; i < n_blocks - min_song_blocks && !found_short; i++) { song_amp = (sample_buffer[i].max_value[0] + sample_buffer[i].max_value[1]); song_window_amp += song_amp - delay[delay_cntr]; delay[delay_cntr] = song_amp; delay_cntr = (delay_cntr + 1) % avg_blocks; if (delay_cntr == 0) valid_delay = 1; if (valid_delay) { if (song_window_amp > min_song * silence_scale) { silence_cntr = 0; } else { silence_cntr++; if (silence_cntr > min_silence_blocks) { if (i - last_silence > min_silence_blocks * 3 && i - last_silence < min_song_blocks) { found_short = 1; } last_silence = i; } } } } if (!found_short) silence_scale *= 1.5; } /* Pick a threshold between the minimum level and the two high level from */ /* above. Use it to mark the songs. Might be good to look for minimum */ /* silence level to help center the song break better */ silence = min_song + min_song * silence_scale * SILENCE_EST; valid_delay = 0; delay_cntr = 0; song_window_amp = 0.0; silence_cntr = 0; last_silence = 0; last_song_block = 0; for (i = 0; i < avg_blocks; i++) delay[i] = 0.0; for (i = min_song_blocks; i < n_blocks - min_song_blocks; i++) { song_amp = (sample_buffer[i].max_value[0] + sample_buffer[i].max_value[1]); song_window_amp += song_amp - delay[delay_cntr]; delay[delay_cntr] = song_amp; delay_cntr = (delay_cntr + 1) % avg_blocks; if (delay_cntr == 0) valid_delay = 1; if (valid_delay) { if (song_window_amp > silence) { if (last_silence && i - last_song_block > min_song_blocks) { int loc = (i + (last_silence - min_silence_blocks)) / 2 * sample_buffer[i].n_samples; song_markers[num_song_markers++] = (loc / SONG_BLOCK_LEN) * SONG_BLOCK_LEN; if (num_song_markers >= MAX_MARKERS - 2) //Should probably inform the user in this case break; last_song_block = i; } last_silence = 0; silence_cntr = 0; } else { silence_cntr++; if (silence_cntr > min_silence_blocks) { if (!last_silence) { last_silence = i; } } } } } #ifdef DETECT_GAPS if(1) { /* this attempts to detect entire gaps between songs, it does not work * well yet and should be disabled except for testing... */ long tmp_markers[MAX_MARKERS] ; int n_tmp = num_song_markers ; for(i = 0 ; i < num_song_markers ; i++) tmp_markers[i] = song_markers[i] ; num_song_markers=0 ; for(i=0 ; i < n_tmp ; i++) { int iblk = tmp_markers[i]/SBW ; #define bsw 256 #define hbsw 64 double midpt_rms = sample_rms(sample_buffer,iblk,bsw) ; int j ; for(j = hbsw ; j < min_song_blocks ; j += hbsw) { double lead_rms = sample_rms(sample_buffer,iblk-j,bsw) ; if(lead_rms > midpt_rms*1.3) break ; } if(j > hbsw) song_markers[num_song_markers++] = (iblk-j)*SBW ; for(j = hbsw ; j < min_song_blocks ; j += hbsw) { double tail_rms = sample_rms(sample_buffer,iblk+j,bsw) ; if(tail_rms > midpt_rms*1.5) break ; } if(j > hbsw) song_markers[num_song_markers++] = (iblk+j)*SBW ; } } #endif snprintf(buf, sizeof(buf), "Marked %ld songs", num_song_markers + 1); set_status_text(buf); free(delay); main_redraw(FALSE, TRUE) ; } gtk-wave-cleaner-0.22-04/mconf.h0000777000175000017500000001250213120075106017457 0ustar00alisteralister00000000000000/* mconf.h * * Common include file for math routines * * * * SYNOPSIS: * * #include "mconf.h" * * * * DESCRIPTION: * * This file contains definitions for error codes that are * passed to the common error handling routine mtherr() * (which see). * * The file also includes a conditional assembly definition * for the type of computer arithmetic (IEEE, DEC, Motorola * IEEE, or UNKnown). * * For Digital Equipment PDP-11 and VAX computers, certain * IBM systems, and others that use numbers with a 56-bit * significand, the symbol DEC should be defined. In this * mode, most floating point constants are given as arrays * of octal integers to eliminate decimal to binary conversion * errors that might be introduced by the compiler. * * For little-endian computers, such as IBM PC, that follow the * IEEE Standard for Binary Floating Point Arithmetic (ANSI/IEEE * Std 754-1985), the symbol IBMPC should be defined. These * numbers have 53-bit significands. In this mode, constants * are provided as arrays of hexadecimal 16 bit integers. * * Big-endian IEEE format is denoted MIEEE. On some RISC * systems such as Sun SPARC, double precision constants * must be stored on 8-byte address boundaries. Since integer * arrays may be aligned differently, the MIEEE configuration * may fail on such machines. * * To accommodate other types of computer arithmetic, all * constants are also provided in a normal decimal radix * which one can hope are correctly converted to a suitable * format by the available C language compiler. To invoke * this mode, define the symbol UNK. * * An important difference among these modes is a predefined * set of machine arithmetic constants for each. The numbers * MACHEP (the machine roundoff error), MAXNUM (largest number * represented), and several other parameters are preset by * the configuration symbol. Check the file const.c to * ensure that these values are correct for your computer. * * Configurations NANS, INFINITIES, MINUSZERO, and DENORMAL * may fail on many systems. Verify that they are supposed * to work on your computer. */ /* Cephes Math Library Release 2.3: June, 1995 Copyright 1984, 1987, 1989, 1995 by Stephen L. Moshier */ /* Define if the `long double' type works. */ #define HAVE_LONG_DOUBLE 1 /* Define as the return type of signal handlers (int or void). */ #define RETSIGTYPE void /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ /* #undef WORDS_BIGENDIAN */ /* Define if floating point words are bigendian. */ /* #undef FLOAT_WORDS_BIGENDIAN */ /* The number of bytes in a int. */ #define SIZEOF_INT 4 /* Define if you have the header file. */ #define HAVE_STRING_H 1 /* Name of package */ #define PACKAGE "cephes" /* Version number of package */ #define VERSION "2.7" /* Constant definitions for math error conditions */ #define DOMAIN 1 /* argument domain error */ #define SING 2 /* argument singularity */ #define OVERFLOW 3 /* overflow range error */ #define UNDERFLOW 4 /* underflow range error */ #define TLOSS 5 /* total loss of precision */ #define PLOSS 6 /* partial loss of precision */ #define EDOM 33 #define ERANGE 34 /* Complex numeral. */ typedef struct { double r; double i; } cmplx; #ifdef HAVE_LONG_DOUBLE /* Long double complex numeral. */ typedef struct { long double r; long double i; } cmplxl; #endif /* Type of computer arithmetic */ /* PDP-11, Pro350, VAX: */ /* #define DEC 1 */ /* Intel IEEE, low order words come first: */ /* #define IBMPC 1 */ /* Motorola IEEE, high order words come first * (Sun 680x0 workstation): */ /* #define MIEEE 1 */ /* UNKnown arithmetic, invokes coefficients given in * normal decimal format. Beware of range boundary * problems (MACHEP, MAXLOG, etc. in const.c) and * roundoff problems in pow.c: * (Sun SPARCstation) */ #define UNK 1 /* If you define UNK, then be sure to set BIGENDIAN properly. */ #ifdef FLOAT_WORDS_BIGENDIAN #define BIGENDIAN 1 #else #define BIGENDIAN 0 #endif /* Define this `volatile' if your compiler thinks * that floating point arithmetic obeys the associative * and distributive laws. It will defeat some optimizations * (but probably not enough of them). * * #define VOLATILE volatile */ #define VOLATILE /* For 12-byte long doubles on an i386, pad a 16-bit short 0 * to the end of real constants initialized by integer arrays. * * #define XPD 0, * * Otherwise, the type is 10 bytes long and XPD should be * defined blank (e.g., Microsoft C). * * #define XPD */ #define XPD 0, /* Define to support tiny denormal numbers, else undefine. */ #define DENORMAL 1 /* Define to ask for infinity support, else undefine. */ #define INFINITIES 1 /* Define to ask for support of numbers that are Not-a-Number, else undefine. This may automatically define INFINITIES in some files. */ #define NANS 1 /* Define to distinguish between -0.0 and +0.0. */ #define MINUSZERO 1 /* Define 1 for ANSI C atan2() function See atan.c and clog.c. */ #define ANSIC 1 /* Get ANSI function prototypes, if you want them. */ #if 1 /* #ifdef __STDC__ */ #define ANSIPROT 1 int mtherr ( char *, int ); #else int mtherr(); #endif /* Variable for error reporting. See mtherr.c. */ extern int merror; gtk-wave-cleaner-0.22-04/meschach/0000777000175000017500000000000013455327365017776 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/DOC/0000755000175000017500000000000013252653022020362 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/DOC/fnindex.txt0000777000175000017500000004144213120075106022565 0ustar00alisteralister00000000000000 FUNCTION INDEX ============== In the descriptions below, matrices are represented by capital letters, vectors by lower case letters and scalars by alpha. Function Description band2mat() Convert band matrix to dense matrix bd_free() Deallocate (destroy) band matrix bd_get() Allocate and initialise band matrix bd_transp() Transpose band matrix bd_resize() Resize band matrix bdLDLfactor() Band LDL^T factorisation bdLDLsolve() Solve Ax=b using band LDL^T factors bdLUfactor() Band LU factorisation bdLUsolve() Solve Ax=b using band LU factors bisvd() SVD of bi-diagonal matrix BKPfactor() Bunch-Kaufman-Parlett factorisation BKPsolve() Bunch-Kaufman-Parlett solver catch() Catch a raised error (macro) catchall() Catch any raised error (macro) catch_FPE() Catch floating point error (sets flag) CHfactor() Dense Cholesky factorisation CHsolve() Cholesky solver d_save() Save real in MATLAB format Dsolve() Solve Dx=y , D diagonal ERRABORT() Abort on error (sets flag, macro) ERREXIT() Exit on error (sets flag, macro) error() Raise an error (macro, see ev_err()) err_list_attach() Attach new list of errors err_list_free() Discard list of errors err_is_list_attached() Checks for an error list ev_err() Raise an error (function) fft() Computes Fast Fourier Transform finput() Input a simple data item from a stream fprompter() Print prompt to stderr get_col() Extract a column from a matrix get_row() Extract a row from a matrix givens() Compute Givens parameters hhtrcols() Compute AP^T where P is a Householder matrix hhtrrows() Compute PA where P is a Householder matrix hhtrvec() Compute Px where P is a Householder matrix hhvec() Compute parameters for a Householder matrix ifft() Computes inverse FFT in_prod() Inner product of vectors input() Input a simple data item from stdin (macro) iter_arnoldi() Arnoldi iterative method iter_arnoldi_iref() Arnoldi iterative method with refinement iter_ATx() Set A^T in ITER structure iter_Ax() Set A in ITER structure iter_Bx() Set preconditioner in ITER structure iter_cg() Conjugate gradients iterative method iter_cgne() Conjugate gradients for normal equations iter_cgs() CGS iterative method iter_copy() Copy ITER data structures iter_copy2() Shallow copy of ITER data structures iter_dump() Dump ITER data structure to a stream iter_free() Free (deallocate) ITER structure iter_get() Allocate ITER structure iter_gmres() GMRES iterative method iter_lanczos() Lanczos iterative method iter_lanczos2() Lanczos method with Cullum and Willoughby extensions iter_lsqr() LSQR iterative method iter_mgcr() MGCR iterative method iter_resize() Resize vectors in an ITER data structure iter_spcg() Sparse matrix CG method iter_spcgne() Sparse matrix CG method for normal equations iter_spcgs() Sparse matrix CGS method iter_spgmres() Sparse matrix GMRES method iter_splsqr() Sparse matrix LSQR method iter_spmgcr() Sparse matrix MGCR method iv_add() Add integer vectors iv_copy() Copy integer vector iv_dump() Dump integer vector to a stream iv_finput() Input integer vector from a stream iv_foutput() Output integer vector to a stream IV_FREE() Free (deallocate) an integer vector (macro) iv_free() Free (deallocate) integer vector (function) iv_free_vars() Free a list of integer vectors iv_get() Allocate and initialise an integer vector iv_get_vars() Allocate list of integer vectors iv_input() Input integer vector from stdin (macro) iv_output() Output integer vector to stdout (macro) iv_resize() Resize an integer vector iv_resize_vars() Resize a list of integer vectors iv_sub() Subtract integer vectors LDLfactor() LDL^T factorisation LDLsolve() LDL^T solver LDLupdate() Update LDL^T factorisation Lsolve() Solve Lx=y , L lower triangular LTsolve() Solve L^Tx=y , L lower triangular LUcondest() Estimate a condition number using LU factors LUfactor() Compute LU factors with implicit scaled partial pivoting LUsolve() Solve Ax=b using LU factors LUTsolve() Solve A^Tx=b usng LU factors m_add() Add matrices makeQ() Form Q matrix for QR factorisation makeR() Form R matrix for QR factorisation mat2band() Extract band matrix from dense matrix MCHfactor() Modified Cholesky factorisation (actually factors A+D, D diagonal, instead of A) m_copy() Copy dense matrix m_dump() Dump matrix data structure to a stream mem_attach_list() Adds a new family of types mem_bytes() Notify change in memory usage (macro) mem_bytes_list() Notify change in memory usage mem_free_list() Frees a family of types mem_info_bytes() Number of bytes used by a type mem_info_numvar() Number of structures of a type mem_info_file() Print memory info to a stream mem_info_is_on() Is memory data being accumulated? mem_info_on() Turns memory info system on/off mem_is_list_attached() Is list of types attached? mem_numvar() Notify change in number of structures allocated (macro) mem_numvar_list() Notify change in number of structures allocated mem_stat_dump() Prints information on registered workspace mem_stat_free() Frees (deallocates) static workspace mem_stat_mark() Sets mark for workspace MEM_STAT_REG() Register static workspace (macro) mem_stat_show_mark() Current workspace group m_exp() Computes matrix exponential m_finput() Input matrix from a stream m_foutput() Output matrix to a stream M_FREE() Free (deallocate) a matrix (macro) m_free() Free (deallocate) matrix (function) m_free_vars() Free a list of matrices m_get() Allocate and initialise a matrix m_get_vars() Allocate list of matrices m_ident() Sets matrix to identity matrix m_input() Input matrix from stdin (macro) m_inverse() Invert matrix m_load() Load matrix in MATLAB format m_mlt() Multiplies matrices mmtr_mlt() Computes AB^T m_norm1() Computes ||A||_1 of a matrix m_norm_frob() Computes the Frobenius norm of a matrix m_norm_inf() Computes ||A||_inf of a matrix m_ones() Set matrix to all 1's m_output() Output matrix to stdout (macro) m_poly() Computes a matrix polynomial m_pow() Computes integer power of a matrix mrand() Generates pseudo-random real number m_rand() Randomise entries of a matrix mrandlist() Generates array of pseudo-random numbers m_resize() Resize matrix m_resize_vars() Resize a list of matrices m_save() Save matrix in MATLAB format m_sub() Subtract matrices m_transp() Transpose matrix mtrm_mlt() Computes A^TB mv_mlt() Computes Ax mv_mltadd() Computes y <- Ax+y m_zero() Zero a matrix ON_ERROR() Error handler (macro) prompter() Print prompt message to stdout px_cols() Permute the columns of a matrix px_copy() Copy permutation px_dump() Dump permutation data structure to a stream px_finput() Input permutation from a stream px_foutput() Output permutation to a stream PX_FREE() Free (deallocate) a permutation (macro) px_free() Free (deallocate) permutation (function) px_free_vars() Free a list of permutations px_get() Allocate and initialise a permutation px_get_vars() Allocate a list of permutations px_ident() Sets permutation to identity px_input() Input permutation from stdin (macro) px_inv() Invert permutation pxinv_vec() Computes P^Tx where P is a permutation matrix pxinv_zvec() Computes P^Tx where P is a permutation matrix (complex) px_mlt() Multiply permutations px_output() Output permutation to stdout (macro) px_resize() Resize a permutation px_resize_vars() Resize a list of permutations px_rows() Permute the rows of a matrix px_sign() Returns the sign of the permutation px_transp() Transpose a pair of entries px_vec() Computes Px where P is a permutation matrix px_zvec() Computes Px where P is a permutation matrix (complex) QRCPfactor() QR factorisation with column pivoting QRfactor() QR factorisation QRsolve() Solve Ax=b using QR factorisation QRTsolve() Solve A^Tx=b using QR factorisation QRupdate() Update explicit QR factors rot_cols() Apply Givens rotation to the columns of a matrix rot_rows() Apply Givens rotation to the rows of a matrix rot_vec() Apply Givens rotation to a vector rot_zvec() Apply complex Givens rotation to a vector schur() Compute real Schur form schur_evals() Compute eigenvalues from the real Schur form schur_vecs() Compute eigenvectors from the real Schur form set_col() Set the column of a matrix to a given vector set_err_flag() Control behaviour of ev_err() set_row() Set the row of a matrix to a given vector sm_mlt() Scalar-matrix multiplication smrand() Set seed for mrand() spBKPfactor() Sparse symmetric indefinite factorsiation spBKPsolve() Sparse symmetric indefinite solver spCHfactor() Sparse Cholesky factorisation spCHsolve() Sparse Cholesky solver spCHsymb() Symbolic sparse Cholesky factorisation (no floating point operations) sp_col_access() Sets up column access paths for a sparse matrix sp_compact() Eliminates zero entries in a sparse matrix sp_copy() Copies a sparse matrix sp_copy2() Copies a sparse matrix into another sp_diag_access() Sets up diagonal access paths for a sparse matrix sp_dump() Dump sparse matrix data structure to a stream sp_finput() Input sparse matrix from a stream sp_foutput() Output a sparse matrix to a stream sp_free() Free (deallocate) a sparse matrix sp_get() Allocate and initialise a sparse matrix sp_get_val() Get the (i,j) entry of a sparse matrix spICHfactor() Sparse incomplete Cholesky factorisation sp_input() Input a sparse matrix form stdin spLUfactor() Sparse LU factorisation using partial pivoting spLUsolve() Solves Ax=b using sparse LU factors spLUTsolve() Solves A^Tx=b using sparse LU factors sp_mv_mlt() Computes Ax for sparse A sp_output() Outputs a sparse matrix to a stream (macro) sp_resize() Resize a sparse matrix sprow_add() Adds a pair of sparse rows sprow_foutput() Output sparse row to a stream sprow_get() Allocate and initialise a sparse row sprow_get_idx() Get location of an entry in a sparse row sprow_merge() Merge two sparse rows sprow_mltadd() Sparse row vector multiply-and-add sprow_set_val() Set an entry in a sparse row sprow_smlt() Multiplies a sparse row by a scalar sprow_sub() Subtracts a sparse row from another sprow_xpd() Expand a sparse row sp_set_val() Set the (i,j) entry of a sparse matrix sp_vm_mlt() Compute x^TA for sparse A sp_zero() Zero (but do not remove) all entries of a sparse matrix svd() Compute the SVD of a matrix sv_mlt() Scalar-vector multiply symmeig() Compute eigenvalues/vectors of a symmetric matrix tracecatch() Catch and re-raise errors (macro) trieig() Compute eigenvalues/vectors of a symmetric tridiagonal matrix Usolve() Solve Ux=b where U is upper triangular UTsolve() Solve U^Tx=b where U is upper triangular v_add() Add vectors v_conv() Convolution product of vectors v_copy() Copy vector v_dump() Dump vector data structure to a stream v_finput() Input vector from a stream v_foutput() Output vector to a stream V_FREE() Free (deallocate) a vector (macro) v_free() Free (deallocate) vector (function) v_free_vars() Free a list of vectors v_get() Allocate and initialise a vector v_get_vars() Allocate list of vectors v_input() Input vector from stdin (macro) v_lincomb() Compute sum of a_i x_i for an array of vectors v_linlist() Compute sum of a_i x_i for a list of vectors v_map() Apply function componentwise to a vector v_max() Computes max vector entry and index v_min() Computes min vector entry and index v_mltadd() Computes y <- alpha*x+y for vectors x , y vm_mlt() Computes x^TA vm_mltadd() Computes y^T <- y^T+x^TA v_norm1() Computes ||x||_1 for a vector v_norm2() Computes ||x||_2 (the Euclidean norm) of a vector v_norm_inf() Computes ||x||_inf for a vector v_ones() Set vector to all 1's v_output() Output vector to stdout (macro) v_pconv() Periodic convolution of two vectors v_rand() Randomise entries of a vector v_resize() Resize a vector v_resize_vars() Resize a list of vectors v_save() Save a vector in MATLAB format v_slash() Computes componentwise ratio of vectors v_sort() Sorts vector components v_star() Componentwise vector product v_sub() Subtract two vectors v_sum() Sum of components of a vector v_zero() Zero a vector zabs() Complex absolute value (modulus) zadd() Add complex numbers zconj() Conjugate complex number zdiv() Divide complex numbers zexp() Complex exponential z_finput() Read complex number from file or stream z_foutput() Prints complex number to file or stream zgivens() Compute complex Givens' rotation zhhtrcols() Apply Householder transformation: PA (complex) zhhtrrows() Apply Householder transformation: AP (complex) zhhtrvec() Apply Householder transformation: Px (complex) zhhvec() Compute Householder transformation zin_prod() Complex inner product z_input() Read complex number from stdin zinv() Computes 1/z (complex) zLAsolve() Solve L^*x=b , L complex lower triangular zlog() Complex logarithm zLsolve() Solve Lx=b , L complex lower triangular zLUAsolve() Solve A^*x=b using complex LU factorisation (A^* - adjoint of A, A is complex) zLUcondest() Complex LU condition estimate zLUfactor() Complex LU factorisation zLUsolve() Solve Ax=b using complex LU factorisation zm_add() Add complex matrices zm_adjoint() Computes adjoint of complex matrix zmake() Construct complex number from real and imaginary parts zmakeQ() Construct Q matrix for complex QR zmakeR() Construct R matrix for complex QR zmam_mlt() Computes A^*B (complex) zm_dump() Dump complex matrix to stream zm_finput() Input complex matrix from stream ZM_FREE() Free (deallocate) complex matrix (macro) zm_free() Free (deallocate) complex matrix (function) zm_free_vars() Free a list of complex matrices zm_get() Allocate complex matrix zm_get_vars() Allocate a list of complex matrices zm_input() Input complex matrix from stdin zm_inverse() Compute inverse of complex matrix zm_load() Load complex matrix in MATLAB format zmlt() Multiply complex numbers zmma_mlt() Computes AB^* (complex) zm_mlt() Multiply complex matrices zm_norm1() Complex matrix 1-norm zm_norm_frob() Complex matrix Frobenius norm zm_norm_inf() Complex matrix infinity-norm zm_rand() Randomise complex matrix zm_resize() Resize complex matrix zm_resize_vars() Resize a list of complex matrices zm_save() Save complex matrix in MATLAB format zm_sub() Subtract complex matrices zmv_mlt() Complex matrix-vector multiply zmv_mltadd() Complex matrix-vector multiply and add zm_zero() Zero complex matrix zneg() Computes -z (complex) z_output() Print complex number to stdout zQRCPfactor() Complex QR factorisation with column pivoting zQRCPsolve() Solve Ax = b using complex QR factorisation zQRfactor() Complex QR factorisation zQRAsolve() Solve A^*x = b using complex QR factorisation zQRsolve() Solve Ax = b using complex QR factorisation zrot_cols() Complex Givens' rotation of columns zrot_rows() Complex Givens' rotation of rows z_save() Save complex number in MATLAB format zschur() Complex Schur factorisation zset_col() Set column of complex matrix zset_row() Set row of complex matrix zsm_mlt() Complex scalar-matrix product zsqrt() Square root z (complex) zsub() Subtract complex numbers zUAsolve() Solve U^*x=b , U complex upper triangular zUsolve() Solve Ux=b , U complex upper triangular zv_add() Add complex vectors zv_copy() Copy complex vector zv_dump() Dump complex vector to a stream zv_finput() Input complex vector from a stream ZV_FREE() Free (deallocate) complex vector (macro) zv_free() Free (deallocate) complex vector (function) zv_free_vars() Free a list of complex vectors zv_get() Allocate complex vector zv_get_vars() Allocate a list of complex vectors zv_input() Input complex vector from a stdin zv_lincomb() Compute sum of a_i x_i for an array of vectors zv_linlist() Compute sum of a_i x_i for a list of vectors zv_map() Apply function componentwise to a complex vector zv_mlt() Complex scalar-vector product zv_mltadd() Complex scalar-vector multiply and add zvm_mlt() Computes A^*x (complex) zvm_mltadd() Computes A^*x+y (complex) zv_norm1() Complex vector 1-norm vnorm1() zv_norm2() Complex vector 2-norm (Euclidean norm) zv_norm_inf() Complex vector infinity- (or supremum) norm zv_rand() Randomise complex vector zv_resize() Resize complex vector zv_resize_vars() Resize a list of complex vectors zv_save() Save complex vector in MATLAB format zv_slash() Componentwise ratio of complex vectors zv_star() Componentwise product of complex vectors zv_sub() Subtract complex vectors zv_sum() Sum of components of a complex vector zv_zero() Zero complex vector Low level routines Function Description __add__() Add arrays __ip__() Inner product of arrays MEM_COPY() Copy memory (macro) MEM_ZERO() Zero memory (macro) __mltadd__() Forms x+ alpha*y for arrays __smlt__() Scalar-vector multiplication for arrays __sub__() Subtract an array from another __zadd__() Add complex arrays __zconj__() Conjugate complex array __zero__() Zero an array __zip__() Complex inner product of arrays __zmlt__() Complex array scalar product __zmltadd__() Complex array saxpy __zsub__() Subtract complex arrays __zzero__() Zero a complex array gtk-wave-cleaner-0.22-04/meschach/DOC/tutorial.txt0000777000175000017500000013163413120075106023000 0ustar00alisteralister00000000000000 MESCHACH VERSION 1.2A --------------------- TUTORIAL ======== In this manual the basic data structures are introduced, and some of the more basic operations are illustrated. Then some examples of how to use the data structures and procedures to solve some simple problems are given. The first example program is a simple 4th order Runge-Kutta solver for ordinary differential equations. The second is a general least squares equation solver for over-determined equations. The third example illustrates how to solve a problem involving sparse matrices. These examples illustrate the use of matrices, matrix factorisations and solving systems of linear equations. The examples described in this manual are implemented in tutorial.c. While the description of each aspect of the system is brief and far from comprehensive, the aim is to show the different aspects of how to set up programs and routines and how these work in practice, which includes I/O and error-handling issues. 1. THE DATA STRUCTURES AND SOME BASIC OPERATIONS The three main data structures are those describing vectors, matrices and permutations. These have been used to create data structures for simplex tableaus for linear programming, and used with data structures for sparse matrices etc. To use the system reliably, you should always use pointers to these data structures and use library routines to do all the necessary initialisation. In fact, for the operations that involve memory management (creation, destruction and resizing), it is essential that you use the routines provided. For example, to create a matrix A of size 34 , a vector x of dimension 10, and a permutation p of size 10, use the following code: #include "matrix.h" .............. main() { MAT *A; VEC *x; PERM *p; .......... A = m_get(3,4); x = v_get(10); p = px_get(10); .......... } This initialises these data structures to have the given size. The matrix A and the vector x are initially all zero, while p is initially the identity permutation. They can be disposed of by calling M_FREE(A), V_FREE(x) and PX_FREE(p) respectively if you need to re-use the memory for something else. The elements of each data structure can be accessed directly using the members (or fields) of the corresponding structures. For example the (i,j) component of A is accessed by A->me[i][j], x_i by x->ve[i] and p_i by p->pe[i]. Their sizes are also directly accessible: A->m and A->n are the number of rows and columns of A respectively, x->dim is the dimension of x , and size of p is p->size. Note that the indexes are zero relative just as they are in ordinary C, so that the index i in x->ve[i] can range from 0 to x->dim -1 . Thus the total number of entries of a vector is exactly x->dim. While this alone is sufficient to allow a programmer to do any desired operation with vectors and matrices it is neither convenient for the programmer, nor efficient use of the CPU. A whole library has been implemented to reduce the burden on the programmer in implementing algorithms with vectors and matrices. For instance, to copy a vector from x to y it is sufficient to write y = v_copy(x,VNULL). The VNULL is the NULL vector, and usually tells the routine called to create a vector for output. Thus, the v_copy function will create a vector which has the same size as x and all the components are equal to those of x. If y has already been created then you can write y = v_copy(x,y); in general, writing ``v_copy(x,y);'' is not enough! If y is NULL, then it is created (to have the correct size, i.e. the same size as x), and if it is the wrong size, then it is resized to have the correct size (i.e. same size as x). Note that for all the following functions, the output value is returned, even if you have a non-NULL value as the output argument. This is the standard across the entire library. Addition, subtraction and scalar multiples of vectors can be computed by calls to library routines: v_add(x,y,out), v_sub(x,y,out), sv_mlt(s,x,out) where x and y are input vectors (with data type VEC *), out is the output vector (same data type) and s is a double precision number (data type double). There is also a special combination routine, which computes out=v_1+s,v_2 in a single routine: v_mltadd(v1,v2,s,out). This is not only extremely useful, it is also more efficient than using the scalar-vector multiply and vector addition routines separately. Inner products can be computed directly: in_prod(x,y) returns the inner product of x and y. Note that extended precision evaluation is not guaranteed. The standard installation options uses double precision operations throughout the library. Equivalent operations can be performed on matrices: m_add(A,B,C) which returns C=A+B , and sm_mlt(s,A,C) which returns C=sA . The data types of A, B and C are all MAT *, while that of s is type double as before. The matrix NULL is called MNULL. Multiplying matrices and vectors can be done by a single function call: mv_mlt(A,x,out) returns out=A*x while vm_mlt(A,x,out) returns out=A^T*x , or equivalently, out^T=x^T*A . Note that there is no distinction between row and column vectors unlike certain interactive environments such as MATLAB or MATCALC. Permutations are also an essential part of the package. Vectors can be permuted by using px_vec(p,x,p_x), rows and columns of matrices can be permuted by using px_rows(p,A,p_A), px_cols(p,A,A_p), and permutations can be multiplied using px_mlt(p1,p2,p1_p2) and inverted using px_inv(p,p_inv). The NULL permutation is called PXNULL. There are also utility routines to initialise or re-initialise these data structures: v_zero(x), m_zero(A), m_ident(A) (which sets A=I of the correct size), v_rand(x), m_rand(A) which sets the entries of x and A respectively to be randomly and uniformly selected between zero and one, and px_ident(p) which sets p to be an identity permutation. Input and output are accomplished by library routines v_input(x), m_input(A), and px_input(p). If a null object is passed to any of these input routines, all data will be obtained from the input file, which is stdin. If input is taken from a keyboard then the user will be prompted for all the data items needed; if input is taken from a file, then the input will have to be of the same format as that produced by the output routines, which are: v_output(x), m_output(A) and px_output(p). This output is both human and machine readable! If you wish to send the data to a file other than the standard output device stdout, or receive input from a file or device other than the standard input device stdin, take the appropriate routine above, use the ``foutpout'' suffix instead of just ``output'', and add a file pointer as the first argument. For example, to send a matrix A to a file called ``fred'', use the following: #include "matrix.h" ............. main() { FILE *fp; MAT *A; ............. fp = fopen("fred","w"); m_foutput(fp,A); ............. } These input routines allow for the presence of comments in the data. A comment in the input starts with a ``hash'' character ``#'', and continues to the end of the line. For example, the following is valid input for a 3-dimensional vector: # The initial vector must not be zero # x = Vector: dim: 3 -7 0 3 For general input/output which conforms to this format, allowing comments in the input files, use the input() and finput() macros. These are used to print out a prompt message if stdin is a terminal (or ``tty'' in Unix jargon), and to skip over any comments if input is from a non-interactive device. An example of the usage of these macros is: input("Input number of steps: ","%d",&steps); fp = stdin; finput(fp,"Input number of steps: ","%d",&steps); fp = fopen("fred","r"); finput(fp,"Input number of steps: ","%d",&steps); The "%d" is one of the format specifiers which are used in fscanf(); the last argument is the pointer to the variable (unless the variable is a string) just as for scanf() and fscanf(). The first two macro calls read input from stdin, the last from the file fred. If, in the first two calls, stdin is a keyboard (a ``tty'' in Unix jargon) then the prompt string "Input number of steps: " is printed out on the terminal. The second part of the library contains routines for various factorisation methods. To use it put #include "matrix2.h" at the beginning of your program. It contains factorisation and solution routines for LU, Cholesky and QR-factorisation methods, as well as update routines for Cholesky and QR factorisations. Supporting these are a number of Householder transformation and Givens' rotation routines. Also there is a routine for generating the Q matrix for a QR-factorisation, if it is needed explicitly, as it often is. There are routines for band factorisation and solution for LU and LDL^T factorisations. For using complex numbers, vectors and matrices include #include "zmatrix.h" for using the basic routines, and #include "zmatrix2.h" for the complex matrix factorisation routines. The zmatrix2.h file includes matrix.h and zmatrix.h so you don't need these files included together. For using the sparse matrix routines in the library you need to put #include "sparse.h" or, if you use any sparse factorisation routines, #include "sparse2.h" at the beginning of your file. The routines contained in the library include routines for creating, destroying, initialising and updating sparse matrices, and also routines for sparse matrix-dense vector multiplication, sparse LU factorisation and sparse Cholesky factorisation. For using the iterative routines you need to use #include "iter.h" This includes the sparse.h and matrix.h file. There are also routines for applying iterative methods such as pre-conditioned conjugate gradient methods to sparse matrices. And if you use the standard maths library (sin(), cos(), tan(), exp(), log(), sqrt(), acos() etc.) don't forget to include the standard mathematics header: #include This file is not automatically included by any of the Meschach header files. 2. HOW TO MANAGE MEMORY Unlike many other numerical libraries, Meschach allows you to allocate, deallocate and resize the vectors, matrices and permutations that you are using. To gain maximum benefit from this it is sometimes necessary to think a little about where memory is allocated and deallocated. There are two reasons for this. Memory allocation, deallocation and resizing takes a significant amount of time compared with (say) vector operations, so it should not be done too frequently. Allocating memory but not deallocating it means that it cannot be used by any other data structure. Data structures that are no longer needed should be explicitly deallocated, or kept as static variables for later use. Unlike other interpreted systems (such as Lisp) there is no implicit ``garbage collection'' of no-longer-used memory. There are three main strategies that are recommended for deciding how to allocate, deallocate and resize objects. These are ``no deallocation'' which is really only useful for demonstration programs, ``allocate and deallocate'' which minimises overall memory requirements at the expense of speed, and ``resize on demand'' which is useful for routines that are called repeatedly. A new technique for static workspace arrays is to ``register workspace variables''. 2.1 NO DEALLOCATION This is the strategy of allocating but never deallocating data structures. This is only useful for demonstration programs run with small to medium size data structures. For example, there could be a line QR = m_copy(A,MNULL); /* allocate memory for QR */ to allocate the memory, but without the call M_FREE(QR); in it. This can be acceptable if QR = m_copy(A,MNULL) is only executed once, and so the allocated memory never needs to be explicitly deallocated. This would not be acceptable if QR = m_copy(A,MNULL) occurred inside a for loop. If this were so, then memory would be ``lost'' as far as the program is concerned until there was insufficient space for allocating the next matrix for QR. The next subsection shows how to avoid this. 2.2 ALLOCATE AND DEALLOCATE This is the most straightforward way of ensuring that memory is not lost. With the example of allocating QR it would work like this: for ( ... ; ... ; ... ) { QR = m_copy(A,MNULL); /* allocate memory for QR */ /* could have been allocated by m_get() */ /* use QR */ ...... ...... /* no longer need QR for this cycle */ M_FREE(QR); /* deallocate QR so memory can be reused */ } The allocate and deallocate statements could also have come at the beginning and end of a function or procedure, so that when the function returns, all the memory that the function has allocated has been deallocated. This is most suitable for functions or sections of code that are called repeatedly but involve fairly extensive calculations (at least a matrix-matrix multiply, or solving a system of equations). 2.3 RESIZE ON DEMAND This technique reduces the time involved in memory allocation for code that is repeatedly called or used, especially where the same size matrix or vector is needed. For example, the vectors v1, v2, etc. in the Runge-Kutta routine rk4() are allocated according to this strategy: rk4(...,x,...) { static VEC *v1=VNULL, *v2=VNULL, *v3=VNULL, *v4=VNULL, *temp=VNULL; ....... v1 = v_resize(v1,x->dim); v2 = v_resize(v2,x->dim); v3 = v_resize(v3,x->dim); v4 = v_resize(v4,x->dim); temp = v_resize(temp,x->dim); ....... } The intention is that the rk4() routine is called repeatedly with the same size x vector. It then doesn't make as much sense to allocate v1, v2 etc. whenever the function is called. Instead, v_resize() only performs memory allocation if the memory already allocated to v1, v2 etc. is smaller than x->dim. The vectors v1, v2 etc. are declared to be static to ensure that their values are not lost between function calls. Variables that are declared static are set to NULL or zero by default. So the declaration of v1, v2, etc., could be static VEC *v1, *v2, *v3, *v4, *temp; This strategy of resizing static workspace variables is not so useful if the object being allocated is extremely large. The previous ``allocate and deallocate'' strategy is much more efficient for memory in those circumstances. However, the following section shows how to get the best of both worlds. 2.4 REGISTRATION OF WORKSPACE From version 1.2 onwards, workspace variables can be registered so that the memory they reference can be freed up on demand. To do this, the function containing the static workspace variables has to include calls to MEM_STAT_REG(var,type) where var is a pointer to a Meschach data type (such as VEC or MAT). This call should be placed after the call to the appropriate resize function. The type parameter should be a TYPE_... macro where the ``...'' is the name of a Meschach type such as VEC or MAT. For example, rk4(...,x,...) { static VEC *v1, *v2, *v3, *v4, *temp; ....... v1 = v_resize(v1,x->dim); MEM_STAT_REG(v1,TYPE_VEC); v2 = v_resize(v2,x->dim); MEM_STAT_REG(v2,TYPE_VEC); ...... } Normally, these registered workspace variables remain allocated. However, to implement the ``deallocate on exit'' approach, use the following code: ...... mem_stat_mark(1); rk4(...,x,...) mem_stat_free(1); ...... To keep the workspace vectors allocated for the duration of a loop, but then deallocated, use ...... mem_stat_mark(1); for (i = 0; i < N; i++ ) rk4(...,x,...); mem_stat_free(1); ...... The number used in the mem_stat_mark() and mem_stat_free() calls is the workspace group number. The call mem_stat_mark(1) designates 1 as the current workspace group number; the call mem_stat_free(1) deallocates (and sets to NULL) all static workspace variables registered as belonging to workspace group 1. 3. SIMPLE VECTOR OPERATIONS: AN RK4 ROUTINE The main purpose of this example is to show how to deal with vectors and to compute linear combinations. The problem here is to implement the standard 4th order Runge-Kutta method for the ODE x'=f(t,x), x(t_0)=x_0 for x(t_i), i=1,2,3, where t_i=t_0+i*h and h is the step size. The formulae for the 4th order Runge-Kutta method are: x_i+1 = x_i+ h/6*(v_1+2*v_2+2*v_3+v_4), where v_1 = f(t_i,x_i) v_2 = f(t_i+h, x_i+h*v_1) v_3 = f(t_i+h, x_i+h*v_2) v_4 = f(t_i+h, x_i+h*v_3) where the v_i are vectors. The procedure for implementing this method (rk4()) will be passed (a pointer to) the function f. The implementation of f could, in this system, create a vector to hold the return value each time it is called. However, such a scheme is memory intensive and the calls to the memory allocation functions could easily dominate the time performed doing numerical computations. So, the implementation of f will also be passed an already allocated vector to be filled in with the appropriate values. The procedure rk4() will also be passed the current time t, the step size h, and the current value for x. The time after the step will be returned by rk4(). The code that does this follows. #include "matrix.h" /* rk4 - 4th order Runge-Kutta method */ double rk4(f,t,x,h) double t, h; VEC *(*f)(), *x; { static VEC *v1=VNULL, *v2=VNULL, *v3=VNULL, *v4=VNULL; static VEC *temp=VNULL; /* do not work with NULL initial vector */ if ( x == VNULL ) error(E_NULL,"rk4"); /* ensure that v1, ..., v4, temp are of the correct size */ v1 = v_resize(v1,x->dim); v2 = v_resize(v2,x->dim); v3 = v_resize(v3,x->dim); v4 = v_resize(v4,x->dim); temp = v_resize(temp,x->dim); /* register workspace variables */ MEM_STAT_REG(v1,TYPE_VEC); MEM_STAT_REG(v2,TYPE_VEC); MEM_STAT_REG(v3,TYPE_VEC); MEM_STAT_REG(v4,TYPE_VEC); MEM_STAT_REG(temp,TYPE_VEC); /* end of memory allocation */ (*f)(t,x,v1); /* most compilers allow: f(t,x,v1); */ v_mltadd(x,v1,0.5*h,temp); /* temp = x+.5*h*v1 */ (*f)(t+0.5*h,temp,v2); v_mltadd(x,v2,0.5*h,temp); /* temp = x+.5*h*v2 */ (*f)(t+0.5*h,temp,v3); v_mltadd(x,v3,h,temp); /* temp = x+h*v3 */ (*f)(t+h,temp,v4); /* now add: v1+2*v2+2*v3+v4 */ v_copy(v1,temp); /* temp = v1 */ v_mltadd(temp,v2,2.0,temp); /* temp = v1+2*v2 */ v_mltadd(temp,v3,2.0,temp); /* temp = v1+2*v2+2*v3 */ v_add(temp,v4,temp); /* temp = v1+2*v2+2*v3+v4 */ /* adjust x */ v_mltadd(x,temp,h/6.0,x); /* x = x+(h/6)*temp */ return t+h; /* return the new time */ } Note that the last parameter of f() is where the output is placed. Often this can be NULL in which case the appropriate data structure is allocated and initialised. Note also that this routine can be used for problems of arbitrary size, and the dimension of the problem is determined directly from the data given. The vectors v_1,...,v_4 are created to have the correct size in the lines .... v1 = v_resize(v1,x->dim); v2 = v_resize(v2,x->dim); .... Here v_resize(v,dim) resizes the VEC structure v to hold a vector of length dim. If v is initially NULL, then this creates a new vector of dimension dim, just as v_get(dim) would do. For the above piece of code to work correctly, v1, v2 etc., must be initialised to be NULL vectors. This is done by the declaration static VEC *v1=VNULL, *v2=VNULL, *v3=VNULL, *v4=VNULL; or static VEC *v1, *v2, *v3, *v4; The operations of vector addition and scalar addition are really the only vector operations that need to be performed in rk4. Vector addition is done by v_add(v1,v2,out), where out=v1+v2, and scalar multiplication by sv_mlt(scale,v,out), where out=scale*v. These can be combined into a single operation v_mltadd(v1,v2,scale,out), where out=v1+scale*v2. As many operations in numerical mathematics involve accumulating scalar multiples, this is an extremely useful operation, as we can see above. For example: v_mltadd(x,v1,0.5*h,temp); /* temp = x+0.5*h*v1 */ We also need a number of ``utility'' operations. For example v_copy(in, out) copies the vector in to out. There is also v_zero(v) to zero a vector v. Here is an implementation of the function f for simple harmonic motion: /* f - right-hand side of ODE solver */ VEC *f(t,x,out) VEC *x, *out; double t; { if ( x == VNULL || out == VNULL ) error(E_NULL,"f"); if ( x->dim != 2 || out->dim != 2 ) error(E_SIZES,"f"); out->ve[0] = x->ve[1]; out->ve[1] = - x->ve[0]; return out; } As can be seen, most of this code is error checking code, which, of course, makes the routine safer but a little slower. For a procedure like f() it is probably not necessary, although then the main program would have to perform checking to ensure that the vectors involved have the correct size etc. The ith component of a vector x is x->ve[i], and indexing is zero-relative (i.e., the ``first'' component is component 0). The ODE described above is for simple harmonic motion: x_0'=x_1 , x_1'=-x_0 , or equivalently, x_0''+ x_0 = 0 . Here is the main program: #include #include "matrix.h" main() { VEC *x; VEC *f(); double h, t, t_fin; double rk4(); input("Input initial time: ", "%lf", &t); input("Input final time: ", "%lf", &t_fin); x = v_get(2); /* this is the size needed by f() */ prompter("Input initial state:\n"); x = v_input(VNULL); input("Input step size: ", "%lf", &h); printf("# At time %g, the state is\n",t); v_output(x); while ( t < t_fin ) { t = rk4(f,t,x,min(h,t_fin-t)); /* new t is returned */ printf("# At time %g, the state is\n",t); v_output(x); t += h; } } The initial values are entered as a vector by v_input(). If v_input() is passed a vector, then this vector will be used to store the input, and this vector has the size that x had on entry to v_input(). The original values of x are also used as a prompt on input from a tty. If a NULL is passed to v_input() then v_input() will return a vector of whatever size the user inputs. So, to ensure that only a two-dimensional vector is used for the initial conditions (which is what f() is expecting) we use x = v_get(2); x = v_input(x); To compile the program under Unix, if it is in a file tutorial.c: cc -o tutorial tutorial.c meschach.a or, if you have an ANSI compiler, cc -DANSI_C -o tutorial tutorial.c meschach.a Here is a sample session with the above program: tutorial Input initial time: 0 Input final time: 1 Input initial state: Vector: dim: 2 entry 0: -1 entry 1: b entry 0: old -1 new: 1 entry 1: old 0 new: 0 Input step size: 0.1 At time 0, the state is Vector: dim: 2 1 0 At time 0.1, the state is Vector: dim: 2 0.995004167 -0.0998333333 ................. At time 1, the state is Vector: dim: 2 0.540302967 -0.841470478 By way of comparison, the state at t=1 for the true solution is x_0(1)=0.5403023058 , x_1(1)=-0.8414709848 . The ``b'' that is typed in entering the x vector allows the user to alter previously entered components. In this case once this is done, the user is prompted with the old values when entering the new values. The user can also type in ``f'' for skipping over the vector's components, which are then unchanged. If an incorrectly sized initial value vector x is given, the error handler comes into action: Input initial time: 0 Input final time: 1 Input initial state: Vector: dim: 3 entry 0: 3 entry 1: 2 entry 2: -1 Input step size: 0.1 At time 0, the state is Vector: dim: 3 3 2 -1 "tutorial.c", line 79: sizes of objects don't match in function f() Sorry, aborting program The error handler prints out the error message giving the source code file and line number as well as the function name where the error was raised. The relevant section of f() in file tutorial.c is: if ( x->dim != 2 || out->dim != 2 ) error(E_SIZES,"f"); /* line 79 */ The standard routines in this system perform error checking of this type, and also checking for undefined results such as division by zero in the routines for solving systems of linear equations. There are also error messages for incorrectly formatted input and end-of-file conditions. To round off the discussion of this program, note that we have seen interactive input of vectors. If the input file or stream is not a tty (e.g., a file, a pipeline or a device) then it expects the input to have the same form as the output for each of the data structures. Each of the input routines (v_input(), m_input(), px_input()) skips over ``comments'' in the input data, as do the macros input() and finput(). Anything from a `#' to the end of the line (or EOF) is considered to be a comment. For example, the initial value problem could be set up in a file ivp.dat as: # Initial time 0 # Final time 1 # Solution is x(t) = (cos(t),-sin(t)) # x(0) = Vector: dim: 2 1 0 # Step size 0.1 The output of the above program with the above input (from a file) gives essentially the same output as shown above, except that no prompts are sent to the screen. 4. USING ROUTINES FOR LISTS OF ARGUMENTS Some of the most common routines have variants that take a variable number of arguments. These are the routines .._get_vars(), .._resize_vars() and .._free_vars(). These correspond to the the basic routines .._get(), .._resize() and .._free() respectively. Also there is the mem_stat_reg_vars() routine which registers a list of static workspace variables. This corresponds to mem_stat_reg_list() for a single variable. Here is an example of how to use these functions. This example also uses the routine v_linlist() to compute a linear combination of vectors. Note that the code is much more compact, but don't forget that these ``..._vars()'' routines usually need the address-of operator ``&'' and NULL termination of the arguments to work correctly. #include "matrix.h" /* rk4 - 4th order Runge-Kutta method */ double rk4(f,t,x,h) double t, h; VEC *(*f)(), *x; { static VEC *v1, *v2, *v3, *v4, *temp; /* do not work with NULL initial vector */ if ( x == VNULL ) error(E_NULL,"rk4"); /* ensure that v1, ..., v4, temp are of the correct size */ v_resize_vars(x->dim, &v1, &v2, &v3, &v4, &temp, NULL); /* register workspace variables */ mem_stat_reg_vars(0, TYPE_VEC, &v1, &v2, &v3, &v4, &temp, NULL); /* end of memory allocation */ (*f)(t,x,v1); v_mltadd(x,v1,0.5*h,temp); (*f)(t+0.5*h,temp,v2); v_mltadd(x,v2,0.5*h,temp); (*f)(t+0.5*h,temp,v3); v_mltadd(x,v3,h,temp); (*f)(t+h,temp,v4); /* now add: temp = v1+2*v2+2*v3+v4 */ v_linlist(temp, v1, 1.0, v2, 2.0, v3, 2.0, v4, 1.0, VNULL); /* adjust x */ v_mltadd(x,temp,h/6.0,x); /* x = x+(h/6)*temp */ return t+h; /* return the new time */ } 5. A LEAST SQUARES PROBLEM Here we need to use matrices and matrix factorisations (in particular, a QR factorisation) in order to find the best linear least squares solution to some data. Thus in order to solve the (approximate) equations A*x = b, where A is an m x n matrix (m > n) we really need to solve the optimisation problem min_x ||Ax-b||^2. If we write A=QR where Q is an orthogonal m x m matrix and R is an upper triangular m x n matrix then (we use 2-norm) ||A*x-b||^2 = ||R*x-Q^T*b||^2 = || R_1*x - Q_1^T*b||^2 + ||Q_2^T*b||^2 where R_1 is an n x n upper triangular matrix. If A has full rank then R_1 will be an invertible matrix, and the best least squares solution of A*x=b is x= R_1^{-1}*Q_1^T*b . These calculations can be be done quite easily as there is a QRfactor() function available with the system. QRfactor() is declared to have the prototype MAT *QRfactor(MAT *A, VEC *diag); The matrix A is overwritten with the factorisation of A ``in compact form''; that is, while the upper triangular part of A is indeed the R matrix described above, the Q matrix is stored as a collection of Householder vectors in the strictly lower triangular part of A and in the diag vector. The QRsolve() function knows and uses this compact form and solves Q*R*x=b with the call QRsolve(A,diag,b,x), which also returns x. Here is the code to obtain the matrix A, perform the QR factorisation, obtain the data vector b, solve for x, and determine what the norm of the errors ( ||Ax-b||_2 ) is. #include "matrix2.h" main() { MAT *A, *QR; VEC *b, *x, *diag; /* read in A matrix */ printf("Input A matrix:"); A = m_input(MNULL); /* A has whatever size is input */ if ( A->m < A->n ) { printf("Need m >= n to obtain least squares fit"); exit(0); } printf("# A ="); m_output(A); diag = v_get(A->m); /* QR is to be the QR factorisation of A */ QR = m_copy(A,MNULL); QRfactor(QR,diag); /* read in b vector */ printf("Input b vector:"); b = v_get(A->m); b = v_input(b); printf("# b ="); v_output(b); /* solve for x */ x = QRsolve(QR,diag,b,VNULL); printf("Vector of best fit parameters is"); v_output(x); /* ... and work out norm of errors... */ printf("||A*x-b|| = %g\n", v_norm2(v_sub(mv_mlt(A,x,VNULL),b,VNULL))); } Note that as well as the usual memory allocation functions like m_get(), the I/O functions like m_input() and m_output(), and the factorise-and-solve functions QRfactor() and QRsolve(), there are also functions for matrix-vector multiplication: mv_mlt(MAT *A, VEC *x, VEC *out) and also vector-matrix multiplication (with the vector on the left): vm_mlt(MAT *A, VEC *x, VEC *out), with out=x^T A. There are also functions to perform matrix arithmetic - matrix addition m_add(), matrix-scalar multiplication sm_mlt(), matrix-matrix multiplication m_mlt(). Several different sorts of matrix factorisation are supported: LU factorisation (also known as Gaussian elimination) with partial pivoting, by LUfactor() and LUsolve(). Other factorisation methods include Cholesky factorisation CHfactor() and CHsolve(), and QR factorisation with column pivoting QRCPfactor(). Pivoting involve permutations which have their own PERM data structure. Permutations can be created by px_get(), read and written by px_input() and px_output(), multiplied by px_mlt(), inverted by px_inv() and applied to vectors by px_vec(). The above program can be put into a file leastsq.c and compiled under Unix using cc -o leastsq leastsq.c meschach.a -lm A sample session using leastsq follows: Input A matrix: Matrix: rows cols:5 3 row 0: entry (0,0): 3 entry (0,1): -1 entry (0,2): 2 Continue: row 1: entry (1,0): 2 entry (1,1): -1 entry (1,2): 1 Continue: n row 1: entry (1,0): old 2 new: 2 entry (1,1): old -1 new: -1 entry (1,2): old 1 new: 1.2 Continue: row 2: entry (2,0): old 0 new: 2.5 .... .... (Data entry) .... # A = Matrix: 5 by 3 row 0: 3 -1 2 row 1: 2 -1 1.2 row 2: 2.5 1 -1.5 row 3: 3 1 1 row 4: -1 1 -2.2 Input b vector: entry 0: old 0 new: 5 entry 1: old 0 new: 3 entry 2: old 0 new: 2 entry 3: old 0 new: 4 entry 4: old 0 new: 6 # b = Vector: dim: 5 5 3 2 4 6 Vector of best fit parameters is Vector: dim: 3 1.47241555 -0.402817858 -1.14411815 ||A*x-b|| = 6.78938 The Q matrix can be obtained explicitly by the routine makeQ(). The Q matrix can then be used to obtain an orthogonal basis for the range of A . An orthogonal basis for the null space of A can be obtained by finding the QR-factorisation of A^T . 6. A SPARSE MATRIX EXAMPLE To illustrate the sparse matrix routines, consider the problem of solving Poisson's equation on a square using finite differences, and incomplete Cholesky factorisation. The actual equations to solve are u_{i,j+1} + u_{i,j-1} + u_{i+1,j} + u_{i-1,j} - 4*u_{i,j} = h^2*f(x_i,y_j), for i,j=1,...,N where u_{0,j} = u_{i,0} = u_{N+1,j} = u_{i,N+1} = 0 for i,j=1,...,N and h is the common distance between grid points. The first task is to set up the matrix describing this system of linear equations. The next is to set up the right-hand side. The third is to form the incomplete Cholesky factorisation of this matrix, and finally to use the sparse matrix conjugate gradient routine with the incomplete Cholesky factorisation as preconditioner. Setting up the matrix and right-hand side can be done by the following code: #define N 100 #define index(i,j) (N*((i)-1)+(j)-1) ...... A = sp_get(N*N,N*N,5); b = v_get(N*N); h = 1.0/(N+1); /* for a unit square */ ...... for ( i = 1; i <= N; i++ ) for ( j = 1; j <= N; j++ ) { if ( i < N ) sp_set_val(A,index(i,j),index(i+1,j),-1.0); if ( i > 1 ) sp_set_val(A,index(i,j),index(i-1,j),-1.0); if ( j < N ) sp_set_val(A,index(i,j),index(i,j+1),-1.0); if ( j > 1 ) sp_set_val(A,index(i,j),index(i,j-1),-1.0); sp_set_val(A,index(i,j),index(i,j),4.0); b->ve[index(i,j)] = -h*h*f(h*i,h*j); } Once the matrix and right-hand side are set up, the next task is to compute the sparse incomplete Cholesky factorisation of A. This must be done in a different matrix, so A must be copied. LLT = sp_copy(A); spICHfactor(LLT); Now when that is done, the remainder is easy: out = v_get(A->m); ...... iter_spcg(A,LLT,b,1e-6,out,1000,&num_steps); printf("Number of iterations = %d\n",num_steps); ...... and the output can be used in whatever way desired. For graphical output of the results, the solution vector can be copied into a square matrix, which is then saved in MATLAB format using m_save(), and graphical output can be produced by MATLAB. 7. HOW DO I ....? For the convenience of the user, here a number of common tasks that people need to perform frequently, and how to perform the computations using Meschach. 7.1 .... SOLVE A SYSTEM OF LINEAR EQUATIONS ? If you wish to solve Ax=b for x given A and b (without destroying A), then the following code will do this: VEC *x, *b; MAT *A, *LU; PERM *pivot; ...... LU = m_get(A->m,A->n); LU = m_copy(A,LU); pivot = px_get(A->m); LUfactor(LU,pivot); /* set values of b here */ x = LUsolve(LU,pivot,b,VNULL); 7.2 .... SOLVE A LEAST-SQUARES PROBLEM ? To minimise ||Ax-b||_2^2 = sum_i ((Ax)_i-b_i)^2, the most reliable method is based on the QR-factorisation. The following code performs this calculation assuming that A is m x n with m > n : MAT *A, *QR; VEC *diag, *b, *x; ...... QR = m_get(A->m,A->n); QR = m_copy(A,QR); diag = v_get(A->n); QRfactor(QR,diag); /* set values of b here */ x = QRsolve(QR,diag,b,x); 7.3 .... FIND ALL THE EIGENVALUES (AND EIGENVECTORS) OF A GENERAL MATRIX ? The best method is based on the Schur decomposition. For symmetric matrices, the eigenvalues and eigenvectors can be computed by a single call to symmeig(). For non-symmetric matrices, the situation is more complex and the problem of finding eigenvalues and eigenvectors can become quite ill-conditioned. Provided the problem is not too ill-conditioned, the following code should give accurate results: /* A is the matrix whose eigenvalues and eigenvectors are sought */ MAT *A, *T, *Q, *X_re, *X_im; VEC *evals_re, *evals_im; ...... Q = m_get(A->m,A->n); T = m_copy(A,MNULL); /* compute Schur form: A = Q*T*Q^T */ schur(T,Q); /* extract eigenvalues */ evals_re = v_get(A->m); evals_im = v_get(A->m); schur_evals(T,evals_re,evals_im); /* Q not needed for eiegenvalues */ X_re = m_get(A->m,A->n); X_im = m_get(A->m,A->n); schur_vecs(T,Q,X_re,X_im); /* k'th eigenvector is k'th column of (X_re + i*X_im) */ 7.4 .... SOLVE A LARGE, SPARSE, POSITIVE DEFINITE SYSTEM OF EQUATIONS ? An example of a large, sparse, positive definite matrix is the matrix obtained from a finite-difference approximation of the Laplacian operator. If an explicit representation of such a matrix is available, then the following code is suggested as a reasonable way of computing solutions: /* A*x == b is the system to be solved */ SPMAT *A, *LLT; VEC *x, *b; int num_steps; ...... /* set up A and b */ ...... x = m_get(A->m); LLT = sp_copy(A); /* preconditioning using the incomplete Cholesky factorisation */ spICHfactor(LLT); /* now use pre-conditioned conjugate gradients */ x = iter_spcg(A,LLT,b,1e-7,x,1000,&num_steps); /* solution computed to give a relative residual of 10^-7 */ If explicitly storing such a matrix takes up too much memory, then if you can write a routine to perform the calculation of A*x for any given x , the following code may be more suitable (if slower): VEC *mult_routine(user_def,x,out) void *user_def; VEC *x, *out; { /* compute out = A*x */ ...... return out; } main() { ITER *ip; VEC *x, *b; ...... b = v_get(BIG_DIM); /* right-hand side */ x = v_get(BIG_DIM); /* solution */ /* set up b */ ...... ip = iter_get(b->dim, x->dim); ip->b = v_copy(b,ip->b); ip->info = NULL; /* if you don't want information about solution process */ v_zero(ip->x); /* initial guess is zero */ iter_Ax(ip,mult_routine,user_def); iter_cg(ip); printf("# Solution is:\n"); v_output(ip->x); ...... ITER_FREE(ip); /* destroy ip */ } The user_def argument is for a pointer to a user-defined structure (possibly NULL, if you don't need this) so that you can write a common function for handling a large number of different circumstances. 8. MORE ADVANCED TOPICS Read this if you are interested in using Meschach library as a base for applications. As an example we show how to implement a new type for 3 dimensional matrices and incorporate this new type into the Meschach system. Usually this part of Meschach is transparent to a user. But a more advanced user can take advantage of these routines. We do not describe the routines in detail here, but we want to give a rather broad picture of what can be done. By the system we mainly mean the system of delivering information on the number of bytes of allocated memory and routines for deallocating static variables by mem_stat_... routines. First we introduce a concept of a list of types. By a list of types we mean a set of different types with corresponding routines for creating these types, destroying and resizing them. Each type list has a number. The list 0 is a list of standard Meschach types such as MAT or VEC. Other lists can be defined by a user or a application (based on Meschach). The user can attach his/her own list to the system by the routine mem_attach_list(). Sometimes it is worth checking if a list number is already used by another application. It can be done by mem_is_list_attached(ls_num), which returns TRUE if the number ls_num is used. And such a list can be removed from the system by mem_free_list(ls_num) if necessary. We describe arguments required by mem_attach_list(). The prototype of this function is as follow int mem_attach_list(int ls_num, int ntypes, char *type_names[], int (*free_funcs[])(), MEM_ARRAY sum[]); where the structure MEM_ARRAY has two members: "bytes" of type long and "numvar" of type int. The frst argument is the list number. Note that you cannot overwrite another list. To do this remove first the old list (by mem_free_list()) or choose another number. The next argument is the number of types which are on the list. This number cannot be changed during running a program. The third argument is an array containing the names of types (these are character strings). The fourth one is an array of functions deallocating variables of the corresponding type. And the last argument is the local array where information about the number of bytes of allocated/deallocated memory (member bytes) and the number of allocated variables (member numvar) are gathered. The functions which send information to this array are mem_bytes_list() and mem_numvar_list(). Example: The routines described here are in the file tutadv.c. Firstly we define some macros and a type for 3 dimensional matrices. #include "matrix.h" #define M3D_LIST 3 /* list number */ #define TYPE_MAT3D 0 /* the number of a type */ /* type for 3 dimensional matrices */ typedef struct { int l,m,n; /* actual dimensions */ int max_l, max_m, max_n; /* maximal dimensions */ Real ***me; /* pointer to matrix elements */ /* we do not consider segmented memory */ Real *base, **me2d; /* me and me2d are additional pointers to base */ } MAT3D; Now we need two routines: one for allocating memory for 3 dimensional matrices and the other for deallocating it. It can be useful to have a routine for resizing 3 dimensional matrices but we do not use it here. Note the use of mem_bytes_list() and mem_numvar_list() to notify the change in the number of structures and bytes in use. /* function for creating a variable of MAT3D type */ MAT3D *m3d_get(l,m,n) int l,m,n; { MAT3D *mat; .... /* alocate memory for structure */ if ((mat = NEW(MAT3D)) == (MAT3D *)NULL) error(E_MEM,"m3d_get"); else if (mem_info_is_on()) { /* record how many bytes are allocated to structure */ mem_bytes_list(TYPE_MAT3D,0,sizeof(MAT3D),M3D_LIST); /* record a new allocated variable */ mem_numvar_list(TYPE_MAT3D,1,M3D_LIST); } .... /* allocate memory for 3D array */ if ((mat->base = NEW_A(l*m*n,Real)) == (Real *)NULL) error(E_MEM,"m3d_get"); else if (mem_info_is_on()) mem_bytes_list(TYPE_MAT3D,0,l*m*n*sizeof(Real),M3D_LIST); .... return mat; } /* deallocate a variable of type MAT3D */ int m3d_free(mat) MAT3D *mat; { /* do not try to deallocate the NULL pointer */ if (mat == (MAT3D *)NULL) return -1; .... /* first deallocate base */ if (mat->base != (Real *)NULL) { if (mem_info_is_on()) /* record how many bytes is deallocated */ mem_bytes_list(TYPE_MAT3D,mat->max_l*mat->max_m*mat->max_n*sizeof(Real), 0,M3D_LIST); free((char *)mat->base); } .... /* deallocate MAT3D structure */ if (mem_info_is_on()) { mem_bytes_list(TYPE_MAT3D,sizeof(MAT3D),0,M3D_LIST); mem_numvar_list(TYPE_MAT3D,-1,M3D_LIST); } free((char *)mat); .... free((char *)mat); return 0; } We can now create the arrays necessary for mem_attach_list(). Note that m3d_sum can be static if it is in the same file as main(), where mem_attach_list is called. Otherwise it must be global. char *m3d_names[] = { "MAT3D" }; #define M3D_NUM (sizeof(m3d_names)/sizeof(*m3d_names)) int (*m3d_free_funcs[M3D_NUM])() = { m3d_free } static MEM_ARRAY m3d_sum[M3D_NUM]; The last thing is to attach the list to the system. void main() { MAT3D *M; .... mem_info_on(TRUE); /* switch memory info on */ /* attach the new list */ mem_attach_list(M3D_LIST,M3D_NUM,m3d_names,m3d_free_funcs,m3d_sum); .... M = m3d_get(3,4,5); .... /* making use of M->me[i][j][k], where i,j,k are non-negative and i < 3, j < 4, k < 5 */ .... mem_info_file(stdout,M3D_LIST); /* info on the number of allocated bytes of memory for types on the list M3D_LIST */ .... m3d_free(M); /* if M is not necessary */ .... } We can now use the function mem_info_file() for getting information about the number of bytes of allocated memory and number of allocated variables of type MAT3D; mem_stat_reg_list() for registering variables of this type and mem_stat_mark() and mem_stat_free_list() for deallocating static variables of this type. In the similar way you can create you own list of errors and attach it to the system. See the functions: int err_list_attach(int list_num, int list_len, char **err_ptr, int warn); /* for attaching a list of errors */ int err_is_list_attached(int list_num); /* checking if a list is attached */ extern int err_list_free(int list_num); /* freeing a list of errors */ where list_num is the number of the error list, list_len is the number of errors on the list, err_ptr is the character string explaining the error and warn can be TRUE if this is only a warning (the program continues to run) or it can be FALSE if it is an error (the program stops). The examples are the standard errors (error list 0) and warnings (error list 1) which are in the file err.c David Stewart and Zbigniew Leyk, 1993 gtk-wave-cleaner-0.22-04/meschach/FILELIST0000777000175000017500000001615513120075106021125 0ustar00alisteralister00000000000000-rw-r--r-- 1 5066 Nov 21 2002 arnoldi.c -rw-r--r-- 1 18361 Dec 6 2002 bdfactor.c -rw-r--r-- 1 8682 Dec 2 2002 bkpfacto.c -rw-r--r-- 1 5524 Dec 2 2002 chfactor.c -rwxr-xr-x 1 60386 Nov 25 2002 configure -rw-r--r-- 1 3711 Nov 26 2002 configure.in -rw-r--r-- 1 8278 May 10 1995 conjgrad.c -rw-r--r-- 1 6338 Dec 2 2002 copy.c -rw-r--r-- 1 1124 Jan 12 1994 copyright -rw-r--r-- 1 1402 Jan 12 1994 dmacheps.c -rw-r--r-- 1 10319 Dec 2 2002 err.c -rw-r--r-- 2 5718 Oct 6 2003 err.h -rw-r--r-- 1 10931 Jun 8 1995 extras.c -rw-r--r-- 1 4082 Dec 2 2002 fft.c -rw-r--r-- 1 0 Sep 12 15:28 FILELIST -rw-r--r-- 1 1400 Jan 12 1994 fmacheps.c -rw-r--r-- 1 4167 Dec 2 2002 givens.c -rw-r--r-- 1 4494 Dec 2 2002 hessen.c -rw-r--r-- 1 6489 Dec 2 2002 hsehldr.c -rw-r--r-- 1 6499 Nov 27 2002 init.c -rw-r--r-- 1 3396 Jan 13 1994 iotort.c -rw-r--r-- 1 9894 Oct 7 2003 iter0.c -rw-r--r-- 1 7143 Dec 10 2002 iter.h -rw-r--r-- 1 33308 Dec 10 2002 iternsym.c -rw-r--r-- 1 15322 Dec 10 2002 itersym.c -rw-r--r-- 1 16178 Dec 12 1994 itertort.c -rw-r--r-- 1 7537 Nov 27 2002 ivecop.c -rw-r--r-- 1 7849 Nov 21 2002 lanczos.c -rw-r--r-- 1 397 Jan 12 1994 ls.dat -rw-r--r-- 1 7434 Dec 2 2002 lufactor.c -rw-r--r-- 1 4184 Nov 27 2002 machine.c -rw-r--r-- 1 3820 Oct 6 2003 machine.h -rw-r--r-- 1 4485 Nov 25 2002 machine.h.in -rw-r--r-- 1 5640 Nov 4 2003 makefile -rw-r--r-- 1 5898 Jun 22 1994 makefile.in -rw-r--r-- 1 5563 Dec 2 2002 matlab.c -rw-r--r-- 2 3030 Oct 6 2003 matlab.h -rw-r--r-- 1 13336 Nov 27 2002 matop.c -rw-r--r-- 1 8919 Oct 7 2003 matrix2.h -rw-r--r-- 1 21822 Oct 28 2003 matrix.h -rw-r--r-- 1 19519 Oct 7 2003 matrixio.c -rw-r--r-- 1 1257 Jan 12 1994 maxint.c -rw-r--r-- 1 10285 Dec 2 2002 meminfo.c -rw-r--r-- 2 4433 Nov 27 2002 meminfo.h -rw-r--r-- 1 20695 Nov 27 2002 memory.c -rw-r--r-- 1 9822 Oct 7 2003 memstat.c -rw-r--r-- 1 17441 Oct 29 2003 memtort.c -rw-r--r-- 1 9887 Dec 3 2002 mfunc.c -rw-r--r-- 1 4533 Jan 13 1994 mfuntort.c -rw-r--r-- 1 4698 Dec 3 2002 norm.c -rw-r--r-- 2 3853 Jan 12 1994 oldnames.h -rw-r--r-- 1 4520 Nov 27 2002 otherio.c -rw-r--r-- 1 8200 Dec 2 2002 pxop.c -rw-r--r-- 1 14475 Dec 2 2002 qrfactor.c -rw-r--r-- 1 18006 Apr 5 1994 README -rw-r--r-- 1 141 Jan 12 1994 rk4.dat -rw-r--r-- 1 18931 Dec 6 2002 schur.c -rw-r--r-- 1 7288 Dec 2 2002 solve.c -rw-r--r-- 1 3263 Oct 7 2003 sparse2.h -rw-r--r-- 1 26329 Dec 3 2002 sparse.c -rw-r--r-- 1 6730 Oct 7 2003 sparse.h -rw-r--r-- 1 9214 Nov 2 2003 sparseio.c -rw-r--r-- 1 36832 Oct 7 2003 spbkp.c -rw-r--r-- 1 16329 Dec 3 2002 spchfctr.c -rw-r--r-- 1 11245 Oct 7 2003 splufctr.c -rw-r--r-- 1 18991 Oct 7 2003 sprow.c -rw-r--r-- 1 7929 Dec 9 2002 spswap.c -rw-r--r-- 1 11295 Jun 9 1995 sptort.c -rw-r--r-- 1 5259 Dec 2 2002 submat.c -rw-r--r-- 1 10508 Dec 2 2002 svd.c -rw-r--r-- 1 6229 Dec 2 2002 symmeig.c -rw-r--r-- 1 28117 Nov 26 2002 torture.c -rw-r--r-- 1 4508 May 19 1994 tutadv.c -rw-r--r-- 1 7794 Nov 27 2002 tutorial.c -rw-r--r-- 1 3599 Dec 2 2002 update.c -rw-r--r-- 1 15005 Dec 2 2002 vecop.c -rw-r--r-- 1 2599 Aug 20 1996 version.c -rw-r--r-- 1 5842 Oct 7 2003 zcopy.c -rw-r--r-- 1 4556 Nov 15 2002 zfunc.c -rw-r--r-- 1 4907 Nov 15 2002 zgivens.c -rw-r--r-- 1 4159 Nov 26 2002 zhessen.c -rw-r--r-- 1 6651 Nov 27 2002 zhsehldr.c -rw-r--r-- 1 7259 Nov 26 2002 zlufctr.c -rw-r--r-- 1 4909 Oct 7 2003 zmachine.c -rw-r--r-- 1 11566 Dec 10 2002 zmatio.c -rw-r--r-- 1 6155 Jun 7 1995 zmatlab.c -rw-r--r-- 1 15369 May 10 1995 zmatop.c -rw-r--r-- 2 4273 Nov 26 2002 zmatrix2.h -rw-r--r-- 1 10779 Oct 7 2003 zmatrix.h -rw-r--r-- 1 15742 Dec 11 2002 zmemory.c -rw-r--r-- 1 4624 Nov 15 2002 znorm.c -rw-r--r-- 1 14186 Nov 26 2002 zqrfctr.c -rw-r--r-- 1 11267 Nov 21 2002 zschur.c -rw-r--r-- 1 7608 Nov 15 2002 zsolve.c -rw-r--r-- 1 20120 Nov 27 2002 ztorture.c -rw-r--r-- 1 12512 Oct 7 2003 zvecop.c DOC: total 72 -rw------- 1 17186 Jan 13 1994 fnindex.txt -rw------- 1 45980 Jan 13 1994 tutorial.txt MACHINES: total 40 -rw------- 1 7979 Dec 4 1998 cornelison drwx------ 2 8192 Jan 3 1998 Cray drwx------ 2 96 Jan 3 1998 GCC drwx------ 2 96 Jan 3 1998 Linux drwx------ 2 96 Mar 1 2001 MicroSoft drwx------ 2 96 Jan 3 1998 OS2 drwx------ 2 96 Jan 3 1998 RS6000 drwx------ 2 96 Jan 3 1998 SGI drwx------ 2 96 Jan 3 1998 SPARC drwx------ 2 8192 Jan 3 1998 ThinkC drwx------ 2 8192 Jan 3 1998 TurboC drwx------ 2 96 Jan 3 1998 WatcomPC -rw------- 1 7287 Aug 28 1995 w-mckinnon MACHINES/Cray: total 64 -rw------- 1 4645 Oct 27 1994 machine.h -rw------- 1 6053 Oct 27 1994 makefile -rw------- 1 7565 Sep 11 1997 mesch-cray.tar.Z -rw------- 1 10459 Sep 11 1997 mesch-cray.tar.Z.uu -rw------- 1 1951 Oct 27 1994 patch.1 -rw------- 1 687 Oct 27 1994 patch.2 -rw------- 1 298 Oct 27 1994 patch.3 MACHINES/GCC: total 16 -rw------- 1 3775 Jan 13 1994 machine.h -rw------- 1 5192 Mar 27 1995 makefile MACHINES/Linux: total 16 -rw------- 1 3820 Mar 2 1994 machine.h -rw------- 1 5604 Mar 27 1995 makefile MACHINES/MicroSoft: total 24 -rw------- 1 4812 Feb 28 2001 machine.h -rw------- 1 6930 Feb 28 2001 makefile -rw------- 1 4007 Mar 1 2001 stewart.zip MACHINES/OS2: total 24 -rw------- 1 3775 Oct 4 1995 machine.h -rw------- 1 5556 Oct 4 1995 makefile -rw------- 1 924 Oct 4 1995 README MACHINES/RS6000: total 24 -rw------- 1 6129 Jan 24 1994 machine.c -rw------- 1 3502 Jan 13 1994 machine.h -rw------- 1 5663 Mar 27 1995 makefile MACHINES/SGI: total 16 -rw------- 1 4635 Oct 27 1994 machine.h -rw------- 1 5938 Oct 27 1994 makefile MACHINES/SPARC: total 16 -rw------- 1 3524 Jan 13 1994 machine.h -rw------- 1 5195 Mar 27 1995 makefile MACHINES/ThinkC: total 64 -rw------- 1 9551 Jun 8 1995 machine.h -rw------- 1 3777 Sep 8 1995 README -rw------- 1 10293 Jun 13 1995 TC-machine-2.h -rw------- 1 10226 Jun 9 1995 TC-machine.h -rw------- 1 7145 Jun 9 1995 TC-README MACHINES/TurboC: total 400 -rw------- 1 44 Sep 11 1997 filelist -rw------- 1 5305 Aug 21 1996 machine.h -rw------- 1 122628 Jan 19 1996 mail -rw------- 1 8142 Oct 14 1995 meschach.mak -rw------- 1 104575 Sep 11 1997 meschtc.zip -rw------- 1 144112 Sep 11 1997 meschtc.zip.uu -rw------- 1 749 Oct 14 1995 README MACHINES/WatcomPC: total 8 -rw------- 1 4788 May 7 1996 machine.h gtk-wave-cleaner-0.22-04/meschach/MACHINES/0000755000175000017500000000000013252653022021144 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/Cray/0000755000175000017500000000000013252653022022042 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/Cray/machine.h0000777000175000017500000001104513120075106023622 0ustar00alisteralister00000000000000/* machine.h. Generated automatically by configure. */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* RCS id: $Id: machine.h.in,v 1.2 1994/03/13 23:07:30 des Exp $ */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ #include #define const /* #undef MALLOCDECL */ #define NOT_SEGMENTED 1 #define HAVE_MEMORY_H 1 #define HAVE_COMPLEX_H 1 #define HAVE_MALLOC_H 1 #define STDC_HEADERS 1 #define HAVE_BCOPY 1 #define HAVE_BZERO 1 #define CHAR0ISDBL0 1 #define WORDS_BIGENDIAN 1 /* #undef U_INT_DEF */ #define VARARGS 1 #define HAVE_PROTOTYPES 1 /* #undef HAVE_PROTOTYPES_IN_STRUCT */ /* for inclusion into C++ files */ #ifdef __cplusplus #define ANSI_C 1 #ifndef HAVE_PROTOTYPES #define HAVE_PROTOTYPES 1 #endif #ifndef HAVE_PROTOTYPES_IN_STRUCT #define HAVE_PROTOTYPES_IN_STRUCT 1 #endif #endif /* __cplusplus */ /* example usage: VEC *PROTO(v_get,(int dim)); */ #ifdef HAVE_PROTOTYPES #define PROTO(name,args) name args #else #define PROTO(name,args) name() #endif /* HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES_IN_STRUCT /* PROTO_() is to be used instead of PROTO() in struct's and typedef's */ #define PROTO_(name,args) name args #else #define PROTO_(name,args) name() #endif /* HAVE_PROTOTYPES_IN_STRUCT */ /* for basic or larger versions */ #define COMPLEX 1 #define SPARSE 1 /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 #define REAL_FLT 1 /* #undef REAL_DBL */ /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 7.10543e-15 #define D_MACHEPS 7.10543e-15 #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT 9223372036854775807 #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #else /* #undef HUGE */ #define HUGE HUGE_VAL #endif #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/Cray/makefile0000777000175000017500000001364513120075106023555 0ustar00alisteralister00000000000000# Generated automatically from makefile.in by configure. # # Makefile for Meschach via autoconf # # Copyright (C) David Stewart & Zbigniew Leyk 1993 # # $Id: makefile.in,v 1.4 1994/03/14 01:24:06 des Exp $ # srcdir = . VPATH = . CC = cc DEFS = -DHAVE_CONFIG_H LIBS = -lm RANLIB = : CFLAGS = -O .c.o: $(CC) -c $(CFLAGS) $(DEFS) $< SHELL = /bin/sh MES_PAK = mesch12b TAR = tar SHAR = stree -u ZIP = zip -r -l FLIST = FILELIST ############################### LIST1 = copy.o err.o matrixio.o memory.o vecop.o matop.o pxop.o \ submat.o init.o otherio.o machine.o matlab.o ivecop.o version.o \ meminfo.o memstat.o LIST2 = lufactor.o bkpfacto.o chfactor.o qrfactor.o solve.o hsehldr.o \ givens.o update.o norm.o hessen.o symmeig.o schur.o svd.o fft.o \ mfunc.o bdfactor.o LIST3 = sparse.o sprow.o sparseio.o spchfctr.o splufctr.o \ spbkp.o spswap.o iter0.o itersym.o iternsym.o ZLIST1 = zmachine.o zcopy.o zmatio.o zmemory.o zvecop.o zmatop.o znorm.o \ zfunc.o ZLIST2 = zlufctr.o zsolve.o zmatlab.o zhsehldr.o zqrfctr.o \ zgivens.o zhessen.o zschur.o # they are no longer supported # if you use them add oldpart to all and sparse OLDLIST = conjgrad.o lanczos.o arnoldi.o ALL_LISTS = $(LIST1) $(LIST2) $(LIST3) $(ZLIST1) $(ZLIST2) $(OLDLIST) HBASE = err.h meminfo.h machine.h matrix.h HLIST = $(HBASE) iter.h matlab.h matrix2.h oldnames.h sparse.h \ sparse2.h zmatrix.h zmatrix2.h TORTURE = torture.o sptort.o ztorture.o memtort.o itertort.o \ mfuntort.o iotort.o OTHERS = dmacheps.c extras.c fmacheps.c maxint.c makefile.in \ README configure configure.in machine.h.in copyright \ tutorial.c tutadv.c rk4.dat ls.dat makefile $(FLIST) # Different configurations # the dependencies **between** the parts are for dmake all: part1 part2 part3 zpart1 zpart2 ar_create part2: part1 part3: part2 basic: part1 part2 sparse: part1 part2 part3 zpart2: zpart1 complex: part1 part2 zpart1 zpart2 $(LIST1): $(HBASE) part1: $(LIST1) ar ru meschach.a $(LIST1) $(RANLIB) meschach.a $(LIST2): $(HBASE) matrix2.h part2: $(LIST2) ar ru meschach.a $(LIST2) $(RANLIB) meschach.a $(LIST3): $(HBASE) sparse.h sparse2.h part3: $(LIST3) ar ru meschach.a $(LIST3) $(RANLIB) meschach.a $(ZLIST1): $(HBASDE) zmatrix.h zpart1: $(ZLIST1) ar ru meschach.a $(ZLIST1) $(RANLIB) meschach.a $(ZLIST2): $(HBASE) zmatrix.h zmatrix2.h zpart2: $(ZLIST2) ar ru meschach.a $(ZLIST2) $(RANLIB) meschach.a $(OLDLIST): $(HBASE) sparse.h sparse2.h oldpart: $(OLDLIST) ar ru meschach.a $(OLDLIST) $(RANLIB) meschach.a ####################################### tar: - /bin/rm -f $(MES_PAK).tar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(TAR) cvf $(MES_PAK).tar \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC # use this only for PC machines msdos-zip: - /bin/rm -f $(MES_PAK).zip chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(ZIP) $(MES_PAK).zip \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC fullshar: - /bin/rm -f $(MES_PAK).shar; chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC > $(MES_PAK).shar shar: - /bin/rm -f meschach1.shar meschach2.shar meschach3.shar \ meschach4.shar oldmeschach.shar meschach0.shar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(LIST1) | sed -e 's/\.o/.c/g'` > meschach1.shar $(SHAR) `echo $(LIST2) | sed -e 's/\.o/.c/g'` > meschach2.shar $(SHAR) `echo $(LIST3) | sed -e 's/\.o/.c/g'` > meschach3.shar $(SHAR) `echo $(ZLIST1) | sed -e 's/\.o/.c/g'` \ `echo $(ZLIST2) | sed -e 's/\.o/.c/g'` > meschach4.shar $(SHAR) `echo $(OLDLIST) | sed -e 's/\.o/.c/g'` > oldmeschach.shar $(SHAR) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) DOC MACHINES > meschach0.shar list: /bin/rm -f $(FLIST) ls -lR `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) MACHINES DOC \ |awk '/^$$/ {print};/^[-d]/ {printf("%s %s %10d %s %s %s %s\n", \ $$1,$$2,$$5,$$6,$$7,$$8,$$9)}; /^[^-d]/ {print}' \ > $(FLIST) clean: /bin/rm -f *.o core asx5213a.mat iotort.dat cleanup: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a realclean: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a /bin/rm -f torture sptort ztorture memtort itertort mfuntort iotort /bin/rm -f makefile machine.h config.status maxint macheps alltorture: torture sptort ztorture memtort itertort mfuntort iotort torture:torture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o torture torture.o \ meschach.a $(LIBS) sptort:sptort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o sptort sptort.o \ meschach.a $(LIBS) memtort: memtort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o memtort memtort.o \ meschach.a $(LIBS) ztorture:ztorture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o ztorture ztorture.o \ meschach.a $(LIBS) itertort: itertort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o itertort itertort.o \ meschach.a $(LIBS) iotort: iotort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o iotort iotort.o \ meschach.a $(LIBS) mfuntort: mfuntort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o mfuntort mfuntort.o \ meschach.a $(LIBS) tstmove: tstmove.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstmove tstmove.o \ meschach.a $(LIBS) tstpxvec: tstpxvec.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstpxvec tstpxvec.o \ meschach.a $(LIBS) ar_create: rm meschach.a ar ruv meschach.a $(LIST1) $(LIST2) $(LIST3) \ $(ZLIST1) $(ZLIST2) $(OLDLIST) gtk-wave-cleaner-0.22-04/meschach/MACHINES/Cray/patch.10000777000175000017500000000363713120075106023236 0ustar00alisteralister00000000000000*** err.h Thu Jan 13 16:38:12 1994 --- err.h.orig Wed Oct 26 17:56:36 1994 *************** *** 129,135 **** { jmp_buf _save; int _err_num, _old_flag; \ _old_flag = set_err_flag(EF_SILENT); \ MEM_COPY(restart,_save,sizeof(jmp_buf)); \ ! if ( (_err_num=setjmp(restart)) == 0 ) \ { ok_part; \ set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); } \ --- 129,136 ---- { jmp_buf _save; int _err_num, _old_flag; \ _old_flag = set_err_flag(EF_SILENT); \ MEM_COPY(restart,_save,sizeof(jmp_buf)); \ ! _err_num=setjmp(restart); \ ! if ( _err_num == 0 ) \ { ok_part; \ set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); } \ *************** *** 149,155 **** { jmp_buf _save; int _err_num, _old_flag; \ _old_flag = set_err_flag(EF_SILENT); \ MEM_COPY(restart,_save,sizeof(jmp_buf)); \ ! if ( (_err_num=setjmp(restart)) == 0 ) \ { ok_part; \ set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); } \ --- 150,157 ---- { jmp_buf _save; int _err_num, _old_flag; \ _old_flag = set_err_flag(EF_SILENT); \ MEM_COPY(restart,_save,sizeof(jmp_buf)); \ ! _err_num=setjmp(restart); \ ! if ( _err_num == 0 ) \ { ok_part; \ set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); } \ *************** *** 166,172 **** { jmp_buf _save; int _err_num, _old_flag; \ _old_flag = set_err_flag(EF_JUMP); \ MEM_COPY(restart,_save,sizeof(jmp_buf)); \ ! if ( (_err_num=setjmp(restart)) == 0 ) \ { ok_part; \ set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); } \ --- 168,175 ---- { jmp_buf _save; int _err_num, _old_flag; \ _old_flag = set_err_flag(EF_JUMP); \ MEM_COPY(restart,_save,sizeof(jmp_buf)); \ ! _err_num=setjmp(restart) ;\ ! if ( _err_num == 0 ) \ { ok_part; \ set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); } \ gtk-wave-cleaner-0.22-04/meschach/MACHINES/Cray/patch.20000777000175000017500000000125713120075106023233 0ustar00alisteralister00000000000000*** iter0.c Mon Jun 20 15:22:36 1994 --- iter0.c.orig Fri Oct 28 01:49:19 1994 *************** *** 103,111 **** if (lenx > 0) ip->x = v_get(lenx); else ip->x = (VEC *)NULL; ! ip->Ax = ip->A_par = NULL; ! ip->ATx = ip->AT_par = NULL; ! ip->Bx = ip->B_par = NULL; ip->info = iter_std_info; ip->stop_crit = iter_std_stop_crit; ip->init_res = 0.0; --- 103,111 ---- if (lenx > 0) ip->x = v_get(lenx); else ip->x = (VEC *)NULL; ! ip->Ax = NULL; ip->A_par = NULL; ! ip->ATx = NULL; ip->AT_par = NULL; ! ip->Bx = NULL; ip->B_par = NULL; ip->info = iter_std_info; ip->stop_crit = iter_std_stop_crit; ip->init_res = 0.0; gtk-wave-cleaner-0.22-04/meschach/MACHINES/Cray/patch.30000777000175000017500000000045213120075106023230 0ustar00alisteralister00000000000000*** zmatrix.h Tue Mar 8 15:50:26 1994 --- zmatrix.h.orig Fri Oct 28 01:52:48 1994 *************** *** 34,39 **** --- 34,41 ---- /* Type definitions for complex vectors and matrices */ + #undef complex + #define complex Complex /* complex definition */ typedef struct { gtk-wave-cleaner-0.22-04/meschach/MACHINES/GCC/0000755000175000017500000000000013252653022021540 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/GCC/machine.h0000777000175000017500000000727713120075106023334 0ustar00alisteralister00000000000000/* machine.h. Generated automatically by configure. */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ #define ANSI_C 1 #define NOT_SEGMENTED 1 /* #undef HAVE_COMPLEX_H */ #define HAVE_MALLOC_H 1 #define STDC_HEADERS #define HAVE_BCOPY 1 #define HAVE_BZERO 1 #define CHAR0ISDBL0 1 #define WORDS_BIGENDIAN 1 /* #undef U_INT_DEF */ /* for basic or larger versions */ #define COMPLEX 1 #define SPARSE 1 /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ /* #undef HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ #define REAL_DBL 1 /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT 2147483647 #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #endif #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/GCC/makefile0000777000175000017500000001211013120075106023235 0ustar00alisteralister00000000000000# # # Makefile for Meschach for GNU cc # # Copyright (C) David Stewart & Zbigniew Leyk 1993 # # $Id: $ # srcdir = . VPATH = . CC = gcc DEFS = -DHAVE_CONFIG_H LIBS = -lm RANLIB = ranlib CFLAGS = -O6 .c.o: $(CC) -c $(CFLAGS) $(DEFS) $< SHELL = /bin/sh MES_PAK = mesch12a TAR = tar SHAR = stree -u ZIP = zip -r -l ############################### LIST1 = copy.o err.o matrixio.o memory.o vecop.o matop.o pxop.o \ submat.o init.o otherio.o machine.o matlab.o ivecop.o version.o \ meminfo.o memstat.o LIST2 = lufactor.o bkpfacto.o chfactor.o qrfactor.o solve.o hsehldr.o \ givens.o update.o norm.o hessen.o symmeig.o schur.o svd.o fft.o \ mfunc.o bdfactor.o LIST3 = sparse.o sprow.o sparseio.o spchfctr.o splufctr.o \ spbkp.o spswap.o iter0.o itersym.o iternsym.o ZLIST1 = zmachine.o zcopy.o zmatio.o zmemory.o zvecop.o zmatop.o znorm.o \ zfunc.o ZLIST2 = zlufctr.o zsolve.o zmatlab.o zhsehldr.o zqrfctr.o \ zgivens.o zhessen.o zschur.o # they are no longer supported # if you use them add oldpart to all and sparse OLDLIST = conjgrad.o lanczos.o arnoldi.o ALL_LISTS = $(LIST1) $(LIST2) $(LIST3) $(ZLIST1) $(ZLIST2) $(OLDLIST) HLIST = err.h iter.h machine.h matlab.h matrix.h matrix2.h \ meminfo.h oldnames.h sparse.h sparse2.h \ zmatrix.h zmatrix2.h TORTURE = torture.o sptort.o ztorture.o memtort.o itertort.o \ mfuntort.o iotort.o OTHERS = dmacheps.c extras.c fmacheps.c maxint.c makefile.in \ README configure configure.in machine.h.in copyright \ tutorial.c tutadv.c rk4.dat ls.dat makefile # Different configurations all: part1 part2 part3 zpart1 zpart2 basic: part1 part2 sparse: part1 part2 part3 complex: part1 part2 zpart1 zpart2 HBASE = err.h meminfo.h machine.h matrix.h $(LIST1): $(HBASE) part1: $(LIST1) ar ru meschach.a $(LIST1); $(RANLIB) meschach.a $(LIST2): $(HBASE) matrix2.h part2: $(LIST2) ar ru meschach.a $(LIST2); $(RANLIB) $(LIST3): $(HBASE) sparse.h sparse2.h part3: $(LIST3) ar ru meschach.a $(LIST3); $(RANLIB) meschach.a $(ZLIST1): $(HBASDE) zmatrix.h zpart1: $(ZLIST1) ar ru meschach.a $(ZLIST1); $(RANLIB) meschach.a $(ZLIST2): $(HBASE) zmatrix.h zmatrix2.h zpart2: $(ZLIST2) ar ru meschach.a $(ZLIST2); $(RANLIB) meschach.a $(OLDLIST): $(HBASE) sparse.h sparse2.h oldpart: $(OLDLIST) ar ru meschach.a $(OLDLIST); $(RANLIB) meschach.a ####################################### tar: - /bin/rm -f $(MES_PAK).tar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(TAR) cvf $(MES_PAK).tar \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC # use this only for PC machines msdos-zip: - /bin/rm -f $(MES_PAK).zip chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(ZIP) $(MES_PAK).zip \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC fullshar: - /bin/rm -f $(MES_PAK).shar; chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(SHAR) `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC > $(MES_PAK).shar shar: - /bin/rm -f meschach1.shar meschach2.shar meschach3.shar \ meschach4.shar oldmeschach.shar meschach0.shar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(SHAR) `echo $(LIST1) | sed -e 's/\.o/.c/g'` > meschach1.shar $(SHAR) `echo $(LIST2) | sed -e 's/\.o/.c/g'` > meschach2.shar $(SHAR) `echo $(LIST3) | sed -e 's/\.o/.c/g'` > meschach3.shar $(SHAR) `echo $(ZLIST1) | sed -e 's/\.o/.c/g'` \ `echo $(ZLIST2) | sed -e 's/\.o/.c/g'` > meschach4.shar $(SHAR) `echo $(OLDLIST) | sed -e 's/\.o/.c/g'` > oldmeschach.shar $(SHAR) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) DOC MACHINES > meschach0.shar clean: /bin/rm -f *.o core asx5213a.mat iotort.dat cleanup: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a alltorture: torture sptort ztorture memtort itertort mfuntort iotort torture:torture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o torture torture.o \ meschach.a $(LIBS) sptort:sptort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o sptort sptort.o \ meschach.a $(LIBS) memtort: memtort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o memtort memtort.o \ meschach.a $(LIBS) ztorture:ztorture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o ztorture ztorture.o \ meschach.a $(LIBS) itertort: itertort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o itertort itertort.o \ meschach.a $(LIBS) iotort: iotort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o iotort iotort.o \ meschach.a $(LIBS) mfuntort: mfuntort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o mfuntort mfuntort.o \ meschach.a $(LIBS) tstmove: tstmove.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstmove tstmove.o \ meschach.a $(LIBS) tstpxvec: tstpxvec.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstpxvec tstpxvec.o \ meschach.a $(LIBS) gtk-wave-cleaner-0.22-04/meschach/MACHINES/Linux/0000755000175000017500000000000013252653022022243 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/Linux/machine.h0000777000175000017500000000735413120075106024033 0ustar00alisteralister00000000000000/* machine.h. Generated automatically by configure. */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ /* #undef const */ /* #undef MALLOCDECL */ #define NOT_SEGMENTED 1 /* #undef HAVE_COMPLEX_H */ #define HAVE_MALLOC_H 1 #define STDC_HEADERS 1 #define HAVE_BCOPY 1 #define HAVE_BZERO 1 #define CHAR0ISDBL0 1 /* #undef WORDS_BIGENDIAN */ #define U_INT_DEF 1 #define VARARGS 1 /* for basic or larger versions */ #define COMPLEX 1 #define SPARSE 1 /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #define HAVE_PROTOTYPES 1 #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ /* #undef REAL_DBL */ /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT 2147483647 #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #endif #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/Linux/makefile0000777000175000017500000001274413120075106023755 0ustar00alisteralister00000000000000# Generated automatically from makefile.in by configure. # # Makefile for Meschach via autoconf # # Copyright (C) David Stewart & Zbigniew Leyk 1993 # # $Id: $ # srcdir = . VPATH = . CC = cc DEFS = -DHAVE_CONFIG_H LIBS = -lm RANLIB = ranlib CFLAGS = -O .c.o: $(CC) -c $(CFLAGS) $(DEFS) $< SHELL = /bin/sh MES_PAK = mesch12a TAR = tar SHAR = stree -u ZIP = zip -r -l FLIST = FILELIST ############################### LIST1 = copy.o err.o matrixio.o memory.o vecop.o matop.o pxop.o \ submat.o init.o otherio.o machine.o matlab.o ivecop.o version.o \ meminfo.o memstat.o LIST2 = lufactor.o bkpfacto.o chfactor.o qrfactor.o solve.o hsehldr.o \ givens.o update.o norm.o hessen.o symmeig.o schur.o svd.o fft.o \ mfunc.o bdfactor.o LIST3 = sparse.o sprow.o sparseio.o spchfctr.o splufctr.o \ spbkp.o spswap.o iter0.o itersym.o iternsym.o ZLIST1 = zmachine.o zcopy.o zmatio.o zmemory.o zvecop.o zmatop.o znorm.o \ zfunc.o ZLIST2 = zlufctr.o zsolve.o zmatlab.o zhsehldr.o zqrfctr.o \ zgivens.o zhessen.o zschur.o # they are no longer supported # if you use them add oldpart to all and sparse OLDLIST = conjgrad.o lanczos.o arnoldi.o ALL_LISTS = $(LIST1) $(LIST2) $(LIST3) $(ZLIST1) $(ZLIST2) $(OLDLIST) HBASE = err.h meminfo.h machine.h matrix.h HLIST = $(HBASE) iter.h matlab.h matrix2.h oldnames.h sparse.h \ sparse2.h zmatrix.h zmatrix2.h TORTURE = torture.o sptort.o ztorture.o memtort.o itertort.o \ mfuntort.o iotort.o OTHERS = dmacheps.c extras.c fmacheps.c maxint.c makefile.in \ README configure configure.in machine.h.in copyright \ tutorial.c tutadv.c rk4.dat ls.dat makefile $(FLIST) # Different configurations all: part1 part2 part3 zpart1 zpart2 basic: part1 part2 sparse: part1 part2 part3 complex: part1 part2 zpart1 zpart2 $(LIST1): $(HBASE) part1: $(LIST1) ar ru meschach.a $(LIST1); $(RANLIB) meschach.a $(LIST2): $(HBASE) matrix2.h part2: $(LIST2) ar ru meschach.a $(LIST2); $(RANLIB) meschach.a $(LIST3): $(HBASE) sparse.h sparse2.h part3: $(LIST3) ar ru meschach.a $(LIST3); $(RANLIB) meschach.a $(ZLIST1): $(HBASDE) zmatrix.h zpart1: $(ZLIST1) ar ru meschach.a $(ZLIST1); $(RANLIB) meschach.a $(ZLIST2): $(HBASE) zmatrix.h zmatrix2.h zpart2: $(ZLIST2) ar ru meschach.a $(ZLIST2); $(RANLIB) meschach.a $(OLDLIST): $(HBASE) sparse.h sparse2.h oldpart: $(OLDLIST) ar ru meschach.a $(OLDLIST); $(RANLIB) meschach.a ####################################### tar: - /bin/rm -f $(MES_PAK).tar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(TAR) cvf $(MES_PAK).tar \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC # use this only for PC machines msdos-zip: - /bin/rm -f $(MES_PAK).zip chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(ZIP) $(MES_PAK).zip \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC fullshar: - /bin/rm -f $(MES_PAK).shar; chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC > $(MES_PAK).shar shar: - /bin/rm -f meschach1.shar meschach2.shar meschach3.shar \ meschach4.shar oldmeschach.shar meschach0.shar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(LIST1) | sed -e 's/\.o/.c/g'` > meschach1.shar $(SHAR) `echo $(LIST2) | sed -e 's/\.o/.c/g'` > meschach2.shar $(SHAR) `echo $(LIST3) | sed -e 's/\.o/.c/g'` > meschach3.shar $(SHAR) `echo $(ZLIST1) | sed -e 's/\.o/.c/g'` \ `echo $(ZLIST2) | sed -e 's/\.o/.c/g'` > meschach4.shar $(SHAR) `echo $(OLDLIST) | sed -e 's/\.o/.c/g'` > oldmeschach.shar $(SHAR) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) DOC MACHINES > meschach0.shar list: /bin/rm -f $(FLIST) ls -lR `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) MACHINES DOC \ |awk '/^$$/ {print};/^[-d]/ {printf("%s %s %10d %s %s %s %s\n", \ $$1,$$2,$$5,$$6,$$7,$$8,$$9)}; /^[^-d]/ {print}' \ > $(FLIST) clean: /bin/rm -f *.o core asx5213a.mat iotort.dat cleanup: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a alltorture: torture sptort ztorture memtort itertort mfuntort iotort torture:torture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o torture torture.o \ meschach.a $(LIBS) sptort:sptort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o sptort sptort.o \ meschach.a $(LIBS) memtort: memtort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o memtort memtort.o \ meschach.a $(LIBS) ztorture:ztorture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o ztorture ztorture.o \ meschach.a $(LIBS) itertort: itertort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o itertort itertort.o \ meschach.a $(LIBS) iotort: iotort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o iotort iotort.o \ meschach.a $(LIBS) mfuntort: mfuntort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o mfuntort mfuntort.o \ meschach.a $(LIBS) tstmove: tstmove.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstmove tstmove.o \ meschach.a $(LIBS) tstpxvec: tstpxvec.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstpxvec tstpxvec.o \ meschach.a $(LIBS) gtk-wave-cleaner-0.22-04/meschach/MACHINES/MicroSoft/0000755000175000017500000000000013252653022023051 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/MicroSoft/machine.h0000777000175000017500000001131413120075106024630 0ustar00alisteralister00000000000000/* machine.h. Generated automatically by configure. */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* RCS id: $Id: machine.h.in,v 1.3 1995/03/27 15:36:21 des Exp $ */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ #ifndef _MACHINE_H #define _MACHINE_H 1 /* #undef const */ /* #undef MALLOCDECL */ #define NOT_SEGMENTED 1 #define HAVE_MEMORY_H 1 /* #undef HAVE_COMPLEX_H */ #define HAVE_MALLOC_H 1 #define STDC_HEADERS 1 /* #undef HAVE_BCOPY */ /* #undef HAVE_BZERO */ #define CHAR0ISDBL0 1 #undef WORDS_BIGENDIAN /* #undef U_INT_DEF */ #define VARARGS 1 #define HAVE_PROTOTYPES 1 /* #undef HAVE_PROTOTYPES_IN_STRUCT */ /* for inclusion into C++ files */ #ifdef __cplusplus #define ANSI_C 1 #ifndef HAVE_PROTOTYPES #define HAVE_PROTOTYPES 1 #endif #ifndef HAVE_PROTOTYPES_IN_STRUCT #define HAVE_PROTOTYPES_IN_STRUCT 1 #endif #endif /* __cplusplus */ /* example usage: VEC *PROTO(v_get,(int dim)); */ #ifdef HAVE_PROTOTYPES #define PROTO(name,args) name args #else #define PROTO(name,args) name() #endif /* HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES_IN_STRUCT /* PROTO_() is to be used instead of PROTO() in struct's and typedef's */ #define PROTO_(name,args) name args #else #define PROTO_(name,args) name() #endif /* HAVE_PROTOTYPES_IN_STRUCT */ /* for basic or larger versions */ #define COMPLEX 1 #define SPARSE 1 /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ /* #undef REAL_DBL */ /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS #define D_MACHEPS #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT #ifdef M_MAX_INT #ifndef MAX_RAND #ifdef RAND_MAX #define MAX_RAND RAND_MAX #else #define MAX_RAND ((double)(M_MAX_INT)) #endif /* MAX_RAND */ #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #else #ifndef HUGE #define HUGE HUGE_VAL #endif #endif #ifdef HUGE_VAL /* HUGE_VAL later defined in math.h */ #undef HUGE_VAL #endif #ifdef ANSI_C extern int isatty(int); #endif #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/MicroSoft/makefile0000777000175000017500000001542213120075106024557 0ustar00alisteralister00000000000000# Generated automatically from makefile.in by configure. # # Makefile for Meschach via autoconf # # Copyright (C) David Stewart & Zbigniew Leyk 1993 # # $Id: makefile.in,v 1.4 1994/03/14 01:24:06 des Exp $ # srcdir = . VPATH = . CC = gcc DEFS = -DHAVE_CONFIG_H LIBS = -lm RANLIB = ranlib CFLAGS = -O2 -ffast-math -fexpensive-optimizations .c.o: $(CC) -c $(CFLAGS) $(DEFS) $< SHELL = /bin/sh MES_PAK = mesch12b TAR = tar SHAR = stree -u ZIP = zip -r -l FLIST = FILELIST ############################### LIST1 = copy.o err.o matrixio.o memory.o vecop.o matop.o pxop.o \ submat.o init.o otherio.o machine.o matlab.o ivecop.o version.o \ meminfo.o memstat.o LIST2 = lufactor.o bkpfacto.o chfactor.o qrfactor.o solve.o hsehldr.o \ givens.o update.o norm.o hessen.o symmeig.o schur.o svd.o fft.o \ mfunc.o bdfactor.o LIST3 = sparse.o sprow.o sparseio.o spchfctr.o splufctr.o \ spbkp.o spswap.o iter0.o itersym.o iternsym.o ZLIST1 = zmachine.o zcopy.o zmatio.o zmemory.o zvecop.o zmatop.o znorm.o \ zfunc.o ZLIST2 = zlufctr.o zsolve.o zmatlab.o zhsehldr.o zqrfctr.o \ zgivens.o zhessen.o zschur.o # they are no longer supported # if you use them add oldpart to all and sparse OLDLIST = conjgrad.o lanczos.o arnoldi.o ALL_LISTS = $(LIST1) $(LIST2) $(LIST3) $(ZLIST1) $(ZLIST2) $(OLDLIST) HBASE = err.h meminfo.h machine.h matrix.h HLIST = $(HBASE) iter.h matlab.h matrix2.h oldnames.h sparse.h \ sparse2.h zmatrix.h zmatrix2.h TORTURE = torture.o sptort.o ztorture.o memtort.o itertort.o \ mfuntort.o iotort.o OTHERS = dmacheps.c extras.c fmacheps.c maxint.c makefile.in \ README configure configure.in machine.h.in copyright \ tutorial.c tutadv.c rk4.dat ls.dat makefile $(FLIST) # Different configurations # the dependencies **between** the parts are for dmake all: part1 part2 part3 zpart1 zpart2 part2: part1 part3: part2 basic: part1 part2 sparse: part1 part2 part3 zpart2: zpart1 complex: part1 part2 zpart1 zpart2 $(LIST1): $(HBASE) part1: $(LIST1) ar ru libmeschach.a $(LIST1) $(RANLIB) libmeschach.a $(LIST2): $(HBASE) matrix2.h part2: $(LIST2) ar ru libmeschach.a $(LIST2) $(RANLIB) libmeschach.a $(LIST3): $(HBASE) sparse.h sparse2.h part3: $(LIST3) ar ru libmeschach.a $(LIST3) $(RANLIB) libmeschach.a $(ZLIST1): $(HBASDE) zmatrix.h zpart1: $(ZLIST1) ar ru libmeschach.a $(ZLIST1) $(RANLIB) libmeschach.a $(ZLIST2): $(HBASE) zmatrix.h zmatrix2.h zpart2: $(ZLIST2) ar ru libmeschach.a $(ZLIST2) $(RANLIB) libmeschach.a $(OLDLIST): $(HBASE) sparse.h sparse2.h oldpart: $(OLDLIST) ar ru libmeschach.a $(OLDLIST) $(RANLIB) libmeschach.a ####################################### tar: - /bin/rm -f $(MES_PAK).tar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(TAR) cvf $(MES_PAK).tar \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC # use this only for PC machines msdos-zip: - /bin/rm -f $(MES_PAK).zip chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(ZIP) $(MES_PAK).zip \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC fullshar: - /bin/rm -f $(MES_PAK).shar; chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC > $(MES_PAK).shar shar: - /bin/rm -f meschach1.shar meschach2.shar meschach3.shar \ meschach4.shar oldmeschach.shar meschach0.shar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(LIST1) | sed -e 's/\.o/.c/g'` > meschach1.shar $(SHAR) `echo $(LIST2) | sed -e 's/\.o/.c/g'` > meschach2.shar $(SHAR) `echo $(LIST3) | sed -e 's/\.o/.c/g'` > meschach3.shar $(SHAR) `echo $(ZLIST1) | sed -e 's/\.o/.c/g'` \ `echo $(ZLIST2) | sed -e 's/\.o/.c/g'` > meschach4.shar $(SHAR) `echo $(OLDLIST) | sed -e 's/\.o/.c/g'` > oldmeschach.shar $(SHAR) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) DOC MACHINES > meschach0.shar list: /bin/rm -f $(FLIST) ls -lR `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) MACHINES DOC \ |awk '/^$$/ {print};/^[-d]/ {printf("%s %s %10d %s %s %s %s\n", \ $$1,$$2,$$5,$$6,$$7,$$8,$$9)}; /^[^-d]/ {print}' \ > $(FLIST) clean: /bin/rm -f *.o core asx5213a.mat iotort.dat cleanup: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a *.dll *.def realclean: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a *.dll *.def /bin/rm -f torture.exe sptort.exe ztorture.exe memtort.exe \ itertort.exe mfuntort.exe iotort.exe /bin/rm -f maxint.exe macheps.exe alltorture: torture sptort ztorture memtort itertort mfuntort iotort torture:torture.o libmeschach.a $(CC) $(CFLAGS) $(DEFS) -o torture torture.o \ libmeschach.a $(LIBS) sptort:sptort.o libmeschach.a $(CC) $(CFLAGS) $(DEFS) -o sptort sptort.o \ libmeschach.a $(LIBS) memtort: memtort.o libmeschach.a $(CC) $(CFLAGS) $(DEFS) -o memtort memtort.o \ libmeschach.a $(LIBS) ztorture:ztorture.o libmeschach.a $(CC) $(CFLAGS) $(DEFS) -o ztorture ztorture.o \ libmeschach.a $(LIBS) itertort: itertort.o libmeschach.a $(CC) $(CFLAGS) $(DEFS) -o itertort itertort.o \ libmeschach.a $(LIBS) iotort: iotort.o libmeschach.a $(CC) $(CFLAGS) $(DEFS) -o iotort iotort.o \ libmeschach.a $(LIBS) mfuntort: mfuntort.o libmeschach.a $(CC) $(CFLAGS) $(DEFS) -o mfuntort mfuntort.o \ libmeschach.a $(LIBS) tstmove: tstmove.o libmeschach.a $(CC) $(CFLAGS) $(DEFS) -o tstmove tstmove.o \ libmeschach.a $(LIBS) tstpxvec: tstpxvec.o libmeschach.a $(CC) $(CFLAGS) $(DEFS) -o tstpxvec tstpxvec.o \ libmeschach.a $(LIBS) OBJ=$(LIST1) $(LIST2) $(LIST3) $(ZLIST1) $(ZLIST2) DLLTOOL= dlltool DLLWRAP= dllwrap DLL_NAME = meschach.dll DLL_EXP_DEF = libmeschach_dll.def DLL_EXP_LIB = libmeschach_dll.a DLL_LDFLAGS = -L . DLL_LDLIBS = -lm DLL_CFLAGS = --verbose --export-all-symbols DLLWRAP_FLAGS = --output-def $(DLL_EXP_DEF) \ --implib $(DLL_EXP_LIB) \ --driver-name $(CC) #--no-delete $(DLL_NAME) $(DLL_EXP_DEF) $(DLL_EXP_LIB): $(OBJ) $(DLLWRAP) $(DLL_CFLAGS) $(DLLWRAP_FLAGS) -o $(DLL_NAME) \ $(OBJ) $(DLL_LDFLAGS) $(DLL_LDLIBS) dll: $(DLL_NAME)gtk-wave-cleaner-0.22-04/meschach/MACHINES/OS2/0000755000175000017500000000000013252653022021547 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/OS2/README0000777000175000017500000000163413120075106022435 0ustar00alisteralister00000000000000Message received from Wenzel Matiaske: From mati1831@perform.ww.TU-Berlin.DE Wed Oct 4 11:34:38 1995 Date: Wed, 04 Oct 95 17:32:37 GMT From: Wenzel Matiaske To: david.stewart@anu.edu.au Subject: meschach documentation Dear David, [snip] By the way: I have installed the library with EMX 0.9a + gcc under OS/2. I have included the makefile, may it is useful for others. [Note: I have also put the "standard" gcc machine.h here as well. -- David Stewart, 4th Oct, 1995] Best regards //wenzel -- ___ wenzel matiaske | / /_/-Berlin | | mail: Technical University Berlin | Dept. of Economics & Management, WW6 | Uhlandstr. 4-5, D-10623 Berlin | phone: +49 30 314-22574 | email: W.Matiaske@ww.TU-Berlin.de gtk-wave-cleaner-0.22-04/meschach/MACHINES/OS2/machine.h0000777000175000017500000000727713120075106023343 0ustar00alisteralister00000000000000/* machine.h. Generated automatically by configure. */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ #define ANSI_C 1 #define NOT_SEGMENTED 1 /* #undef HAVE_COMPLEX_H */ #define HAVE_MALLOC_H 1 #define STDC_HEADERS #define HAVE_BCOPY 1 #define HAVE_BZERO 1 #define CHAR0ISDBL0 1 #define WORDS_BIGENDIAN 1 /* #undef U_INT_DEF */ /* for basic or larger versions */ #define COMPLEX 1 #define SPARSE 1 /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ /* #undef HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ #define REAL_DBL 1 /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT 2147483647 #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #endif #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/OS2/makefile0000777000175000017500000001266413120075106023262 0ustar00alisteralister00000000000000# # # Makefile for Meschach for GNU cc/emx (OS/2) # # Copyright (C) David Stewart & Zbigniew Leyk 1993 # modified by mati1831@perform.ww.tu-berlin.de # # $Id: $ # srcdir = VPATH = CC = gcc DEFS = -DHAVE_CONFIG_H LIBS = -lm # we don't have ranlib RANLIB = ar -s CFLAGS = -O6 .c.o: $(CC) -c $(CFLAGS) $(DEFS) $< # we do not need the shell ##SHELL = sh # if we have rm, otherwise use del. RM= rm -f MES_PAK = mesch12a TAR = tar SHAR = shar -u ZIP = gzip -r -l ############################### LIST1 = copy.o err.o matrixio.o memory.o vecop.o matop.o pxop.o \ submat.o init.o otherio.o machine.o matlab.o ivecop.o version.o \ meminfo.o memstat.o LIST2 = lufactor.o bkpfacto.o chfactor.o qrfactor.o solve.o hsehldr.o \ givens.o update.o norm.o hessen.o symmeig.o schur.o svd.o fft.o \ mfunc.o bdfactor.o LIST3 = sparse.o sprow.o sparseio.o spchfctr.o splufctr.o \ spbkp.o spswap.o iter0.o itersym.o iternsym.o ZLIST1 = zmachine.o zcopy.o zmatio.o zmemory.o zvecop.o zmatop.o znorm.o \ zfunc.o ZLIST2 = zlufctr.o zsolve.o zmatlab.o zhsehldr.o zqrfctr.o \ zgivens.o zhessen.o zschur.o # they are no longer supported # if you use them add oldpart to all and sparse OLDLIST = conjgrad.o lanczos.o arnoldi.o ALL_LISTS = $(LIST1) $(LIST2) $(LIST3) $(ZLIST1) $(ZLIST2) $(OLDLIST) HLIST = err.h iter.h machine.h matlab.h matrix.h matrix2.h \ meminfo.h oldnames.h sparse.h sparse2.h \ zmatrix.h zmatrix2.h TORTURE = torture.o sptort.o ztorture.o memtort.o itertort.o \ mfuntort.o iotort.o OTHERS = dmacheps.c extras.c fmacheps.c maxint.c makefile.in \ README configure configure.in machine.h.in copyright \ tutorial.c tutadv.c rk4.dat ls.dat makefile # Different configurations all: part1 part2 part3 zpart1 zpart2 basic: part1 part2 sparse: part1 part2 part3 complex: part1 part2 zpart1 zpart2 HBASE = err.h meminfo.h machine.h matrix.h $(LIST1): $(HBASE) part1: $(LIST1) ar ru meschach.a $(LIST1) $(RANLIB) meschach.a $(LIST2): $(HBASE) matrix2.h part2: $(LIST2) ar ru meschach.a $(LIST2) $(RANLIB) meschach.a $(LIST3): $(HBASE) sparse.h sparse2.h part3: $(LIST3) ar ru meschach.a $(LIST3) $(RANLIB) meschach.a $(ZLIST1): $(HBASDE) zmatrix.h zpart1: $(ZLIST1) ar ru meschach.a $(ZLIST1) $(RANLIB) meschach.a $(ZLIST2): $(HBASE) zmatrix.h zmatrix2.h zpart2: $(ZLIST2) ar ru meschach.a $(ZLIST2) $(RANLIB) meschach.a $(OLDLIST): $(HBASE) sparse.h sparse2.h oldpart: $(OLDLIST) ar ru meschach.a $(OLDLIST) $(RANLIB) meschach.a ####################################### tar: - /bin/rm -f $(MES_PAK).tar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(TAR) cvf $(MES_PAK).tar \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC # use this only for PC machines msdos-zip: - /bin/rm -f $(MES_PAK).zip chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(ZIP) $(MES_PAK).zip \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC fullshar: - /bin/rm -f $(MES_PAK).shar; chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(SHAR) `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC > $(MES_PAK).shar shar: - /bin/rm -f meschach1.shar meschach2.shar meschach3.shar \ meschach4.shar oldmeschach.shar meschach0.shar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(SHAR) `echo $(LIST1) | sed -e 's/\.o/.c/g'` > meschach1.shar $(SHAR) `echo $(LIST2) | sed -e 's/\.o/.c/g'` > meschach2.shar $(SHAR) `echo $(LIST3) | sed -e 's/\.o/.c/g'` > meschach3.shar $(SHAR) `echo $(ZLIST1) | sed -e 's/\.o/.c/g'` \ `echo $(ZLIST2) | sed -e 's/\.o/.c/g'` > meschach4.shar $(SHAR) `echo $(OLDLIST) | sed -e 's/\.o/.c/g'` > oldmeschach.shar $(SHAR) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) DOC MACHINES > meschach0.shar clean: $(RM) *.o core asx5213a.mat iotort.dat cleanup: $(RM) *.o core asx5213a.mat iotort.dat *.a torture sptort ztorture memtort itertort mfuntort iotort alltorture: torture sptort ztorture memtort itertort mfuntort iotort torture:torture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o torture torture.o \ meschach.a $(LIBS) emxbind torture sptort:sptort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o sptort sptort.o \ meschach.a $(LIBS) emxbind sptort memtort: memtort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o memtort memtort.o \ meschach.a $(LIBS) emxbind memtort ztorture:ztorture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o ztorture ztorture.o \ meschach.a $(LIBS) emxbind ztorture itertort: itertort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o itertort itertort.o \ meschach.a $(LIBS) emxbind itertort iotort: iotort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o iotort iotort.o \ meschach.a $(LIBS) emxbind iotort mfuntort: mfuntort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o mfuntort mfuntort.o \ meschach.a $(LIBS) emxbind mfuntort tstmove: tstmove.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstmove tstmove.o \ meschach.a $(LIBS) emxbind tstmove tstpxvec: tstpxvec.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstpxvec tstpxvec.o \ meschach.a $(LIBS) emxbind tstpxvec gtk-wave-cleaner-0.22-04/meschach/MACHINES/RS6000/0000755000175000017500000000000013252653022021776 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/RS6000/machine.c0000777000175000017500000001376113120075106023560 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Stewart & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains basic routines which are used by the functions in matrix.a etc. These are the routines that should be modified in order to take full advantage of specialised architectures (pipelining, vector processors etc). */ static char *rcsid = "$Header: /usr/local/home/des/meschach/meschach/RCS/machine.c,v 1.3 1991/08/29 06:42:11 des Exp $"; #include "machine.h" /* __ip__ -- inner product */ double __ip__(dp1,dp2,len) register double *dp1, *dp2; int len; { register int len4; register int i; register double sum0, sum1, sum2, sum3; sum0 = sum1 = sum2 = sum3 = 0.0; len4 = len / 4; len = len % 4; for ( i = 0; i < len4; i++ ) { sum0 += dp1[4*i]*dp2[4*i]; sum1 += dp1[4*i+1]*dp2[4*i+1]; sum2 += dp1[4*i+2]*dp2[4*i+2]; sum3 += dp1[4*i+3]*dp2[4*i+3]; } sum0 += sum1 + sum2 + sum3; dp1 += 4*len4; dp2 += 4*len4; for ( i = 0; i < len; i++ ) sum0 += (*dp1++)*(*dp2++); return sum0; } /* __mltadd__ -- scalar multiply and add c.f. v_mltadd() */ void __mltadd__(dp1,dp2,s,len) register double *dp1, *dp2, s; register int len; { register int i, len4; len4 = len / 4; len = len % 4; for ( i = 0; i < len4; i++ ) { dp1[4*i] += s*dp2[4*i]; dp1[4*i+1] += s*dp2[4*i+1]; dp1[4*i+2] += s*dp2[4*i+2]; dp1[4*i+3] += s*dp2[4*i+3]; } dp1 += 4*len4; dp2 += 4*len4; for ( i = 0; i < len; i++ ) (*dp1++) += s*(*dp2++); } /* __smlt__ scalar multiply array c.f. sv_mlt() */ void __smlt__(dp,s,out,len) register double *dp, s, *out; register int len; { register int i; for ( i = 0; i < len; i++ ) (*out++) = s*(*dp++); } /* __add__ -- add arrays c.f. v_add() */ void __add__(dp1,dp2,out,len) register double *dp1, *dp2, *out; register int len; { register int i; for ( i = 0; i < len; i++ ) (*out++) = (*dp1++) + (*dp2++); } /* __sub__ -- subtract arrays c.f. v_sub() */ void __sub__(dp1,dp2,out,len) register double *dp1, *dp2, *out; register int len; { register int i; for ( i = 0; i < len; i++ ) (*out++) = (*dp1++) - (*dp2++); } /* __zero__ -- zeros an array of double precision numbers */ void __zero__(dp,len) register double *dp; register int len; { /* if a double precision zero is equivalent to a string of nulls */ MEM_ZERO((char *)dp,len*sizeof(double)); /* else, need to zero the array entry by entry */ /************************************************* while ( len-- ) *dp++ = 0.0; *************************************************/ } /*********************************************************************** ****** Faster versions ******** ***********************************************************************/ /* __ip4__ -- compute 4 inner products in one go */ void __ip4__(v0,v1,v2,v3,w,out,len) double *v0, *v1, *v2, *v3, *w; double out[4]; int len; { register int i, len2; register double sum00, sum10, sum20, sum30, w_val0; register double sum01, sum11, sum21, sum31, w_val1; len2 = len / 2; len = len % 2; sum00 = sum10 = sum20 = sum30 = 0.0; sum01 = sum11 = sum21 = sum31 = 0.0; for ( i = 0; i < len2; i++ ) { w_val0 = w[2*i]; w_val1 = w[2*i+1]; sum00 += v0[2*i] *w_val0; sum01 += v0[2*i+1]*w_val1; sum10 += v1[2*i] *w_val0; sum11 += v1[2*i+1]*w_val1; sum20 += v2[2*i] *w_val0; sum21 += v2[2*i+1]*w_val1; sum30 += v3[2*i] *w_val0; sum31 += v3[2*i+1]*w_val1; } w += 2*len2; v0 += 2*len2; v1 += 2*len2; v2 += 2*len2; v3 += 2*len2; for ( i = 0; i < len; i++ ) { w_val0 = w[i]; sum00 += v0[i]*w_val0; sum10 += v1[i]*w_val0; sum20 += v2[i]*w_val0; sum30 += v3[i]*w_val0; } out[0] = sum00 + sum01; out[1] = sum10 + sum11; out[2] = sum20 + sum21; out[3] = sum30 + sum31; } /* __lc4__ -- linear combinations: w <- w+a[0]*v0+ ... + a[3]*v3 */ void __lc4__(v0,v1,v2,v3,w,a,len) double *v0, *v1, *v2, *v3, *w; double a[4]; int len; { register int i, len2; register double a0, a1, a2, a3, tmp0, tmp1; len2 = len / 2; len = len % 2; a0 = a[0]; a1 = a[1]; a2 = a[2]; a3 = a[3]; for ( i = 0; i < len2; i++ ) { tmp0 = w[2*i] + a0*v0[2*i]; tmp1 = w[2*i+1] + a0*v0[2*i+1]; tmp0 += a1*v1[2*i]; tmp1 += a1*v1[2*i+1]; tmp0 += a2*v2[2*i]; tmp1 += a2*v2[2*i+1]; tmp0 += a3*v3[2*i]; tmp1 += a3*v3[2*i+1]; w[2*i] = tmp0; w[2*i+1] = tmp1; } w += 2*len2; v0 += 2*len2; v1 += 2*len2; v2 += 2*len2; v3 += 2*len2; for ( i = 0; i < len; i++ ) w[i] += a0*v0[i] + a1*v1[i] + a2*v2[i] + a3*v3[i]; } /* __ma4__ -- multiply and add with 4 vectors: vi <- vi + ai*w */ void __ma4__(v0,v1,v2,v3,w,a,len) double *v0, *v1, *v2, *v3, *w; double a[4]; int len; { register int i; register double a0, a1, a2, a3, w0, w1, w2, w3; a0 = a[0]; a1 = a[1]; a2 = a[2]; a3 = a[3]; for ( i = 0; i < len; i++ ) { w0 = w[i]; v0[i] += a0*w0; v1[i] += a1*w0; v2[i] += a2*w0; v3[i] += a3*w0; } } gtk-wave-cleaner-0.22-04/meschach/MACHINES/RS6000/machine.h0000777000175000017500000000665613120075106023572 0ustar00alisteralister00000000000000 /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ #define ANSI_C 1 /* #undef MALLOCDECL */ #define NOT_SEGMENTED 1 /* #undef HAVE_COMPLEX_H */ #define HAVE_MALLOC_H 1 #define STDC_HEADERS 1 #define HAVE_BCOPY 1 #define HAVE_BZERO 1 #define CHAR0ISDBL0 1 #define WORDS_BIGENDIAN 1 #define U_INT_DEF 1 /* for basic or larger versions */ #define COMPLEX 1 #define SPARSE 1 /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #define HAVE_PROTOTYPES 1 #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ /* #undef REAL_DBL */ /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT 2147483647 #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #endif #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/RS6000/makefile0000777000175000017500000001303713120075106023504 0ustar00alisteralister00000000000000# Generated automatically from makefile.in by configure. # # Makefile for Meschach via autoconf # # Copyright (C) David Stewart & Zbigniew Leyk 1993 # # $Id: $ # srcdir = . VPATH = . CC = cc DEFS = -DHAVE_CONFIG_H LIBS = -lm RANLIB = ranlib CFLAGS = -O .c.o: $(CC) -c $(CFLAGS) $(DEFS) $< SHELL = /bin/sh MES_PAK = mesch12a TAR = tar SHAR = stree -u ZIP = zip -r -l FLIST = FILELIST ############################### LIST1 = copy.o err.o matrixio.o memory.o vecop.o matop.o pxop.o \ submat.o init.o otherio.o machine.o matlab.o ivecop.o version.o \ meminfo.o memstat.o LIST2 = lufactor.o bkpfacto.o chfactor.o qrfactor.o solve.o hsehldr.o \ givens.o update.o norm.o hessen.o symmeig.o schur.o svd.o fft.o \ mfunc.o bdfactor.o LIST3 = sparse.o sprow.o sparseio.o spchfctr.o splufctr.o \ spbkp.o spswap.o iter0.o itersym.o iternsym.o ZLIST1 = zmachine.o zcopy.o zmatio.o zmemory.o zvecop.o zmatop.o znorm.o \ zfunc.o ZLIST2 = zlufctr.o zsolve.o zmatlab.o zhsehldr.o zqrfctr.o \ zgivens.o zhessen.o zschur.o # they are no longer supported # if you use them add oldpart to all and sparse OLDLIST = conjgrad.o lanczos.o arnoldi.o ALL_LISTS = $(LIST1) $(LIST2) $(LIST3) $(ZLIST1) $(ZLIST2) $(OLDLIST) HBASE = err.h meminfo.h machine.h matrix.h HLIST = $(HBASE) iter.h matlab.h matrix2.h oldnames.h sparse.h \ sparse2.h zmatrix.h zmatrix2.h TORTURE = torture.o sptort.o ztorture.o memtort.o itertort.o \ mfuntort.o iotort.o OTHERS = dmacheps.c extras.c fmacheps.c maxint.c makefile.in \ README configure configure.in machine.h.in copyright \ tutorial.c tutadv.c rk4.dat ls.dat makefile $(FLIST) # Different configurations all: part1 part2 part3 zpart1 zpart2 basic: part1 part2 sparse: part1 part2 part3 complex: part1 part2 zpart1 zpart2 $(LIST1): $(HBASE) part1: $(LIST1) ar ru meschach.a $(LIST1); $(RANLIB) meschach.a $(LIST2): $(HBASE) matrix2.h part2: $(LIST2) ar ru meschach.a $(LIST2); $(RANLIB) meschach.a schur.o: schur.c $(HBASE) matrix2.h cc -c $(DEFS) schur.c $(LIST3): $(HBASE) sparse.h sparse2.h part3: $(LIST3) ar ru meschach.a $(LIST3); $(RANLIB) meschach.a $(ZLIST1): $(HBASDE) zmatrix.h zpart1: $(ZLIST1) ar ru meschach.a $(ZLIST1); $(RANLIB) meschach.a $(ZLIST2): $(HBASE) zmatrix.h zmatrix2.h zpart2: $(ZLIST2) ar ru meschach.a $(ZLIST2); $(RANLIB) meschach.a $(OLDLIST): $(HBASE) sparse.h sparse2.h oldpart: $(OLDLIST) ar ru meschach.a $(OLDLIST); $(RANLIB) meschach.a ####################################### tar: - /bin/rm -f $(MES_PAK).tar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(TAR) cvf $(MES_PAK).tar \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC # use this only for PC machines msdos-zip: - /bin/rm -f $(MES_PAK).zip chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(ZIP) $(MES_PAK).zip \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC fullshar: - /bin/rm -f $(MES_PAK).shar; chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC > $(MES_PAK).shar shar: - /bin/rm -f meschach1.shar meschach2.shar meschach3.shar \ meschach4.shar oldmeschach.shar meschach0.shar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(LIST1) | sed -e 's/\.o/.c/g'` > meschach1.shar $(SHAR) `echo $(LIST2) | sed -e 's/\.o/.c/g'` > meschach2.shar $(SHAR) `echo $(LIST3) | sed -e 's/\.o/.c/g'` > meschach3.shar $(SHAR) `echo $(ZLIST1) | sed -e 's/\.o/.c/g'` \ `echo $(ZLIST2) | sed -e 's/\.o/.c/g'` > meschach4.shar $(SHAR) `echo $(OLDLIST) | sed -e 's/\.o/.c/g'` > oldmeschach.shar $(SHAR) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) DOC MACHINES > meschach0.shar list: /bin/rm -f $(FLIST) ls -lR `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) MACHINES DOC \ |awk '/^$$/ {print};/^[-d]/ {printf("%s %s %10d %s %s %s %s\n", \ $$1,$$2,$$5,$$6,$$7,$$8,$$9)}; /^[^-d]/ {print}' \ > $(FLIST) clean: /bin/rm -f *.o core asx5213a.mat iotort.dat cleanup: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a alltorture: torture sptort ztorture memtort itertort mfuntort iotort torture:torture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o torture torture.o \ meschach.a $(LIBS) sptort:sptort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o sptort sptort.o \ meschach.a $(LIBS) memtort: memtort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o memtort memtort.o \ meschach.a $(LIBS) ztorture:ztorture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o ztorture ztorture.o \ meschach.a $(LIBS) itertort: itertort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o itertort itertort.o \ meschach.a $(LIBS) iotort: iotort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o iotort iotort.o \ meschach.a $(LIBS) mfuntort: mfuntort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o mfuntort mfuntort.o \ meschach.a $(LIBS) tstmove: tstmove.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstmove tstmove.o \ meschach.a $(LIBS) tstpxvec: tstpxvec.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstpxvec tstpxvec.o \ meschach.a $(LIBS) gtk-wave-cleaner-0.22-04/meschach/MACHINES/SGI/0000755000175000017500000000000013252653022021566 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/SGI/machine.h0000777000175000017500000001103313120075106023343 0ustar00alisteralister00000000000000/* machine.h. Generated automatically by configure. */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* RCS id: $Id: machine.h.in,v 1.2 1994/03/13 23:07:30 des Exp $ */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ /* #undef const */ /* #undef MALLOCDECL */ #define NOT_SEGMENTED 1 #define HAVE_MEMORY_H 1 /* #undef HAVE_COMPLEX_H */ #define HAVE_MALLOC_H 1 #define STDC_HEADERS 1 #define HAVE_BCOPY 1 #define HAVE_BZERO 1 #define CHAR0ISDBL0 1 #define WORDS_BIGENDIAN 1 /*#undef U_INT_DEF */ #define U_INT_DEF #define VARARGS 1 #define HAVE_PROTOTYPES 1 /* #undef HAVE_PROTOTYPES_IN_STRUCT */ /* for inclusion into C++ files */ #ifdef __cplusplus #define ANSI_C 1 #ifndef HAVE_PROTOTYPES #define HAVE_PROTOTYPES 1 #endif #ifndef HAVE_PROTOTYPES_IN_STRUCT #define HAVE_PROTOTYPES_IN_STRUCT 1 #endif #endif /* __cplusplus */ /* example usage: VEC *PROTO(v_get,(int dim)); */ #ifdef HAVE_PROTOTYPES #define PROTO(name,args) name args #else #define PROTO(name,args) name() #endif /* HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES_IN_STRUCT /* PROTO_() is to be used instead of PROTO() in struct's and typedef's */ #define PROTO_(name,args) name args #else #define PROTO_(name,args) name() #endif /* HAVE_PROTOTYPES_IN_STRUCT */ /* for basic or larger versions */ #define COMPLEX 1 #define SPARSE 1 /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 #define REAL_FLT 1 /* #undef REAL_DBL */ /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT 2147483647 #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #else #undef HUGE #define HUGE HUGE_VAL #endif #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/SGI/makefile0000777000175000017500000001346213120075106023276 0ustar00alisteralister00000000000000# Generated automatically from makefile.in by configure. # # Makefile for Meschach via autoconf # # Copyright (C) David Stewart & Zbigniew Leyk 1993 # # $Id: makefile.in,v 1.4 1994/03/14 01:24:06 des Exp $ # srcdir = . VPATH = . CC = cc DEFS = -DHAVE_CONFIG_H LIBS = -lm RANLIB = ranlib CFLAGS = -O .c.o: $(CC) -c $(CFLAGS) $(DEFS) $< SHELL = /bin/sh MES_PAK = mesch12b TAR = tar SHAR = stree -u ZIP = zip -r -l FLIST = FILELIST ############################### LIST1 = copy.o err.o matrixio.o memory.o vecop.o matop.o pxop.o \ submat.o init.o otherio.o machine.o matlab.o ivecop.o version.o \ meminfo.o memstat.o LIST2 = lufactor.o bkpfacto.o chfactor.o qrfactor.o solve.o hsehldr.o \ givens.o update.o norm.o hessen.o symmeig.o schur.o svd.o fft.o \ mfunc.o bdfactor.o LIST3 = sparse.o sprow.o sparseio.o spchfctr.o splufctr.o \ spbkp.o spswap.o iter0.o itersym.o iternsym.o ZLIST1 = zmachine.o zcopy.o zmatio.o zmemory.o zvecop.o zmatop.o znorm.o \ zfunc.o ZLIST2 = zlufctr.o zsolve.o zmatlab.o zhsehldr.o zqrfctr.o \ zgivens.o zhessen.o zschur.o # they are no longer supported # if you use them add oldpart to all and sparse OLDLIST = conjgrad.o lanczos.o arnoldi.o ALL_LISTS = $(LIST1) $(LIST2) $(LIST3) $(ZLIST1) $(ZLIST2) $(OLDLIST) HBASE = err.h meminfo.h machine.h matrix.h HLIST = $(HBASE) iter.h matlab.h matrix2.h oldnames.h sparse.h \ sparse2.h zmatrix.h zmatrix2.h TORTURE = torture.o sptort.o ztorture.o memtort.o itertort.o \ mfuntort.o iotort.o OTHERS = dmacheps.c extras.c fmacheps.c maxint.c makefile.in \ README configure configure.in machine.h.in copyright \ tutorial.c tutadv.c rk4.dat ls.dat makefile $(FLIST) # Different configurations # the dependencies **between** the parts are for dmake all: part1 part2 part3 zpart1 zpart2 part2: part1 part3: part2 basic: part1 part2 sparse: part1 part2 part3 zpart2: zpart1 complex: part1 part2 zpart1 zpart2 $(LIST1): $(HBASE) part1: $(LIST1) ar ru meschach.a $(LIST1) $(RANLIB) meschach.a $(LIST2): $(HBASE) matrix2.h part2: $(LIST2) ar ru meschach.a $(LIST2) $(RANLIB) meschach.a $(LIST3): $(HBASE) sparse.h sparse2.h part3: $(LIST3) ar ru meschach.a $(LIST3) $(RANLIB) meschach.a $(ZLIST1): $(HBASDE) zmatrix.h zpart1: $(ZLIST1) ar ru meschach.a $(ZLIST1) $(RANLIB) meschach.a $(ZLIST2): $(HBASE) zmatrix.h zmatrix2.h zpart2: $(ZLIST2) ar ru meschach.a $(ZLIST2) $(RANLIB) meschach.a $(OLDLIST): $(HBASE) sparse.h sparse2.h oldpart: $(OLDLIST) ar ru meschach.a $(OLDLIST) $(RANLIB) meschach.a ####################################### tar: - /bin/rm -f $(MES_PAK).tar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(TAR) cvf $(MES_PAK).tar \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC # use this only for PC machines msdos-zip: - /bin/rm -f $(MES_PAK).zip chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(ZIP) $(MES_PAK).zip \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC fullshar: - /bin/rm -f $(MES_PAK).shar; chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC > $(MES_PAK).shar shar: - /bin/rm -f meschach1.shar meschach2.shar meschach3.shar \ meschach4.shar oldmeschach.shar meschach0.shar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(LIST1) | sed -e 's/\.o/.c/g'` > meschach1.shar $(SHAR) `echo $(LIST2) | sed -e 's/\.o/.c/g'` > meschach2.shar $(SHAR) `echo $(LIST3) | sed -e 's/\.o/.c/g'` > meschach3.shar $(SHAR) `echo $(ZLIST1) | sed -e 's/\.o/.c/g'` \ `echo $(ZLIST2) | sed -e 's/\.o/.c/g'` > meschach4.shar $(SHAR) `echo $(OLDLIST) | sed -e 's/\.o/.c/g'` > oldmeschach.shar $(SHAR) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) DOC MACHINES > meschach0.shar list: /bin/rm -f $(FLIST) ls -lR `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) MACHINES DOC \ |awk '/^$$/ {print};/^[-d]/ {printf("%s %s %10d %s %s %s %s\n", \ $$1,$$2,$$5,$$6,$$7,$$8,$$9)}; /^[^-d]/ {print}' \ > $(FLIST) clean: /bin/rm -f *.o core asx5213a.mat iotort.dat cleanup: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a realclean: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a /bin/rm -f torture sptort ztorture memtort itertort mfuntort iotort /bin/rm -f makefile machine.h config.status maxint macheps alltorture: torture sptort ztorture memtort itertort mfuntort iotort torture:torture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o torture torture.o \ meschach.a $(LIBS) sptort:sptort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o sptort sptort.o \ meschach.a $(LIBS) memtort: memtort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o memtort memtort.o \ meschach.a $(LIBS) ztorture:ztorture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o ztorture ztorture.o \ meschach.a $(LIBS) itertort: itertort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o itertort itertort.o \ meschach.a $(LIBS) iotort: iotort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o iotort iotort.o \ meschach.a $(LIBS) mfuntort: mfuntort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o mfuntort mfuntort.o \ meschach.a $(LIBS) tstmove: tstmove.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstmove tstmove.o \ meschach.a $(LIBS) tstpxvec: tstpxvec.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstpxvec tstpxvec.o \ meschach.a $(LIBS) gtk-wave-cleaner-0.22-04/meschach/MACHINES/SPARC/0000755000175000017500000000000013252653022022014 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/SPARC/machine.h0000777000175000017500000000670413120075106023602 0ustar00alisteralister00000000000000 /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ #define const /* #undef MALLOCDECL */ #define NOT_SEGMENTED 1 /* #undef HAVE_COMPLEX_H */ #define HAVE_MALLOC_H 1 /* #undef STDC_HEADERS */ #define HAVE_BCOPY 1 #define HAVE_BZERO 1 #define CHAR0ISDBL0 1 #define WORDS_BIGENDIAN 1 /* #undef U_INT_DEF */ #define VARARGS 1 /* for basic or larger versions */ #define COMPLEX 1 #define SPARSE 1 /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ /* #undef HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ #define REAL_DBL 1 /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT 2147483647 #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #endif #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/SPARC/makefile0000777000175000017500000001211313120075106023514 0ustar00alisteralister00000000000000# # # Makefile for Meschach for SUN SPARC cc # # Copyright (C) David Stewart & Zbigniew Leyk 1993 # # $Id: $ # srcdir = . VPATH = . CC = cc DEFS = -DHAVE_CONFIG_H LIBS = -lm RANLIB = ranlib CFLAGS = -O .c.o: $(CC) -c $(CFLAGS) $(DEFS) $< SHELL = /bin/sh MES_PAK = mesch12a TAR = tar SHAR = stree -u ZIP = zip -r -l ############################### LIST1 = copy.o err.o matrixio.o memory.o vecop.o matop.o pxop.o \ submat.o init.o otherio.o machine.o matlab.o ivecop.o version.o \ meminfo.o memstat.o LIST2 = lufactor.o bkpfacto.o chfactor.o qrfactor.o solve.o hsehldr.o \ givens.o update.o norm.o hessen.o symmeig.o schur.o svd.o fft.o \ mfunc.o bdfactor.o LIST3 = sparse.o sprow.o sparseio.o spchfctr.o splufctr.o \ spbkp.o spswap.o iter0.o itersym.o iternsym.o ZLIST1 = zmachine.o zcopy.o zmatio.o zmemory.o zvecop.o zmatop.o znorm.o \ zfunc.o ZLIST2 = zlufctr.o zsolve.o zmatlab.o zhsehldr.o zqrfctr.o \ zgivens.o zhessen.o zschur.o # they are no longer supported # if you use them add oldpart to all and sparse OLDLIST = conjgrad.o lanczos.o arnoldi.o ALL_LISTS = $(LIST1) $(LIST2) $(LIST3) $(ZLIST1) $(ZLIST2) $(OLDLIST) HLIST = err.h iter.h machine.h matlab.h matrix.h matrix2.h \ meminfo.h oldnames.h sparse.h sparse2.h \ zmatrix.h zmatrix2.h TORTURE = torture.o sptort.o ztorture.o memtort.o itertort.o \ mfuntort.o iotort.o OTHERS = dmacheps.c extras.c fmacheps.c maxint.c makefile.in \ README configure configure.in machine.h.in copyright \ tutorial.c tutadv.c rk4.dat ls.dat makefile # Different configurations all: part1 part2 part3 zpart1 zpart2 basic: part1 part2 sparse: part1 part2 part3 complex: part1 part2 zpart1 zpart2 HBASE = err.h meminfo.h machine.h matrix.h $(LIST1): $(HBASE) part1: $(LIST1) ar ru meschach.a $(LIST1); $(RANLIB) meschach.a $(LIST2): $(HBASE) matrix2.h part2: $(LIST2) ar ru meschach.a $(LIST2); $(RANLIB) $(LIST3): $(HBASE) sparse.h sparse2.h part3: $(LIST3) ar ru meschach.a $(LIST3); $(RANLIB) meschach.a $(ZLIST1): $(HBASDE) zmatrix.h zpart1: $(ZLIST1) ar ru meschach.a $(ZLIST1); $(RANLIB) meschach.a $(ZLIST2): $(HBASE) zmatrix.h zmatrix2.h zpart2: $(ZLIST2) ar ru meschach.a $(ZLIST2); $(RANLIB) meschach.a $(OLDLIST): $(HBASE) sparse.h sparse2.h oldpart: $(OLDLIST) ar ru meschach.a $(OLDLIST); $(RANLIB) meschach.a ####################################### tar: - /bin/rm -f $(MES_PAK).tar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(TAR) cvf $(MES_PAK).tar \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC # use this only for PC machines msdos-zip: - /bin/rm -f $(MES_PAK).zip chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(ZIP) $(MES_PAK).zip \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC fullshar: - /bin/rm -f $(MES_PAK).shar; chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(SHAR) `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC > $(MES_PAK).shar shar: - /bin/rm -f meschach1.shar meschach2.shar meschach3.shar \ meschach4.shar oldmeschach.shar meschach0.shar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(SHAR) `echo $(LIST1) | sed -e 's/\.o/.c/g'` > meschach1.shar $(SHAR) `echo $(LIST2) | sed -e 's/\.o/.c/g'` > meschach2.shar $(SHAR) `echo $(LIST3) | sed -e 's/\.o/.c/g'` > meschach3.shar $(SHAR) `echo $(ZLIST1) | sed -e 's/\.o/.c/g'` \ `echo $(ZLIST2) | sed -e 's/\.o/.c/g'` > meschach4.shar $(SHAR) `echo $(OLDLIST) | sed -e 's/\.o/.c/g'` > oldmeschach.shar $(SHAR) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) DOC MACHINES > meschach0.shar clean: /bin/rm -f *.o core asx5213a.mat iotort.dat cleanup: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a alltorture: torture sptort ztorture memtort itertort mfuntort iotort torture:torture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o torture torture.o \ meschach.a $(LIBS) sptort:sptort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o sptort sptort.o \ meschach.a $(LIBS) memtort: memtort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o memtort memtort.o \ meschach.a $(LIBS) ztorture:ztorture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o ztorture ztorture.o \ meschach.a $(LIBS) itertort: itertort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o itertort itertort.o \ meschach.a $(LIBS) iotort: iotort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o iotort iotort.o \ meschach.a $(LIBS) mfuntort: mfuntort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o mfuntort mfuntort.o \ meschach.a $(LIBS) tstmove: tstmove.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstmove tstmove.o \ meschach.a $(LIBS) tstpxvec: tstpxvec.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstpxvec tstpxvec.o \ meschach.a $(LIBS) gtk-wave-cleaner-0.22-04/meschach/MACHINES/ThinkC/0000755000175000017500000000000013252653022022324 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/ThinkC/README0000777000175000017500000000730113120075106023207 0ustar00alisteralister00000000000000README file for compiling Meschach with Think C =============================================== Received 8th June, 1995 from Brent Boyer (boyer@jumpjibe.stanford.edu). I have modified this file to make the Meschach routines work on a Macintosh with THINK C 7.0.4. I realize that THINK C is now on version 8.x and that Metrowerk's CodeWarrior is a competetive development environment, but 7.0.4 is what I have available. My system is a Quadra 650 running MacOS 7.5.1. The compile options described below should work for any 68K Mac with a floating point unit; they probably have to be modified for Power Macs. Below I describe the steps I took to build a library project for all the Meschach routines. Step 1) _________ First create an appropriate version of THINK's ANSI library. What I did was copy their project "ANSI" to one I called "ANSI(020, 881, 4b ints)". I then selected these compiler ("THINK C...") options before bringing the project up to date: -- first, under "Language Settings" 1) choose "Factory Settings" 2) also change "Infer prototypes" to "Require prototypes" (as a former Pascal programmer, I curse the person who introduced infered prototypes!) (Note: you _cannot_ choose "ANSI Settings"; if you do, then the compilation of the ANSI project will fail! Talk to the people at Symantec about this one ...) -- next, under "Compiler Settings" 1) turn "Generate 68020 instructions" ON 2) turn "Generate 68881 instructions" ON 3) turn "4-byte ints" ON (so int == long int <==> 32 bits) 4) make sure that "8-byte doubles" turned OFF (so double == long double) 5) turn "Native floating-point format" ON (The other options probably do not matter either way) (Note: 2) and 5) ==> type double will be the 96 bit MC68881 floating point extended precision type; these options give the best speed and good accuracy too) -- optionally, under "Code Optimization" 1) turn "Use Global Optimizer" ON Step 2) _________ Create a project ("Meschach") containing all the Meschach routines that can serve as a library. After opening a new project ("ANSI Project" type) to which you added all the source code files, select these compiler ("THINK C...") options before bringing the project up to date: -- first, under "Language Settings" 1) choose "ANSI Settings" (tragically, will have to leave "Infer prototypes" on) -- next, under "Compiler Settings", make the same choices as when compiled "ANSI(020, 881, 4b ints)" 1) turn "Generate 68020 instructions" ON 2) turn "Generate 68881 instructions" ON 3) turn "4-byte ints" ON (so int == long int <==> 32 bits) 4) make sure that "8-byte doubles" turned OFF (so double == long double) 5) turn "Native floating-point format" ON (Note: the THINK C compiler, quite correctly, insists that pointer types agree exactly. This means that the function "px_sign" in the file "pxop.c" will not compile unless the line numtransp = myqsort(px2->pe, px2->size); is replaced with numtransp = myqsort( (int *) px2->pe, px2->size ); since the field "pe" is a pointer to type u_int, not an int, which the function "myqsort" expects. I made this change.) [D.Stewart: This change will be made to the next distribution of Meschach.] You should then be able to simply add this project to any of your own projects so that it functions as a library. The original "machine.h" file may be found in the folder "origStuff" along with the *.shar files. -- Brent Boyer 6/7/95 [Note: The file MACHINES/ThinkC/totalMacSetup.hqx has been moved to the top directory, and is not automatically part of the main distribution. The reason for this is the amount of space it takes up. -- David Stewart, 8th Sept., 1995.] gtk-wave-cleaner-0.22-04/meschach/MACHINES/ThinkC/TC-README0000777000175000017500000001575113120075106023523 0ustar00alisteralister00000000000000From boyer@jumpjibe.stanford.edu Fri Jun 9 03:54:33 1995 Received: from jumpjibe.stanford.edu (jumpjibe.Stanford.EDU [36.4.0.23]) by gluttony.isc.tamu.edu (8.6.11/8.6.11) with ESMTP id DAA18702 for ; Fri, 9 Jun 1995 03:54:31 -0500 Received: (from boyer@localhost) by jumpjibe.stanford.edu (8.6.10/8.6.10) id BAA13677 for des@isc.tamu.edu; Fri, 9 Jun 1995 01:54:48 -0700 Message-Id: <199506090854.BAA13677@jumpjibe.stanford.edu> From: boyer@jumpjibe.stanford.edu (Brent Boyer) Date: Fri, 9 Jun 1995 01:54:48 PDT In-Reply-To: David Stewart "Re: Meschach setup question" (Jun 8, 19:07) X-Mailer: Mail User's Shell (7.2.0 10/31/90) To: David Stewart Subject: second additional message Content-Length: 6352 X-Lines: 168 Status: RO dave, below is the text for a file I call "Mac/TC README" which explains everything I did to get it running. -brent /* Introduction -- Brent Boyer 6/7/95 _____________________ I have found a procedure which gets the Meschach routines to work on a Macintosh with THINK C 7.0.4. My system is a Quadra 650 running MacOS 7.5.1. The compile options described below should work for any 68K Mac with a floating point unit; they probably have to be modified for Power Macs (in particular, check the floating point type mapping and precision). (Note: THINK C is now on version 8.x, perhaps they have fixed some of the terrible features of the 7.x release; Metrowerk's CodeWarrior is supposed to be a better development environment and it allegedly can easily translate THINK C projects) Procedure _____________________ Note: all projects described here should have the folowing options made under "Set Project Type..." (which is found under the "Project" menu): 1) "Application" type 2) "Far CODE" and "Far DATA" checked 3) Partition should be raised from 384 to 4000 (required to get all the *tort*.c projects to run) 4) Under "SIZE Flags", you can set "32-Bit Compatible" but leave the rest unchecked Step #1 _________ Create an appropriate version of THINK's ANSI library. -- first, you will have to modify two of Symantecs "Standard Library" files to let the function "isascii" become available (this function is required in "err.c") 1) in THINK's file "ctype.h" add this code in the appropriate places: a) int isascii(int); b) #define isascii(c) ((unsigned)(c)<=0177) 2) in THINK's file "ctype.c" add this code: a) int (isascii)(int c) { return (isascii(c)); } What I next did was copy their project "ANSI" to one I called "ANSI (for Meschach)". I then selected these compiler ("THINK C...") options before bringing the project up to date: -- first, under "Language Settings" 1) choose "Factory Settings" 2) also change "Infer prototypes" to "Require prototypes" (as a former Pascal programmer, I curse the person who introduced infered prototypes!) (Note: you _cannot_ choose "ANSI Settings"; if you do, then the compilation of the ANSI project will fail! Talk to the people at Symantec about this one ...) -- then, under "Compiler Settings" 1) turn "Generate 68020 instructions" ON 2) turn "Generate 68881 instructions" ON 3) turn "4-byte ints" ON (so int == long int <==> 32 bits) 4) make sure that "8-byte doubles" turned OFF (so double == long double) 5) turn "Native floating-point format" ON (The other options probably do not matter either way) (Note: 2) and 5) ==> type double will be the 96 bit MC68881 floating point extended precision type; these options give the best speed and good accuracy too) (Also: this 96 bit floating point type will cause the test in "memtort.c" to wrongly report that 756 blocks were allocated when only 516 should have been) -- optionally, under "Code Optimization" 1) turn "Use Global Optimizer" ON Step #2 _________ Next create an appropriate version of THINK's UNIX library. What I did was copy their project "unix" to one I called "unix (for Meschach)". Build this project with the same "Language Settings" and "Compiler Settings" options described in Step #1. Step #3 _________ Correct some errors in the "Meschach" source code files: 1) the function "Mmmtr" in the file "extras.c" has an error in the line Mmv(n,p,alpha,&(A[i][Aj0]),B,Bj0,&(C[i][Cj0])); the correct line should read Mmv(n,p,alpha,B,Bj0,&(A[i][Aj0]),1.0,&(C[i][Cj0])); 2) the function "px_sign" in the file "pxop.c" will not compile unless the line numtransp = myqsort(px2->pe, px2->size); is replaced with numtransp = myqsort( (int *) px2->pe, px2->size ); 3) the function "chk_col_access" in the file "sptort.c" conflicts with the same named function in the file "spbkp.c". This causes a link error. To solve this problem, I suggest renaming it as chk_col_access -> chk_col_accessSPT (Dave Stewart tells me that these errors are corrected (along with other stuff?) in a to-be-released version of "Meschach".) Step #4 _________ Ideally, you would next create a single large library containing all the Meschach routines. Unfortunately, you cannot do this because THINK C requires libraries to either be, or be built from, single segment projects, and individual segments can only have 32K of compiled code size, which is way too small for all the Meschach routines. Instead, what I had to do was create 7 smaller, single segment projects. I added code to the segments strictly in alphabetical order, with no regard to partitioning (i.e. putting similar routines together). To make each such project, I first opened a new project ("ANSI Project" type) and then added alot of source code files. I then selected these compiler ("THINK C...") options before bringing the project up to date: -- first, under "Language Settings" 1) choose "ANSI Settings" (tragically, will have to leave "Infer prototypes" on) -- next, under "Compiler Settings", make the same choices as when compiled "ANSI (for Meschach)" 1) turn "Generate 68020 instructions" ON 2) turn "Generate 68881 instructions" ON 3) turn "4-byte ints" ON (so int == long int <==> 32 bits) 4) make sure that "8-byte doubles" turned OFF (so double == long double) 5) turn "Native floating-point format" ON If the resulting single segment was over 32K, I removed files from the bottom of the list until the segment had < 32K left. The file "main.c" which was automatically generated was also removed. Note: I never added the *tort*.c files or any of the other files with a main routine (e.g. "maxint.c") in them to these projects. The *tort*.c files were made into separate projects. In order to echo the screen output to a file when running the torture tests, you need to add these lines to each *tort*.c file: a) #include (put near top) b) cecho2file("filename", 0, stdout); (put inside main) You should then be able to simply add all these projects to any of your own projects -- this will give you the whole library. */ gtk-wave-cleaner-0.22-04/meschach/MACHINES/ThinkC/TC-machine-2.h0000777000175000017500000002406513120075106024555 0ustar00alisteralister00000000000000From boyer@jumpjibe.stanford.edu Fri Jun 9 14:17:09 1995 Received: from jumpjibe.stanford.edu (jumpjibe.Stanford.EDU [36.4.0.23]) by gluttony.isc.tamu.edu (8.6.11/8.6.11) with ESMTP id OAA24615 for ; Fri, 9 Jun 1995 14:17:07 -0500 Received: (from boyer@localhost) by jumpjibe.stanford.edu (8.6.10/8.6.10) id MAA15164 for des@isc.tamu.edu; Fri, 9 Jun 1995 12:17:24 -0700 Message-Id: <199506091917.MAA15164@jumpjibe.stanford.edu> From: boyer@jumpjibe.stanford.edu (Brent Boyer) Date: Fri, 9 Jun 1995 12:17:24 PDT In-Reply-To: David Stewart "Re: Meschach setup question" (Jun 8, 19:07) X-Mailer: Mail User's Shell (7.2.0 10/31/90) To: David Stewart Subject: Re: Meschach setup question Content-Length: 9498 X-Lines: 369 Status: RO david, did this file get thru to you last nite? (someone else told me that i sent it them instead; maybe i accidentally cced it to them). -brent below is the new machine.h file for Macs: /* ================================================================================ */ /* machine.h. Generated automatically by configure. */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* RCS id: $Id: machine.h.in,v 1.2 1994/03/13 23:07:30 des Exp $ */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ /* ================================================================================ */ /* #undef const */ /* leave this commented out -- THINK C has no keyword named "const" */ /* #undef MALLOCDECL */ /* leave this commented out -- THINK C doesn't supply */ #define NOT_SEGMENTED 1 /* this must #defined -- Mac's don't have segmented memory */ #undef HAVE_MEMORY_H /* make sure this is #undefined -- THINK C doesn't supply */ #undef HAVE_COMPLEX_H /* make sure this is #undefined -- THINK C doesn't supply */ #undef HAVE_MALLOC_H /* make sure this is #undefined -- THINK C doesn't supply */ #define STDC_HEADERS 1 /* this must be #defined -- it will cause precisely two effects below: 1) the macros MEM_COPY(...) & MEM_ZERO(...) will be correctly defined using memmove(...) & memset(...) 2) the macro ANSI_C will be #defined */ #undef HAVE_BCOPY /* make sure this is #undefined -- bcopy is for a BSD system? */ #undef HAVE_BZERO /* make sure this is #undefined -- bzero is for a BSD system? */ /* #undef CHAR0ISDBL0 1 */ /* for safety, this should be commented out (Dave Stewart's advice) */ #define WORDS_BIGENDIAN 1 /* 68K Macs use big endian microprocessors */ #undef U_INT_DEF /* make sure this is #undefined (Dave Stewart's advice) */ #define VARARGS 1 /* this must be #defined (Dave Stewart's advice) */ /* ================================================================================ */ /* for prototypes */ #define HAVE_PROTOTYPES 1 /* this must be #defined (Dave Stewart's advice) */ #define HAVE_PROTOTYPES_IN_STRUCT 1 /* this must be #defined (Dave Stewart's advice) */ /* for inclusion into C++ files */ #ifdef __cplusplus /* (Note: THINK C must #define this somewhere, since it is used in "ctype.h") */ #define ANSI_C 1 #ifndef HAVE_PROTOTYPES #define HAVE_PROTOTYPES 1 #endif #ifndef HAVE_PROTOTYPES_IN_STRUCT #define HAVE_PROTOTYPES_IN_STRUCT 1 #endif #endif /* __cplusplus */ /* example usage: VEC *PROTO(v_get,(int dim)); */ #ifdef HAVE_PROTOTYPES #define PROTO(name,args) name args #else #define PROTO(name,args) name() #endif /* HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES_IN_STRUCT /* PROTO_() is to be used instead of PROTO() in struct's and typedef's */ #define PROTO_(name,args) name args #else #define PROTO_(name,args) name() #endif /* HAVE_PROTOTYPES_IN_STRUCT */ /* ================================================================================ */ /* for basic or larger versions */ #define COMPLEX 1 /* this must be #defined (I want all the complex routines) */ #define SPARSE 1 /* this must be #defined (I want all the sparse routines) */ /* ================================================================================ */ /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* ================================================================================ */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* ================================================================================ */ /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* ================================================================================ */ /* any compiler should have this header */ /* if not, change it */ #include /* ================================================================================ */ /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* ================================================================================ */ /* standard headers */ #ifdef ANSI_C #include #include #include #include #include /* #include so that the macro HUGE_VAL will be available to us */ #endif /* ================================================================================ */ /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* ================================================================================ */ /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* ================================================================================ */ /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* ================================================================================ */ /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ /* #undef REAL_DBL */ /* leave these both commented out, so that the dafault of double is used */ /* choose double precision by default */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 /* this is what we want: all reals to be of type double */ #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* Note: under THINK C, the type "double" gets mapped to the type "long double" as long as you DO NOT turn on the "8-byte doubles" option. Recall: this project was compiled with the "8-byte doubles" option turned OFF (so double == long double) Also Recall: this project was compiled with the "Generate 68881 instructions" and "Native floating-point format" options turned ON; this means that double will be a 96 bit MC68881 floating point extended precision type; these options give the best speed. (See the THINK C 6.0 User's Guide, pp. 313-317) --Brent Boyer 6/7/95 */ /* ================================================================================ */ /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 /* Note: the extended precision floating point type we are using actually has DBL_EPSILON = 1.08420E-19 (THINK C 6.0 User's Guide, p. 317); out of caution, I will let the above value for D_MACHEPS stay the same. --Brent Boyer 6/7/95 */ #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ /* ================================================================================ */ #define M_MAX_INT 2147483647 /* this value only works if ints are 32 bits */ /* Recall: this project was compiled with the "4-byte ints" option turned ON (so int == long int <==> 32 bits); if you do not turn this option on, then ints will be 16 bits so that you will need to do #define M_MAX_INT 32767 instead --Brent Boyer 6/7/95 */ #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* ================================================================================ */ /* for non-ANSI systems */ /* we #included above precisely so that HUGE_VAL will be #defined here */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #else #ifndef HUGE #define HUGE HUGE_VAL /* actually, since HUGE is used in several Meschach routines, you need this line to be executed even on ANSI systems */ #endif #endif /* ================================================================================ */ #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/ThinkC/TC-machine.h0000777000175000017500000002376213120075106024421 0ustar00alisteralister00000000000000From boyer@jumpjibe.stanford.edu Fri Jun 9 03:51:40 1995 Received: from jumpjibe.stanford.edu (jumpjibe.Stanford.EDU [36.4.0.23]) by gluttony.isc.tamu.edu (8.6.11/8.6.11) with ESMTP id DAA18674 for ; Fri, 9 Jun 1995 03:51:38 -0500 Received: (from boyer@localhost) by jumpjibe.stanford.edu (8.6.10/8.6.10) id BAA13657; Fri, 9 Jun 1995 01:51:54 -0700 Message-Id: <199506090851.BAA13657@jumpjibe.stanford.edu> From: boyer@jumpjibe.stanford.edu (Brent Boyer) Date: Fri, 9 Jun 1995 01:51:54 PDT In-Reply-To: David Stewart "Re: Meschach setup question" (Jun 8, 19:07) X-Mailer: Mail User's Shell (7.2.0 10/31/90) To: David Stewart Subject: Re: Meschach setup question Cc: new@jumpjibe.stanford.edu, machine.h@jumpjibe.stanford.edu, file@jumpjibe.stanford.edu Content-Length: 9353 X-Lines: 364 Status: RO Dave, below is the new machine.h file. -brent /* ================================================================================ */ /* machine.h. Generated automatically by configure. */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* RCS id: $Id: machine.h.in,v 1.2 1994/03/13 23:07:30 des Exp $ */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ /* ================================================================================ */ /* #undef const */ /* leave this commented out -- THINK C has no keyword named "const" */ /* #undef MALLOCDECL */ /* leave this commented out -- THINK C doesn't supply */ #define NOT_SEGMENTED 1 /* this must #defined -- Mac's don't have segmented memory */ #undef HAVE_MEMORY_H /* make sure this is #undefined -- THINK C doesn't supply */ #undef HAVE_COMPLEX_H /* make sure this is #undefined -- THINK C doesn't supply */ #undef HAVE_MALLOC_H /* make sure this is #undefined -- THINK C doesn't supply */ #define STDC_HEADERS 1 /* this must be #defined -- it will cause precisely two effects below: 1) the macros MEM_COPY(...) & MEM_ZERO(...) will be correctly defined using memmove(...) & memset(...) 2) the macro ANSI_C will be #defined */ #undef HAVE_BCOPY /* make sure this is #undefined -- bcopy is for a BSD system? */ #undef HAVE_BZERO /* make sure this is #undefined -- bzero is for a BSD system? */ /* #undef CHAR0ISDBL0 1 */ /* for safety, this should be commented out (Dave Stewart's advice) */ #define WORDS_BIGENDIAN 1 /* 68K Macs use big endian microprocessors */ #undef U_INT_DEF /* make sure this is #undefined (Dave Stewart's advice) */ #define VARARGS 1 /* this must be #defined (Dave Stewart's advice) */ /* ================================================================================ */ /* for prototypes */ #define HAVE_PROTOTYPES 1 /* this must be #defined (Dave Stewart's advice) */ #define HAVE_PROTOTYPES_IN_STRUCT 1 /* this must be #defined (Dave Stewart's advice) */ /* for inclusion into C++ files */ #ifdef __cplusplus /* (Note: THINK C must #define this somewhere, since it is used in "ctype.h") */ #define ANSI_C 1 #ifndef HAVE_PROTOTYPES #define HAVE_PROTOTYPES 1 #endif #ifndef HAVE_PROTOTYPES_IN_STRUCT #define HAVE_PROTOTYPES_IN_STRUCT 1 #endif #endif /* __cplusplus */ /* example usage: VEC *PROTO(v_get,(int dim)); */ #ifdef HAVE_PROTOTYPES #define PROTO(name,args) name args #else #define PROTO(name,args) name() #endif /* HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES_IN_STRUCT /* PROTO_() is to be used instead of PROTO() in struct's and typedef's */ #define PROTO_(name,args) name args #else #define PROTO_(name,args) name() #endif /* HAVE_PROTOTYPES_IN_STRUCT */ /* ================================================================================ */ /* for basic or larger versions */ #define COMPLEX 1 /* this must be #defined (I want all the complex routines) */ #define SPARSE 1 /* this must be #defined (I want all the sparse routines) */ /* ================================================================================ */ /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* ================================================================================ */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* ================================================================================ */ /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* ================================================================================ */ /* any compiler should have this header */ /* if not, change it */ #include /* ================================================================================ */ /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* ================================================================================ */ /* standard headers */ #ifdef ANSI_C #include #include #include #include #include /* #include so that the macro HUGE_VAL will be available to us */ #endif /* ================================================================================ */ /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* ================================================================================ */ /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* ================================================================================ */ /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* ================================================================================ */ /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ /* #undef REAL_DBL */ /* leave these both commented out, so that the dafault of double is used */ /* choose double precision by default */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 /* this is what we want: all reals to be of type double */ #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* Note: under THINK C, the type "double" gets mapped to the type "long double" as long as you DO NOT turn on the "8-byte doubles" option. Recall: this project was compiled with the "8-byte doubles" option turned OFF (so double == long double) Also Recall: this project was compiled with the "Generate 68881 instructions" and "Native floating-point format" options turned ON; this means that double will be a 96 bit MC68881 floating point extended precision type; these options give the best speed. (See the THINK C 6.0 User's Guide, pp. 313-317) --Brent Boyer 6/7/95 */ /* ================================================================================ */ /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 /* Note: the extended precision floating point type we are using actually has DBL_EPSILON = 1.08420E-19 (THINK C 6.0 User's Guide, p. 317); out of caution, I will let the above value for D_MACHEPS stay the same. --Brent Boyer 6/7/95 */ #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ /* ================================================================================ */ #define M_MAX_INT 2147483647 /* this value only works if ints are 32 bits */ /* Recall: this project was compiled with the "4-byte ints" option turned ON (so int == long int <==> 32 bits); if you do not turn this option on, then ints will be 16 bits so that you will need to do #define M_MAX_INT 32767 instead --Brent Boyer 6/7/95 */ #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* ================================================================================ */ /* for non-ANSI systems */ /* we #included above precisely so that HUGE_VAL will be #defined here */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #else #ifndef HUGE #define HUGE HUGE_VAL /* actually, since HUGE is used in several Meschach routines, you need this line to be executed even on ANSI systems */ #endif #endif /* ================================================================================ */ #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/ThinkC/machine.h0000777000175000017500000002251713120075106024112 0ustar00alisteralister00000000000000/* This file was written by Brent Boyer (boyer@jumpjibe.stanford.edu), June 7th, 1995 for compiling Meschach under Think C 7.0.4. His development systems was a Quadra 650 running MacOS 7.5.1 using a 68x00 CPU with a 68881 FPU. Power Macs will probably require modification. For details on how to build the library, see the associated README file. */ /* Begin stuff from the original Meschach file: */ /* ======================================================================== */ /* machine.h. Generated automatically by configure. */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* RCS id: $Id: machine.h.in,v 1.2 1994/03/13 23:07:30 des Exp $ */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ /* ======================================================================== */ /* #undef const */ /* leave this commented out -- THINK C has no keyword named "const" */ /* #undef MALLOCDECL */ /* leave this commented out -- THINK C doesn't supply */ #define NOT_SEGMENTED 1 /* this must #defined -- Mac's don't have segmented memory */ #undef HAVE_MEMORY_H /* make sure this is #undefined -- THINK C doesn't supply */ #undef HAVE_COMPLEX_H /* make sure this is #undefined -- THINK C doesn't supply */ #undef HAVE_MALLOC_H /* make sure this is #undefined -- THINK C doesn't supply */ #define STDC_HEADERS 1 /* this must be #defined -- it will cause precisely two effects below: 1) the macros MEM_COPY(...) & MEM_ZERO(...) will be correctly defined using memmove(...) & memset(...) 2) the macro ANSI_C will be #defined */ #undef HAVE_BCOPY /* make sure this is #undefined -- bcopy is for a BSD system? */ #undef HAVE_BZERO /* make sure this is #undefined -- bzero is for a BSD system? */ /* #undef CHAR0ISDBL0 1 */ /* for safety, this should be commented out (Dave Stewart's advice) */ /* #define WORDS_BIGENDIAN 1 */ /* what's this for? it doesn't appear to ever be used; I will comment it out */ #undef U_INT_DEF /* make sure this is #undefined (Dave Stewart's advice) */ /* #define VARARGS 1 */ /* Don't need routines with variable number of arguments */ /* ======================================================================= */ /* for prototypes */ #define HAVE_PROTOTYPES 1 /* this must be #defined (Dave Stewart's advice) */ #define HAVE_PROTOTYPES_IN_STRUCT 1 /* this must be #defined (Dave Stewart's advice) */ /* for inclusion into C++ files */ #ifdef __cplusplus /* (Note: I do not believe that THINK C ever #defines this) */ #define ANSI_C 1 #ifndef HAVE_PROTOTYPES #define HAVE_PROTOTYPES 1 #endif #ifndef HAVE_PROTOTYPES_IN_STRUCT #define HAVE_PROTOTYPES_IN_STRUCT 1 #endif #endif /* __cplusplus */ /* example usage: VEC *PROTO(v_get,(int dim)); */ #ifdef HAVE_PROTOTYPES #define PROTO(name,args) name args #else #define PROTO(name,args) name() #endif /* HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES_IN_STRUCT /* PROTO_() is to be used instead of PROTO() in struct's and typedef's */ #define PROTO_(name,args) name args #else #define PROTO_(name,args) name() #endif /* HAVE_PROTOTYPES_IN_STRUCT */ /* ======================================================================== */ /* for basic or larger versions */ #define COMPLEX 1 /* this must be #defined (I want all the complex routines) */ #define SPARSE 1 /* this must be #defined (I want all the sparse routines) */ /* ======================================================================== */ /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* ======================================================================== */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* ======================================================================== */ /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* ======================================================================== */ /* any compiler should have this header */ /* if not, change it */ #include /* ======================================================================== */ /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* ======================================================================== */ /* standard headers */ #ifdef ANSI_C #include #include #include #include #include /* #include so that the macro HUGE_VAL will be available to us */ #endif /* ======================================================================== */ /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* ======================================================================== */ /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* ======================================================================== */ /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* ======================================================================== */ /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ /* #undef REAL_DBL */ /* leave these both commented out, so that the dafault of double is used */ /* choose double precision by default */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 /* this is what we want: all reals to be of type double */ #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* Note: under THINK C, the type "double" gets mapped to the type "long double" as long as you DO NOT turn on the "8-byte doubles" option. Recall: this project was compiled with the "8-byte doubles" option turned OFF (so double == long double) Also Recall: this project was compiled with the "Generate 68881 instructions" and "Native floating-point format" options turned ON; this means that double will be a 96 bit MC68881 floating point extended precision type; these options give the best speed. (See the THINK C 6.0 User's Guide, pp. 313-317) --Brent Boyer 6/7/95 */ /* ======================================================================== */ /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 /* Note: the extended precision floating point type we are using actually has DBL_EPSILON = 1.08420E-19 (THINK C 6.0 User's Guide, p. 317); out of caution, I will let the above value for D_MACHEPS stay the same. --Brent Boyer 6/7/95 */ #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ /* ======================================================================== */ #define M_MAX_INT 2147483647 /* this value only works if ints are 32 bits */ /* Recall: this project was compiled with the "4-byte ints" option turned ON (so int == long int <==> 32 bits); if you do not turn this option on, then ints will be 16 bits so that you will need to do #define M_MAX_INT 32767 instead --Brent Boyer 6/7/95 */ #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* ======================================================================== */ /* for non-ANSI systems */ /* we #included above precisely so that HUGE_VAL will be #defined here */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #else #ifndef HUGE #define HUGE HUGE_VAL /* actually, since HUGE is used in several Meschach routines, you need */ /* this line to be executed even on ANSI systems */ #endif #endif /* ======================================================================== */ #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/TurboC/0000755000175000017500000000000013252653022022342 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/meschach/MACHINES/TurboC/README0000777000175000017500000000135513120075106023230 0ustar00alisteralister00000000000000This directory contains a makefile for Borland C++. It was written by Andrew Gockel (contact information below). Use at own risk. This is provided as part of the standard Meschach distribution to give the library the widest possible use. However, problems with the makefile should be directed to the author, not the developers of Meschach (David Stewart and Zbigniew Leyk). No representations are made concerning the fitness of this software for any particular purpose. # Borland C++ V4 Makefile # # Saturday, 14 October, 1995 # # Andrew Gockel # 123 Settlement Road # THE GAP, QLD., 4061 # AUSTRALIA # # Email # INTERNET:andrew@kittyhawk.aero.rmit.edu.au # CIS:100245.1253@compuserve.com # MSN:Andrew_Gockel@msn.com # # c:\meschach\meschach.mak gtk-wave-cleaner-0.22-04/meschach/MACHINES/TurboC/filelist0000777000175000017500000000005413120075106024101 0ustar00alisteralister00000000000000README filelist machine.h mail meschach.mak gtk-wave-cleaner-0.22-04/meschach/MACHINES/TurboC/machine.h0000777000175000017500000001227113120075106024124 0ustar00alisteralister00000000000000/* machine.h. Generated by Totte Karlsson, April, 1995 for Borland C/C++. */ /* See README file in this directory for more details */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* RCS id: $Id: machine.h.in,v 1.3 1995/03/27 15:36:21 des Exp $ */ /* This is for use with Borland (Turbo) C/C++ */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ /******************************************** ............................................. ........ From Totte Karlsson ......... ........ Physical Chemistry, ......... ........ Arrhenius Laboratory, ......... ........ Stockholm University, ......... ........ S10691 Stockholm Sweden ......... ........ email : torgny@physc.su.se ......... ........ Phone:+46-8-16 23 74 ......... ........ Fax: +46-8-15 2187 ......... ............................................. ********************************************/ #ifndef _MACHINE_H #define _MACHINE_H 1 /* #undef const */ /* #undef MALLOCDECL */ /*#define NOT_SEGMENTED 1*/ #define HAVE_MEMORY_H 1 /* #undef HAVE_COMPLEX_H */ #define HAVE_MALLOC_H 1 #define STDC_HEADERS 1 #define HAVE_BCOPY 1 #define HAVE_BZERO 1 #define CHAR0ISDBL0 1 #define WORDS_BIGENDIAN 1 #define U_INT_DEF 1 #define VARARGS 1 #define HAVE_PROTOTYPES 1 #define HAVE_PROTOTYPES_IN_STRUCT 1 /* for inclusion into C++ files */ #ifdef __cplusplus #define ANSI_C 1 #ifndef HAVE_PROTOTYPES #define HAVE_PROTOTYPES 1 #endif #ifndef HAVE_PROTOTYPES_IN_STRUCT #define HAVE_PROTOTYPES_IN_STRUCT 1 #endif #endif /* __cplusplus */ /* example usage: VEC *PROTO(v_get,(int dim)); */ #ifdef HAVE_PROTOTYPES #define PROTO(name,args) name args #else #define PROTO(name,args) name() #endif /* HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES_IN_STRUCT /* PROTO_() is to be used instead of PROTO() in struct's and typedef's */ #define PROTO_(name,args) name args #else #define PROTO_(name,args) name() #endif /* HAVE_PROTOTYPES_IN_STRUCT */ /* for basic or larger versions */ #define COMPLEX 1 #define SPARSE 1 /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ /* #undef REAL_DBL */ /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT 2147483647 #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #else #ifndef HUGE #define HUGE HUGE_VAL #endif #endif #ifdef ANSI_C extern int isatty(int); /* tk changing */ #define fileno(f) ((f)->fd) #define _fileno(f) fileno(f) #endif #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/TurboC/mail0000777000175000017500000035740413120075106023226 0ustar00alisteralister00000000000000From andrew@kittyhawk.aero.rmit.edu.au Sat Oct 14 21:46:38 1995 Received: from kittyhawk.aero.rmit.edu.au (kittyhawk.aero.rmit.EDU.AU [131.170.71.222]) by gluttony.isc.tamu.edu (8.6.11/8.6.11) with ESMTP id VAA22854 for ; Sat, 14 Oct 1995 21:43:47 -0500 Received: (from andrew@localhost) by kittyhawk.aero.rmit.edu.au (8.6.12/8.6.12) id NAA17054 for des@isc.tamu.edu; Sun, 15 Oct 1995 13:43:15 +1100 From: Andrew Gockel Message-Id: <199510150243.NAA17054@kittyhawk.aero.rmit.edu.au> Subject: Meschach online manual for DOS/Windows To: des@isc.tamu.edu (David Stewart) Date: Sun, 15 Oct 1995 12:43:15 +1000 (EST) X-Mailer: ELM [version 2.4 PL21] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Status: RO X-Lines: 1957 Content-Type: text/plain; charset="US-ASCII"; conversions="7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit, 7bit" Content-Length: 120396 David, As you may or may not be aware, their is a strike at ANU and mail is being affected. I have had to use the online manual while awaiting a copy of the manual. To get this working under dos/windows, I have had to shorten the file names eg manual_0.html -> man_0.htm, and changed the extensions of some files so the default viewer is automatically launched. Most windows based programs have a text viewer, expecting a .txt file, so I have renamed some files eq FAQ.meschach to meschfaq.txt. I have made items unavailable in the page in italics, and included a link to the page on thrain. I have included a zip file that has all this in it, others may find it useful. I could not include errata.html as the permission mode on the file only allows root to read it. Also not all files in the manual.html files are in the html_manual directory. What is the differance between manual-27.html and manual_27.html ? Cheers Andrew Gockel The meschman.zip was created with winzip 5.6 (available on archie.au) and the uuencoded. begin 644 meschman.zip M4$L#!!0``@`(`)=:3Q\F`Z\.VS8``)ND```<````34530TA!0T@O34%.54%, M+U155$]224%,+DA43;NBBS9/GD(;\Q3Q:#<_<0?ACS-IW669%7)^;)9@DMEMEY M]"2)%F4Z/[OWY22ILNFX6%?WSK]/ZB2JZG(SK3=E6D5)/HNJ8I5&U,84Z[1, MJ*0G=O*NR_%+;5M$<^L*W553,(VBQ M6:5YW3KY99I`)]5O]\Y'$?T[JG[;)`B#=5E,ENFJ[:-JG915.DXO\2O^`4NN MRVP;I=L$%]3VU:*X'M<%PVA61,^C/OSY#V[Y$/?'/,^C>I%5$6SQND[+&'[) M%D2SY@Z5:93E=5G,-M-T%ML=,[!@_`H`KY\ZH/)7R^4&.DKJ=-8W%XLTYYV6 MB1/$%KR+&U@6]C7;Q0X#T(%QZ2>TK(KE5\C*[2G,:+)IG)UU$!_^CU9BE`?P68 M-#-IV"ML3SFSTW>@K!1F#(E$UP][=`5/$#D93PSAR33E_BH/[JXS`CH"'[9" MF\>*8/,$*26K=$=AC:;2(6ZJ&F$.WRUA]DD9-:9O!YL!'RFS20H`"G&.400; M('4YWUC_FN1+04_J+,UP1*&3H$_14FU!I*.!!MY8K@9 MDS)+YS3K>5*:>5FLHFFQ6I(FRSJMK@K@&?'9X#4>?)*CV[Y_'0BW9*\?AH%/)18-)#('I&JS)%%@(3 M:R/T>E%4"N8)3H;9I2+%5&D2D'93>_L-'RT20,=)"E0."#5#B$[+%'&L.0YB M/U/@-JH3P-UD0P^-8)(`%ZCBDKD-]7>=`;6V=N5Q19Q?6D]A2HZG"$:4Z3*# MP6[BZ*;8X&9OEK,H65XG-Q4U?9*=KPO@&19WBLA4F=LX`ZZMLAOS9 M_`"3$:J-O=U+E!T`@$8$&:`&&(D@=A1MHV-\"!LEJ&+@\5;:F5FV0F*#&0X. M>2^!7SG<(:`'?6(SG>2\6"Z+:T3":3%+0;,`VCTW7PK]1/=X7OW%/=,/_AC$ M[D[7_&XB_//3Z`+^>S`ZY9^_/'N*/[?R\]6S-S_!S[7\]'JAWZ/H+%J-+].Z MT=49=XM\Q/?N% MGVWY&?$0?/SJ'_Q\+<]AX8(72!/`-Y'D@5&#I= M5FD_8N'#,J6R,B($KJXAF2*)0N^SK(118<@-*78+Y!*.&"RN*:6>.T6&Y6>>4OTOC; M&NO\@3=P9UDE8E=Y!7^Z%;Z"@@U9`S^U&"LKQ%>ZP)<%:33`ZPB)\UFZE97" MAXCY*`02G`9U\A&4(!#QV/A&2`7505+XS-,8Q&FC,YIY)I/.6_8!\:I,0)6, M2-TX1(VAL5J826^`PQ.J;GCI=5$#EW;`!"0!Y85-"B5J@!*@%NU4HTO<6E61 M$)V6@&78O-K,Y]DT0XRK22Z!:I)8Z0HCB<#*;U#@`QK,G/G%XE:$/^V!E:\D M7(`JH0'T`:HO\"8:1*29<2/$48X48:FK=WTS`DY4+)TH7V"MD3,41\ M&.`_/I!Q5>W9,$=.E\O*%]O$;0DRQ@IIG3!:%IMZO:F)7V\JUG)Q1)X/#SG? MY%/99A`*S4Y83UTP:4150K;6OU(##YQH05DNJH[E;$QL:`DL67\JJM2GYKYY M/J>YR#1PB&0)H\]N>-]Y)B3,P M0KY"9$K]=GE#0:!QE]C#=5F@]*#OO=%(B^.];1TLZM!@^P;J>TP0<4&WR.E2 MNO6"&8PLT56RW*0\/LBR'.W\%.C:B`RFJ8`E4N0]1E-J+@@B7:CSHR\:CF`/ MD-8L`4LVF99%Q<^00DM+]8"HH]DL(Z46"&I2D[TD2FT%J`XFP6JSK#/U&2@E MBQ1'[-O4+#Z1,$AU:BKG)T("R6R&Z!##8U\]N1K#P(T7A''5U7BUK#M5O'5O M@#[2,O6@;@7DC9..64Y@Y:F:CK->ZINU<`!01`\4/?`!#!`P!-T:)LH.;KFQ M772-#EK9CQ)@YYL).3O2:4:B5&1*)QR:FRG&7-!R2'*`R`,]"60U6@T`6#`! M61P('&/A#0+S"I5]>'-V-1X\J(`TA\P;<_*QY)=+R[)8I2!@XA9<#>*K85PY MF#JD`>($[@YL+]W6)7!STLK2^68I9@W/DIQ.3K``ON>>\L98TQ/("?+0/#4NZBF2A.C59:/L:7C24)%M(T@F+RN M?&ZH:ML-LT9'N+#R%/2-F;>/*5(<;X7`Z'(#TP4!2;8;^Z&4U$B@+9?I%B2P1X$'8YZCSV6^;#(8GS=49J@(2>`!\9H6&0&[E*N_V MBJAM%'\7/[6$@\BCP(&E/ST;/?C.Z7F$SBNAN%'XF0D^JT8,-.L*0=QFI1,5 M58^TOPM)]*DC4>2-9*^`@7@@7Y!E9&@7I"]'7FWD$Y'&`A`(+3-BDB@[6%#3 M*%;@XW[])#B)&.M[5IK,;8:ZW.3&T9.5W-BUP)EYU"C@41ZTD$!'$:.<6'Y( MBZO=KTSSJ_<7HH47Y.`3-"`EGEJ\OSC;OK\8-1&X5HZ2HWU1`8'QG"=I?8UB MOD1-U-H*=LV;?)E]2LTT+6OT3Y$S)B&S`43&508"DZVZ:D-N/[3L7XR^P[G! MOYZ.7CP%R+[R/%/.R`%@.F\(T+EU%ZZ3Z:?D$C;OEQ#N;/B24!&^0O;&=@QS M[:P!9NOQ5@5(B^EC?:^?[0\_A@Y'T.'(%SSP"KKC5Z/Q6L?"87SGF_8O/"Y+ M9]R]]H%;O![$ZV&\'HS70V=^HX\)X*SM=3KP%(9`^SP[(.](A8->K39'_A$0>+`G"T;<'8\G0XI4G2:H^.'(QUN+8OAFK>B% M&CAHEAM@QL7D(VX#X-8ZJ<2'C-8I;U.E2I4.'Q,')^Y/9LPD-<4$.0=\288; M&^[XR3Q;6MTEXWE7-5CZ,@>8`K=#+I]\`FC3]TGT*;V9%"A224.78$FIPZ%0 M7ZUQDSQ5FU6TC*(CZ+I*9Z>D^+?VS_.RG7,CZIV5_\),K,5,*C]B1R)>"_A[ M+5$YW!U/9700XB7#9BK]<(LF!;,.U#09!H,L!>BUB\TJR<6P MGB[00$63#CW[?Z/M10OB&K"(HBRI^"I9:A<"A*@@;P+I<8'9P$.967H%[%0W M3C7EF)G'-`6",K+3#K#X4K[;USM_PXU,B!4Q[13'B-8`YW69H9%LU`9/)@7& MD-0ER0;G'*>KLP-CD_P#6U+(`"*XD^AT,MR8ER9-Q3L^F^GD)1BA1A9',YV- MU?36$UQW??4.P,*N/WR8E^D,QY.9&VL:[GC8H[T^]H:+_8?G+YY%T<%@- MEWOX*3V:H[]\#NIDWKF'$[H7W[N^IV[SU7@N:#<'\==M[<7ZTR]:.(,XNS2\ M`NT`/%.B).!HK$1DN45#M$#UA3[G#@%1REH<2`G`;I%4"]C6Z2)!Q01VY\.' M+V7OS+1`Q].&Y1M+A)G2+D:VFGL66.5`2J!;98J1Q$^BHY[UB8+:PEJ2W:3H M8F&=^Y&U=`!'T#@`KH'R`EIMHS/1;4[0PWH2'9G>-P3/Z)#^>V0#$S@]C5_3 M-!X*G:O-ER/WD>5EE?"BF('-81J&K0E@B-A7.4)A@PDWM\%LYL'3%?D+-+:( MTDBCBD"(:(F@C!(&'*TPTG:9(I\-B9CL1<,A=E@5.O,_?*CK&_0#Y=&['$CE M(]!4D8N'!@GI4[:FX#R)'HA`UX_[]B^S;5# M$!VASW]3JSM=":5O_,06WUY2%1"9'8B`*DR$PMTH-I4),DLWO=8YQXA%URGH8XC8ZQEJ`$%/?B_1ZS?ARF');S?K=5'6 MXI@23I9XV_(CP"N%3C`+J09;H&*"TOG_'2._U7W0.NK`$0==CY84H%+?G0T. MS"T;UV%1'7A-ZH!F]I!X:2XZ-M9!S8HKL#'0_J<9&?P)17Z*>8VNZJKO&7D! M0":<<+-W'QC\ZOIZ\?V+]Q<4(FP"CJ01FZ9DA*1;`1KL27M8BM&H!:O^Y908 MP:JY[=NEO7E6!0:G]_4R;'2C\0^<8%O>E+=ARDQ=3Q*,06YALX)((9<)A\'R M?X6/8?=1L9X5^?U:@N2$821OM3\4:92=&@,MEV-HE"#_0E#.W&!TAP%C.J,DO):.F MN*&\(^N/H%@BFN9(_2Z[SDN7XU!859B@VP"\F.B75VD4>J2S:2)1#V[[XIUI MH1Q^9QE-T&)G4[.:Z/[*6Z._@[`?+=#&CSQ02X**X*/J;+K-H2P/4=+NA>_^ M":`"IA0[/=U$A=6J5\_`''HH=\@_GZ)7+?^XN43."PQ_1NY^_035M7`W4)7G M2)N?[F3M/6BVJ"PZ=&A=:,AXQO"TJ#J^*P,^#=X#3PQ^+XO+X'?U6UD'#Q+7 M(^6F=8W0+,`#2).]8;P7.W--411,JV@!*DA:[AIH3[!1?W$>;!WS$W)T@2W` MD89-75!7%%"VO`$=R]:_$FG&M^'1F)&@VLF?M' M/@O.<+[,LSD`.J]-LBHVG'6$2R%I!4-+1F6G2FZZNTGQE/T",)`\28R8:S2B M+@J`4_K;AB(!?9[D2.:#X0R>[V3#IJB;*U$]O$YLFF.-[NO[:*X:L1HBARIA MSE;?-$\.4!<(P[R(ED5^B=C%:HM,>I)Z"HR_`3&(*-"OUV0C5(@G4VM(2$9_ M@H8'S*FO.,QS(H,$*`UW55.@.QJ.>)%5ZVX0^\"$%!S>?/APF903))(IF/Q\ M5@+T>=B2O.CQY'L$`08>`/4A[?^KU\#D_O#!^(A`;XA/X&I6U]JF1)/H9`M!VHI+V\&"\EIFHBC MFB\=2KVCGK%,]I4!C MZ>IRG!(\;<[?S=D+4"A,Q6E6IFO*`4%T'P&6`3S3Z2+/@`98UC,.8<8WR*,I M`J_$O&).+)=I7&85(I5M9"*'=#PI2OD^.G_9!#@\,XVD"MI^XMP>=1')I>BZ M"(BND5GJ0NV-/8O:]RPJ-Y(.5JW(QPT,/YUEFY4AP.[TWO1R(1B5'A/RA(D8 M>_V&DFLI16<44WRT>TH^J8<'EGMZN9Y@L$0'#U74>0+"RPF-"0@X6XUC3VV8 MEU--7[^17"!4#C/-5O$R0M,K1WV&UL) M((O@S4$N54E(QC$H$T@(V>]K`IPGR/_B'(OI=%-B8A]8Q]D,X<]>ZI)?+XMB M3=$/$GG7N%55(?$(F?*U;MV'#\NBJH%RT*^26+^T.U>##M!IBKE#$8B;;"E[ M?XV&8^XERC&%2,1$<90SYK>UZ,M&/3>OWWCN&6I0;285,U`ZL6&/PR17139C M^U)=Q1M")"^^2\D MC=H=>6D0I;<*%'@,3SH;0G(%)ZQZ'2ZZ@W[NZ-3[KWK9]Y#+K;0BQ,3TYPYH M.,0$B*($O,#&'IR#T5*8DU:0GCP*#?'A'*8V] M(L8JG'XJ!S8JR<*;XF$79O_&685TGH;][HG+E2C(7\2GR%Q>[[5ZS[2=IC_$ M-FU.5F/3@&V/G+FH4-2\U08-*XXQ?FTR)EK<'9N$AU,3=*XX/#%+F^+'./%# MW$U/A\R3K.0\*3[0A,VGFZ6HO1WH@T^A)4:-4+'U-2&*PF=ZHBO1@S*(]'J6 MJRNT]$:%:*1"E(B(5^AD(>?I2DXSZIHR53+$5TT]EJUO7;`A7<(N5"0O&;>4 MC2A9:<`H6=$.4E/5BX$^2)LNS=I@2]A%_4<4$1WX:8!#^8%VFCH/_+.!-OJ' MK&BI1@:V4CI\"%<7;&/ZK!"Y:!.4%7@W.?N%,U(.K MH?OGD?Q3:-'^.;@ZMHU@#]?\@P-G?MSM:@#_P1Q:UHHP#X\3R27(=C5LO!\V MWA\UWA\UWA\WWA^'[W%N_GO\';9H.R]#YT\Q;X$33RPU-C9!]\;EIGCX="U< MVDO1]=(T&"/(F4S";U:D%1HF*PP!`W&O-I14@2JFKW?L0R#&'T14EO@!Z[#3 M@^$X+FQ33A@H*KM1.Y/TNJJ%>K*YQZ*,IE$[+,1L]5OGAWB)&IU&QG>/%5S< M@5BX+R0`,#B69%BR:L-!#41IS4$Q)$Q=CEA61P*7:6Z.'2V[E#[)1: MH>F0?(EPB63Q/\="EZ<6JY5Y^JJ\M>)W[`EGG8KJ416JN#,:&,F=F:1\]D&1 M@$Z-:!XMK.Y2?*4PB2L,U8!:MT?V8O:"SBT3"@BS;DE?48THEVS_:59.-RL^ M4`%[]F-QC130#'>W:G#D#",?;T7>"LHM`1@L9Y450VA$N2VR`!)Y]`.Z;V`X M/G'8'P(-H2Z'>3`MH!0=Q3/.4K(.`;C&\ABK`:1H>=*YX*D]0#8OT:^Z63O! M2*ZE&7/].*1[\4I;]_O^/::3%X51+Y]-:BAK/NI!=@5R?%(([=IIV7M6;?Q5A]K#W:7W/O+W=>B[B>1PPPR);8`D2@WLMW:=0*F?TG3- MIW'K"<)R';F;P-AC4&S[WHA5ENF3%9>QGLW>%IE$5/HI?P MUX,'8.[AKH3+.;W#>B[<<4RRN41[I2!-,'8C&R/L67(DF.4(_0!M._!<@I:U MEH%<"KYULNPLDP?#\X67.56O&*CG@#P3>>TYQ/R^3T/GS<[ZM5^%.AH\Z'FA M=-S"D'5,9MPM?-9#;#+@T!$K6GMS4@-TR82!D'^KL(Q&1OBL`%:'V)3K0H]% M\AE/+OCA:E*(>,2U[AYEQ#.`?"I%"W%XQW8JT>&T1(BZIG?HT@:=]I1$X8"; M#7C__/TSBE%DY]O[9_-.'6^[<11M._7XL'NV'1\B8F"#N1Q&AQ=9EP\2P,_L M;!`/XZ.8.'5FQ59V#JW.H(L'6;3PS\?0#V-=GT"Q[B0\*L=@\J:62&]=@"3" M:H6B+[;CW[,'@S]ARMF#J+-X^'7W=SS)-+P:#_$_1P^NQL=_?D'SXP_@+:YW MG,7P25>?#?G9@VCQ<(@O'D!7PR[PY(%MM4-E1@8?XZC MGU)*EAW"*^BF]ZUE2+&KA9 MRB*<-PP-&CD1!P./8^!D<6+KCZKXVAQ M:KA>2'30.9AW.\#FL'+(7_;7.`?-Z$>+%$SK&$$WQ1'=16U56O)MYR+T='^YWN0 MU%=G].UZ]6?TYO#UT>VOCV]]32MH-*`-(B_VKM]'YD_XB`A[!=H0 M?D!>9N1$V3(5_?7Z)+HWMXWNV3W48[CX/#[L/SI8Q#@+CKY!5P+D[0-\!;@= MCOG`?1%?#77?O#Z'=^AS>$N?1RU]'L5^?\T^H<.C1H?:&5;M49CF>.YP-CL! M+'XPA#G@?T#('SO`4'0%@!(.%0[GX&$G*+"(A_U#_=1O3X/M^>CHUH]HANY+ M]]GQ7FBTK$W7G\PH,WK;@@C4*VA`,)ZAGO"LX6[RCCN<.)-CKLG258?)*J\P!XU-!MBFQ1]O(@>,5/+2>6M01!ZA>QZ!5 M6EW1UM;84\;")4NZG$Q`]3V\'O!Y#Y?WC=(?K4/*MHRQE:WV1+6(U$ZU3ABW M%?2M]1^3JFAU1ZP]F.:7(!WI4+9U6TM)CRN+/ZZXE5?<@W&%8(()4XBIKE^[ M)\;O.K8'"WA)&#=UJ^'([JQ@EQ&A&!X1B]99JD>/9JG:E@IYK8>TU[,>&SK4 M,TE])!1]T*L8XV5UZ)'QADN[U4M]9Z7%IO;>Q=E]&L1NO)H!MGB'J[_@%?EP MSRB;R58CHRP+1&KZE`_N-@KF:7YK4)!`2C2!WB.(\4MC;`]8M"KFKUR;(N)# M\?@XCL0"Y#-[9\!@;2A@MT:))/6J3JL%1*!-&E_YY46 MV8F)I#.3"U=*`5@@M-;6H`&],B<[:Y`1AS+DJ)(\30?:+/?R-?UT5(U`)]/I M9D419S"'FJ5:8DFDK.CT?:.8AQM&CEC06JM4B"9PNZKW[]]26Q03_TMX-F&* M?P#CPP';M82TWKY90EBMJ4,&O8IT)`]/:>W2\S9ZZ]NNZ-"NM>`?: MY;`]?L'GO/WN%"G0H\(O4U@_.6JR(%P5P6V4<@"[.9H+968 M`$.%2"-*%X(N?_[^F5:M!6@"O7]QP!HE`H%_;X'HX=>IV$U?U&H@-2V3/_Z@ M8WN?M53F:J=P!R18HK^=14/IP7NPV\7;Y__GV5OI@U[2!U?I/P]_1=R@?PY^ M/0U>#?!53UX>_BH?BAY#2W/*R\AJ&("M@`RD=JOWCE@\>O%P,M%TD4X_J0]; MSF+'+`DV904JP(JR=?W*7E4R!TA/Z'"C9!=7H,?C\8T?Z-".L^LI?2A4E?CL M/*@/6.B4+$B;MHPY+9@4=[FPI\8,.R`E@>O:Y0CA40_FHFX)\*P1O;7%C6R2 M1[M:P?58]>0GS;1>A-40`W3?6KF]4V!/RFAA+3[D.-`$J:6G5?VX-E8LD08Z M98>'=>U(M$'ZXY`K'Q&"NQK%++*SZG:BP7*,A_?/MN.!=6K"O^^?]<3WV5XO M!;^Y_P#^>W;(_A%+S+7U!O-F["3Z/\'3@04F^K?Z.X+3V.*PB+PJI_XCP!9^ M*%X._`-86. M=?O9K8@UDLH-4G3N%TQ, M^@<).^_<^S(:B2-,S"1;-8'[XBHZG:B.GC#4A`_];KD1<#G/IP0:?`=D%;;L MU=WN*9JB:!GY!==>;3.A4=[<(:^*OSWGXY7_:AFDW4.Q5Z4ALU4*G6&LE0?'TZ=GM"AZFQIX-5S>B^\`6'>0#'L!I M/):P2*C*%%9:N='2FLW)DL8) MI&%,^@5*6D!#8&AYCM!0+[=OQ5S#.BE/R!YKH2HC]*WZDT/V2[E!"9X>:2D1 M(%GM-G"IQ7TC>ZJJBCHV__U:@>Q;W)A//ZWI+/5UZH4S=T@W\LD-45)0CW25 MBT+]44&J\"9'?RP>9,;ZN!<_263('CZE\G%X^,BTE(.G4_,RF^DTZH$5+@TB MUQ(+`E"@OY^T'$KD8H9Y-'KY]KEUF,5>G]_CF_'3NW=NE3+,2$2146$EW<+W MT[,IJ.Q=!G-!W#:6>FAVN>C`M'&^L,+#T#"%')Y$O8'\>W`23=QC-*/]/[T! M\B/LW;9N-HD.N8E.RN.@A_V!43YU&-OD%H1('A\>#K;V`!A_W#;[]]?$1_HC#+PBL:HOW?I?='QX='A\-OL7?L_O'QX/B; MP^-O'D>ZZ=_=:(XXGZC**C1F7+](5MEY?3:P2CA%DLI-ZDY#9Y4H$YU!]TS' M/#I\]-C7*_"=G<&WCX\?N^@*I[Q,-.&%3U5QI3JR?XG+VU/@S7Q'/6^G'(?/ M5-14K9#3PS"]6`2%*_)ZZFYR0&<:9OVK_#8SJD[E6%CE:B196D#4$LY,*=C! M),D/(X&L"^UF2K$Q]+AAW@Z,+M5V=-VDK'W*UFLZ&*P9E[S(^Y5Q4_<*(C&7 M!F-I@06;9\SH40!8STS$E5@#X=FNJ)(3CI=-FK^ANQRH.O**CE0C8*>^Q?7_ MA_*/'(D?.5)6?C`D?O#OD^]12+Y'(?D.FQS%F'N.:8*6A7[%Z)MO3Z0`.="- MG#B3X["@S]+M&#**M6-!+H$(+,F$F4@M!6&DQD]^89M+(4\J%%6JI7@ MH1=)>-SQ;N>1+192IU4]\,6<%(>YHQ'<8@#O^N9E$WS/2%`Z-"P#8`/WUAYL M&+9J]R)=LD>;R-2^IT(+(.[GY+XJTVJS].HWSF`;*O&5D=L#-C^XG6+NG4_X MW(TS_I'S8+>Y&Y^NN<0&7SDC9>^`1&:]8M[C4EE63Q*G"VHR,"F*R,W%:5]- M-Y7SVC.C0YS$FN<:WKB66U'04V#\4D$\KJME+(>P_)))=#:C+E.^LPAM>5)( MHT[:O^S'MG8<**_9.J5M!;Z32!&BKBTIS9IN8U:)3@ZNPJP+8VH__,!&4!)26%N'G%K/S#!RW"Q!5PW%@X M)7(?4L(M^C.HKM+=*DQAG:8;OCE"U/T/7][?4[J+"D<]^_F'+KL0Z"P=)[H; MRDV5";8<-0F%AT9V;.JX7"<4:KS9U;H/2]/ZLJ[BUW-/2)A#>/"#E0]F`#_? M.K4"D[&ZH)IWL/A`W8U[6.8`3$^L"-8Y[#:+@@V-*F/8[5L5#@9E@\=B!34$ M,H%.VU1U>8)P34JI,5I;SE6ETOW>)91_'Q%Z)+5(:S M^[GH/G4Q+5.,@H4)>O_.I6V2G_>V6-DL"(VKK_PJ0D0^5PDF%>2U'DFAPR*N M)!4+$.,/X1^N#C@=9RZ#836&SZN`7OI]B9WYKVQ1&'B+*9'^.QW$W5.B<-JM M=J,CT!%`CR#MH$T:DO$Z+1>V-$L2[:2?ENEEL`9U>FI]9T[:J,CUR4[5_B3!$^VH'[C4O2.1KEIP.'\;&U9_L3E^0K8%W1Z&/.*PC(A]57B:\#V[@ MGG;7]6H)+1N$,3&`8]5#K8R"("!,N)>O]&/$`'+;2Y4P/^A@$5SMG,I&.HV5 MNWWS/RUG:U^6_O^3-*Q;L[#VIV'=+0LK8`FL',9?00=?P7J^@N5\!:OYBG(Z M/!?H'3.C=NGUT.8GW6F0OY:ZY/_9'^*[)?_H]O2C6Y*,]N<8W3F1:'_.#7>N M],]=#.)!_U#SA"3S!V"(#]E5_>\DZNQ-U?ELKL[=LG4:0O4NMYB*%"7&>IWZ MU:?".CWM%TUV,!""_!`/,Y=@5N#1\J!-5ZYJXC--H-;-W,$Q,0Z"N1GK<*%[ M,U=:]I4N8/*[XCLUL:\.Y0=M,Y@B:-/6U$![`(OK;CE_:'L63>)FMGN8U.ZN M^:*0[`JV*O=K\77PX3D]0F>KD<0'A9F;$5[DL-+*8`)LG`[PXC$."W;A:-N; M_/''>/A^2)GU5'SY.N4+=+CN.58B\&?WVIL=V-:+XI( M%YOUFLH6@A)TB7O5ND"T1`AL#]Y?_`HO3/29/_!1]'/T:]3#CX;P482]"0;CUMCUON&0G=N/W$YW M9S$BG"C^H?N(\8DYUBHOD_R3./I=KQKN(#\2EM?'V]2D'Y?PQ6@:T([%3[DU MS4,O>]\9;/$9]5JE'1BP&Q%\N(&7,>*5`)`XM19N^FV#:"#I[6SLB>)CN$@% MTYA5E]0!DUPEV9(T6JOCLS'>;_V.TM;<26!K:,)ZZ@(=!:(%<)%HD-*V`[J( M8Q2S=)YER64WS"32XM:VGC[58`&((()C_I^=7UA&+[@5!-2:+%5#- M[\NTB#DP4G1G4'Z`V9VH#RB.FUN5'($;GGS7`/WK-\1Q=I#@4ZZW7(BF*\%T M!2*Q!_J4$A!?OVFBL-T;>Z9+AQK%.)UX$F]=:A0Y::EZH-Y(8AVNC;BY9M5Q MZ7\)I0=%T&/KO<*735D2&^]+&NP%])0L@%!?./YB@6ALSG3C%1&H51R,%@HV<$BTN`QV.B.6%$4I">NS'>1$=_H5\<9[5/$6K3&^SNJ/WJ_[9#-I'9]1:VGK7&DA6`X#*!C!Q MBDYE!:S(M"93&Y;@GHX4F*V5>.2-L++7;V)F8/"PN3>3AN40[HV^/7$+G[1- M>N(%7B?RS(%B$H+"9@U,/"76H;5%$U0CE2QE"4"7?AJ%#O&+C5Z3.,/BB3:' M&R-!;O8[&0LP--8U0@HBRZJ@2H%,-TPS^+H!'*"@`R(AF*$)+`;\=-CA&]R\ MJY!XTG;V7;_FD#.R&]Y]LHO;*M78,V)T0Q&[,3V?"7V,]WF'#5O\G=9Q8['3 MOR+%EUU@^,*C7D^V23MNE;GJG0FYMY9?LWYQ-SLLT:=5@5J+THK740`:2.:M M_.TR9/O.]<^=-4L-:5)LQTH!S7Z0G/-T7G=E2+F8ZC-#QBQ0Y**J+2A"[D:P M]B5[66VJT=+]H"DZ!'J]GI8>L^G![@XS!:="K#WCU[N]3`59>^$E_P._/4BV MMRD5._3NH*^*DOV4K=6ER1/*-<;3V8EY\:[QOD-`0.&=(X[_/<&@!3JZEIGZ M<+H,2;*XDJ599U<%E4/6=*`7[]IQ[<4[']?ZYF>JD-E:1MT6N&VO8DPH_?3' M]F&>_ABB-!=:;XQ#*^#KM^P"A"">O@KZQ2O"M(&F,>.UPE[%6+THC>Y`9>4U M`TR]Y@W#"\-9D6P6*'W5,)9DSUM55PW1M\;JSKG^Q5\/KK]>;46#:739#A9%1 MDE>_:4"3+TBC9)N9"5*`WO]^\=.?;(+1U65!=H_T$MG>O/2;J+=<*4L?-5-O MW+5F\JDZ@2GGP<;A&PJ1^8G_YDO=\`:VDT?1D<$+ZPY/)([>.8P/NR["#C\' M72_5!GX/NQA2>2H7PIQ$]/W`?C^@[X?N9_C]@+X?>-_GK1WLI.@,.46GT?&^ M9)_F@#O=:5)0?V/'CWBI*[CP^'CP3>/'SV6S1P< M'P\&CP>PI[ZZ^77_F\??'CT.7!%-(U[XH+U_SBL\+4>Q_+@0YOV_#E)6V_HC M[Y*7/"L64NBIPW">C;H8OGR^<`XKNHUH7W.^=8^C`-XWS<6@5$(?JZ;,[%R6 M(M_R31[-*"P7Z!^GE^@Q#N^HBL]ZOWW+I`H!,$/,+7. M8>>OQ5+S["G>C'_/XH\/!G\^X'_UY%\/!O%'_EMYEZ.*,SW:^)!>O]6S"]X?0T1D-(- ML^5(;+U1TYK0P^5^=SIKG%&2*A.+K)Q)6^OI^>PN:NJ.J.FL6U+.'=_.::^/ M"'!P]SX*6Q746C>?'SJIZ!9F>\\%WL\"VG]-BFD(-ZK1WCB9U;@>.*BN9_R2 M65]R\E7T,AH<'MI?=(2F`QC0C3HO#SJ=K-L;=!]T/N)?+C4174+5FC36EP]`\?=@#'U..`)\HHW+[),W7GL$G?J,+E5S[&8E@# M*H9U%E;#XM?W1OG:^)7(^43$M[V08Q7W7XXJ2*Y:=4>Q6K_]$0NG& M(`$./5^3='8.@O@O==;;V]G'OSXSY!W[.OO+,T/VL]/99[_IQL?!!Q,^DF5? MT^&YQ<'B8-Y9'&3QXN"C]<_)+O_,*<*W8K16[-RL8U<-W/$36^7*(\@[$;AS M@DO>AIZG)MJAS"MG;"LCD-.9XCS7+^BTY\RF,;QX<<$$PHY`6'2U?F[-6'CK MPAWRI+E\WHR3I<%2N;&G`^BL9-/Q)^2#U^>,J_7T$O8,1HHG M\2#M?8V',F.@\\/XJWR#0?QT7<%7UN-J#[W*[3LHL\B=%A*E>J(D*$P4TP2/R6Y6&-=X@*RAYP1N&1%&BNF=3_L M:172B:I$2DKS!>!XA$3O(7277\/RDX;;8&=Z:KUZM^BZ+IN*S**X'M<%7WHS M*Z+G!+3_\)27'^QU8&!SYYG>.*K)\#&77_//'HMX12S7"WW3`A#:V!NWQ&'E M[EOAE4ARDA_7\&M0"1BTW*543\7YBGKBU?INREXII=J\ME<=):/MV<37(CC: M30GP3H&4PFWH?<\K;WS91/>7)!PZ$)7UYA^X?G0K=QK;`@Y*7H[N11\5T%A;T.) M@F#2^^'9?U=`Z%FG,]IVQUEO,LZZ[X<*'US8G%5U8T:K/ M:V6]8#ML(6HY^&'#S*#)P!3L#0E^Q@-N,Z<04#`N=W%`RA/`R`\^L,.0V.S);6:+[FXL?/LTIJO."!>A;MO M4)B<&&!T%4+I[DM4.:/)+``2M3/O,%.Z`()S&H!5^%?&]([_#_?XSQ<@KX*UL)\J?8`S_E?^(;1P.M)'#1%IJD*T!8 M?6*\05(^H9#OZ_Y%'_-O8$85ONI,@`E)GA\9\$&6T)5W_R(PE>,N]L;*ZWN,81TR1="6TN!A8WL+F M^;=K"+6']T7?H3.;..)AG;&N)YMRCVU[SK<1N8PV+W/W18(EM#`DI'F_>A). M75AXBP)=H.[JC$CM33_][[YT\=_0!#/ MP8G92[1G`5;P383HR0!^R_GK!<5.Q]70-38^S&BA6 M+++*Y]:5+&T@WPKP:Y*R]+$7\71@#EQ]$1[#92MN=+`-$&E/=1F>1)#]\_SBV9OH(%M[E3P4CWF>^>_WW\_?.?Y(*HIJWM97NT-;?(X94.%**8M-X*E:T5`;&S":>C1T%5 MSFS=.R\7%8U(M#*)Y9'7(,OG!;2@DF/J1I)#^WS4X1K/4F(KN2/[LYFA?#6G M71!5SZDJEU9-U9=PZ*W-E<$Q).FCR)G2#+0:;4F(K[T*9OM7...].I! M7;YXB@2>9Q8[?TSC-I'_"U!+`P04``(`"``37D\?$7:`/JX<``!61@``&@`` M`$U%4T-(04-(+TU!3E5!3"]214%$344N5%A4C%O[GQVJX]/CX^%V#A;=3O_5IBZT95=Y[7-7NJO MFX4>KZJ\&.F3%R^>_][C#_BE+Z]OW]VZV[1Q M58W]&UH\+QM;9C;C-6I7K+&`KK>0TA)S9ZK`!J;2]M^M7V^0V;*VO%2],E5M MAR.>9W5AZ?@U1E;8:U6Y:8%%1BIURQ41.M&O! MKI&>MK0&%H;X01?4$`?04U/GS)_-(@?'EZ["TVQMH"59MW*M4VC(U&*1O&@2 MEI*7@LH#Z]VJL%C&Z;O2;<".I6T6=&`SA8AP!@MI8>-Y998D(5V8PE06-HF*R?MI6_&SMG0GVL>5"Y,`'7)IRJV;6-"UI M%JUG*CH)OUR1P;FV#M.AVI,<<_F,2PNQXH#0W[RR2^Q2*^)>"76J\G4.-#`3/FKC%!CH4C:'H\QV'X@+LE\2[;EV;942JZ!Q M9,IKDQ<&FY",H%,P6FAR-B)]SM@D5I`7_B2MQ.'`2;"O;D:DHY@%TVOYY&P6 M=$!86P%W17LWO-^LV=`!O:R8]VY)#BE1MWL#4K?:5OE\T=CL6](],JT1+Q/? M:#.O+/,-?,))-^0Q%`V9.==`A*LZ;/T:`_4D+/_:M64F;(%IDHR(?VP2."O3 MKUP*R=`U.F%L3+,F\K5[9EFC-U+W4^(PHSUT[!YMIL]9.E/:P7IKI[DI`0 MR4F"5P6IO"U=.U\DZMR5!^!-?0?!Z2>_++9P$K"JO.&#_?<3K7\D_6%+N=-1 M5*ZQX0,L#3R%@V4M12`S1=(/$*>)'O\\OKP:O[J\NKS]E0EGC3(MU`)<6YH[ M8B.+$.#@<,9W/ MT:HTZ:523_7E3&]=*T*J%S"KNBT::,#4<[FM^R(8Z17%!!9##9];X1`F)1<) M("VBPR2]K;*\3D$DG'FYU8C#='1_'AH:MR`M7S6@%1J_;$LXHH8] MP!)[XH!-QSE1`CY?4/.+OKW1/US%_3>8,_Y;ELYGX7,('O)P$/-I[R4:. M?2V`3V^;6Z>[0%F#:+"G%)"085"53XD)701@+S"#<=;B0`"D[BEFK[W7Q%M@ M`'$`16.K$L;'D`%^523Z6Y(DOPO'H(WD#Z&$@XD;J5EEL]].3I_]#N]JL)/( M/L8>>GTRXE^G[$+IKV?)L(=;,9!A%W:T#)SL2V1&1T[(M2AF MU4L=AOUVC/,]_YW?Z8&(Q_LN7CQ&X(9T;CA28>+QEZ;4#&W(B:8MJ9"X86+- M$E-@J)#ABE!?V0@A+%>&F5/18S^N'H+^FYF/I)[4'J5>X.0C5.^]?\MQUMH` M+FD1H2O*Q1_K6WX'BZDRU2WADV[(A$O MXYT8<8$I=)@`+:I$^[M3,/6T.@9$U6%%V6&""`N/_@4DF24ICE^5F)(G*1\! ML#+][.HD]0#$,75]!6)*O:(KQ4Y./OT-OAR8&=L"ZB1@E&(_2%&-YZ11I??< M3%]M..#X!=EDTS)$\1#A-V0+T%:TF0T$N:HLDKE;Z\&-N=/O M\@QP6=]>C_3[R1@YAQ]5FC0IG1K,5_ MCO0/MB*(RHLI7HQ\UVLRJ@<>I-[S%E[`(1H&V^@9`N,/(@&+D"38]X*$GIT8>N4JMNPJ"&8KSE42AGUSLNAL_!-)8\3/1(,5+ MDAGPBY`-:&OVG"F%)(\-.;YZY!$Y[VTEZ2DZ9^&"TACIP9R?A/$OJ^Y&#J:FU9WB.-GV)["`@[4E2K$&<'1Z_%J5>226M3J MJS\M:_Q9/2,4,D:]2D:OBD&[4JJ!??_R[%@/)'5]/_G+Z>E0_R=I5X.$]8A@ M`.%L\/Q7>#;*C5T%:$?8%X?:(&?VJHR3X6!;/ZB'JI:4=8A6>;3LP\Q"ND9;4.I$^:8K=YQOQEB=\SG"D$MLN1V)!M6-6^FY644J@[M\ M^O3FZOSI4R4B'Q%F61#RIU-2S:`EZ*Z1W\`EP3!VK9S\):3[T(1>ZJ.^M1QY M%3U)3J9'4R0*V3IG'?XM^4"'3N:??U?J$I$[RW(2Z,B?!0HCA'J8`HP,!42V M+=D6>U$ZWOG-6>=HU!Y$:%H\1?Z;-/>-P";XH,S>\V<92^X=86%%=KBVQ9;C ME`H3-0ZQ0BS3@\;>Q^1]&"/R##F6IPC+[HW:`;+Z.57#)K?CJZNQ5,-".7"H M;TK&DA&1A,"&Q2J3-KVP&&H7N\YB)?67)4>RO(3*0>QMWI!SZGDQ(AJ8DU9' M7O,=3?ZK!T&:K>"I:EKS[>T0LTMYZP2D'Y^Y6MOV6'CX5,AC0!#'IPOY[IOL,4*PU@*OJ_,*4MZ4F<@`^\!UAHA(E2 M=(G:+HDX>\)9/F\I9P"R7W$!J8:"M2L6N&?]802-D0E<4/!3D([6NV!@)9XP MZI+B(L=>NMYE)W4[Q:;1'2,5+;J$I.,40T@E)QGYQ7UYIY9LM0^J!8I&IL:3 MXF].H&4U_R%%*EE&L8@A<3E4L"?2YTJ\\8-]=W#\8WOJPT,J=1S*GW%;F#=1E!=! M/8FZII<%(9R`B(*R?IOF#!\&7$5Z9^&7B*:U*2B[@2+/"F<:``LX45[-D\"/ MO8Z2OD<:_Y#JG=F/'X%8-W%+28,/BYS$[$OJ2[.56$2%WU[%D6M@5#/(6JG( MM'.H7.!@EW@2!@&5FL3<453ZA.9S"AHLKL6]CT3M9K.6NZ@]]&$D^G M(1=2M71H_DR8K?2%)"JD!*?PB-5+=.L-J+L00VXQU,M8<+0>V?N[R='7Q\?' M<8HD/(A_.OKZ^KP1C]< MS)=4PB/O>&0&4+5H^!71\&J8^.%1'3DTU7PO,*A)Z&>_U@&3R*6^.%'^)0P M?%HPYU94RZ-"YF[([`7"0%WV,\D/[1YK"/ M,TD(@U`48"EP/-5".@_?EI0]V)SSSY]L5>9SY!A,U#N$F!P:/;@0_*M/AOJ, M>\0R:7P]N>0]!F,(D'$F]5+R;L>.4GB#J:.&+,_A1E^YZ-[+K!GY"`LM(SZ1)$'%`1K16I>3IZM MZM.G*86S,CLX8(])A7[NS,CR;E-VM#)"WB=U08G8QA:%=*<>#3I8.VAXB*2^ M_N:+Q9S0*<#*BFUHY>"`NNK@IT]K4^(HV%TL0=9%I1#?UBO_ M."#&OICOJMX3#RMK%2-:*8\G$8F+N;P]$W,9/7"DFT`(V1:AEQ7T`AG>7:+? M"S"Y9U4Q+Y_JKB3'!K7:<@?*[=1K=\+S+0GUTZJCKAY-F'@> M87H(2NSNWDS.;R:=YI.J*(\)>\C>PWWA)KQ[BGRXX@3B+(;1SFCBH4*>8U:8 MLT+*V9`@@SY!DM&\>H$R:'9X1&9&6ET@1R;G$-7:2[SA$EQ`%&#?CDHO7>;[ M/7^0")'JQ5ZZ"/H71]XA)8@'<6SHT\@7V>>(/R5<3B!PA.S2IFUCX7.^ZQYK M"H5_11:9*N;S89_1"0-S>V\(&(\PL4$,I:&TQ6U;39T^8['BU;+N7KW)T\I1 M3Y5>$[07)$1Y_H[;IB7_G18\CY0#II)ROPO/>SNQFC088*I,`D\4A%=WWX5W MTW\1#!-N<31CYQQATNBAH\%*4_9,U,+S8"(4Y@!D2@)T(FEJOQ=QYX,ZU.FD M5T4=X[J[6Z$RQUC7BVD10P0[#0$K]5%L&G")A2!@U]+.?]#[=HZ1(+N1]$@'G(N/Q.48,HM]`$VNFZ01CHNX(2 MON/6?$E#7(Z4ZB@U=JJW/-U5HY7/7E^-?YCH[RDMIG!.14H16:5I MD!HO&@J]Y(0:1U"R#@UI8FG_OA[;P=KEF7>WO>('5>])'7%:1#ZZ%3#T701N MOC3N#KZ:]OMX%IJ*2-CHL/^103ZE/6"0+\T(L)@*DE)$Y#M]U+P@=Q)S!AS7 MQX(^',`C*O-X_DGKA<@C#OE]`A$GO=23$A;)CJA$'R_Y]);1W#Z1HR)S/?>+ MS`H#LQG/#;418VB1VWLNUF)VAG/@1FSHRESD*TI2?<6571&K!/BRME6SHV8 M-\PKZ*9DD#T<'_W-\$&?+ MC48N;$NMC^M(X;YP_Y94GZ/2'`Y:%_+PJ!7)SK73>%\DW#`(IQF&$J,G<,C] MF:YK_\6>IEA0=X]A0+D3@R)V5O&F'L7GY3#I@RU.,%I6,-\^]Y0`,D4JZ-K* M9'<+W[.4^\&8//@[/.W!B^=#7Q/K)_,-7R*)&ZIE6Y:FRA/WF:]_P&ACA<]? M$&G;I+1(S.;`2G<625V59#:ERR]Z()=,I-:4WR<$3TUBTJ2]XZ6XE/C3T+.[ MPTH[E^NB7:CNM`P+_7&I[$)-?!R,"DDU8PJJ>QY-Z^Q09%@?T94/_$^/\&+/ M,S4;!S]=<4GF87+:\UA[GHIV5W+IAI8)52"[JO."F"FI'0[>D&V6F9O-))UR M[;3?=5&&K\A;.+BNUK(T]_FR76J^YT]!/FO3#EA7&`9U\R8?^DC`8ES$`?MH MP,>U3;WGX8\(-^Q\`@`+%\;[AA$U@&3?-\WQV8\7;R=?G2:G]O#DZYTW__SX M;GQ]KD^3D^?_]?R;9U\__\:^B)L(_73?0E;H\2_T%1C.0,:7%Q<7G7<3+JFN M-]5Q2008PY=X-21\WW%#"1ZIZ\]WJ*8GQ_-75Q]!RN75S34GYD3^1YQCQ(Z\ MU],E+X?LKNRJ,9.?*3/D6\(8K][;>+8Q%\!.<:"25?;6T=ZCK M]OWWTFK3XI`]R@B\ZQ/>?^LE$,X1F8\!AC)\$8+43+B"$68`0)S^[[,3S37:JISGWX[/=NWZQ64&GARW`0%D[%>-K/CUK MJ%1T^QXV7*V@^S\^M^2DMX[N/"B3"@S93\B2KFGH@CT3*"!]J%PAOM?P78RZ M?].8+FB6MM-^6-+DXHW%^>>KDYO>TBYJ_Q0"R)^F<)$9^`JU:6$Y#[H MVS/R_0^J=_JO3)BJ,MLZ7"&7KT+PS=V=`E43DB:*0U=?/?YIN&[N_(2-_$#W%Y[M0'"CR)>%D^4)2]R4HF5HZ M%5?5+XY?'&MN[!!<)F8$#>UX>2(MK;YE%`7?2%;,GNY+5E6?,&IB;B@?0`J3 M+^V#>R^3\9NW5Q?Z]F)R.XF7_/=N<(?BCMQAI9+ISA<=?$3U_5SE>V8O8X,W M'<8K(_+=K>[>:;VB03I.D<]^ANK=N^VF?`Y]Y-";^[RWCXFW%;K@')K/(Q)] M?\O_Z^-JFAK'@>A=O\*3"S-57D^Q57N9&PPIF&5"4H0:]K:EQ,;1QEA9VX$- MOW[?:WW8"0FY^S^%SN-E;Q@F%3:I(GMV[/UP(#?3L6NJJ;(X1 M/R-`'=ZCPH5P3R]0V\`S-[*_W$R%14T38_>:T3R?A$KS9+%G&W.CEFEHTGB&O47Y78M?@W"F\9*3G?D2./A6'/`6M M9SGY-'_2/ENX,,&B/Q"6"M=JYV-YJ1"PRL+Z"F:IJ&,:(`N%>4F;B_=KA;'G MJ1#TP=21('JIET:X72+]4!7CQU:D=]D!Y3HF?P1Z!+7*T]%`DW&CZM//1PI9 MQU)[9W$LNEHM8V6'>_NQLKUZ$^R^+ MI?;/[([2QA2N?!\;5)_=`9(F$[VDGVXQF%\7?WW]-<&U60//"[3U;$JR7SLT MD`J]X$M,1E3%D^.[6>6GN!E`RMB/TT5%(=4[)AV9F"1B"KOP@W(1J:?#2J5W MT$P.ZG:=':.I.">`G\5D.[FVV`L'HJOD)8/)_"?9).6/?D^"9*>=B(JD@PCI M1K;*66YJL]5(*9^[6A2E<20`ZTMJ/>O/S=G"KXOV6*"W=:)*:3"L61QS7_QQ M69<\^5QD99:,RJ)SJ'_DB_?T`FKT\G?)\'3T)?0[E%1Q>@99,HHKI--G7-A0:X?=P\8.LRG5?;KNAIMOA:O1=O#"+1W:#FN?3\QA;F M38)V]DX,HCX0@[A-1%!SH`?9,XU7:O`P`0,'",CGS5*&E4N)V3TJEU!*(4KG M.39?Z^-D.3I.D:_ERU/L:X=7KJW-DVJ[7']2R0#;7'R_O9L^_AQ?"8":N^`- MVQ,.W;M"&>&JJ#8.OX7Z_BL!I3@[@[/?H6DOTG.5]#M,8"75-DN]ILNAR2'A MH1RI@&4U.SQ`G3D#1,/'\'NA3]WIOC8#Q% M*/J67#<:C27?A3+/<,^]%>&J2!Y-1T]%!Y#,L:K-+E430'5=5`3."UK!;&6J MY-94"SS@GW95(VJL.G]Y1G%$YVC;#Q8S^JB[3JS6D>$^E@)\2R;,,TS;A6UH M'O...?][BT?K6AE7B8GLDEN]JB7*?(!)MUI>PH`^;O%EG5P7)*&'_;T_"?&5 M"9&&HU6O\I1(K%_:O7E'\V/1"/0^("%EB#4'EE2(?Q3:8,R2^G/XP*#$GS*# MB<6G4:2'N$&"PSV!)>PH>D]`,U9IFSR*%G9F$2+BV@ULA`>Y4?.5`8S3IM''9^7!KG=X MIC%I;C!V.;'&N:D7VX:@Y,8T=JU?=7*_->JC!C#$M<6H=F_'^^$6!82H75[P MLB'Y:X(#A-=.C`PA<-O'HZU3CY"D+F4!D9:X5$434G$P9Z?;EO=)B$E+NJG= M6"GPB6?<"OLFL!M$JJ-ZX;M'@\PF2JG!9?;I_\7MM4EI:?/N/1#6J_&].]92 M:"#V+4FPEM[ZJ%S((&))KI#"9BA%B7T[M@L13/\:&?S]#U!+`P04``(`"`#Q M74\?-2B,[X(E```C90``'````$U%4T-(04-(+TU!3E5!3"]-15-#2$9!42Y4 M6%2L6VMW&S>2_6S\"D0S9T,I)&4YR>S&/K-96K83G4AV$MG)[.PC!VR")*)F M-],/4:L`&O/HT96OL[7+UO95Y7]I?='D M>SNK;_S"?M?ZN@EE46/4(XL_/_BJQK-]/#W35T^*A;UR%2:???'%9\:8M^M0 M6_SG;![JQI9+N^RI.J'Z2Z)J*[]RU2(4*YMXF)J+AM,W+A0-_F+X?&]?N-NP ML->-W[FJL0YK_GT>5D7P.WOI]S=CVZR]7?A;GY=;<,@1IJ.`9W#1+6#MS&;E M=L^7363VQF^Q:B%D7%$6^TW9UG;9;(VKO#.&6V_6%:A-7=%._:*=NM8^M:?; M=GZZB91/7\V^FZ8'8R8?Y(\QWYV!Y1_73L22=O&E^>Z)O-[;HFQL6WM[;F]5 M.;+=RXO7W\[.OQG;EQ?7_&#+RE[.^(E3W50I8G0\V:+EPO;E"K;>7GK[=9E-V[E M:Y#X%)L@B45I+^S*-_B0M1L8BZ.!8,!G&'#Q,28MRQ9J=W;>KKA^8O&C*!LA ML"@QXW/.:.RN+#YNA($`SF"RF[U]7L$P_@;;RM9@SU9M4=#V_C9Y??)($/!01!OXS!G826Y2^YL)K=TM3LG?XD^31*^S+]U;[%WQY MCO$7HLN.W"XT:WLU>WLY>XY!7Y`EC.<".U<^V#X3YU0PEAF]A+RIX MD,:_H5A@7.TEIL'0RFKA*]*]*;#8CCQTYNWO$.*^_'"N/GO8U4VG@QA7YY6K M)'XMVR+32,I=-[X0UX2O5!9Q$/]L*,B-:ZIP9^@+K3I6C77>PA\9+?6%S;#W MN;>C>17\,M\?PVHV&U>%&M[K:F,>G6#A`F*AH.>AB-/`Q*W/FE*#KBZ%*/(, MC"#R4KV+-FOJ9P:Y0OF8Z/A^^-U$_^D&URSWM<-S0_+(9FXF),& MP[RKFTF-KRKH)1J5C-!=%=C% MD9T[VC;%21]"W,)3'FX0.ERQTEB9=BPY!YLLVCRW.G3*;"C1H_)CNRYW2%#5 MF!HLQ0A3U*4S[TEL+$OY.T=C'7>;.5Q-HH MU,`LZW+8L1@`G`"$]YN-)]MCNRWKT(1;9D_LG9X##N@#^C3F5JI:WJY=#98V MWI2R1MU44%9;^6A+58LX"_,;F!F6!1=KC_^%C(GVJ7UYM\W+T)CKP>SK,D;9 M(.$6E"%+X`+[E6OK.L`P7^9A$TT.\:!9EPM*RD"?L-]<-SBB0:4W<:O'G7H@ M=CB)AV[P[_FZS'U]LS=+1U,,M5(>B=^\)Y!.6AVQXS$D':(_SA$-3+/#>Y)> MP@[']O+%I3VDK>,E(!?>+^H'J(Z1VQH#DLSH+A>;(,>3N6?$7(SM\V^^M:/G M\/GUY!O7+C>NF'SKJMPWS?&]Y2B=7HL/+-9O8+@$.;`(MSX)<&R^^_[!G6#B M'"B..4)TH1YH[WO@U,R@%2BU2(D4?Z-)#50CF?T6T<8W^T//:'RV+@(1H^$J M@R_V6W7`>]3@=+,.>M*:EM[1SNX!FS)'\N+@1Z6UBWWA-A".P\M,=CF&^B?# MQ\I/ZO"K>".8)7X4EUO:3AX+_6(,\%DR1>_P/Q/A'@`QY*Y&K M03BMX7A,-32%Q<\EL+LPKZ*(Y!`#N`(C6%DQIH]%V&4!@]@A4]F>CU_:L@EX M/51,9"&9LY?%&&0]-WCY;MP%!O'@_WX[MM]]/P:G\`$"L4=9F;>;PF[#;:FK M]WXU<+81W/3XMY=5+VJW"]<,D#(92$MBQ5%O''=Q+`RX0%Y674HJ$Z&<]FGM M@-H@Q@NMZVS=4E4++R)CD*-=7__P8HR,`PUDS9"L+#-TK3M[!.)Y:/9'W3H/ M#/H-X0X$^TZ^@8RXS0>#V<-B/9#?\7!I&)*XW/U!]7!E6?7RG7I6([`'K/7A MA6.W\/*L1#;E;$\W+WYN5]33JG(+,2>:P_E7KU]B(]PT0Q&)3(6B6';H%T=]P(B5 M:,O%< M'C%0K6,VO;-_Q4NR<"=?;2MZOQ22OF[S!E$:H#[^8;#/Z70Z<-RHFF=1#[0"\"\;U['3@;Y8KF%:JR"!=:MC M=&8Q+UOFH.7HZ$^8_]?_+(Z4T]N?-+>-[HZ?#>H<%[34G$L-#62QGS3E!%AC MW#TL_+Q=35#X51.QPU@530FY8SI#U'0I0]I13*WCWLU\DTV/!9%4'JY?@U-I M-YG:YTL&@MB`$CH=W$W0*19,:AD+`@8,*?9*1/`++/"ND+(G5I+" M`R2&_Y\"+62HH@35@O_6H7YFW1(Z8Z8<)P&)A\KX;3O/ MZ=$EN[J:/VC%TDF:>^E[9&6U+2MA#$-T@HD3ZG+9[*3TB!;Z)FNT0;>PW^>. MI@IG='`O%D#-KD3*>=XV6C1**`-D3SN7+4L\C\H91S`>';H5\!/[RYXU)F$3 MA*)^%B?9'(JD(BX*Z4H%>E$U[BOAHK2N0=6_!4.EZ<*/]FL1D<884<62N=(5 MN3*KIUC.1+\9E#'F_.-:';V#_W:D&;SVS<^;[>A89)*7Q4J>&%Q>`>\SD@PX M,Y+Q3C5V3P>!6WJ!%`*Q:L=J%SP%:O3RD&85)`]KO0T+_SMQ=ZS*B2U[*3QW MR8CO[0D"`_1NV78YZ*B(`KKF"'-`'W([N+)!J@M;6(_(+#F9VIHTM!NV.24A MIS[:>YLD7LH160^X-+^I&%F?$+$/?YI!2`O)OZL>*R^2-=OUOF:A)D$RTJ'A M+R-LDB,6O!#4H%V*6S6=K*VD?CY:A]7:[!Q];N.JFR,QQ7L5)]>;E^!>)`MZ M:BNTHHO3-T-50N)1BVEN$_N8,C^UW$E[W1+KT_]Y:(!EG\/`JKW1K#$9B#A2 MDK[,H)9B!Z:3\**4QCK;#*Z0SI2!T)=M'K'O$/I&MD/TQ-"HT"-F5JS2H6_J ME,T$+=CI;85//87#PP$HG.M3TS7FA!C2?U``=!M5?<]ME0B M)[)-.J)95MY#Z>[6A9PR4T_PMZFK,M9H&.,/&_7D0G4VEJQ82$9<27B$TE&' MB5KBPM3*H7R'1QK<7>?2!ZR:^\@H!N8>OH"-C;OQ*3*Q%ZC,N]CJ.Y20MH=^ M)PI$6O=Y[XE$9"888!/N`&",^?>R!2=[M1G);F`M+\L;2QD7]0YN,'OB/B0^ M2(=LL:O9G['IJ<8?.6(SKT)5-T\EQLS#:L6.VX!.,N3A^4`Z"-""(X/&Y1S# MG&N/:$<4*B8.V4CFOJ_#SNH.]6#Z3BZ[R0E5]TV\#E\/"I=Z?+\]9Y#2C]41 MV"K['0P]$1!M$X@VYMJS/G_:@26,2A*3^(RD>>A,R1)U]_BZ+ZK35\\.35T< M@X.U/P6)1(J'O87H0?1SLP1SDXA+COINQ-&]*7(>$*J%ZM/E*WS5K#?1ZL,& MSET]0[31K9R"H#\3T6+;R:W@-X7'T)P;U04`?]9U*,_3PZV;Y M$V\6R+EH?Z8I^Z39BR5IA==6F3?B;J(`E.M$Y/)*9.,UC8, M0>[:51:FZ!4?%0NDPK.K^;[1IE-B;*P5DL3`SR:?]P,ZXIJD3DX@/-A?0O!& M[TL4*[&N:']=L*#:!L?RJ%O)[QP[D3Z:=,0/CUMXBJ*`#M'*K5PH!N#7I2QX MO\-_9P9GEL,%$]R(C'2;^9&@7Y%`2OJA%L2-C+IH?;J:@*2H&2F5"A(+O-:L MZ@!B1H>Q@M\[>\;3M2<,?'4I%2PLXED2$<>MW4*J=T4((OJSQQ8@)9\T82-] M:^1FX(\*0>)'S_L.G*(NP)!7;B3L#N/V&FCQ88;319C%A\IF74K[?U_X,%H5 MIOKNO?BM`JWDK@=MDF<.0!U/'ML]/B6X/6]7XG=MOJ"`]&K(G'7J[B,Y3MQ) M:N$U#("VFJV$+'=AHQ:0`NS>-X:PU//@Z^3D[=],B74V)('@ML5'4$L)]"$RZ=RF.V';"*22&B%)<&J>^\S%8COY`BT0 MR+I2F7=1Y/Z)3M?U1;KOO9W"&@@7_$CZP\)LI8FBV`5&[-T5R*;4O2Q"44\'P(7`2^6"M0^H+7^WMVB M>#@?]%0[]0R'8U25O%A2]Z7F,.J6RT'/\D$IV$2%+9.J$\F]%'RX:N?(TL2H MUYK?G)D3KHX4GTA?K?XX'IU6/D%"E%:MRX_9Q32/SD&RBM%_<`XOX`;@;;;M MJESD^_.KV;%Y=)VMRU(,]VJ(]ZY9D\HQY:Q%,'0Y3^5?IT/^=T607E"SQYJN M@/54;FQGYV_MXR>/'P_F&(.-'"61/>4:!&GG@]:40)M7G[Z9.4/8^^ MY:&)7T@&*J6-:<'S48P)&>RJ.X^WLS]_^AB&2:>\F]IWUW]^\N38?L+#_0:! MZ#3AE*EYP^L]7S$6F9.3-YN-LVN.20*D]IW/)B)##Y'[T6 M&2F?3<_FIS3AQ6V8-H`J_S'].RN>Z>K7_]+ZC$J0^BQ>$$OEF;AGK+Q_US_- MP#^UN\9I+]Z0K+L%6F;CW=Q!U6R!G6I%BFHM7>\[Z8P M,I7S@&TPF7N2?=/W+U)/CM57.Z^;`#'YV)0^#'31(@V!7XCW$'DR(#[!,I3W M\T25A^>*T;7B:>W+H7!AROX M_^&KJN8<(0%8MHU-90RX].P?RUU#/+V6BT"YYF$MR?78%PM*(DT6(@,Z&"2I M0<;#RAH04&?I[^1<<:K,.3`H'@GQ7N=!1K;V6U[M8>-?P,+"2U>E\%IF21B6 MC2(H9YEV/T?QJ$8QS9CGZDM!+WMM+XM]2M]!#Q:%#V=)@9!^"8#YLO(;4:);`YG4S0E$L%NW8XY&CK:.7!&I/>6!Z1(\/ M\9R=&S0:B]B:FOM!C;"KF"YL)_U[(5'R!'N[,2P*%#2I!I*S5B]=W!ZW)"Z4 MC<@;3;:_!A^M2:^\XN',3\X^9XSFA\]BZ=3*4:!T]Y61&.Q2_S/:*#!QVH/< M#L0N>$(7\UF26(HP>J60\B.)6`[5Z3H?:!$1\_9VN<'*^IH[3#:=+N11CHR! M6>8DFT449MB@&=[LT)+ZCF5A;"6(SNH\K-:$I[FK5F`HGHG*Z+9&Y)HR?Y?% M@&="B7$:R&*56H&\_F)'M8.]\]I2&4&8M@&9A8S>8JQ1=[QX\_(:^3?:!96< MO!QN]0'#TP>Z%Z\M22)X]G5K/9'"``9PW@P_@IB7825W4GC5I7M$T*(M3L3\ MX$Y`Y!(\RJWF-A(@(%*#*>296C_B0@GEU=+I(M(;1#:3KM.HE(%&[[H+PT17 M>G=#W*1H0M7=%6#WQCQZCT&0-8]D=_R4`%O":F1IE65R@UB.6_JV@_X(9>EX M52(*&$E<^AN8U2VU*MK?6(H[',I/DWHBSQO=;&/H_8P4?S:AYIF;8"1%C%/S M:GCFM>/Z.\UVMM\L-'\9BO9N3+<6(NJ)[-%TKFUXR]*V/P6YHUSWQ[8>]705 M^W+\M8X7Z:P36/-T-+T?22J]OT83FZXE:0M-;8(AIKZKTT]UKB-J=O[UQ>N7 MUZ?RNY"$2$-_J42Q8<_+V'9ZTO@^'K< M7&7D!:MV$G;::RFKB0KB:>.G5C)-)U..P.9D(2$!%@"E,QT^M^[[^WNW8&D M'<^$_2!;I$C@<+>WM_OVO84I?`A8PA$O4+T0^\0&]PB%K/X:-F-XB=-&(]JH MIVJ^"#4J6Z61"\#?&=VORJ68%6\3A@E99W.(4G2O_A0HRKQ\HRP:G`2$MB]D/S<0"ZCU[%X=W1D:VEOJ".0!0-@`RF`L5(R M$@,3R+(G]1O!;RZ4D.M)4(NR2D/(5737KIJ)2G;AA;M0"12]PWS!6HD]&D(D-'O/4*-B.AGXL\))M[(A'6 M9?%%<5H<%6?R>[6>FS34C/%N^+S3L^/3J;3(LQ_S\ZYZ_^^]$S)LUA M/'CKZ&*BDX)X39F6W7H!1$;-1';5>K%6GIZ&&;**8DIM<1G&QM29#&S'B@9*/1?C`55P@J20+CL=AB9;UJ&[DRPE31KKSE.)SQXBHDA"SJD3`6`MW;)>U7T. M+W[<^08OH54$5*@<*0D*Q&Y18K`IFK>=HA-!#L&;TF@G;LY%9LYZ<-X0DKQ! MKD1+<0$IOGG`&.$08ND4/S`GGV_4#I3$(Y,U\B^.&%WAZGJ7&8U.BS`**J=: M$17^7J[[K+Q$Y7?@MT@D[!UQBQD^!V+ MP'7,]#0E>B)_!9,G4BDCNQXPPQY!+/)9RZ8R%!J@K-Y\E*1"GRB=893-MF^L M*ZT_!H]A0;##J9N$M!@+Y43%0$RD5JF//W4GT@03%VE=,J%NZ0C+=;DL""85 MD@5Y%`=1- M\/"WM'H8`.QC?I5B^^W\Y[J7$Y:&8WC=$GL"$$86@:D0'F_"8"PW0HY@KCZH M$HI59X5K"=#S2#!.*JRCWS-G3\-S_B7G\C,Q`]>L=?M!,/&4N\J@SZNJ[W7[ M7JUK>5(YV^\'3^C+/"U6I8FJJ-!B&!4!9*%Q<_9L2)@RWT;VRS$61I"^.6*1R`%]S] M].*)ID68J*EZF8H$R3!&8@86',:PY<'&Z+TM1G89K[0^.N:;%-W:6X_YUK%V MY8F%1R4@K#+>CN/P2H)P'V[:M4&,'\;/XSE%!G+5M.N;6T-T4RFD)7?.X!UY MR+=]&K(=<*%.8_]4Q[Y5(J)],^F0LG\^^%@^ MT[$,1I&QC9-ZU$#\J::-\?N_V_-]%X7O"*.S&.1X"VS>&?WX/HEV=B<%A#HN M`8K@N];QCT>//_TG1P;![])6?)%.:G.\&7X6&.[F&+FAU6J>V]!X.9OI7L@F M+%I8CH!G8+L1P/6R]N*]U_6)_+4+.^=0K^RO#M>IY7VM=,).A,N6%EH1]SI9 MG>M^3,&@)_;+5]_+QP+PSV:ST-@3L$SL(&(8GB0#T"PE'^,3ABXF\!-3U@M# M?X_B90T0$20ON>V-..4ZX@"*.SUY.#G@]/S?>PE9G[!_KX$M>9P>0YQTGO@- MQ%:2LC"VV<$U`CVNH:\:H8`3YFU5$$UD*6N19:BIY\3X^746OZLP99#+RDZ3 MHTSVW5S&("-X\,!0`JX;HA:5C85R46J;B2VR,#SI"ZO^*IJA1XQ\,SN7%'ZU M<"'$I+"`Q/V2YP!K69\FNBKDK/L0IK&E%L_V?],.DH7]7QRLO5@EY4' M[I`&*1JN3`8PB$#TVQ0CXY7+CI9/(1\=[6/AA%G=O5EW#LP[W@&#)?4`A\RN M1&V(ST@*>T!O<;BV8.$%*O=)_ZHIM(F&"P,TV=0J=51@2\!Y_CUXA=8I+GKV M./(SB+ZIM.C;N9);Z,1`SF?-O^L#U0,.U9>.?\6Q>88-=VX`I3*?Q5`>%6_Y MWS28;]N`4%2#6-QUTV+K3:2O1O2Z1GD>.UIVP,W&828%G&)&9Y+/K%*YH"WOW--;XQ^M/&J_JH1-A(A-1*%D`UY%XB/*!5P],X1*=^1A;X%, MM`OEX5T1%FMM/;S>LB.PB+S%X_"Z>DA>BR*+L>M'RJOYE.,UX(-^WP. MSG&X]F#R24!DCOEH]#G1UA>S]9MJ:RS^?.Y8KS:N"\X"6E(8.@L!\_*AAM?F MLW="SZWQ>ULW]&;9PB`'-*\K5L7DMJ._KC;S]BZU-QO%P@ZL/OC&*2-RI7:$ MA*!RX!XT2/:*L/C&M/X6ZKX-8ZM*9X2IV/#GX;!A4+S:O[X_?IMT8HI#Q]'D M[8$9[$9+RTD:@X!WH/?,4WF.@?*3'8'>#P$/Y/HT?=Z9 M-T:8!DTX?!%8N@;7>+FJ98G!F5M5D6YD`84D]+4R^&/[IK`GE?`^",3P39S` MO@:9NA\>&PS,QC8VV5'O[H)C=#QR9\1N;QKRD=0JV3V"<(J-@&5^=X/:7$YL MZ(F64!&OHI;I7;CP(F[QJ2JG;U;U+"RSYW=^-;RAQF+0E0%,F9<="XUQ(L?L M^/;PLA(O-9\6EZ]>3\,E_BW.;ZNK37=;W;%>.+>4:3)P48GK,VSDLS)V12`5 M1CM8N491#4^2,D2D8RCEDQP<\`3^PF67FXDE69%L/),)-!@'7]P^6I=NH9?2.GF#SXB'KI MKRH4/C9!__2L7L[;Q0A;Y6Q3//[\CW\P5I7V*ES!,\!C?WO[K+A54E-$J_CW M@&7$B)@/8=2U+X6G]LJ$0FP-(U.9C:0IC'1)/P?A M7&I]P-3236+"^::KM5'E_AT\P?'3X`D_']!H[LN$I>A=XBTUDK#F<+XT5LX+ MKYY=:">A57>2LM=:*RE=C_.>_@#='9V'B2I-TX:=4D6FY&W:'13`Q,T&/::\ M&JT2Y#PW+/]+QL)JF+90]Z5.IH;)/[57V$`L)/Y$KAW@UUQRB#9!;`U+)+,A MVU1#QTXFN?*B8VS;9$^ M6U<5.J(TLVGB2AB>5*YQJKZ,UO="+>14&PHBXNX*IW]/M3E&HO9H)2E1P;)V M`I(`DRIA\`D2SWGD."^4+1+L[E[YP3&S:ML%^25EP_6?#CDC-#NF[7Z(IBWM MEN4>EESU;R62?SAKWV!FSMM5HR?:WVA:6CO/.I+KM0"]J,_5VE<9\GZ+1EAK MF'W&/L6D$.#3V7A':]RNO&E$+`H%:5=H13HU,M M690NAFJQO,4>-RZH]Y,9=@A`;QRXP<\?JQ?D17Z%DP.!=WVG4GY<.5%KPEYJ M#3-;SA469D%BRLQBX8%>?\8Z0T@SG4MDNS?REK8HHQ-0%28C11ZPI39/<4+Y M/,#'Y@5J+'MB,QE27S=\>&:-AIWY.'Q3DBV"3SWZQ#YJA#,09];]6@5$\@Z9 MS-&R[@<2=50'`B>71[UIZE5A(5?]C"H(^:96'36U9RV<5=B?J)Z%5O>N[MC[ M1Z-`%9#Q\;U`_?CXT\R4HF_=T]PC\X13SMY=N<"D>WDO1Q#VQ+8:2,7T\CIO MV;.KM,_[29O:"0_T#N9W3&F^>OG#Q_+Y==\"$SYDC/:^/N+ASW\NGD.U8<*G MQ89ZO%+K'49LM)D]OL6G-5[11*_7I"VQ':WWQ*S@)^59C%RFU`S20(GN:]2( M6+5W5_$47R$H0O(VV\S8;;49-'.HV=,BA,$?<'#J*0@Z8*8#$]MXS8IKVI:I MA'E-[#]@[0I?YYLUTI'&N;$RO(:U7JEWHIU1>LJOZ5,_*&KS)9Y8+%3=;]2$1&?S'(Q+VFD=-TN M/D;(>KAIOD#9)-._?GGZ70CA?U!+`P04``(`"`!68D\?04\(&DD'``!.$@`` M'````$U%4T-(04-(+TU!3E5!3"]-15-#2$%#2"Y(5$V=5VU/&TD2_KR6_!]* MWM7%9,T8#)\(ZXWCD%TD8+/!9'6GE:*>F;:GP[RENP?;G.Z_WU/=,X.)?8$< M$O+T2U4]]=+UEPIFPJ MQ]U.MW/Z^V%+<4*7PFJUHJC(RLH*JXKCK$-;[>,E>&!$WW4Y$O*I:3 MJE`+O:9B3KJHK,JEH7FAJ90:/YG*%Y0YYMW.)O>@VSFWE`CF%A5I*B/>9BZQ ML(*,U55D*PUFRT1!K-"2C$SG^U&16V@EXP%%(J=0@J^6PO)&+$%7K&5,(H\) MQ.J>ORTM59K6C%0>I14N,L"L03/H=NZ`H-!FX-%&$E\JMW(A-;5'K$`J5\V& MD])<=PM3"FV`J-D,3M_7QAZ-SU:"J5G%RD@8=O38L%$1PYI%<6M@TUL)[RES M`M)2L\,RZ-S?ZW;^W>T0_BXG,Z*7DP'^HZ)'OX$A83,;O=.XSFNLC@B1@[+X<\#O_L$6K;J:@\N_@\B9NA#IMMY M!W.JG)^A5\?E!`G/Y)5(!WA/TJW#PEK8'$;BF'/I(VBB]J]$V!>&$JGEKVW, MSD`T5ZET6CF:6&GGO37%!>5P1_W,2.#A^:MM0J*3^E5<_3$[HQ,ZMS)SG$[5 MF,YI!E==X'=*UT2G0^SQVR_R=$WB3JA4A*E;(@=0\[P$)5K.?^DEUI8GP^%6 MXAN653C,ZI?6?@2)S=+>F%B=FP\7+FVQ/>850+LDJKSF@"'&#M[_(<#I\#70 M#V>3MY=G@5W9WMA_>Q%\K;WDV,S%%W_MW>3/H&',EY&TZQ7\\T[++Q5B!4:: MF%L9=SM_5DB&+H_W?3CE9BFUV=LEXW`DO(QV)?*\J/)(>D&3>N6B$=Y%:F-C M<=+4A@/K,!C5?*%JPYHSM5:A"VG3&]\8J8'TT2ZS;\WS@,G%)QNO-WXOM%4B M;1SNCQS9(Q*5QW+U2(X:A\NE\L@EQ;U*RCT8M@;7[F%\X,C)6B+ M@.:HR.62:EUWFB\,K-#!OS:$N[6W'C[=$Z"Z='%)])7$HE0T];//6T@7YD6\ M]PT9B_NOA"SN'6).)_W%O2K_-SD.-VBQ>B#<16<+*])+$5U+6Y5!\F75&[]1 M^>]R=1P M?ZZR\K,*96"LX`P5\T/:A1SQ?1"89,.\&SO>P/R]P\(:UFU;DB?,^\"S-?#F MUG-,C/N'6T`/GP8:"J.BNF5848$Z5O=?3T,^W(9\^)V01UN01T]#;AJZ1\7R M.8!'VX!'WPGX:`OPT=.`F[Z,ZZVRSL*HTIFT21$_!_?1-NZC[\1]O(7[^$G< MOF7FCO.[PN)X&^WQ,]$6:=P6KP;O]MZW$./VAHF?\?ZVV#/N'9M/(->1^906 M"Q2:YLNCG":85+BQ7J"C2@5]F%X_)JSS^F%P&/;&&PM/_K9M;#B[/=0[G._F M,A(;7$;BVUSX_*$Y0'?%'5N&S+79MD'EMO/:=4XBY.ZQZ08&)#$LI*[FQ>). MQ4BQT%3DH=1:X.9T M1@>C@P-,?BT1(T7C.RM@FABE:HT2YF<9(P%((&$8PVVA+1Q^V!TA+N*8XYJ5 M*@6>*;'U!\3MD2?+:W:XK+UOF`&4_XRI%%`#DZ%!^]H[KFES"!Q7-P&FC3#7 MGD\+8T]JYT]^.CJ@OO7-.A[=(D$G>'/]TVBT1S]3B9N,F\V*YQ"CE5HX%O\L M*C=%EV+-_7DL4[;5FG7AX5?GC1&S(I=KK\>`Y[Q8V2'\KL$T$AKMIK11L,FB MF7RO"BM/N,/6KIL6J?&VLQ57#G`&E]*R=>8;LPD'SN1Z>G[.D9%U.[$ROFE$ M\#C#-&'7B'G/ZB$-033?@7W_0@^'T6_X]H]K5@=NSF&Z)?U61+!AC\:5ZCQPY#A;8_%6WY6=.V?U6`C"P3!,)9F*.([3G?U M?#&)[P3",]Y\&O0;G.0:L,'V^%+*--V8+7KC-O!I9]S7;+X=_$X+@'N]-;O\ MP"/C@W+_!5!+`P04``(`"`#<74\?286]:WD&```$#@``'````$U%4T-(04-( M+TU!3E5!3"]-15-#2#$R02Y46%1]5VUSU#80_AS]"G68:7-P9Q(&F"'YPC4% MABE)6PZFGV5;=Q9G2ZY>[L[Y]7U6\EL";6:`V)9VG]U]]MF%G9V=<2.\52=>F*8-7GCX$+XNN<.14`-;.G'-7"LL M`OM!S'VP9#,WON*ELC`4K2@?PS_@GO25*6-^D.!6%'NQ(VM[H`NPBRA\)?E6 M"A\(4T?:@1S$*H6*"`/NL0] MP3_7.=WA3F+:S:E)2'F0->I;\6*DQ M-M@0'L!TQZ2N1-\=0)^''=^J$P5"`9#YJ59P-&NW[#*[S+-''36&L+6FP76/ M#HNFEC%-\B2:MI;+1()0UR-%"J%9#G[D?9+SCB-GJ@9K0`GTHU8CSX,@:7L?>`E`!&\!%=2NYT M0U'GA<@PNIR./R]F5J!E@Y447R4.,EIQ)MB"V%>2UG%71=S(/'H=*I.PIJR" M6,R3R*$0Y^U^<:]:?DXUO]W\]L=F,;`4TC#3YKL9OZX8>_KTZ5S1H>21KZ1" MM3R!RWJ0)K1:]-1W&X@;_8+6]8)-)Z9,TY?_-0`%;T:IPQ=&XK$#!_H3Z-B; M'L<#J9[$?!@&`]Q/7Y=L^/VOS]$;Y71XM2FJ8`&)G@WRWBB$[P9`_AP^_G= M)N8`HO4'815I=QQ. M>K9/72[[PWPZ+*P5'=7<@F=:%.@G%_GG3!I4P$B/-X&,&S@H((L1&B M0@TAC#K46TN;V&!T&VRT-C00FS70D(!?,#2/^OM2'Q$K"@+^@@\=D7SNCR75 M71*)"OSJY$^+!^R3<12E,EI*(=$OX8BS=V!,9T*:>F6:Y$4MG)..T2I))OI( MC2.B0"#+KC=:CNXV-)?H[K"E#IO4K!45Z1GM#[*\&LZUYDB;%VM-W6G3*!`Q M6J.IF_%B=++F_=;IN@:;&<09F2SE5FD:B`_5]CP=9;\"2+7Z780MMIC5 MG\+6TOO%M/?,0*45`O2[%79OD/O[55RJ6*L.)N[(J`WD:M=]+[]&KVAYYZ4I M`EF;=DU4-/K@/A`\J"$FX7IS\_$C3TNF9_UR.QNB<[>!,:"XP52[Z^^<(O7EQ3Q\!.&:XR@4``&Q9BWJ=/LR(*`E.F(KD2I)V7%__LYC?"3D?A49I,B[-.@)Z?NFTM6B$\2Q/(<%88L?II4$7! M8>&JP>R22\4Z+$&F(SZ;OO68JT):AC]8%+>U,+(2RO&2:75:2B58ILM29$YJ MQ?2*#6!Y$*RRE3;,%8(9W3A(VC39,S-,DW\*[DAS;?1:YB)GA3""?M"JW#+. M;+.TPI'6390$GA0NM?[(!ETVTN22.R-OV86NZL9Q\L7+7@Q.`)6(B?Q?[61Y MF2:+3`J5"4C,&^L,+R6R]9='(5/OE5P+8Z7;GK`+KI;"&`[)BRLVGHS')VG2 M@:8C.4-BYJ431@&^%B4P5L"9K6X,\HH"H+BR9,LM$_X#SW,CK&5.H[YR]D&6 M9'UH*^F*7^!A88=<-4.1-T/>D`$?F^5;I!)9A5ZVD;8`GM6-04:M8#Q-,EUO M?4%WI.O-\I!8(A02!E4E?`/OM'6H*)3"P(_>2@V3($DN2DK'EC56JAOV4*H8 M+.7J49I46@D(FER8$Y89D4LW@@/F!E3C)L<39F6%4IIAQU!BH?5,H:J"@@W2 MCIK/OSD?LX=\"0*R]XMO)I-'[#OO&OCITU#@/[#X)D2PAPR8R=-QY'*IO1"U MV62O#Z\:IXWD)3ILXGUY%1C:-9J+`J'1VF\,\!IA4YO%"B!M*PF/@$Z3%7I* M;R@]-K26A>UI4U*;EZC@G>H?++F5V;6N[6"6,IV+CQG M<\7>_?DX3>*D.*JRE-9=@Q)0^MZSJ!TQOH_I*8;(*DT@TM"X.AYE*3A4VD^# MV9SYS\Q^:CBE#M,)0Z,ZJL'6W%AQ+6Y(1?B"1/F.$;><(C^JHM";:Z=#FG/- M7K$A_OT<82-?_B\)^(+JR5X*!6NQ/]]TB64=+8G<.U)UV4*`Z$>;&;F,X_>Y M-W$'TU#SZW%@\05W&*F88MK3MW>DCR'GTR@^LY0>PJU?[^3+(OE*88%'8KP/T7K^!QP'TIG&$`O_O$WX2 MA'\7"E7`*"%+(^VA?9"G`?)2`ZQ6.7-KK![A(Z^8&X#"%^CV-K'HGK/R,)CF^6?'00,XBF+=4R'$\\_:-3&?D7PD_&!-H5X^^?*V;[LZ6E<0O_/T.$`B+3% M'(BDU=3:][!V$HGX5I@J'DX,]ZYR_B(\="'V,-V+O2-F+B4V[C1]:] M=XG'1KI51M>Z^PT0S?!A+Y,Z!7363BW\'Y>[ES/KYKD,`R=CIH MUU2XZ/O!9VV]`^&H3:#8L!:0T/]]5V;J\YS@[JMZ]1_OE.[721_!9'!=3DXG;O M[H@OC[NDK)07"5E9?0'#.4P7'.:8?\G:O2L&*S@+:!"32#C5#PUA;MEX^]'K M(RZ'UYNF=F7RR15.*ZP])N M3T]/OSS]]/B)RUVAGAF96R64,=I8(;9^5_'D[?G M9^?XB*\&3[_/R[2H,B6$.%A+9_+/P]5!DI<.#UA;CS[CTZRLU@.1KJ01=Q=5 MF=DNNJUE;14%JJ\M7G'AKND9N.,7T'^V]&_,$KU]IE( M$KEM&Z&RO8(A++VXQ3?<^N0>1P=Q>CDZ?S$]>WMQ-AE3U)*+56X%_KM9*=,$ M'!_)(4N5P7CA5DK8K75J/82\$JDL"G$%KU$,GCCWS$K!_?I0 M?`(V*=/*BE([892K3#E,DOONL^%49/4P:GSK-I@7UP8Z-07"MT!6[3UDKERI*6I=!DN60$%F> M2H/!LTV7G(19;P?N3RBW>Y& MU[;WKO&+Z@F&.Q]\J_KBQCL_U>L-PC4O%%)@4J:DB$MEH0W.R_&P/OJP%>%' M7>O2&5WP+1;*<';A(1D/&2>-\[F%6N`0 M2X08"G6:PV59TDY&H.7']8;%??6OM:60EM>JS!7#SI8.#CG.O6JSNTU>IXM, MZ.5P.$PIHO@=L]SC`@($DQ`LDAI-IZ-?SBZB!-Z%IR?/)]/X..&%P^1LL;LM M)3[!P5RIDNRCLWJW;(Q>&KE&EN;.POU8O=65N,GMBBS-M+!ZK1`/'&@#?7E: M%8#4?($23)5Q,H_YQ/5B!UXU="0^V6,;A+C&KX61RS4Y"\'T;EU#13R9K0AH M?!4M=%'H&^P;JP1[]D2/M#SUH>B%,_;[XKNGXK[H)U^X+%B0=WLJ1K,WHS>B M+^[=1<&NM=EZ:P=(CJVX>Z\N([S?>]"6R!>!*`W%5WZ@"JOJ-^2\WOW^-9I?C/X\G[\?!V/MD6E5^*O5-#%VO*I&2 M69],&-%.?&:-AZ%Q7U-98EN+0 M_/RN%9%>IOJH,YWZ6O/+UZ\;RW\F:7[D$3&"EC_D7RY/IJ,H^NB6\?:?%75> MEIR>C%_5@D<=G%YPAL5'3#JYMW2&%._ M,&[",4TEM1Y@@=XH$P`YJ/%++D;3)F$XM$YKZ"VQGPM+@OH7D_&[1I9#RA!J MEHJ0/S6T@!N9S(O:11RZ)2,65>C4^BZX\XJHM">S:@ M/J=JP^:'D\+N6!9'#R,&$#0I4\JBG8FCR6D3SJ.??0V!#L'Y,%*5V:%>''(/ M]5;\$2%].7LW>H'J.'H4G.@96:'0_(0%,\7*V!A]THQ:V?Z`XUNJI>3E2>JY6\SG5E$FKQ*]5&-7)Q4.,;I`;^^]"P<.X)!^&4YWU$KJSVZ$CL M2!)T"4)U3;[)%TFI4J)99COL(B!KM5VUE,K[\.]T1LV3D8_\1&`M:I@1AX>1 MK[%G3V?<4PGW2%C.M6E)DS!!-E!"!7&":<8^$D>)%+I<4F_J"]9ME2(E""`W M)+_F'&1Y?`$,#&M\7FQHJ]"=YI7K*FNB>,9^)^)$SQ4'7` M`O=@&N4Y=+++H?&1O;S/L8]Z!X22&-^&6W20-,0XJ?P76A23$ MWDQ9XMEK%H47MMILB*\I&Q@)#,190L2)K>QP[H:3MU_C<4@A/Z<062SA".!0 ME@2"AS['S&JM9$GYPRQL9\YM9MQZOA7U$,L#;(L&PG#,#$0*PN]FP:@A`Y%+RB3'9&H#("44T26&%T5I[NL[!2_G:O_PP9\#(T?C6`.,-!1M^'.N:#U7 M1;RH&20T[=3JU);]V]MH!SC-03RV?30;)PL^`(V"^$>6<:_N5CPY#WB,^-]' M]?K.HJ9U9S31;3$(8AB/-P6!&T=8^Y[)#)KW=N8O'?R' M6P.\N/(D]?\QL@4X[!)M\F5>DK^HZAAJ;L6XB3T-EYUP>V0BE+!^Q+<>F8A. MKG/P.6@-,!3O(_HM)`*ESRFB-NGF3`-X_U6M]U*K<+O7>C4W\%D1`ZF( M(0V,E5M<='+%[>\M7N:_B#@N65Z=MMJ?\#V-!0T#VJ'MV!$4Z%C M@%7#>-'$/:$*MP2H&M\Z0-_@ZFO03$EC#?F.MQ_RC>[HEY,W;U^/^&KPTJJ( M?)UXQ,V[&=N95[\3)Z)_^UK4*_%#PH#NA[>S>+%R`&S@A2>'S]8TUN)W66N( M"_W(,-B[,!=/P'1^^PT?GCWU:OKU0C^P[2PDPLZMV`-=J4`BT<(WP&-B'JP7 M'35/Q0\_-'/R#`$"&LR(BO>3MGV>6>_;)K>V4@UA(8I$\;$.$>>BRTO/Y*-/ MWY],QW&"W5$8B6TW0)U6WHV)OP^&%A+Y^S_$4TSU!S@UF%>:F[3*W<%`'&@Z M=_PNOAZ'*^:PC#(1"^\?)XF_NPC7#E2RO1TA<=Q^]../P5/U/<5W^Z^X6VOZ MK27TPW5Q'/W=.6QKU>#!('P;<&WTCX.2(?_PEQ9*A=/.`)N8KL&_>R35A\=Q MQ(-]B[MW]VU[Z1XDN=9Y)KZA-3BLHX[FTY;;F]EK7_LZ:AI7VS4'._L=#+J& MM;:%D3%]Z`\XHY&`FR:/A4B2W3NWP;X;MT'K6O`V)-3,/?0;VN/YY2O^`U$R MULX/QV%:LGPCN+=O-`,2WV[2:P+`A33)PNBUH'N9`BUWF+Q4\VJY5.&/%J52 M6;S\#/>M`THX)NV.;F;YZDYBCDX_L=HANV%R.7TQ$N3FQ[&_@K">Y@=*,G6IR$U`GB=VAEPDR!.AFXP8%`293.A M2(&D['A%__?='2E'=I-U]5-TY/WZ[KL[9NRE5^*RX+Y8,V&ML6Y\'F3C]2]' M:UR(Z7;Z_R8:C9'Q.B6+ZOV?S=[?3F[OI]14BD-RM!1M['^`: MC@!!?\EJ7EC#&FLVLA2.<;;E.V8J!G@(VQ@G]8KM3&N9V>H`\>F:ZU*!/+&F M]5*CEBXI(=!B'KRTKN7JZ#;Z*$396N'._BN4K;&/CBGY*,"4=!<,[ZZ4R;E* M-MQ*GJN@"X8\MS[H#B%DOVL$HZ.'NEGF;45'(R8=;+"`>; MH!>_075:098A);:5/M*-`5UR8UW+I1)FB/YU0LJ^PYO]XX]J`'7OH MM>>D=ULIEHMXD)`R9NR`*8?:W-&!L7(E=5>NE.6M#T9XTPB@F3=L#>@EA0$# ME34U:;U/$E/Q/FJEJ@GG/`)N);>,:-*MN&J1>(< M,@<;[07R/+3.=PQZE6?BJ1`-^%ASOUA74BUR*_CC]Q6*R8J-Y277N\7Y^%Q> M[A-/0N*]>'M=?1`&)0MY[*#U7",*R15!MA'62:.Q%2&)Y/64,0$&:(5J'O5< MI?@**]A8G&_0KF2LU:6P:H<7(FFP/E".?<4@\"DP"H+8L8*[`"36(=S?VX>J M^=8]DP[*:"Q$#X%C??$*.HSD(##BT'@N2QA<(27*HVT0"[E"4I(G(*N+B0+@ MG,"83S^`7M0*=WOM$'(I>+M:/Y.,8N\\T;%2$"MW"5#=&L"(>Q%F4T@SLC?? MO:@.+8?B;`FA7$UF04Z7SFC\9I\F'V]F&8W>L'UJ+C6,Z,^T!#Y.[A@[F;RE MCYOL]B,[:>3&^"#X,WL'IT\I.\G?QIUQ1C_ZZ)%IOU!F]Q4O`/WA)"4[H[>] M(V?41G0G:9X^]4Y37(92#T9'CN(FV9H6Z@Z5;97OYGN`IQ;.\95P,;N!:D,$ M9\4@A?:#&K_Y]8)=W<]FS.0/L.8<:[A#1,%,U>K"`\'W81SD,$H&#ZU^[%GZ M^9N66(1W;JS=I7O^0657EM==.KD(0MQO);8&UM#Y$E@9*UL!>P7V'9Y,@M"$ M$4_P=1*B81Z^ML(&1F.,)"(>0>-T(+&`(U?`9.B4+@!JR7T0@.L^B*.X$F`< M[`#H#-C+-0YL8-EU*$=8#=@J::Q%X$:VQ'#2Y"6$D0L]$ARQ)%+D!Z('Q5H- M!]?&-"YEE8'Y`7'TRK$`]L#U"+&3=0/S#(`OVT*$N11AH*Q>MQ.3U[3Y:?!` MDG^8+0ZBE'K_8`V:HFBM8T/'H=Z]:LC@B0) M(V6>96PRFU]?,)90-F'RQ632K\94D,!0Q?VUQ&5P<)#=WF:?IG<=%L(7PQH0!-)\7WB\^PZ!;?/DR.B-TK^]OWV7L_72679#1[G\$,HB`_`M02P,$%``" M``@`@UI/'TRAU:2`!0``+PT``!D```!-15-#2$%#2"]-04Y504PO34%.7SDN M2%1-E5?K;]LV$/_.OX+H`B0V%*5NL`U+7`-NY@[!$C>(DV++HPTMGVUN$JF2 ME%_#\K?O>)1M.7:WSI_$XSU_]Z)9TTF70NL2;#(6R?B$2R6=%*FTPDFMN-&% MDPIL\R@P-L>-UE=9\(Y5?\V\U?N]^^&J=][#3SP::+'OI$K28@#\52:Q4_T)?\UB-33,])28Q,M!_YL`T$JQRW`8'U!=(3*'9"HN'^,N.=*0=58 M\X@0>8G+8@W,7>E@?5$&=+?T\*YTL;XH0[I;^EB5(>=WRH2;I4SI":7LYT[O M[/K\ZN;\0]=GC=V,89ECWG2NM9[E#GN`UL;3#E=.\#_Z.D81T M\Y(I1J7"<6DCDAQ(,=(*X4$F(\%R8<#K107/C8AC=,2FA\/#+59D>1UO.&E+ M+ZDP@I,1D295$A_*-*TZZZWXXXR.;"K=F'O^7:\.-KZ<))$X;R_%,R"80&;X5*?(\'BXG.\A1FNXQ&&U;'8H)FM7>_>NH4=OCA95JY/T0Z4@;]#KC?6'!0\Y_584;[UN>BM$(*>]E'YLK M223/P(TUIDVQIFSU`#-29("IQG2VEVKL"??.MHW#UN1G6!T%)H]?&3TR(D.1 M4?-(8A8F.HV?W["'WD/O.'YS>'@<'\<4IO3UE&'5A$6"&*P<##^/+1\BXEMH^NY8+3.T M2TA1*=@-/DJUP(*802@!KY.N?!R%W=9,!9`;/2@2"%Z(#%[DS,*7`A3>'Q0J M!6MW&$9$,.X4%XJ/>2"'0S`(%S>%PI9;G_,`N:59R?J%HWB7]TF`;)AJQ!E+ M(=>TI^;6@1?15LXZPT<3D190YI2A M%4&-Z)&]##0SD:-QT\W>W'Y;*!E7V^? MAK5?7^`7;?GZ[#3L^_H"OZXZUY>\GLM3QGE,/U8.P';ME/.C.F_SMV_#-"[W M>/V(+3<]\:RY7BSSP$FK=4,9Q/#I)EP2**O+>_EX_\>C!Z8$%XL3*Q(,%@RG MH>6EEFMR@7(HM=@I%KAG:ZERA,]*6[-55`'?P$*^;K!`N""#JPLT^)].EC*+ M67!R6V;+P^53"Y/[[O:7WK<\L9Z>IMK\:??W.4QP9VYM#J6QG;\4.,Y"L?NQ MAN6<6AW>37WKW:89BRTST>JY"T4FE(KX7P^0\8_83QI[ST$R5O*+;]K"]RRZ MGVBE@-;MQDMD($?2V;\CWB6U",F[`BNZ\/I[#GF$P:%[T/CI^T8-IW3\?/S# M"6-/3VTUITT_'6NOVF*8QK]2?`N!HR$?-H_UFLK6QN[8,.O?C0RO$UT8"_X] MC8/!XA+Q3T2.#1KO[X<_'Q]NK\\Z_/WY1>>$(//#/DXB7[@Z]Q^+RA=DVLSQ M\T'!-/696&#-^$O"F?+T#U!+`P04``(`"`!X6D\?Z![<53T"``#/!```&0`` M`$U%4T-(04-(+TU!3E5!3"]-04Y?."Y(5$V-4TV/VC`0O?M7C+:7)4I9]0II MI(BF$A)?6MA5RP5Y$T-<.3:R';Y^?<(\NM8/&4F:R@ M63&`-F(GJVEF(5.B*J4!I4&KHR$`6ZU***G5/&,F>KF6B(IO\7^G();4*]K' MR]^S^6(Y7F*(6\UB\H7+3%0Y@R>?<^H73^0]'8%;P8[9#3(\3Y,5!$D(7'K& MC:S*$!PJ./2Z:&RB@\9]%QV]>-I[\DO+OJX+!I>&?OV0?]V4[":X#M8/6UC_ MTT/\(UV.7L>+U7@^S@87TRWG[:`C

YM,7'6K%)B2"A$Z!@D4 M)#LV%=3''PP-?* ME@N!U8[<%OZ5DJ&1#-5GR*FEOAZB?'<-]8,'":IW#-]34-E6J!_EJM(\YY8K M204PB3(RXU1M:Q"J&502?XC<.0(W&IQ"N1?LA#.H+)PUI])!0``?`T``!D```!- M15-#2$%#2"]-04Y504PO34%.7S&4Y7\RU-KVD?>G+2GK[Z^07BOZ1'+<=. M-=I'+DF>ILJJSI6QCW1S]7J@QR%95J^%T4 M+,]5>M"`]F$[_G9KJ.:YPZ[8Q4C9*"H54+139FE;=%9<*V\IYOSVJ'TD.D`] MXPLA)WA9:7CVT5L+$SG:1Q3".87$^!.D-GV6R6BZ!YHNS4>:#5O7$RI2HO"VE0>1#:)SR!T]P1";T1 M^B*T1!D<"6J&4`,,31#)'T8@K'"R)V^M*&!;[M%[`=!.8>24-*!PIM' MI0/(%B[!`3RH^4;N9AB`A%-,D_IVWP>@:E\6Y8D>[I2SW7MX]-(\/.[AJEQ[ M%E),6$@4GQ]%A1["5=M7D?.DG)+"0X M^@71*4H+U0(B!N<<#CX$3]Y4$UG8J3*NXC%0&9@+N]P$CTE/0:B,A2V?0;U] MA--LZ4L(%)!S/`=FT38QA,4TGT!)^U"OV6%)/[&5SM9P2V\?CJ-6*+.M4X>M MV\=:LK=3;U.P-[/OF5X[(N=CMF80QW6/WR:!50^M<$<39JZA'UIP74C7%V'9 M(J^9PDK1!B\"2,&2G*.D0",(:5@!'1-:=.R:?EA=V^Z*K\81EMS",('?5',68YY855`6;2@XWHHC]+X M2!8GS]*& MRX+UQ`$E2EZI_%9N"./,9%DD'%.25%'RJ9O%;L[W_^Z>7Y[UW8SW\KKOGV9W M0[^C9IUHK6.ZH*T/51=J'I$NB%N$^1>U/M3:NN_S?I]VST87IY220/A.#J0+0$H<6?YC)W9R7=Q<]?KT MR^"L?^J'@CL7IQ%=U8])=L>PS\2IT\6I0?X#4$L#!!0``@`(`&-:3Q_!LF=7 MW0,``)T(```9````34530TA!0T@O34%.54%,+TU!3E\V+DA438U5;6\B-Q#^ MOK]BFDH)09O-D6\-%"GEN`HI(5%(HI:J2LPRL#XM-F=[8#UOSSQ^QNXYZ7+LWZ%-,Y%FUS!'ZXS>@9Y]Q=19$&H."X,(Q1I6N-)FU[L, M,5$OZ_3_CSNY18>_WKH_^7-\_S`936A)GX;2_2Q5FA=SA).5<$:62782;;2< MP^CE]07LMJ^V7RI!X1.7ITL%\?5>I=,HW'9+X?L3D-O+6F![Q-*XZG M!PR]-YN=-KJ=-KH]QOW>Q#UM`)\V@'^/VXOB\W`R>!P]/(WNQUX7T5.&T'.N MGR0!W3EIS_7!Z,))A:0V@R`5+$3J0.0YK$1JM(5M)M,,#-HB=]Z>DLU&3H/+ MOB*DVI!IK=5\3[\H5.JD5C%8'R(<.^U52/ICMXBSLJD24FU*&#@N M%C02H!=<_P>UI`7"93!'89%[LF5B@QRZ$7F!?-P! ML:&:FLY-&RBL9Z8"';`)5J2/>WN;"[5D[M::Q(7F[`S61L]R7"5!'M67]>T? M.UMB7BGM8$8D*2>I6;JI-FA2O4)NC,0AHE2KC3=K)7+(*4++7U>"QQNG7+F-H[[H1CV@2E?`KS?,2 M7:OSZ;P;[>BS[$+]NVS#CADM0>EMP%^Q"U80V'4N4H3V952IL#SOUI&EY\V' MO7B&O1.G\SLG3`G:$[BXJ*C>>5(\(]Z$-$K61^PN^AO\ZY>_"5YDHH5F4O+:M^?LI<:)9!4T-\)5+X:!6;.[=:81(,P@M4A M'90]+3OQ:7D5^ROIM!S'![<2,8O?"DD"1CZ1PP2MLN,9*#M$FP_K?ABNV'!5 M&X(.2`FUQY@]QK5'53',ARN,HE;#X%3M_(BP^CJ40:2J6,W04%2T?Y5]"%T6 M_.[2,WAS.[F_!HBJA%Z51ZG8];?GW_EYCCX?S=5^Z%AW2&-$6_5\+63IKP=% MLTUFZ?R&/YF$J]\_/PZ&\&5T.[SF?L)]DZ0QO375DI%PW7\`4$L#!!0``@`( M`%=:3Q^2'0F/CP(```0&```9````34530TA!0T@O34%.54%,+TU!3E\U+DA4 M38U4[VO;,!#]KK_B2#^L+<99Z;?4!$:70J!K2M-]&.O85/MQ_ MW^EDN_DU-A.(;)W>NWOW3IE7OL;I)W1Y)?-J`D^HTJO6:3422GL`*)G@^&I^/8/3LDV`$K5PVEK3M+Y_*QM:/AM5P.FSM"?=T7CR M_^/+&(3V+VQ]W!"VO9F-N3JJ\^-L>7DWO[V?+VY"U>*^0FAD;HV#S/MI5]() MR>FG('7!7[<_6H32V.UV)$+6M7E1^HGWE$M`E1&:7J"D.D"2X#4F`42_,1Q[7'LB[>DE_'@X>B=6VJN: M^9"*,"4O:Z(XX0+<3]6V6"1^FK.\`;E$6K$_`"\6,"11E$Z5O(R#)=+@3CZ^B@U=Z*W0S,C(R M0./[ACVM@E8A`]F7D1OMI=)AV3?%Y5*7'8R@+,GNR6`!\N)0;S@P@.*ZQ;QK M[QX*]=[8@DE,+)IA-[7LTTR%N")E<"V;EKMLHEQ*=XT'+1L,G=0&&D,]])74 MYT!2"M8)[MZV2`FL'';3S4,!90#Z>G[V[4(`I/R(*.%HSIT:V"8P2D;] M\.R-RC!K.].R^]T%!X;B?SUX+^+N[UZ"?<\$._K!-9LN.=ZTB=(B1.72L2B' M,DIVI&#K'`D7H!`[DAR19ML$"6EJB(J41J>5%L?WUG2,F2O6X#!+') MX9P9GC.'F3OI2K&X$S8M>%I<@O:N]@Z(6"14# MN39X5R`5?!8R+2#CCE-AM:$#&95*7RO!5=#31L!&NP(*7W$%7&6L0EU*127S MC&]*<86HE-'."-X(.FY]GLM48I>(%"&IV9QJ%QHIP-3,JTP8ZS`GUA(R#*N8 M$1CDWE#22ALQB]W%^E,L9A-K0`36MD[=)LE;+A41-0EMAS3MQM&Z01#LPR:, M+16(+2=I='RT,%1PD%8J+-7WC@0INCR*P>[,+H3@-W86>X#Q$NZ&TV]I([7= M;BBO>FOUM8QG9V$5AZ9=QADY]!/`FFYGVVY$0@E!_/2RX:4(%+*8O9.O=1G= M;H?"6I23[2$:1+23B!:5]/;F54"M>9LY3!Q_>.KSK MU&@;.V'.<&5+E#;&H!)37I:VY0TMA8M!H\-L^B&J0A/4@C7)1$ M)C;^_9W.U-[4VI(&HAD<=1^YH?1C=)13ZKOU>CMDJSFL;X?Q^S[/?GG"WKX_ MLV\.[E("`<"?YX5.Q)BFCLQU6UAJAA3&W4*#U1X;M)-I)Q;>R\A7@M'@1U-5P([6W[*=' M!T2!X.K8>AJL=DXY\B*K6`,QS:%!_6N#&3'D4Y0E_46Q!EL8I%'D*66Y&[I< M-.7V?+OJ7_R+:8>X)(N/`PW3"S;PH"N*2I*$W$W'-^7#JW^2-E+F,(9QF*Q$;(5#O36$$ M.N2-=\>3-(.=]G@3.U!"9!@12P["/KC:5?<8AW]V5BM8WCX_7`*<]>?9N8B'GE[H4:TE-Z.])9GHI[F'L>U1LQ8?#H6TK%@0QA/V3C`[4-PKX4[1%&2*4G#%G!?+5-90)]"UH(U`OM M*G-M:R2K?.O\TKLX.>^?7?:'`RH%[#(1=ED]@&,I<8F`0L7"I#.IILNY"58& MGF;:.OS#G!8*)4/&LL6B%ONL4GD3E&C\,4MYJ?"KM)#*L>%F1DMFN!E!:0>. MHTRND;$P%IQFUIDB0-NY#NT^+):N\R.).I!$PPFTCC1P1VI6[;>)+M(8Q@+:LC/AUK4/9*?% M_ODRGD!_`C-=((I-D&&@/"G0$SR^Y_])A@Q M$6A'3)X;BU3?T2=TB[(>99&Y)%1,N1.L#.#"*TK7^(GR%*H%`+#"6?^= M]I&\AI]]P9;7>U2KY7581/Z@-3*\&JZF9/O$Z`QH"Q$YFL=-LW]8`C_&G3\# M//>X\]?!;L"E&KQ`7?6=+;)%N@>;&SNP^1O`O=V-5]D-,JBB-"@_!.=>C0;# MD^'@MY!-C))O&XN0=\2EOC,R%96-@:I.F?44">%9YJ;=1:0VHG]1X@[WN:CB M5.6I?7LGL<<1\^7BL1\J"B%H1*2^`R9/AZML$;?N9XK2#H+T-.3\K:N';T6> MJY;[.\C'9X!]"NR_8;6T"^#0$Y7`E'_E]X<3R(@](/2^];XB`B^P?W,[@:=T MC&=IZ%VP5%'5PGN7"2I.>Z>CJ][Y<$$*D7$!ZPXN^O^=/'!H)C)D7%ONDM5# MV!_:$;>A_9JDFON3W_=5S%.6H6GGWJ+>^-I]U+ZCH;W28TCH_8U>^]$WJ]Q]?9$?/7'7QXFB?\"-O9 MEG_H8HF\H8L.[L)>F&X=TZV2;*B!),\?X5\;,OS;VX,Z@X?7O^X^6H\Q:AXO M!EY+$[]3CXL(WD2C[^`#6=$E[54>!.D/URO+OQ8RNJE:#ZD4=JNYT3$VGB0Z M'Z'?\\+5%L??_7[G5C1G_A?'LQQ"T\H(= M-6%>C7T$?0_^/U!+`P04``(`"``X6D\?&GI)&((#```;"0``&@```$U%4T-( M04-(+TU!3E5!3"]-04Y?,S`N2%1-M59-;^)($+W[5Y1F.03AF(]C($BC#+M" MRD`49J19"25JVTW&]_HRR\>+O MV?QN,5W@5WS4?.S](624YC&'#\6:62UV0?+!JXMAZ!]^$:L\3#EHSE(?J@>Q M9D_M%URDY/>+P]/1/R1_.HY7V5"PT#3B61R_Q/O^X;6*P1'(Y.'[H'5JWP<) MN6FD$8O-;]#X5]O&;+[+&N.I>B7&J.LF0'/Y-%G6QQ#N7;&1M>,J&5?+ MCB%FEH&Q.H]LCBG;1$2))PS$?(5,8F"FVAN[SS@&*RS`#X![7!!LXN-R#`'@ M9TUK6+\ID['K2IL$&=,6U.J8`A3#D@4VI'`1:%X&*%-8X]9.2*;WGDL_X,3: MX0+OEEMH%7`-NX[8MP*G9*UCB74K[7;9[7!97W-\7=22V+T6$[;")HYQV9)J MT-,1KYH3'``4J@B=$G"W4KQIW%J&3(,C#I>`U!L2Z99.\BZ+QK>D^SK!/A?/ MUTO:VA^[AT%G_S#XB;DS96FQ&*KI!(T5UC!LQ5-<$05LHT0,:L/U*E5;$"LL MLWMN@=+X98]?,"5*%6ZK51Y"<"GE$V1*2`NI6./0&NGAF>-=X3F]H5@\]CO% MXZ#QG>CLSR5=GDLB&SB7!.>2R!9.U.MW2>J/TD$FCXOI[*\2P;5&-5`'S83! M&R&-BNM>8V4REG-TNB6=W^WP.#C3P_G2Z8*YP1#?5`;.=,+YGU.E)O_1"OW#WE)/G8`>I[*%* M$W5RSE/F9?2:/V!)_+N[6$;*P+XCED9(V+<;52"S/2U51O\?#=X8@1.BZH>G M@#8>U49<6U76Q\*'UF9/+5##R!P'Z\,H*^4J^>JN>OSG=C;=KOM(_KX4RT0H>:S MB5^>D%\@LGVP\FW"=2DT0@ZFW>IW>J(UK./4U=EM/^CYO:#7'M:F2#]%YE_O M;R;PY_1V%``` M&0```$U%4T-(04-(+TU!3E5!3"]-04Y?,RY(5$VE6-MNVS@0?>=7$-T"M;.J MXJ#8E]8-X*0N-D!N:-IBUPB0TC)ML]5M)=J._?4[,R0ERI+3;+9@DY`)[^$KF7!Z\DT>C$V'2/UG;ERCE>.V=-'FP`;1.WLA='DJVE M'T?3-?.;V-]T$##>_+<7TXF=>.+Y:U:HG?%7F*FDC;GG;8V5&+!?][:-;'E8 M&R+:7CXW7KNT_4T!>7A,:FQI+7C:J/+09''RR]2WW/6D4KMK5_D/8JF]K9/J\)Q>_H_7'>B6 M$Z>9R4]%+V\\7--78W-HICKI>2%P"D4EGRH=:GKJ/U MH6_JTX#&7`?SQY+&$,,AUVY\LXZ9N\94+M(9S=XU3#FCMB3`Q6Q.7LZ$%GQ> M9`G/4OM6ZF(5Z54AN9B(1G[:&-H99,`X0:45B64"!,D"TBE2RJEE MWB<[P`\I5Y0/@%.0#]`RY)<5O3(G MCZJ@!$@35W![-Q0U%BV4-'356OX^B6ZSK4R-7$3K[-U^SAHIX-,XBWX@E)^!D-VI1,6B MB+0:6Q*$`U7VB5D;-=(2R\?F/K!K2+;1O]==7U#'$*8JJE*`R$NJ-HIV]W0)&)L* M63?$SS,H1*@\#JE3A01F1"KB;)&M2GB&')N%@=H8C2QM>("UBG M7=8BTP&!!%+RJ=0;";5/91%ARH'9-32HK`"H$2^S51%9:^P=@M<%I&;HVQPU M!WL"2M=^J_8HUO,DVB=-`/.OLV*F4H@-\K)?W'U7LSK+>2SG&NRAY10H91PV MCJ"3^):NDBE]@W@W%BT96"`TBK)XE:3V2SIH+,$(*^3$EQ8%[#9UK1^.LU&U MUA'6".I@!+R.P`9^$L#9S;$C'R.9:Z;,/A&)4N(^X: M#T_\":QS@JU0>RQ='UZ!Y.+@&633SN0][#H8Q'1+ M0NB;LTU;0VT\YC``KNH;/;$0H-Q]U+!%Q^X9?+CN7/'B3LO/GMD@:)<\02DQ MM+\@AK8'U<$8.>Z/@+,`QPH(CK_QGI=8BIK,,[6AT8D,H1QG.ML^C`,YO MP>CU:8)_\'^6:BQS-ZK:LG\VHWW)QA>&(0&N#R!N@S<&#PW-H;:$>=+?OY!* MZQ&8T^PC,WL/SGF6FAVO%";G)$)`9Q9$]\][RI\-Q[ST>7=S5MNKF%P*O`N6.[`0)8W7SZ= MC_G'B\OQ6](WIG0'7">JFV(LVEY8HBYA$>B3E M*$[\WWY[3RB/[I9[#R.QM]U_K]:S4!G\@Q^"1FZ(Z M2V1\7T8@T(^7+L2@K@B1%"/5H0:0BS\4#XVMXDP54@HY1M*)KQI]( MSM9\CWZ(GJOH>7G][FG_8Z1*"/E*O,2%LN*"5$?BD3/\5^JGAOG?H_T` M190G/@P@E`XAR97`$Q;8-B?1<#)D`;1.*MM+D1KX(+$@,!&I]4&:FUHT"9R MU?]JXM24ZB'T`>#0BA2;G+;H;53=6G0!)-6EY`I%?QYF;AAI6FD_6&:JS)S^ MA392.*X<)\F%KA,U5(`\:4Z+L7\=PA"_GRUNQ]CMB>+$EBB.]XI=V!U=U#AL[0T3 MY^?[CPM_DQFF*TOOC5"*K5C.]*.CS8E;IR"/6,`LIK#5/7'KY9`1=9A\A1^8 MSJ#2.VIJ(&1")=P:;DT;GCP9RU_O/X;6>+^_=,@6M_>?;T+\83H+Q]:YO5]B MJV01_P=02P,$%``"``@`&5I/'P7E:&5B`P``E`<``!H```!-15-#2$%#2"]- M04Y504PO34%.7S(X+DA43:5574_C.!1]]Z^XFJDT;0EI`V@>:*C$L-E1M9V" M**QV.LQ6)C'$FF!W;2>4(O[[7#M)4TIG7C926]<^]_B>^Y70<).Q8<8%HPIB M^7#+!35<"AWVRB,2IL'N<]PG[@D7P^G7R?G%=#3%)?Y5:/:>BSC+$P;O'JA1 M?.FG[\C?T1E`MY@CG:5J&"WW:XVW[Y[D,C\-F-`ZPT"6X_#R]QT-@DM MN%V?U)Q!PQ:\Y=EB+`X:-"Y]WT>:R?5XW"%ASVG:5K9JI,TJ-MMF6.#Q; M9&SY&W7XS!J%F[Q.XJS1.%N+7+/^1N5L+7*-KE7.MF4._XBF9Y>CBZO1^<2F ME%RE#!1>BG6@(31FV`CM8*68(5"1N(/5FQ-[76X8&.0H"XEL%!*T;G3^,'_F M)_V7?Y_%?O!"Y[R8\Q8\IDPQ:+DUU\`3)@R_XRR!1VY24GN!4>3?&Q]:=#?> M.4=?X?U2%M-Y9JR%-E(AF@N'1;4.Y:$C/$XM(%:,&D1(9:WX"I=4$\%BIC55 M3SZ92*>3&L<@2J_0T$H/^3!CXMZD-[VPQX<@[ZJ(:*-]0D[+6Z/Y:#(=75V7 MIDPIO.N19QG4:^O?7>T?G)S`5@CN$$_%DXL.+[@BE-A="6'T%M9L"IBB00A#8;JOYPC5#.#U]Q#OD!.-%;T M"56APPS0M\1F`T.EF,F5T%59<'A=#39BN&]CBOUQ7792[NV?[^7[DQ%%L[8[0)'FUN7J+6VT!'?^GZ\_N14B: MU^/Y]>59!'^.QM%QR<]BN?!C#U;5REF71C\!4$L#!!0``@`(``]:3Q_9N;H@ M-@<``)03```:````34530TA!0T@O34%.54%,+TU!3E\R-RY(5$VU6&UOVS80 M_LY?<>N,Q78=)QF&`4T<`UGF;0'2I(C;HNNR.K1%V^PD414I6W)??OON2$J6 M':CW?W/'<\NF>D"47_J="3.9_,C^%<18F*16R64@M0B4BYD2K6 MO0,GR7KSH_[#0CC)-C^]I#_\\^KZV?!BB(_XFJ*2[V4\";-``#R*N$EEWIT_ M8B\'YT"?]F(T4?$"FC30SCM@OPO_K3+3JHLF)/MUHA%/`)J!RL:A@&9[&K?\ M2\LOR.L+O1P`+@<6B?MXK"I`7OLMVBL;N^8$80]%[D/GWS!VK\N= M7Z^MJZ\EIYM;0L7#TM;OSXJ7AL#*>E4*UYSJ_SH8GM][G_]F-CUQ[)SDTX8%9*%#@F&6BB4J+&(521[JCMO1"E6CT,B;IE5Y*T\//[YY?QN(&>3D MK@3S1C8($M8H'A`L/F),G&!W)[C$URUL5YNC21(6UK!I%D\H.#8@CMM>!MTD M@4E9[BS<))57\S.Y$'5$:18MJ2+*#4B,@A_>[R_$7_)O],CMD_N!UAJ!5`"G MOU`KU)EJJJL^2\LD&3E'-@K90LD`VIVRGC'8_+CI:3Q*>,HCO:O>^1QLCW9F MN]=?)?WV!O=WV%45?'Y:RC\4D[6*^]&1&D3,T4,-D4(54[1%4A`R.H>0?211 MXMEEORCDGAT6>HTSKN5%1>6>[&/AUM)DMP>]`]FWA+54R.'T%-98[D@//!=* MJJ3"9&GLDAN'983%%AF3%GY_SP^V9D_'$E,+XRAKSXJ*5F-'*CM8.5;J7?`P MH[F:LBZ[4C89D6];VJ2NJ9HB1>D-O9[*5!OOL[/4IZK4S.Y``<^<<;CS",/A MCL(F8OJ#]'Y'@ENO_;YYA>8IV$5E\'9%3\8[HR?C_R=Z7J_UC6D9R9"G5`+4 M/30]<^Z9N3XEZLAS:H*P.-+,8#2\>#T8NAF1IAAN.65H3&&S.N&:.+<2J0*L MNR*F],:"6!TANTJ9/3[OU[+Z<*T8LTF].>L`6O`'#WC$TZ!3+]2U,E8J+;Y8 MM4IXVX5_<`J(53P,'1([^;AI+J7QNTPB$F@F`1!EH9%8CV4\JUD"8XP:"R2? MV2"Y3A'/2X7QKD:))I(./`PO%>.85A'ZY82:;N2)+2(E$;]8".`+A:#"R#8M M.T"JCS^($MC^F5!9&UV/0ZG0^X!=G(\N%CUJ\[YK?0:S$JJ#_!LPLQGS#3"Y M=*/SRM=A<0^W`.\8J1QCI#',KFL0"ZFPPE"YGZ4\F7MT)BH+`X_+-`NMJ2B, MS4@@J8#C]AT:9"+G=!S]=U`IP@>^OA2;:-^O6QN8VNS7]?2_^GTS^^N9-N>: M<9?^KKPU*1#N]H111K,IM!8!27!B842,"M`J7+@9`;K01D1$:P3'W;N@\6I% M2/MFTK:54F_T(JV=!QA='$I/Z%EO9K-:^3Y4C0U'1P)B7Z91S(*7Y,C"$5I4"T=QCR3/ZQ]ZPQI_G2"U=R MZ"R6_;-2A:9]SEUDT+R;[J>A"&9BB2JP!B?=3T='/^_O'_WX$S2/GCPY;#U0 M4_!FLZ.BK$?=J>E(D45EWFV5D.H$W@BP[S)CU\=3FW=WAP?=WEZ''GB^MT<' MQ]T=>8RQQ=?2.,2:(",-&"-4H#-IJ"6KX157;3-ICK-H+.SAAC>QP:NSI\\N M!_9.=A9CU(U(8V0%=M%+;H][5R5)3^/V0W[[870KXZE!;C?'F0&-@.&]]GBK M)<:6A.Z([=4)L]=?\!?@$W:#&82OL4JC$T:W+RLG7":$75\A0=['A.ROZ5#5U8+$4H.4IS?$;E'7?[/F$';<``J*7- M+J1-^\!NN*:I%:SMB@L*%]BEK^]R)JF*YK2VW/^%+JM!>;971SL52\Q$%\#" M7BJ7^!^O58WMH"V%G,V-K@6#%C>!UAR>X%+(X\?0LIU_-5Z>,KBZ MIL=^I\F-QF(9HI[: MG*XFRQ2U$Z%^EZX-(8>O7]R<#^"WB\N!=PCW2[J3#JS\DQ6V:?$O4$L#!!0` M`@`(``5:3Q\&B&.G!`,``)('```:````34530TA!0T@O34%.54%,+TU!3E\R M-2Y(5$V556UOVC`0_NY?<6J_``U!Y>/((E4=E9`HK4H[;7Q!)G$62\[+;).& M_/J=G03"2[:Y MX`'5/$N!IB'0,.1&\$:UK1??^I^Q0CAI'B_WES\73\_+V1*/*$KFDVN>!F(; M,KA*J):\=.,K\GUZ#^89J&*="-T+L^U&,%`.&,V@;'ZSK>X?L,4:@_:LHKAM M$,7X`RAZO8P^"75JI[:;OX;P1I;4*;7JP&W5>!M4-;<@2W+!2A-QU;);'1QV MX2;CU3[Z:A_^`WC#\9+%6=`S8T/T'['V7/UOT^7]R^SY=?:T,(TEKS$#B1B> M,@6>UG[3QSX.D?;M@)C;ZN@V9S+*9`(:C>L!(R>#E44=9>WWX-!HFGDTFO)( M0R13Z$L!E0QR00,6`D\M$-.T4/="VG7)S[/NWH:AZL1N[&ZMDK0FQ=C*SC[1 M.AW@"D]Z*]/_3:=IZ<4Z=A2*Z2-GH#/8,&(B"_2&Q<,!V/"T+FN=\8URFS0O MAS8#<1ZWL)M4B+;S=),5A\0)O/ M'0/&/00I>V]G(HLL?9KG,LLEIQKGB%?,F`22H1BZ^VA[YIT\>^\Q0U$:GV)G M8%E@K`!MTDSWNT1<$*T89#C6MLP*$KK#+K1SCJ8>]Y&RXGKKC3C2G4II M)LC,J*1$IPA!V""50/\4Z M1Z>P<]-[OH_5H`,9G"3=U.NX.!B.R_S8,U-X[50W&S+!N[/>6%U1@ M483%-ZNJ1NXLMO[@2Z>RTN%K*YQWQS!U"KQNMJ']DWMZ>[F?PL-L/OU2-X4% M6>X&#E3-R?;$KLH_4$L#!!0``@`(`/I93Q_6(^O&*4Y!,LU;7,#:LDE MKH3$EV*(6BYHL1=L86RZNR8)O[XS:V,#2M)3+2'MQYLW;][LT-.)3H4[$BJ, M>1AW0`D-,G]6P+,(PCPM=IF"?`T[KF42"M5KEQ&]^*O[;RR"6/GU]F[P>SR9 M!H,`E[B5PF6?DBQ,BTC`C0EY<>(;-O)F`&`A]Q(I[VAK>38DF8:M#4]^'ZR\ MT*US'&IX']=KFU37"8]-QH6ALHZGE(LKKD5#=@ZEK!]`Z[SN@Q_T'P?3V6`R MIM+9+!9H6Z&33"CH:>V>$K?07.T:-^GX>'V^R@^"&J1`(\6!IX5`NQEM;K>W M.JYZ0"V@>*\,TSFL1!.A3M>HP``<(^@LH'0&5`Z[/$K6B8@@42"%+F0F(N>B M@%H_N?&Q3FAT(IB$_U>1@TL"NAW/AT.;DF3HL;GUEW16`H24N30D/%%$43%L MZ_A,;+A.L#;$;:3@6DAD0RKE91&B!^@@E]2EY\^Y3$2FT1\" ML`9@UZ17_3NU%B6LN:J+1#1[X[56:,>,N/_+&TV'?C/AU91Z74:3@2N]VW<9 M@&,^UK9`A3PU0N&>#/-@]0K?G"]@M1EBX3ML*G6>?6\_4;M:7:8.RUVJ[Q!G M(XA^='@&+$^J&31_/KX/WC"8=`!,%9NW9VYS8449.9D_]GWX.1CZ'8/!IY?O MG="&8[4R6#/:["]02P,$%``"``@`\5E/'VRDPX6F`P``;`D``!H```!-15-# M2$%#2"]-04Y504PO34%.7S(S+DA439U6;6_:2!#^OK]BU$.G"W*)[FN@2$[J M2D@04"#57>ZJ:C&;>B5C^]9K8OSK.[,OM@DTBLZ*A#T[^\P\,\_.9J*E3L5T M(=OT9WK3-F"#UG6AK6[C>O](FSS`[D M_Z;[Y-H0>DVKZ7@].42*WE!XZ"?PY"&?.LS>#DJA.NJK>X6=UE/@V5,ANJV$"A2;`B,TR*+C2,JY2K@(3[$)ZM)G,TGQ^ MU`F%(%0R8G.MERR9=RSD1]3M/_+;I0T^]B:I2AC\FVSS>B(MC)Q^6H4#>$D$ M,A^L!HAI@ENR7,L\\RQV>,B4W(H=;(_,QFQQVV)?*FJ<[PL\)Q="AZO!R/5* ME%6J*7J))PECR.R4:Z'R@T2)20T)1Z_J^5G&4F0:RH+'MFN8.+-`6.>S6L'] MXWQ.YU;G.91[GJ;XALEEFF,PW26!KQG%P2U*%"FB[]CVV)Y]WUQ>8$Z%DAQ' M0"D;87HK)"[AR."EZ$,:*%VI3.R0\%KN)78_/0:^7"3UW`R5()+"B"%*\%3ZSH*S+E*1>WZ7Z*P M9N<=>Z?H`Y<@9.+%JP;'2XP!-9Y&Q\#+N3NC4K]?]CB8H[_"Q6H>=3>BF>\T MX,?N!J()/]3[8NRN@V&#WXTQV,N/[KCA[9@!C,S#KH>M6&HB]P-+"+@!AM>, M?CZ!JS3>(G6`EJLQ:]J%QJTTP=-7JA4N(B#F3Q01\'=H"*@VWEZ]Z(\`08W. M/>42"ID;BU$>]WM!E\>)+A#KUD8V\Q[WA,'"!0[M@IF=N'`;A&AT=YSYAR** M()ROES<`9F@ZD6`1O$9R#&7BE&/J3G?3>%],UOE:Q.7CPUT$7V;SZ,:YY,4H M#H`(T9MQ-3I?9R(*2C'-8"8D6AS8'^2RT$3R2*[[+$@MI`K$S&_?\-\;;?O@_ M:(0Q=XW3\'FD[MKCETI8'1S%YH: MV,A*;.,>I82Y?9PL/MQ-Y_?3VQO*E-UO!=?H"*3@8VO#,J\`R;4A?AHL1`D8 M8;P>O-PJOA3<(KJ@FE4JP-7:Z0S\%O3LD9V0WCT>;1"F#UT7015:]0*&:V$S M+<6JRZ;K4]W-PVQ&?B16EPNME2;I1DBA(TN0<^E1:?+DBGXH<^M[^?*0OP_* M9#?P+!@)\6-.6,93",J`,`JK%#>[*$G:/KQ3.RV(B57.8G2.NEAI+6+K*"22 M$!5'4BI+B)6B?"`$B7J;C7L0GD^6VBI/-E:[-+.8JBM:/A6YLU?X]\7!8)$G M"MM8I3%JJ"?T5R;PL4)&Q.N9LM-,R3[6@JK7YOLMQ-MZ#Q0\G"'AL4/&+@.(E.M@HU#V7E/ZXP M,A(VX#$1:]PBFZV-L%'W_*EQ/B@WN#BR9XI&JG^H&!6*+/'>:';ZP?>T@50* M+6KCDY.XUV`M#9!WD6JURK`6Z*61-JI]:?)/X\\1CVD:I3'RC0/2,-,?WU_/9Y/CLO=KUF]KMZ=3&([P(.FZBZ&<7]%> MW0C;[+\-1JQBUNA#6<['&XB]W(6SUV;#AR,FR_\RA$D#&F*+$K MHI.^\3B:8@)57"',S;!UZ$Z'YU.0(VC)><0`_T-".4=#R@+Z790[2XUGQKIY MD3?=,$`UX_5#A)RVCB^#H%U1#0.DPA\N_A2]?;C[,.&?IK/)9=[1*NW&CGEW MWK`_4$L#!!0``@`(`-Q93Q\0GWR\J0(``/D'```:````34530TA!0T@O34%. M54%,+TU!3E\R,2Y(5$VM55UOFS`4??>ON.KRT#!*U#XV%`EUF10I_5!#JPU- MJ5QPAC7`$3:,\.MW[;@A_5";5?4+<'U\?.[QY=I77.4LN&`RR6B2G4)!5<7; MHZ.&)4I44-2YXJN<)U1Q4?JC#=S/CH-W@(@@_?!7P?SGY=7U?#K'5_RL6$"^ M\#+)ZY3!P8;+RP[(W>0<]'"*YK[(U>%%&($3NJ#C3FN?HE;#'MD4^R(WG#1- M#\UD^#'K^#'M MN.?KT=:B/=&]3?$VIWB;5/Q&5I"(8I6S5N?UAI!/I-YZ%GR;S,]OIM?1].I2 MEQB),@858GC))/A*!=:R(1:Q"H"6J8E::VQT*:H"!F$[T/-D$"ZB]NRP743A M@]$Y,X@\`O#2DN*WA\UZJZ%Z7T;VCPS$Z'-3A M?(Z._I!?-61G0FLA@^;^&+Z"A+"Y/S&JH`\M(C#175UN+TR2CSCTBK3N(]J< MCTN;+I\$@$NXO)W-`-N=$@)D0?,9:52*M$^7JCQ(XLDJ"_+QC MJ89J2"*J"K6`#GJF4.6.!:F`4BCX*ZH_X/,`:257]:^1/^+!&-=33>D^%5;4 M4L$#(RE?+EG%2J6WTHAV:].^OX`QA]AD$HK*Q/+_"F9?;JICD4K!#5&F^H)-,XSUPKDQ_AQ?5LTM\JNH?H7A..'YNT;G0. MGKKN&&-RPY`*@.:KC(ZQTWAF$)R#,[`&A6[KWNFC'HX1.G)@,QMZ+3@C8OW2 M(-V#QCM-JHW=Z<3^#[ M=#8YW1P956+E)2YT]LT8;KHC^0=02P,$%``"``@`TUE/']ZROXN+`@``Z`4` M`!H```!-15-#2$%#2"]-04Y504PO34%.7S(P+DA437U444^C0!!^OOT5$\\' MO51,?:R5A/.HUT2M$4WN#+D&82EK8+'+TBJE__UF=XM"J_($WWP[W\XW,PPE MDRFUKV@1)D&8#"`+I&`OP'.1%<-C$QTF?;N+(T`VS_#9]OY>3VZ\L8>O^"FH M3;XS'J9E1&'/G+.2/7)+@Q0`LJG*T3^X,QY]$8I$_OH6&QUIF M6ZS:4:L:N8>MK%5+\+.8EGS8T;1_N=[Y[?CF;CRY5B63NX06%$1>2L9I`6&> M/9>2=JRT%.F=,I32;FYVB#9+&P(>:;C:PIML,NED)'FLZ8YA,=XF](^.%.>4 MM(1TI2TMG]-EBI=I:;8IN[)$Z\)7NOL^9I"O^XU\6Z/MZ<MI_\S/@I?IDU^4V((ZF*[8T[KN^?-Y&40-R3AKF$PS MG]Z9?L-:C=9G?C$77KEX6 ML[-JJ0#7"D<4+/V09\&XC`_VZMJIT10X@RT('=@%1PK:K*;^%[DN.)?>9``( M8[<6G6WJP3O6FG8#5Q]QJQVR*>GG_877+#]L#6C+H0(-?H5\046,TP`L_F*P MU"BIMT#```7"```&0```$U%4T-(04-( M+TU!3E5!3"]-04Y?,BY(5$VE55%OVS80?M>O.&0O29$HV&MJ&$@Z;S#0Q863 M8"M0H*"ID\6%(C62BF,4_>_]CI)<-TBQAQF!0QU/=]]]]]UYEDRR//^3HVZ4 M;JYHUZA$R5/ER3OB$'R870Y.L^;7^:O7L!?XS+KYW[Y1V.>`P\+WXQ M3MN^8B(Z:54*YKEL3HK%>KWX>WE_>O96CM778S!C M%?^-1FU\^#]PKN5]X[9D'#TX\TQQ'Q.W$<[*"4"T2&54V@<>\-3&YB!5WW9< MD231RM&&D4_9?12@-?+QLVH[R^>TV=-IW+<;;XT^0\&;?KOE$,OBAAOU9'P? M1`#.NXL?("!%[T"/<8)T8N=[7U]CAU!X8)>HLTIGE)%1P0]44^#4!U=T'B20 MJ5'!R!#<@S)QB.7[;8-_.;Y41ZVO3&U0,>J1<)D5E70S0BE:I8,OB_OQ[B52 M@3G%ZGJ@2CG,AK?&.>F!!Q1J%5HQM3?Z(K=`>Y>"MZ3L3NWC6$"4X9$(,:F0 MRF+EF'`M8?J8>YJD(A1?>VO]+EZ-F-YZ(L(S))9S3'*3I-GX]!GVT3J\>//P1UZKQ5\"5F0) MYH`D,H%+T,+@3BO4V_8Q91CJD65$\\(&E>+=`E0T%1?#_%'=.RW=QKN]LU@V MPT#B4GB>;LFT+5<&1:%]@2\PG]DQ%S"*:BA@`\UP(%4G?$^ACO),8U`.'=J9 M`1;]+-#.H-#`.+*L2T7#`O!N&B+]6.P:HYO!$U7[)X0-)B74CJ&/_2;RO[VL METDN4FYF^@!*0,;R2*M0TL9FLJ1SLG&&A,*B'W8:./BG[5XVSGJW_6X>]HIW M8$VDKM"HO-WS-A\S")'A(*N#S(<9]'6A_<74WW)L_BN+ZAP(:QE@)NM]-\@[ M_Z00^-@3JVCL?I3@ZF'];D&_+]\OKG*LZ7I47, MX*3D]I(3$@:3"P!G$3^4B=IVP0E<*!^N;F<=,@YF@*"LQIAW`['W/42FY4.6 MZGU$^!92R^P(LM>UJ@^U;QKQ=Y;,V60/567:=S7=7<.S16749CS`A&^#:78< M7"DTU;X83/LWP^O9\&IB"DYF"0,I"LUS!CVM_:;`'6RR]B$2V;+03(%&Y+;) M(![MP@([S.+*/<00!&68Z3S&E6&2*30!\-RF0$D6XY%0Z`2H+#.;/I:Q2LLB MT@5&>:\%9@?Z&M_95)4;#Y0H+60)(.]I>9VG[E6=B/ZNI/@17W2'LBC/"$ZH/JVPI&F-$TAJ8KNMX&=6R5#K9G M=M<*6H8[9CF2QO@Z=UIO]:X^=E5)'X7,RB(LI8BQYQ@9SF9W;^B7G".,;)ZECN^B:BN27>XVU< M9#QDA"%WQM#$I2,0N\;!K;2Q7*$PXPKY*Y-]:4QFO6SML[OJD>]BQ9Z9=&$M M"JM`:9ZFAJDQ:EAAR:60Z+/4"J0+\=R(=]&^>Z?"E&!R.QH!AF@A0&4V4)BC MJ"E6I3E0KN'+@6L3@TM\@[M`9'F`I618!K/HVCUP5<)Q/.#@R5GLV6DY^!&, MKT<#.RG+^5[]%G#0FAGK],\(@&!TR?80 M!&[H]BV@O&J8%U;`VGCO`>B^N=NV5UQL2$/^],[87-H27+^TBP3*>MV?F\'D/.EZ"2:1V`UQ#(1O8[7["WV^F_KX"'S3R_K3_X^'W^;C";X MBO\:T6>_2C5/BDA`+>4VX;/VHL;0&=#33&_(5_W/T>D0FG'6`LS(0+.I>"H: M536*6U&CD^:@5/?:WX='7GOY4IM.FJM-[4@7LT2@>O12.YQ$F_J]CD/S-J:K MD&WS_GU05;T7D:]>@W45<#7OMW!=O09LKM,L$2N`>Z<.U3S"T?T;T/K'P\G1 MQ>C;=#0^IP:RZ4+D`HPNK%0B!R.P[UQ%<&>D%8$VU].S:R#`'1>..)&WT5+F M(!3'2I)=7B0V)\K,!%C#59YI8T6$_]H[(53)0/)=TI)\/,6&GK7]4-<&TM+V M7<@\\V#E8SM@N/`"0E+0MC!)( M`\J*/%*U?&P\SH4E/)F6RC)\(5,*$)71EMQ(@@]D!CIV&CYBFQUJNZ@(GH*] M$FM!6?,DT7-.%4M%JLT:>`Y*B$A$;390(%:<.EM&*?*GU[)^F*&[M4_%HB`# M'X%B99UV4EL;KLF4U[+?_W2YJUV&#:Z*G6JIE:HP&_',#YY>DI--@#(Z8/Z-M7?P)*JV]UJJ%/MAC M>=$<]SRAW84.A"Y;1;*\2HY*JP+1B*.=W&+.*:MP'=[A^JNL1!YOD*W]G-OR M@]P\7:!"EP]R0\9RY?5W^I%,G?33P^.UE:G(]SZ5:.NR+=K73AT'5E*DBOE8 MC?\27O0!O+`$L%]SF4NM0!7I3'B\48F7O<`+_T,OMGW`'.L8";Q*1%C(BQGN M:+CCZQPP3TK)KC,W`%(+W211#A@"IQ(:_BGR"U.),R'1Y%4/[%E29@VVR["^->*`K/3Z<)^[NK_3]*Z,W.ELG9>#J^&)\.*B:_[^_OK]XQ M^3[X<7.\&05%&.-F/_9Z5EC< M&=CQTI-SLMEL;"=GM[>)M,B?'4Q$^QQ-"[Y2ULC09(OQ& M,')&^W*&,]?G-1E?7AP-@;;2UT`_]VTV;\%]^>I2=,G_"U!+`P04``(`"`"L M64\?...L-2L(``!X%0``&@```$U%4T-(04-(+TU!3E5!3"]-04Y?,33Q29;H,`"+BW1-AN)5$G* MCEOT?OL]0U)OMA/40!#+FC?.RS,SG#GI2G']0=A\P_/-6_;@N),YVVGS9&N> M"Y9KY8PNF=&-DTK8V45@F6VFUW^#&%1)]YG5UP^_W-U_?+A]P%<\&G&=_$.J MO&P*P;ZJN#/R.=M\E4CE&/LP_[!X>+QY7'R:_WBVU;)@YUMN4D8OW;X6DT!6 MB6IA8?W[P]55=P\>37TY?#ER@@Q>.DE=B^+IJK/?KA]/V?GJ_J0TV[T+LB>)+,+ M[UBX^/OYP[M/MQ\?;^_OR.')?5D(P[;"6*F597K%VLBSLVTVS:9+QE7!P+Z5 MNK$3MN$%X_!()2G46L$ES&VX2Z1C.VZ9L%8H)WE9[IFL:FVM7):".=VE@ML( MUEA!NNQANG!C^-XF>%VPG70;"._L634J)XTV2QXWTK*<*U8*F`/9M='04EFV MVPA#VC2K&O#`&]K`$,L@G%!6;D4GF93"YJ5W M`^.E$T;!>%#P&C1D(&G1K!`XN\ZY$\-S.7]L`5?J52+@[WUWGA1&2[#3>9:" M_=Y(L(KG.AJP%#F/[B(13E8B'L;I9*",PD0$IO^)'N.!$*B@M;%\+;*$3@.A MG4_IG%N)FN.(XIZ4<V8)"&XCS-9X+FR;"Y<$P9I$Y)3B]+?`IG=]M7O-OB"#2A;=0 MD\R!##EKBE&G"(-$3O[-@(.H^+$)QG7Y'1RQ=C%.?OUUS5D MUFSZYLWX#%'K^45"J7/&)/N.?7N%?S.F\.^;;]C$X\3`"D@DD;T,``W0!4E; MD&%#51`[AH'6GH$'AO2]3'#&BB=GYJ!FY(SQZ0CT@D^L<-8'+F^,0?$.)`7I M(%T*$\LN/*"\$)XEY0MJ7/I"H*)9$]W'D$LA'WUYU$:.`Q:.;0*$M,T!#O70 M4$#4Z?`AM00K(K5$F3=V`?>5\4O;&PC)RH6R.2H8N[(D;+D!SU%HY"POKC9"]$ MU>=(']4^2PBNRA>QMJ4BIQ]YA!1`I)>8>NMX:5&/ZC!GD@/.+'G0:8OZ4C5] M/"@.1[9TYTV35S(U92BS+TKL2@3H!)W8+099O=%-622AU($K/PE1>SC;Z6"B M[W:#+'G9*':FE:#V,$S*J,;[!`%"9'T#Z2@N(\6D!?:"A+P"/B]CR)\>18[` MZ0A;3I!=#LDN(]E?!\!RZ6')0XM6;PAU41SM(=[8,;(<@%GX@/4)_FVM.6** M<)0D/^C0(VIT#E3^S@`Z$)0.`2+8'V9I&DN'JH$GL5@H?`V%A^:/#I"">RF= M5[%UC>`%"I8!9+)DUI3D_UDIKP]PI`]]*Y;B&C(DQ+W6!'?&6]R.*-[3!7>< MA:;7&(&YH5>P[Z1))6E&DH1UP2*:#-NFV.(439JHX[SD`2C'LKPONN)M+/F1 M>SNS#/.KE7^(-DFC!U[C7PKDWZA*A]3M<3O'$(C5W$;[2>EH.&_K==DX[Y23 M1=O-V(-2>HW`2S("`Y()L\U,7O.BP%'MEXO9!2R-,U)K;/!L,!/1OJ!P$W:2 M$O)MC"2\6Q'L$_L+)XEH$AI>Q7.CHRZJVLIS/?[R<;Y`503Z.(=NJ$6'D(07 MZ-,R`*>"TFZHHT"'G+S!H/;,:?RAEQ(H2_5P@!D_S]^Q\UAKSRG;`Q@;-PD_ MX_DV3:WX M4QJ9(LZ,?->2>-=`^^2$Y&J[J$I'<)*ED3Z..7'HW?4H0[$Q#R=%4*A8J_ MRY22_NOGN]1?"URUB8EC$,AM>4E'QY9W0K#//1+3R>QN,JY.4EZ>I#S>?`8L M=R=9HI%WVB^8Y8PD)1D<3106OVS M6_@/.BEP3C<^9H0,KU8C^B?FSM_BK1>H1&S?UL>6I>9E;W:P5/_,5,:WH_)_4Y[T-VE/@ABPNQXDWI MPNT.R?O7M__QJTYXHEL56R'3J?Q&>UV%%LS7@%T)4,,+P<,J,W9G@DKW*\&& MJW5HCD&39^L&]1OG1%4[/UFU%M*UQ'@D#`VG(XACI_70*[6G_' MU+C__.G=G-%-W=M6"RG)@JD^!_X/4$L#!!0``@`(`*%93Q\/H454Y@L``!LC M```:````34530TA!0T@O34%.54%,+TU!3E\Q-BY(5$V=6GMSTT@2__OT*>:R M5,7..<8)>]P2YZ@*8-A4Y55.6`IVM[RR-+9GD26O1DHP%/O9KQ\SHY%DYP*I M`J)1]TQW3_>O'^*X4$4BGY]+'2W":'$DXG4:+E4DEG*9Y6NATEF6+\-"9>GQ M8Z8-CA<'S^\C@]>!_W.\>G[]_N+RZOKT&GZ%QQPV^4&E45+&4NP`6ZX^]1<[ MP6VF8MQQ@MMUNH%*"^&>)UG:P84B+^4DRR>S,-&R2:,TDN$^W?INDYE*9.?U MZ=E([,U6/8%LB=+%)"V7'FE<+E<37-]*FF3IO-IUNBZD%BS7>B61I,E0%Q"6 M;L/\80QA4<"5L#@^"3.DR*][`NXM%WMP&U+_^GLO$)M^D+ZS-\LETG0[W9XX M'YU/3L;CD_=T=1-=+N%%=322M@_VE='TVL@HX\X6@Y*!-JB;)?%$J\_2Z"+O MZ*G)6(GP$.[-RF\1;.M%Q&HV,V];Y-OD\7CNN8%*BN/'%`,8&:]&UR_'IU;HQ<=%\?R7T4N(\^)Y3^#3BY.+ M5_P8X./YR8WW\FHT/O<>3^NLIS>CL?=X?>68`WX>7[[SWG^PW"),8UZQ#-T^ M&D5$H`J]\`'A9OQVU!TRHY8%V$O,DG`N[A8*-52YC&"1+,.&`',%>$(LJP4Z M$BR@/BN(;6=ZL+4NLEQN-K4U<+$("Z'`>K'L5L9V.\KX'NE?GYQ=._'A$E(6 ME33(9K,^>8,5J,[-0-=EUEQ6S+H(BU(#.SVQD(&O`>Z..V=B+@NPUURF,@\3 ML5+D!Y83]Y'U;3QGFJZ='P5-/VJK2M@+4.H"@,7F2UKE$!MX<8!!RQ"$-6:` MI@6$FTICA0IK(RO2D4WH3#@`9!KB7\%GF6=..$L&-DSC,(\;,4?O+X<0SP#R(F.LPK9`6CI%P&O M/;PT9_<%9]C:$J"L"J>)U(834>K[.!'"OH\3X*IB?';8YCQH<@K#>5IC_98S M$5*_CY/0]CLY_7OY%LX/GIZ'@Q^_P4(?:J[PT#,S\,0CSX,.GSUM_BZ/[ MD^&0(A$/L9%8,;F4R!G3Y<.^$!:W'%KT^WV7#*K206?B+LL_DB*XKPJ3P(0L MY0+M*]'O(B)ANC.LQ8;<4]7'#0S/;E6,9PJ`:AFP,D6%;SU#"'OK4A5TVRA5 M+*?E?(YV6Y7Y*M.(BYB:'E;DB(U%3C;]D[(^O`\#4CLJ$ZB1T;=Z"-9UTW&% M:M1AF&NG!$!<0,TBJW`^W(#N5?+!F@7H%,+L`Z7.P7T@_1DHUB2I@5&RXJRS M\X+\&.P"GK%[+?XK;*W94.;F_=5H`C20.+I#Z^!;2PE3";,%`K^6@#=3F6_, MK1@G82X;2DBT`MJY'[S5\AX["F?'^ZP(OC#"%?>*X&$1:LPUH=99I.AH6J9, M2$>2^A`1OH>B4P=ZB8$+MI1SF7,"_N,/Y+#$N[M(B*J[Z\#&RI9![$&ZA/U` MAEJY7*N/A2PBW)YAI(KNHBH-VG*2_-IF3GI7X>``_CS>X]P=0WY&=;%K%GN/ MF;3*@0<>Z131I4%9Y;Q#IES)?%D6'&26J,+N)]YVIDJP1%4F^Y&)C&5;="YO M_=O006W%Y[F[=L15JGKJG6P0U:B20TM4T5LK_6]`,&:E2E&20RW#B!7*@VM,J40"&+,%$T0-YT,)9P^#4^JM%1O MF\BC(0K*3RI1Z*AXVA"\75(EUB#NL$$"L%R7`=YU*II2`Z%E(SE9+J-PMXWT0KN@@7#6U17JERT MSZ@?8",R;^RRI6WRIRD&[2,PU%1R8P&8%,8QSA(H1K4K\P/N(SQ\XG(`P6N: M85&P;`8;F>;C6PJ4> MG,U(T=CDFKM<"YE+8%GJ1E8EQ M]*D,C!F78&MH3^?@T+:;)[_L;SBK7B"8TRA-FB-M>$*!F19JMN:3@WHO;N0P MT=Q_*`+XU0Z5)%D:0'Z/I-;0Y]JT#:[#\?RHLW_0?204Z61*9?0P:,957.G5 M#T[8TJ/)Y2^C\;LQ9$!3&.0Y7-R=@C($1,U#A;HI,W%9R4C-E(S;9@FHYDD@ MM<5K8`009BVQR"3XJ6$/UZ?IFL#,W%9]!-9KS;^"]OS+M#]:&A.OL]*:V2^B MO4%MUTWP@M_@[`2VL53^_-20X952;#H`V=3.,-K:H5``$)S.<237<$J.)Q\K:-U7A6G5U1R)1_\Z>,3>:YP3_#%D^2Q5C[+'HWU# M:-(($SJB>KK4=5M[;MI0TKV!T/ZSU&:Z!A4`EE\TUFRZ]4;GW[)KS=N"+8UF M;8[X?WJC!V)<'1H!X;#DX)YT"F5)FJ+QH"@(L8V?PZ4"G2D+(,RA*%(($MBV M\=PR^+F"/ODI1(3$&UW0=PI87JKYHO#K*OFID*FGA!DE0JD0,+*@OFD6H]/* M>(XQ"N0@R6KA^B%(A"-S5L5>`=R1N+A\->J)T:LW(^)^,SZY^AGSX@^<_,3Y M^\G9Z?6-.'`K5.HC&[17]47:I4G).QX&IGSCSV[+]<1\>8-N_(L0.[C?3D_L MX!;X+W'M"/%U:!DIOW>0TWZ/(]:4'L$`YM]Y3K]XC-4G.^`MP&/TKT]^'YK& M2^%P1QF#HQ-I5#Y80HQW`$V[P1E;5 MGI6\9\7H#MM[A^"EX#(T?O+W;LVVS0%=5H22NC_OQ\K&EC/.$]()?KK8WS=? M,-!U&A.*8>TK'%TR57F(X@:$!K@WO=FC_7PSL5?LI<.`'E.XH8O1NPXN&V4A M9W=P'5Z\/3L377,>Y?<.=.ZC\]X.;;O3I2H.6HW=PJ&>5=$SC(SOG_KT3?;%VS?T/Q6"<\\3.=US[YFLO7[/^_)'^W'!TN%*&]== MVL2EJ+V4R_::GN8?+8#C-*D;($@NH`"$`H(25)H59NS,E7TU8]3U!,MBFGS! MSD\4;M!(_0"4O'30;R(J<^S]$G]"">Z+YTVQM@0+!&0,[*;LI`+_C\=H)$[. MKB]Q"&_:00PK7ZMZA^C6^$MILV\O/UYI'T MQ"J;R^115B+C(KN%@ENCWH%OM\HJ70(OMU#4N57[7`E.ILG8^TRRWY)KT`AC MS3/9)ZN_GY;/J_D*7W%I9,)^4J7(ZZV$+SYW)LA;D_>M2=R%4N(KH=3+5=#0C]#%/I?OU-#`K=]2\OML-7V9/Z_GRR<: M$UMG$G9U*6B@%4RL37Q+-Z@%FT3.MDIE2LS1P1JFS+?*=H6(`ZRRW%H@]"&R.%!3)&<,R4R!#%G*.1MC:EW,9L MB6MS5)7L!NM7W(+[=$:!3QKF@,_6A*ULK.'"=DA][W0".Z.+0:/_*TY7JE`Y M-_FIH9/T'KAK#B3Y747"I2+9#]A+OR$C$:C/2"0./P@,A/"F`R1OR`%#/V$D MMTA1P\90+T;75I6AZJK;7Y!+SP9\HP]RJ(`*D[/`QDF5WX;$!C(V)S]IP9%1 MGR^T5P[5A^?&AYI0.B7(TIHP@^;;U=+J%&DS!.J]-.X."10.@W94E?&#O*`U M]L3Y\07:/V+V*5[W\F&')]@@?=+LM"DPQ40E6&2E;#T9JX3P'!6!>_>D:X>N M4::.0KB_AY:5R]%='IR]?=X(L3_-)H([.;$-9:`YRX6N2RO-GAMD3O`2CMK\ MVZGWGS%5?(=>H>)6KJR4V%JI+?6Z5;N=-#@^HE,JVGM=36C3V1\Q^U,?Y4&: M3S9;T\"Y9STJ'+?AM)FY'^3LZ_QI-5^_^DJD,22.73%S-YN_OYN+$N]#ND%' MTSOV(M$=@.?[C-\Q@-@];`KWX$>81@_1(^GZY@Y@/`+ZDO[R`*,Q\Q,EP)0^ M-D\#^M6!PH1=@BC]0`:0,\>ICT:X[T:+7;1P=[L_6+,9I(O5\A;`[='#I>(. M%\='=6DZ]QR9'^JGL-;D"5XM7U^F,_ACOIC=^H3Z_XM1^Z`^AT'[MLDB4TBX:4-2TTR8A#9-BSU6"#];KHC&#F+GDOX.$7,) M"`L4T="*Z#'502?:Y5CXP9@$0>`T28:L.>EE9`J M9W31YB';:9BW-1J1DP@CQ>7."KL%@K.NF M=:'D/O^.\N^T;-?`50%C.GWA"J::JR@HMN6RQ;X'(NA;(@W`.DKGIH!2:L)3 M&VBT4`[QN>]5RMW_;U,5#U#H=BTQ0`Q@W3K2*ZA/G3D" MZG3K1"/":P2RG=I@X=59=QP">D_"A`@-:P.OD"-VFB$&3G2]<6C\*%Z7B,Y8 M&-EHGJ4P!E$W$FM4O8B#C@$]%IVO[`Z2Z3+0]55OKJ??R6CIE)SXFLWM]/'? M.)G$:.C\5_B&?58GBW*!6WO<2U+D0I.J)A MJKHU.=*NH,(M>I=O:;2,DKG2E&`.?PDB:/-V^HW1.5KK`R0H89=H2.FNX^S^ MZ6$\@=MT.KD*I/8+505:@3C[`U!+`P04``(`"`""64\?S;2&FLH&``#T$``` M&@```$U%4T-(04-(+TU!3E5!3"]-04Y?,3,N2%1-G5C;LP!(4?)EVNJ)!!:[ MB[-G+]2^53:5@R-IXIF(9Z_XJ33J6N57/!%6<&/+*K95*\Y[DV1< MD@79<0N]8<3X]D_EEN=R,4XG4?-:W,+>%]+)2KKLJ/A M.13VLB#&.[0`HXU4MJ'V9'1Z!/%B6:MU"WA?2]%RESGSO#=O]#KSRRWK]-+V ME4N5%7N4QJN7L0<#]_I=[R1=0\[D6\W^]'_/C3X6&C/FMKYYOJ<;V- M]_PA8PZ7WA"VPM.]IAI@[KD)+3^DW<.(X]#?/-]K8?[(91[!:@W5O4CM[SI> M;K/S>DW/"\>4WG4-9N?B<:9<>`)>-P2\>(P!U]G#N/WK$%VL8W3Q6)"N_Q_= M+M887CP&(J7\^]'9N].#D_.#C\>4]6R$\L+UE-N9-)*7NK(JEX8;:0VM\8XH M"E'*W':Y2Q>(;I87;C6?2*82R*A8I/1N9\)R/;%"D?>3%:\,U:5]:P?]_OA* MV@[="`YV4;^PQLYGE3='(NX*;H.7$B:"CDN<2:&01)K8+:,Z8/[`3!A&`LN= M`1;]FOR[\F[11A!O['J3+BCWF)Q-59I>3DHI?I!80[%AY./O*>4/*L,%JTUX M`T]O;B^MRJ2YN7U:[^1>.O"7.1>F.DWU@B`JJQ3HSW2:8+'D(DU#<+B8Z#DD MJSRV2N>&RV4L"\M(BE2O"U^-Z1\SF/[[W-"#F7*RQ'/(WO!63O>BEOWS$8"1? MB^T,,OGUQ;>OOWQK=&_Q%4"D7N^V<)_]KA>$8W17WZ]K??X6[+<'PN%1=<&E M.QN=`0TD2:*F4TGIA:#$HC*2%;+,*BM\D!/-VJCQ!;$V%]!7E M1-E2E"NN(>+W^^P@-U:*)")KW#8.O[" M,'!M\K@=KL8FP!\BBV+G$HGC]/J=6!/K8D4Y=K>$U72D.\XU[I@P@%9H8]0D M10WTN1:1;8H<9NIKM+-Q5,E'^>/Z<3Y5, MR9\\5,B%LC/HDE2+-UU[[1*\51D]-'42'#0K6S,?5]8%@;P3RZ;B16PQ4S`2 M3/N:*W`$P(I,5^`AT,EDID$F5\514$%-!"Z`"6\[6"88&*5FEWL'86S3A5#4 M;RXG4UXVDZF&:\3HI`Z.#-9N?V+G.KB2KOBTE))71=A$GT5STKFL:T[H)"15 M)UC3NCQ>+(C\=CH:U2*9B$N-S&!?=,7-3%<(@D\O6-2>^W.15KZV-66NL@:4 M\%"%9ECW0JHS=Z"?5,`^;\X`?Y5560M`J!".(\:52B"I% MJ2QX%G%I"ADKA\MDU5QNBW4U`*&EA.NWQXEMH,(`+-R0L`-Z9BHG_UBJC.-! MH3&72`QSX#TT*(%D,%&[*1F!;+"K0OI62JV`=#:]@42;DY0NM.C4B]`)2$.? MO8,@^!'&O"V_OV;1MSQZAO'F&>8:&FN>+8^CC!K^YHM]S9W]IH=3H,3?FQYO"ERW(@$HYUC;:7/DN_?"6_:=Q@CQ56> M*(JV:0MD4;V=H298"K1[8,1"Q!]JC2LLB2PD%%"QRCG:)K5P?I=KL#+7Z1R4 M<<-'Z)#0"GW]K@M)4\L=L;?RYS%V*%\<\BJ;P#:H[B>%FC9)WW]"COX<'IT< MCMPLZ4'?[5&C$"F8`SJIN9L0%[K\80H1$^%+L3*\MXLP]WFV&M5YT6/1D?CL_/A^?AT]`&[YU]. M1F.H[-ZC:#ZF[M!Q,_-R6^"V&:#IQF\_?7`?S"R$OQ[-8IUE"-ZK_UCRZDK7 MJL2A_JX+Q@KU:H%)%`F&-\!)Y?#1(L=;76.K4-9X-MFET5492\S+\L;[WX\C?KU^G"137$^7_?CFLLPN M70N[!3N`>S^^!;3_`%!+`P04``(`"`!W64\?9_%A1QL"``#H`P``&@```$U% M4T-(04-(+TU!3E5!3"]-04Y?,3(N2%1-?5-A:]LP$/VN7W%T7YHL%GLJ$-P/#=PH5U3HE+@P`ZIJ2JR0S$K8D4_U MQK8E%@))5A[-7HN=*LO7K4'^G5W'SB6#H1%USB4CX+4$TNL,%YX`9XSW,&`B MEM6`-`?0.W`%6@1#%E2-=@(>3I>`!&7!H%4G4N8T;'$@@-#&D#KP3TSM0#F0 M&BW4VD'!#QA`EE<(4I$SZX5P"[V46?_?7FB?N`F)R/>)"DKDQ@5IESVR5%WP MEJ12+;IA?5"6[[VP@KM0K^*JAJ8UC;;(?"-;J^K]7^TD,GDI="GI26)'L@E+ M*8,T0$MS('O55M67R>;$8_69\(,:) M.#1W>?S%E9XZ#-?33L2XV,,\3>%^D:]N`=C+GQ]1:/YA0[J&O;B8R*:?^O#0 M.\]7SX_S%#YGB_1V@*'0320")C2$_0102P,$%``"``@`;5E/'W6;ISL^`P`` M`P<``!H```!-15-#2$%#2"]-04Y504PO34%.7S$Q+DA4375476_;.!!\YZ]8 MM`%:%X*;>TU<`[E4.?C@VD&<]",(JM`2(_%`DP)%U;:*^^^W7$J*K>0,V!:Y MY,[LSHXF3CHEIE]$E18\+HF'T-X4OPQ'01PA_G/I)RN?BR6 MUZO9"A]Q:<64O94Z574FX,V&.RMWX^(-RTR]5@(0(/%)WG^-+^'#+@+ZWX_8 MY"-='29HGC.D9E,JL8.F2W'?Y;A_D63Z.5Y=WLRN;V?+A>?%;@MQ7!N<['[> M[N$3/%3U)I&PP^\^D2=@GF#BW'2'Q;LI<)W1 MCGH%D_^5,&K/AO_4Z']Z4;>%3`OJ;.T$$3PB5H',M;%2YQ1[DK9R09_34*_0 M.$BB&K,K[(,_TE9"AY)!)WWG*(WB.1WP5/J^^8W[Y'*Y^#L(];[M[.W-74P[ M(W\Y=+&%1;*T/)#CET@=7O1]]]GKG#M4%D5G)S0;O^5#CD6>_GL\(P=C<,X, MYK1;B?*U4K_"<['LF4+'].IBOCJD.H1\#6U,;H^_7WRYGL=DJC`!7CG2\,/^ MG`4=&[]J<'DCN$+JF7$)KGH'^YW$QP'&]&'M&?1%)\0NVH_.61,"C8_T&F'Z MQ@?;R:"74!P#UK0\`V`D:"++)&G5C(+&*/+S'CG;D5=M/PLX'93MS[N_5OUK M@Z=IO:D5=Q*-@?W0QD%><\NU$RB8,[`6D!GM!Q(X%#(O:"Q%*BN\PES!-1'P MS6CY<.4*4^=%&$1J,+A]*3K5@JLZ4YMG/-AXNI32H=78M`_$)[(=.0CENL?2.<3,.,KI9W-Y](X6V2G&Q. M+_\VGKRYO+C$1WPU6/AU7J9%E2DAQ,%:.I-_'JX.DKQT>,"J>O09GV9EM1X( M&&3$O455IK-2KE4_2M[,(-(+;_-"#41G&7TI\E+QMT2T?\*:DO5%2>M(,FJW MRI'ZV:*02S:G5+?\I=\8.N-%TCDXK-=6TE)9J/+.YAT;[I&:C3-^!3EO1__" M*-7;9R))Y+9MA,KV"H:8].(6O^'6D_L<'<3IQ>CR^?3BS=7%9$Q12ZY6N17X M[W:E3!-M?"2'+%4&XX5;*6&WUJGU$/)*I+(HQ'MXC6)PXMRICVP,3[,O\LF= MDG8H6W4QI@>U MZL&#^E!\`C8IT\J*4CMAE*M,.4R2=R%E^42^VNV6PC+PQV M)K]I9ZUCCZ%'>PSU]EGQLS)ZF#0^=9I-"^J#'1N#X%JA*W:?LE8N592T+H,D MRR$ALCR5#F="P"2$2Q].L9)8G::5,2H;^$KF8",H_HQDK,MU*7*7=`4I\I1R M0B^"LF``!4U4P(?>`XHOR65J(:O"]8?).>349[G><.$ZD>JJR$2A]2 M!"\>.&7=T3`]&'`QBT>/GPB;_PS=V$W//ZH4Q\YT^:U#UCC8F9=WRZVV?-&K MW>S/%+Q!AG:<<0MGM%*;P$5\^$"^#-:P,[_]5DB7D%7_?O1XT&SC)1=1QON1 MRR/:[6YU;7OO!K^HGF"X\\&WJB]NO?-3O=X@7/-"(04F94J*N%06VN"\'`_K MHP];$7[4M2Z=T04_EY:2&5&@[?%_(K/,(#C"RINF;.?58J$,9Q<>DO&0<=(X MGUNH!0ZQ1(BA4*:/*7#'L;.G@D./O9L,HV/$UXX M3"X6N]M2XA,XLW(_56UV)V]RNR-),"ZO7"O'` M@3;0EZ=5`4C-%RC!5!DG\YA/7"]VX%5#1^*3/;9!B&O\6ABY7).S$$SOUC54 MQ)/9BH#&5]%"%X6^Q;ZQ2K!G3_1(RU,?BEXX8[\OOGHJ'HA^\@N7!0OR;D_% M:/9Z]%KTQ?U[*-BU-EMO[0#)L17W[M=EA/=[#]H2^44@2D/QA1^HPJKZ#3FO M]Z!_G'Q)ZN>TH?R$>JBX,*2K,:C,"B0B0_3':KV)6W2:\>A\]N?KUV^@,M0R M)UP$()RZS*3)@DK@[5P9;E[+',F(,,-ST6VCV?7X+^/)NW$P]@&95I6?2GT; M0]>K2J1DUB=31K/+B[^/+FM@.2+Q=HV&"F?19Y/K\8M:]J$7S=1GQF@8.M<5 MM366I3@T/W]H1:27J3[J3*>^UKU-P93QRV;-'SE*"!!'QI,J+_=F4]1MMZ47W0^F;X^NXJ+_A3/"]S-UDZ=!^?CZU:O&\A](FA]Y1(R@Y0_YU^NSZ2B*/KYC MO/U719V7):=GXY>UX!$',N@+_C:R7*IH[N7%U?7#(,M1U&6QA;V'\$9%!XRZ M>;DOLY\*2H/[Y9/RV MD>60,H2:I2+D3PTMX$8F\Z)VT=79M/;]T??1]US]5+`WLJA43)F7X[/H^B.. MZJ+0G@VHSZG:L/GAI+`[EL71HX@!!$W*E+)H9^)H6/&KIUW#E+3DQI@;DVQ@2.ED#-0%Z#5*(N`?> M@20R,PBD*/1:C\ISM9(WN:Y,0BU^I=JH1BX.:GR#U,!_'QH6SCWA()SRO(_( ME=4>'8D=28(N0:BNR3?Y(BE52C3+;(==!&2MMJN64GD?_IW/J'DR\I&?"*Q% M#3/B\##R-?;L^8Q[*N$>"2&Y-=<@BR/KX"!88W/BPUM%;K3O')=94T4+]CO1)PH3A\K(BQQ^ADT MC3T>J@Y8X!Y,HSR'3G8Y-)YS.GC2"^"T@/SM789]S#LPG,3P)MRRFZ0AQD'E MK\"ZD(38FRE+/'O-HO#"5IL-\35E`R.!@3A+B#BQE1W.W7#R]FL\#BGDYQ0B MBR4<`1S*DD#PT.>86:V5+"E_F(7MS+G-C%O/MZ(>8GF`;=%`SDG?@_F0<7&@ M-"NF03!J:10XI:%T+V$8)@9B9:%WTP"4T*'H!66R`WDH(RVM&[X?/OM^8]`4 MS%6NO2TL;8@F1()9M8?8;UU?[M,5SEJK@L'2&$]O=_>R:!\8+?O+L.33&T`I(0BNL3PHBC-?7VGX.5<[1\^^'-@Y&@<:X"1AJ(- M?\X5K>>JB+QOM`*VCV;C9,$'H%$0_\@R[M7=BB?G M`8\1__NH7M]9U+3N@B:Z+08AC!E0?PL(6*&`"JY)#^/QIB!PXPAK7S.90?/> MSORE@_]P9X`7[SU)_7^,;`$.NT2;?)F7Y"^J.H::.S%N8D_#92?<'ID():P? M\:U')J*3ZQQ\#EH##,7[B'X+B4#I?U7KO=0JW.Z=7LT-_!5) M:'K$0"JBG*R"1[5H5U(_P;:QBY(F'J&-3%5;7/3RQ1UO[9ZF/PAX;IF>W;7: M'[!]31)KM;E#JZ/G5U1EN#2SK69-,HE'!I6]7X&U%._G`*=/N_#EO4_D_-92 M!.!++KA#FA?V6;)S5W?'H'CAT\4"=/K&M-^WB.$H*!_4_FZAB*8ZQ_RJAO&> MB5M"%2X)4#2^Y0#0P`O/#D_7--7B=UEKB`O]Q##8 MNS`7)R`ZO_Z*#Z=/O9I^O=#/:SL+B:]S)_8X5RIP2'3P#>"8B`?K14/-4_'- M-\V8/$.```8S8N+]I&V?)];[MLFMK53#5X@A47RL0\2YYO+2$_GHTW=GTW$< M8'<41E[;#5"GDW=CXJ^#H85$_O%/\11#_0%.#>*5YB:M:SAV_BR_' MX88Y+*-,Q,('QTGBKR["K0-5;&]'2!RW'WWW7?!4?4WQU?X;[M::?FL)_7!= M'$=_=P[;6C5X.`C?!EP;_>.@9,@__*4%4N&T,Z`FAFO0[QY)]>%Q'/%@W^(N M[+3MI6N0Y$;GF?@-K<%A'74TGK;^[K74=.WVJXYV-GO8-`UK+4MC(SI M0W^_&8T$W#1Y(D22[%ZY#?9=N`U:MX)W(:$F[J'=T![/KE_RWX>2L79^-@[# MDN4+P;UMHYF/^'*37A,`+J1)%D:O!5W+%.BXP^2%FE?+I0I_LRB5RN+=9[AN M'5#",6=W=#'+-W<28W3ZB=4.V0V3Z^GSD2`W/XGE%"Z"V?+_`%!+`P04``(` M"`!564\?H`H9,4(%``"3#```&0```$U%4T-(04-(+TU!3E5!3"]-04Y?,"Y( M5$V55]MNXS80?:Z^@G`?:@=*TNY3D34,N%OMUH!S09P4V\*`04DCFPE-"B1E MQPWVWSL<4H[L3;I=/T49`. M5[^,#L_Q(,'?L![-_KJZOIE-9O@G?AH8)3\*5R_STF7-,UX0PO M(`3UAA&&+@P[J=1"\35$IXN/-UE_D`S/*5&?_N_9[,/MY.9N&Z:T*$)^NN"HE MGB=&-TXHKZ5*2@BUF$,OC6VX/+KM?110-@;LV7^%LM7FT3(I'@%-"7O!_-VE MU#F7R88;P7,9=-&0X\8%W3Z&['8U,!(]K.M%WE0D&C!AF>4;*,EM")""]3=? M1SC81+WXC:J3"K,,*;&M<)%N#.F2@R%3D3U[7<.%A3+U_E1"R;[!FO_CC2N- M=LRAUXZ3SFTI60Y1D)"RS]@B4PZUN26!-F(I5%NNE.6-"T9X70/2S&FV0O22 M0J.!RN@U:;U>/`IAG'QY!0&JQQ-X\/`E'Q/FJEEX/++@$70MGF98EVW#9 M>.(<,L6BL:QGT)L_@J8`:?:RXFZ\J(>>Y`?[X?85BHF)#,>)J-S\? MGHO1/O$D)-Z)M]/5!V%0LIC'#EO/UE`(+@FR#1@KM/*MB$DD;Z?L$V"(5JCF M4<]5DB]]!6OCYQNV*QEK5`E&[OR%2!I?'RS'OF(8^`09A4'L<.K:`*2O0[B_ MMX]5UPMU..X1<"MXL5R\DH]A;3R26$F/E-D&J&XT8<0=A-H4T M(WOSW:OJV'+^.%M@*%?C:3BG2VE_Q`M'OCU.R M,WC?$5DM-]!*TCQ]ZDA3OPR%Z@V.',5-LM4-UATKVTC7SO<`SQJLY4NP,;N> M;$($9T4OQ?;#&K_[]8)=W4^G3.00#OU^*WUK^!I:5R(K8V4K9"_XOO.2 M<3C48<03?.T)T3`/7ULP@=$^1CHB'F'CM""Q@".7R&3LE#8`:LE]$(CK/HBC MN!)D'.X`[`S0]ASH4."(Y9$BOQ` M]*!8JW[O6NO:IJS2.#\PCDXYYL@>O!XAMF)=XSQ#X,NF@#"7(@R4U=MV8O** M-C\-'DSR#[WU@RBEWC]8@[HH&F-9WW*L=Z<:(OC<&NU'E/@'!B]+N,TR]C&U M^+Z7`7OY[VS6:66_64?'=!QJWG2DO+4JN?'#+1/TC%(;GW/(U;X!M$ MQ20Z)`DC999E;#R=75\PEE`V8?+%9-*OQE0XP:'J]]?"+X,#079[FWV>W+58 M@"N"F]_N/]&;F9XAK!15A?0.[V--#P(B'4(0!ZQ07RW9Y.@!1"JX98&F,>$7 MGB$V;KBC=PCCV%!26QGWM+I*4CL*[]Y8(U1I6^L5P506A]L#@G@ MJU_'49[[FTB:Y[ES\V<<=/,O7P9GA.[U_>V'C'V<3+,+,MK^CT`&"9!_`5!+ M`P04``(`"``G64\?\3?OO&H#``"?!P``&@```$U%4T-(04-(+TU!3E5!3"]- M04XM,C-E);US[W^)[[E=!PD['A&=-Q2N/T"#(N&%40 MRX=;+JCA4NBP5X)(F`;#G>>X3\HG7`RG7R;G%]/1%)?X5Z'=>R[B+$\8O'N@ M1O&EG[XC_T2G`-UBCGR6J\V%`>&!W7:[VGS]YD$B\]N,`:TW"&P]#B]ST]DD MM.!V?5)S!@U;\)9GB[$X:-"X]'T?:2;7XW&'A#VG:5O9JI$VCBZN1N<3 MFU)RE3)0>"D6@H;0F&$CM(.E8H9`1>(.5F].['6Y86"0HZPDLE%)T+K1^.<3#C(E[D][TPAX?@KRK(J*-]@DY*6^-YJ/)='1U M79HRI?"N1YYE<(N>4JZM?W>U?W!\#%LAN$,\%4\N.KS@BI.A=&5'$)O9<&JB"42A#08JA\Y1ZAF!J^YAWR!G&BL MZ!.J0H<9H&^)S0:&2C&3*Z&KLN#PNAILQ'#?QA3O4=#BQX%WX-TDTN@6Y)CP M#*@3[TIZG0!,7)RRI,ZE3F6>)6#H]Y)RD=&860E2L#HQ+AC?'<,?_RM!V&7% M(7X^>-AL==RQJZ)_3\XNQE$S,MTTPWFV_!KT<52XSG8-V[7V721PC3\@EXQF M%DE+8#K`IO?=0VS^VX`YAOX`?T(([._>'G3(,UHLL5#P#)$#:[[Q!UZ(EU77)>YN&?[^Y]S8RBV=L*.JHE36J>]C]UV$>P=H./VZW"O M^-"!;H\4\Q53LFV'VF#S)E=0;IQ9N6CN]ST7L[1WB,O=X\S&HSRW8:VL=D-+ M[P?U;',OJRB"D_'T_`C`E8HNY@]97=5>U06X0Y/DU>;J+6ZU!73\?UY_[.5E`^1MA(_CM&5X%IFIQO%8M&B;8)G7AI-`+26&&NF!84ZE"!U&_S:!$]+ M<3,1)+7`,_V"1J_D?LV+01+<`C=-J]#CF\J@9?S(#@@G*[U''0-1(L$1:;%P M2#(971?,,W#>!NZ#19?(+\F\(O?&.KBRR%24ZO&`1*%%L<@*SM>_I1R/89KS M.WBB="IDF4)JKH+`_XJ%`1"=9HWDI%H9GN"QI*OII\65DS])=@K,3=O%_Z8" MLW\A?2['26WH--S2'N'KV M,L%VMT_;VSN*Y-@KKI5A(B*)(85++5_CF6,;4QJ;GP[WS%'^;[9QM1IV*+F] MU,,82:W1QN&R1H2D(^5S7N4\DJI^)R\P(.E2;D$LH[=,N]8X%.D&$R^&NIS$ MYU+TX1JI(\.9NFVL3X,;BVTT:G^25(Z+CA_!>$G;T\;T$BH6@T5X)'-&O6), M7X3CW6`=&JRX'1GE`G8NRSO^9 M"O-HH[0R#]HCKT-LETN:4XYBF!I MNX.4(8KEQ3#()9/W#C*)\R(T/PAFI0D.EI1M-+3EW!QXC?R8S,JUT1^B4>UZ MWT[W&VR,[>+#R[AX*9L=??2'"MG1%<6.:5FA\V25@_7__<[5S"ZH8C6)P"-B M&^^-$OZ"?E3(U$-572[^,U[,AI,?R-QL+NCW(SKCYLV]X#Z,N/DLFC;5;X;] M=\3.;'H&_@502P,$%``"``@`'%E/'Q=YUF7T$0``&5,``!L```!-15-#2$%# M2"]-04Y504PO1DY)3D1%6"Y(5$VM7&USV[@1_IY?@0^:UKZ+FXD_=M)T%,?. M96HWCFQ?VYM,.)0$2;CP[0A2EM3VOW<7)$``7)!,VYE[D<1]=O&RV%WL+OWF M450)?WO'Y6H7KW9_9#=UMJI$GC&1K?GAS:OF^8LW/[U^ZS^"GUZ\^)BQ:L?9 M&AB4HL#'DBUYDC^_9&EE%SRK.)KMCRR55R(*DY8PJN*E_+E MBSU?57DI\1F`>0D4DNO'+,[63*[B)&XHMB7GWPBZ/[QX`2.][$:*.&MH,.;+ MMV_N8=AOEF^7\/`2QGAV_N;5\BV[RK,]+RN&/S=#/[`J!W0&_)OOB$3@.MK` M`%K<>QXG2;Z**\[.0%15YL=SFTD'VG(M:ZX12"8R48DX$2"&A%5EG,FB13ZJ M+WF(%I98G/3(%NH+27C[_G83XX*WI.^09@:_?GV:)D+%:,@LB\V2OF3_@ M9S:;'_ZTG+%:BFS;"'*9R`[^1`E\"DI[FB;LJ2=)R/U:PWY^S_(-6XJ+M8BW M>0;ZYJS#N[_/7C)=E7K*S-%Z5^;E-#LKE(K+C*":ZN;]V0)LDA['#JA6YR"H- ME+R2\"C>:O#53\YRO%>J?[7+$RZ_'#M_QS9Y"=O24K\G]OW]X4_'V4OX_XSIC6RIKQ>+^;M/BT=]KI8YG&`X M]_X,T1A9JP2PZ[]_U*CK@Y@"4H_UT<(=@+UP]N`EDYRS-U7UEO%]!$^0&+Y9 M#"(XYE445U5L%&&NOK",/S-\B`JKF$H?9=L<`<:P7(SV726,RWJ"NS\30S#N:7NSAC+C+P#ZH'UD1 MEW'*T2NUQ+M=58)LGWPVOT=[^;SCX"5G]S,FP-VQG_):PZ#/H9MQH6!@M".41Z'Y!XVYN'C55%L$FKXW*9,`&?ZA7 M2NG;B,$03]4NK2XB4]KB&5"@*Z.XS(I_0YANR*,'X@46"6>[R-8&(1,DW M(S#V+*H=V$`X$#R%@,AF,W\\:-/'*U`-U`PPE#CDCX_7BV;`<#A@">J2.T@7 M.!7VSH9!A+;*L[7`8PYK/8W#:ML%4+_66XQJMF6\%C`S.;ADJVW&!Z"H0AEZ MAH3QWVKE=*0+-V?@P\.PH+PX&D'%T9N4T@XS,^D#+_7ZH"<&,X"_H?9-9K*N M4QV\O8>/@T"T9I[Q4SPLTW\#'S'0U$'G^90](B+/*:@4IM+B/MPMKH=7.8FS MU2G7]+?-MRF(2P]BGY*K.@%CS7['_B9@X/5V!\$_/U1@7WUU2.1OVC_ M#`I.MRM->_?A:IC6B:BO=G&VY0Q_D1./ARQ<8_(`W\V%PMB(OER#LTW*$'C( MK,C"G%*7Q=4'4K1U-`/TH\<3F<@`CP=2J*UN+J)1/@KC*IV+6L92K#RM(M&7 M]#`)U1MDUBF@RTBI(X6PU-!%**5T$?LH7FM/.%_CI;'B6[#1GA/<]XR=2]C1 M^6;)I:,,T3XB0C@/1H5O",SKJD-^4E_&)7[\.;I97%\'#5^<^3P\5[X?-IP^ MV(]P6WRTA[VQF<0F[@[NPOA5OS=X!VS+-!Q&I4[;GI'X9Q]-VRS-!J@#?*AD MQ,"T&W)[YAHS/G-9+_5)JI=-U$[3^HF/H9R'E_'0I,[E%GZK"W#BFNA)?1EF M2]QP;]L;[NVLS6J!'0!74R>Q$?1(P;X^C@.?,*;C4F_HM:Q$JA22F6"/976Z M!'"36B&R*E[VQEP9+,K&_V#$+59PG\9L'5_CG0`UGA5BGV,&PO`;2>^08Z"6 M8(Y+H&`T*O4,ITY*ZL?Q-_Y9'VYP9VSV>:;-,+JXV><%O8L(7#C`Q51@=8G) M*^^2::<=U3$E$H]W7H+F+E^+C8!5IG,T[`R^U6#OCF:/9O,?WWN9E)=P4F3% MXS4>,+@XG)N%\UT),:*TYT?:*8S&M2E/V^R$RE1T.X373DR&;.)4)"K4KHY% MMU\`6QXK$RC\%;1JP,*A)\"A MAH69]A]2H]16+CF>RGBUJE.P+15?_]D'&^1C76;2$2F/$F_?>?8JWVQL M')VE`M':X*LU9?JY+=-='G\3,VJ]M.=?$WK1L!M4C&&>%B]9Q95]+M0>2+44 MF.C$DPG_E'P+PG@)PWG.RV\0[Z^XS\0+7Z0=O\ASAC00X@;A:5Q^ZZ[WL"?P M71DG'W%W?1<]/,X?H\7U!^-[F^'UA!"+IX3)7?YL2[RJRQ*N(19P6^9U80P' M/Q1^"JBU'?`DSP`J3)HWI4)/VUCZ&DU'G%U5QZ._&PDT-=*;^G!XJ3%^6)F. M196^BYH23?IF>2R&[,D08-TK5UGT8JE'HCKZ,H:W9#C,1+3*]QF\*KYY$I(\ MUD;A%CYJ_H'201JEB1[/79U4`D(1K5765-.JM`B-\LWF[R!B,ZSP;ONZ1_/E M7_,O_XI>SQK;ZXT6(;"W^=*'88'T!G[GF:BENC6'\6`E`E*_P*/J2(N&\R*M M1)ZEZ$G"7O^^V^;A8S$2TZ=1D2='?WCF=.##+$_M8UN89+J5YVWB\D*%J\1D MRBXX^L`SS,P`JI"\7N<7^`QT2Q60&GML1%FPA:+"+LRX4;3.X=^K6Q,Y8F;3X]GH(+LCK8J4_I8?'U\9X[% MGB8YN`1=Q-W1'+]LT:K,#S\>NT-VXF7>4OX"'_T]^O37Z'JQ^*3#[&M5B-KA MOG'_KC]4(DJY5-$@H>`:?8BLRLP]+U.\W>"Q;8I%E`(IC!L@%PIH!_M`Y`?( M%M%XE`QXPO/9+"CWARCJH-NXOJS[OX]Y01OO+?]AV!: MXA;)+0DYQS&!/1_I+:AVE!9B?.^&_:3BL7>=)#4G((IZ%3DX=O=P/>Y5]>PQ M>#J-?$[_`R-VMLJQZ':P)M#SRL?`^D[0V1$/!4S(K!.M!Q/L,SU0JP!K&PO\ MF;844FPS(Z)2%R0$X,_JF@.?R1$&+#?,)Q;*>;8.KD.0>_==*A#8__]J]S\O MKMP6FWY:I,D;M45Y+TWT>3$"-G1CZ:0P\`&SFD449<3W<:]=@HLMS^#W&I12V4\UR0$F,`*:1]MP.,;$Z2+!X+K; M&WM=F^FJAA!OTL``6W*PHZ@K=U=EGK`EW\5[D=>E+BB[?4,6@ZXI18\`6U(F MB;>CN@?50GEQT6+2]I*TLI5:V@$X2I.<-^4^'*%Y:(VO\/OHVFJ6/*8IQU!4 M-8QNT"]S?1Z$([+PNNF&&#CI=UEX*=$6.=BTAB!"&MV]IHB/J0FRX6,.*\;D MD"!VEN5^TUT.YO++1>-)S@USU*TH7D&T+NW`HBZTBC7/P-Y7.]U6(^UBH%NML-D%X.TN)%#W0RRT%;N\6,,.U, M3]CT:$Z?LA];NP,8C:Z!`Q%=NTRH^!IQ5*SBKP`M<2A.#LYT2JP;AD*(DYA[ M;F,_9F?BY:_G,Z47Q\:2T/B/]`D366/WJ]'#%I&M6>XB8TK$"X0-WJL]M?+[ MO<.MMPY4G)!/S]-+-TJ0/=;20C^2<"=2&&(0A2_/2LDU=C[K((22R2$M\Z)A MX$!'P_1.@TMQBV72"C1;"(83#H`\"!TQ>080]QT*#>0^%*YB!TNA%0.55]^H MCE6ET[:E\UFDO-SJ5;G#SZQZSH-S=%(:#]WA/ M)PU0DJE,F[RI'#4O1;C07D;(`S8FS3/,B#P4756RP-T@AT=,Z;L,2K0G$DUL M=OCZ.`^?!#]3=+8$-5OG#&8!@5N:[]%X)HF;\"/E[[WKKW2\V8S,1#:.0-PM3KPE`%M1\@O5]M_V>GLG'2?]WTB'_]"O M1I"U]J?6V+7WP"=U#ZR+@FH[\!N6W#8,[%,R:0U\\P:"'76`@_V]_18#'\>XC$3+_28'+W_B"`C97L'V83G$D:%\[- M5Z^^N@*KDN4SKEC_XHO00[_:>=`KH6QF1RNR'JW(`K2#V?8O<5+L8H8Y=S4U M;05F!VP",8GX/9WY5Q;9(2%%?7ULA,&''QU(L(9V:&IHS6)["X68RP#FU@%=/(,7C5-.MH.]4TNE-N1.BHT"2:#`;Z@_$+U898Q8H5P$BB>7.WQ/W M^&`K=DY*RTOCC.&CU,(,W"+M5\6HA833;\A43;9C1:YCOU[E$)SBI9UJPJ08 M_(*;R9GRPZ`!X-Z2VB0`3JZ3U*DTM]9X`I7XM?>FA$NK2==B;]X1V\,9";%T MNR^0H-]U<7(]XP)[Q%QVC0G'=B.&<9OM]DZ>FVR;8#P\G!(:3;Y9Y68:?V]2 MC1KDO6'5&&G[):1*OY.F8']LWIKR<]8G[Q6K"6SF]P$V?JYTB$N38R?8]-^T M"K/1*/?=*;W'PGZ'RFS4I$U&8]:[G)^$%<1I`_OZU8F8QNV<[%_]`0/*IG]5 M2PWTL9Z2?.M-!WZ)2U'MC-8$6FNG2KA]FI/%@!^L*[[FW`_7::X=EC)0[Q@;I-\5J>J]S0-']BMG+7L]'\[,VF09[,,CXF_5R M5Q-_DWJELNXJY$SCKC:3NKWTD-JWFO1\6GZ\.W6SJ7@T*,5/$W<"0LFG$]5V-0!3]K9+5)[ZC5CTZF5\VU/#"\K9 M1_W0CXC\VK/H]6*=>CT#5Y:1GMX[H/A,])/!"O_)ZT"XF@`(QA#LN^320_\> M'EZSP54@>FY47O4:V$COCPR$D%:R_!0\'^V>A\Z'WQ>`D+803\VK7Y+ORO&T MXO9+Z&WY/$">$D=0NK5S+XB6OW5WT]]J]0>/\KS"!!,\^.?IW\0A&;`)G@L@ MP](G$SL_=9%M(!E[H@+&I^GP?2!>=._3IWZ.UB7LZ$(A4S"+>MH/!4T#Z=I? M?IX6-I%9V--^6M@42L>>]E/#IMY*#D1-_F).CYIZ4J8N*1TV_9^RLZ?_2WKV M]'WYV=!BA@]^NR+>P0]X7DE7BWS/NP]>-:A40#@)BP!,\O8A9(37CLJ+\/K) M5XOV\N*"G<'_3>[UG/6Q1)C7PDV8UW"1=5'RM$Y])H-AG[]50V$?33LI[.NI M5)(LNG*..@QQ5%HC!/>W_YQR'%=]>N/MW_PW8[[==B2Z7G9@O6G& M9A(E^R@Z^4NH=\!CK?+'AK"?05;D'36LBR%NLMR93V)M#IE:[&T28.S5N;(E MM[;2,ZP-PIZA!XH/A34B3Q\1=H`^KAP``%9&```:```````` M``$`(````!4W``!-15-#2$%#2"]-04Y504PO4D5!1$U%+E185%!+`0(4`!0` M`@`(`/%=3Q\U*(SO@B4``"-E```<``````````$`(````/M3``!-15-#2$%# M2"]-04Y504PO34530TA&05$N5%A44$L!`A0`%``"``@`5F)/'T%/"!I)!P`` M3A(``!P``````````0`@````MWD``$U%4T-(04-(+TU!3E5!3"]-15-#2$%# M2"Y(5$U02P$"%``4``(`"`#<74\?286]:WD&```$#@``'``````````!`"`` M```Z@0``34530TA!0T@O34%.54%,+TU%4T-(,3)!+E185%!+`0(4`!0``@`( M`+1>3Q\!.&:XR@4``&KP``$U%4T-(04-(+TU!3E5!3"]-04Y? M,S`N2%1-4$L!`A0`%``"``@`+EI/'U,2@-FV!@``GA0``!D``````````0`@ M````-,```$U%4T-(04-(+TU!3E5!3"]-04Y?,RY(5$U02P$"%``4``(`"``D M6D\?<95ZY;,#``"C"0``&@`````````!`"`````AQP``34530TA!0T@O34%. M54%,+TU!3E\R.2Y(5$U02P$"%``4``(`"``96D\?!>5H96(#``"4!P``&@`` M```````!`"`````,RP``34530TA!0T@O34%.54%,+TU!3E\R."Y(5$U02P$" M%``4``(`"``/6D\?V;FZ(#8'``"4$P``&@`````````!`"````"FS@``3453 M0TA!0T@O34%.54%,+TU!3E\R-RY(5$U02P$"%``4``(`"``%6D\?!HACIP0# M``"2!P``&@`````````!`"`````4U@``34530TA!0T@O34%.54%,+TU!3E\R M-2Y(5$U02P$"%``4``(`"`#Z64\?UB'(KST"``!0!0``&@`````````!`"`` M``!0V0``34530TA!0T@O34%.54%,+TU!3E\R-"Y(5$U02P$"%``4``(`"`#Q M64\?;*3#A:8#``!L"0``&@`````````!`"````#%VP``34530TA!0T@O34%. M54%,+TU!3E\R,RY(5$U02P$"%``4``(`"`#G64\?\XNO+40#``#W!P``&@`` M```````!`"````"CWP``34530TA!0T@O34%.54%,+TU!3E\R,BY(5$U02P$" M%``4``(`"`#<64\?$)]\O*D"``#Y!P``&@`````````!`"`````?XP``3453 M0TA!0T@O34%.54%,+TU!3E\R,2Y(5$U02P$"%``4``(`"`#364\?WK*_BXL" M``#H!0``&@`````````!`"``````Y@``34530TA!0T@O34%.54%,+TU!3E\R M,"Y(5$U02P$"%``4``(`"`#*64\?I(7^/>T#```7"```&0`````````!`"`` M``##Z```34530TA!0T@O34%.54%,+TU!3E\R+DA435!+`0(4`!0``@`(`,%9 M3Q]JDBX]!`,```4(```:``````````$`(````.?L``!-15-#2$%#2"]-04Y5 M04PO34%.7S$Y+DA435!+`0(4`!0``@`(`+593Q_W^<^X=P0```4+```:```` M``````$`(````"/P``!-15-#2$%#2"]-04Y504PO34%.7S$X+DA435!+`0(4 M`!0``@`(`*Q93Q\XXZPU*P@``'@5```:``````````$`(````-+T``!-15-# M2$%#2"]-04Y504PO34%.7S$W+DA435!+`0(4`!0``@`(`*%93Q\/H454Y@L` M`!LC```:``````````$`(````#7]``!-15-#2$%#2"]-04Y504PO34%.7S$V M+DA435!+`0(4`!0``@`(`)593Q]$B)ESD0,``($*```:``````````$`(``` M`%,)`0!-15-#2$%#2"]-04Y504PO34%.7S$U+DA435!+`0(4`!0``@`(`(M9 M3Q\KWL?/@0(``(0$```:``````````$`(````!P-`0!-15-#2$%#2"]-04Y5 M04PO34%.7S$T+DA435!+`0(4`!0``@`(`()93Q_-M(::R@8``/00```:```` M``````$`(````-4/`0!-15-#2$%#2"]-04Y504PO34%.7S$S+DA435!+`0(4 M`!0``@`(`'=93Q]G\6%'&P(``.@#```:``````````$`(````-<6`0!-15-# M2$%#2"]-04Y504PO34%.7S$R+DA435!+`0(4`!0``@`(`&U93Q]UFZ<[/@,` M``,'```:``````````$`(````"H9`0!-15-#2$%#2"]-04Y504PO34%.7S$Q M+DA435!+`0(4`!0``@`(`&)93Q]D;)Y<^`H``$$;```9``````````$`(``` M`*`<`0!-15-#2$%#2"]-04Y504PO34%.7S$N2%1-4$L!`A0`%``"``@`55E/ M'Z`*&3%"!0``DPP``!D``````````0`@````SR=9E]!$``!E3 M```;``````````$`(````( #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ /* #undef REAL_DBL */ /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT 2147483647 #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems #ifndef HUGE_VAL #define HUGE_VAL HUGE #else */ #ifndef HUGE #define HUGE HUGE_VAL #endif // #endif #ifdef ANSI_C extern int isatty(int); #endif #endif gtk-wave-cleaner-0.22-04/meschach/MACHINES/cornelison0000777000175000017500000001745313120075106023256 0ustar00alisteralister00000000000000From - Fri Dec 4 08:05:39 1998 Received: from cliffy.statsci.com (root@cliffy.statsci.com [206.63.206.72]) by server.divms.uiowa.edu with id MAA14931 for ; Thu, 3 Dec 1998 12:28:13 -0600 (CST) Received: from adlib2 (adlib2 [206.63.206.104]) by cliffy.statsci.com (8.8.8/8.8.8/Hub) with SMTP id KAA28911; Thu, 3 Dec 1998 10:28:02 -0800 Message-Id: <3.0.5.32.19981203102809.01371ec0@mailhost.statsci.com> X-Sender: johnc@mailhost.statsci.com X-Mailer: QUALCOMM Windows Eudora Pro Version 3.0.5 (32) Date: Thu, 03 Dec 1998 10:28:09 -0800 To: David Stewart From: John Cornelison Subject: Re: VStudio version of Meschach Library available?! Cc: Zbigniew Leyk In-Reply-To: <36669B2E.809B959C@math.uiowa.edu> References: <3.0.5.32.19981202145120.0106bec0@mailhost.statsci.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" X-Mozilla-Status: 8013 X-Mozilla-Status2: 00000000 Thanks for the fast reply. I'll send you another note once it's working. It now compiles fine into a .DLL with the following mods (hacks?!): The largest problem was figuring out to not include some of the miscellaneous source files that are used for QA & utility & legacy support. Once I read the makefile it was easy to set up. I'll send you the necessary project files once I complete things. As far as coding goes, in machine.h, right near the end, I've added: #ifndef WIN32 #define LIBEXPORT #else /* Comment out the following line if NOT building Meschach.DLL! */ /* TODO: Eventually this should be defined on the compile line only when building the DLL */ #define DLLCREATION #ifdef DLLCREATION /* Including code is internal to the DLL */ #define MLibImport _declspec(dllexport) #define MLibExport _declspec(dllimport) #define LIBEXPORT MLibImport #else /* Including code is external to the DLL */ #define MLibImport _declspec(dllimport) #define MLibExport _declspec(dllexport) #define LIBEXPORT MLibExport #endif #ifdef WORDS_BIGENDIAN /* Win32 is always little endian */ #undef WORDS_BIGENDIAN #endif #ifdef HUGE_VAL /* HUGE_VAL later defined in math.h */ #undef HUGE_VAL #endif #if defined(_DEBUG) && defined(_MSC_VER) /* WARNING: Disabling the many "signed/unsigned mismatch" warnings so others stand out! */ /* These happen when comparing an unsigned int with a regular signed int but should be fixed! */ #pragma warning(disable:4018) #endif #endif /* WIN32 */ The only significant thing here is to explicitly define what routines are being exported (or imported) from the DLL. This is done with Microsoft's delightful _declspec(dllexport) & _declspec(dllimport) expressions. Next I had to go through all function declarations & insert the LIBEXPORT define. Ideally this should ONLY be done for routines that are made publicly available from the library, i.e., not utility routines for internal use only, but I put it in all the declarations in sparse.h; err.h; iter.h; matrix.h; sparse2.h; meminfo.h. I left the complex libraries for another day. A sample of this is from the matrix.h file: /* miscellaneous functions */ #ifndef ANSI_C extern double LIBEXPORT square(), cube(), mrand(); extern void LIBEXPORT smrand(), mrandlist(); extern void LIBEXPORT m_dump(), px_dump(), v_dump(), iv_dump(); extern MAT LIBEXPORT *band2mat(); extern BAND LIBEXPORT *mat2band(); #else double LIBEXPORT square(double x), /* returns x^2 */ cube(double x), /* returns x^3 */ mrand(void); /* returns random # in [0,1) */ void LIBEXPORT smrand(int seed), /* seeds mrand() */ mrandlist(Real *x, int len); /* generates len random numbers */ void LIBEXPORT m_dump(FILE *fp,MAT *a), px_dump(FILE *,PERM *px), v_dump(FILE *fp,VEC *x), iv_dump(FILE *fp, IVEC *ix); MAT LIBEXPORT *band2mat(BAND *bA, MAT *A); BAND LIBEXPORT *mat2band(MAT *A, int lb,int ub, BAND *bA); #endif It is sort of ugly, and I probably messed up all your formatting but it at least works and won't break things on other platforms. The only warnings that now appear during a full compilation (again, I've left out all the z*.c routines) are: Deleting intermediate files and output files for project 'Meschach - Win32 Debug'. --------------------Configuration: Meschach - Win32 Debug-------------------- Compiling... bdfactor.c bkpfacto.c chfactor.c copy.c err.c D:\Meschach\Source\err.c(328) : warning C4113: 'void (__cdecl *)()' differs in parameter lists from 'void (__cdecl *)(int )' D:\Meschach\Source\err.c(337) : warning C4113: 'void (__cdecl *)()' differs in parameter lists from 'void (__cdecl *)(int )' fft.c givens.c hessen.c hsehldr.c init.c iter0.c iternsym.c itersym.c D:\Meschach\Source\itersym.c(424) : warning C4113: 'int (__cdecl *)()' differs in parameter lists from 'int (__cdecl *)(const void *,const void *)' ivecop.c lufactor.c machine.c matlab.c matop.c matrixio.c meminfo.c memory.c memstat.c mfunc.c D:\Meschach\Source\mfunc.c(174) : warning C4244: '=' : conversion from 'double ' to 'int ', possible loss of data norm.c otherio.c pxop.c qrfactor.c schur.c D:\Meschach\Source\schur.c(158) : warning C4101: 't' : unreferenced local variable solve.c sparse.c sparseio.c spbkp.c D:\Meschach\Source\spbkp.c(1244) : warning C4113: 'int (__cdecl *)()' differs in parameter lists from 'int (__cdecl *)(const void *,const void *)' spchfctr.c splufctr.c sprow.c spswap.c submat.c svd.c symmeig.c update.c vecop.c version.c Linking... Creating library Debug/Meschach.lib and object Debug/Meschach.exp Creating browse info file... Meschach.dll - 0 error(s), 6 warning(s) At 08:07 AM 12/3/98 -0600, David Stewart wrote: >John Cornelison wrote: >> >> Hi, I'm starting to get the library to work in the Win32 environment and >> was curious if you are aware of anyone else that may have done this already. >> >> Specifically I'd appreciate pointers to anyone that has wrapped this into a >> Visual Studio project. I know Visual Studio is super platform specific so >> is not something you are likely to promote, but knowing about this would >> save us some time. >> >> Also I understand from the readme that you have an electronic form of the >> manual I can ask for. If easy, I would appreciate a copy of that. We are >> using the sparse matrix processing functionality for a small research >> project we're considering and getting improvements of many magnitudes over >> our previous techniques. >> >> Thanks in advance for doing all this incredible work! >> >> -John > >You can get a **partial** on-line manual via > > http://www.math.uiowa.edu/~dstewart/meschach/ > >However, this doesn't include the sparse matrix stuff. >There have been some others who have worked on MS-DOS ports of >Meschach. However, I haven't been keeping up with the status of these >efforts. And I ceratinly haven't heard of anyone using it in >Visual Studio. Zbigniew and I are glad to hear of another happy >user though! > >Neither Zbigniew nor I have had much time to devote to Meschach >in the past few years, which has (unfortunately) stalled its >development... You should also look for matrix re-ordering techniques >(I have some code for the Gibbs-Poole-Stockmeyer method for >Meschach, if you would like that. Someone else developed it, >so I can't say much regarding it; the algorithm is not the best >matrix re-ordering technique for general sparse matrices, but >it definitely better than standard orderings for most problems.) Sure, if convenient, I would appreciate getting this. >Also: please note the new email addresses! > > -- David Stewart Thanks again for developing the library! ---------------------------------------------------------------------------- http://www.MathSoft.com, Data Analysis Products Division 1700 Westlake Av N, Suite 500, Seattle, WA 98109-3012 206.283.8802x243, 283.8691fax, johnc@statsci.com, NIC JHC7 ---------------------------------------------------------------------------- gtk-wave-cleaner-0.22-04/meschach/MACHINES/w-mckinnon0000777000175000017500000001616713120075106023164 0ustar00alisteralister00000000000000From bmck@bnr.ca Mon Aug 28 10:57:50 1995 Received: from bnr.ca (x400gate.bnr.ca [192.58.194.73]) by gluttony.isc.tamu.edu (8.6.11/8.6.11) with SMTP id KAA05152 for ; Mon, 28 Aug 1995 10:57:42 -0500 X400-Received: by mta bnr.ca in /PRMD=BNR/ADMD=TELECOM.CANADA/C=CA/; Relayed; Mon, 28 Aug 1995 11:55:55 -0400 X400-Received: by /PRMD=BNR/ADMD=TELECOM.CANADA/C=CA/; Relayed; Mon, 28 Aug 1995 10:04:07 -0400 X400-Received: by /PRMD=BNR/ADMD=TELECOM.CANADA/C=CA/; Relayed; Mon, 28 Aug 1995 09:30:00 -0400 Date: Mon, 28 Aug 1995 09:30:00 -0400 X400-Originator: /dd.id=1736981/g=bill/i=b/s=mckinnon/@bnr.ca X400-MTS-Identifier: [/PRMD=BNR/ADMD=TELECOM.CANADA/C=CA/;bcars735.b.396:28.07.95.14.04.07] X400-Content-Type: P2-1984 (2) Content-Identifier: Re: Meschach ... From: "bill (b.) mckinnon" Sender: "bill (b.) mckinnon" Message-ID: <"13392 Mon Aug 28 10:04:17 1995"@bnr.ca> To: des@isc.tamu.edu Subject: Re: Meschach v.1.2b Content-Length: 6245 X-Lines: 267 Status: RO In message "Meschach v.1.2b", you write: > Dear Bill, > > Thank you for your message. Please accept my apologies for the > delayed response... We are glad to have you as a Meschach user. > We would also be glad to hear of your suggestions for fixing and improving > Meschach. We have had reports of problems with HP machines. > > Yours, > David Stewart > David ... No problem on the delay. I understand the problem ... ;-) I'm using HP-UX 9.01 on an HP700s. I started with the "GCC" version of "machine.h" and "makefile". After running "./configure", the "machine.h" file which is generated "#include'd " before (which the HP version of "cc" does not like). My amended version of "machine.h" is included below; the differences start around line 68. Also, the "cc" compiler seems to require "-Aa" to be put in the CFLAGS in the makefile (this option forces ANSI compatibility). Otherwise, the library and its entries are created, but the functions do not seem be accessible from code. Also, the ".o" files which are created without the "-Aa" are on the order of ~400 bytes ... a bit small from my experience. With the "-Aa", the object files are 1K or 2Kbytes. Several "redefinitions of macro HUGE_VAL" also occur at compilation which don't seem to be a problem. These changes seem to generate the "meschach.a" library ok. Let me know if I can help further. Bill McKinnon ---------- machine.h ------------ /* machine.h. Generated automatically by configure. */ /* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* RCS id: $Id: machine.h.in,v 1.2 1994/03/13 23:07:30 des Exp $ */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ #define const /* #undef MALLOCDECL */ #define NOT_SEGMENTED 1 #define HAVE_MEMORY_H 1 /* #undef HAVE_COMPLEX_H */ #define HAVE_MALLOC_H 1 #define STDC_HEADERS 1 #define HAVE_BCOPY 1 #define HAVE_BZERO 1 #define CHAR0ISDBL0 1 #define WORDS_BIGENDIAN 1 /* #undef U_INT_DEF */ #define VARARGS 1 /* #undef HAVE_PROTOTYPES */ /* #undef HAVE_PROTOTYPES_IN_STRUCT */ /* for inclusion into C++ files */ #ifdef __cplusplus #define ANSI_C 1 #ifndef HAVE_PROTOTYPES #define HAVE_PROTOTYPES 1 #endif #ifndef HAVE_PROTOTYPES_IN_STRUCT #define HAVE_PROTOTYPES_IN_STRUCT 1 #endif #endif /* __cplusplus */ /* example usage: VEC *PROTO(v_get,(int dim)); */ #ifdef HAVE_PROTOTYPES #define PROTO(name,args) name args #else #define PROTO(name,args) name() #endif /* HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES_IN_STRUCT /* PROTO_() is to be used instead of PROTO() in struct's and typedef's */ #define PROTO_(name,args) name args #else #define PROTO_(name,args) name() #endif /* HAVE_PROTOTYPES_IN_STRUCT */ /* for basic or larger versions */ #define COMPLEX 1 #define SPARSE 1 /* for loop unrolling */ /* #undef VUNROLL */ /* #undef MUNROLL */ /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif <<<<<<<<<<<<<<<<<< differences start here --- BMcK >>>>>>>>>>>>>>>>>>>>> /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif <<<<<<<<<<<<<<<<< end of differences --- BMcK >>>>>>>>>>>>>>>>>>> /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 /* #undef REAL_FLT */ /* #undef REAL_DBL */ /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #define F_MACHEPS 1.19209e-07 #define D_MACHEPS 2.22045e-16 #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif /* #undef M_MACHEPS */ /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #define M_MAX_INT 2147483647 #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #else #ifndef HUGE #define HUGE HUGE_VAL #endif #endif #ifdef ANSI_C extern int isatty(int); #endif gtk-wave-cleaner-0.22-04/meschach/README0000777000175000017500000004312613120075107020646 0ustar00alisteralister00000000000000 Meschach Library Version 1.2b David E. Stewart (david.stewart@anu.edu.au) and Zbigniew Leyk (zbigniew.leyk@anu.edu.au) School of Mathematical Sciences Australian National University Canberra ACT 0200 Australia [last revised: 6th April, 1994] 1. INTRODUCTION The Meschach Library is a numerical library of C routines for performing calculations on matrices and vectors. It is intended for solving systems of linear equations (dense and sparse), solve least squares problems, computing eigenvalues and eigenvectors, etc. We do not claim that it contains every useful algorithm in numerical linear algebra, but it does provide a basis on which more advanced algorithms can be built. The library is for people who know something about the C programming language, something of how to solve the numerical problem they are faced with but do not want to have the hassle of building all the necessary routines from the scratch. The library is not a loose collection of numerical routines but it comprises a coherent system. The current version is enhanced with many features comparing with previous versions. Since the memory requirements are nontrivial for large problems we have paid more attention to allocation/deallocation of memory. The source code is available to be perused, used and passed on without cost, while ensuring that the quality of the software is not compromised. The software is copyrighted; however, the copyright agreement follows in the footsteps of the Free Software Foundation in preventing abuse that occurs with totally public domain software. Detailed instructions for installing Meschach are contained below. Pronunciation: if in doubt, say "me-shark". This is close enough. Don't ask us "Why call it that?" Have a look at the quote at the front of the manual. 2. AVAILABILITY The authors make this code openly available to others, in the hope that it will prove to be a useful tool. We ask only that: * If you publish results obtained using Meschach, please consider acknowledging the source of the code. * If you discover any errors in the code, please promptly communicate them to the authors. We also suggest that you send email to the authors identifying yourself as a user of Meschach; this will enable the authors to notify you of any corrections/improvements in Meschach. 3. HOW TO GET IT There are several different forms in which you might receive Meschach. To provide a shorthand for describing collections of files, the Unix convention of putting alternative letters in [...] will be used. (So, fred[123] means the collection fred1, fred2 and fred3.) Meschach is available over Internet/AARnet via netlib, or at the anonymous ftp site thrain.anu.edu.au in the directory pub/meschach. There are five .shar files: meschach[01234].shar (which contain the library itself), meschach0.shar (which contains basic documentation and machine dependent files for a number of machines). Of the meschach[1234].shar files, only meschach[12].shar are needed for the basic Meschach library; the third .shar file contains the sparse matrix routines, and the the fourth contains the routines for complex numbers, vectors and matrices. There is also a README file that you should get from meschach0.shar. If you need the old iterative routines, the file oldmeschach.shar contains the files conjgrad.c, arnoldi.c and lanczos.c. To get the library from netlib, mail netlib@research.att.com send all from c/meschach There are a number of other netlib sites which mirror the main netlib sites. These include netlib@ornl.gov (Oak Ridge, TN, USA), netlib@nac.no (Oslo, Norway), ftp.cs.uow.edu.au (Wollongong, Australia; ftp only), netlib@nchc.edu.tw (Taiwan), elib.zib-berlin.de (Berlin, Germany; ftp only). (For anonymous ftp sites the directory containing the Meschach .shar files is pub/netlib/c/meschach or similar, possibly depending on the site.) Meschach is available in other forms on thrain.anu.edu.au by ftp in the directory pub/meschach. It is available as a .tar file (mesch12a.tar for version 1.2a), or as a collection of .shar files, or as a .zip file. The .tar and .zip versions each contain the entire contents of the Meschach library. There is a manual called "Meschach: Matrix Computations in C" which has been published by Centre for Mathematics and its Applications School of Mathematical Sciences Australian National University Canberra, ACT 0200 Australia and costs A$30 (about US$22) + postage/handling. You can order it by writing there or you can send email messages to one of us (david.stewart@anu.edu.au or zbigniew.leyk@anu.edu.au) and we can pass it on. If you don't have any money, as a stop gap you can get the **OLD** manual, although it is out of date, by anonymous ftp from thrain.anu.edu.au : /pub/meschach/version1.1b/bookdvi.tar [.Z or .gz] In addition, don't forget that the distribution includes a DOC directory which contains tutorial.txt and fnindex.txt which are respectively, the tutorial chapter (text version) and the function index (text version). 4. INSTALLATION a) On Unix machines To extract the files from the .shar files, put them all into a suitable directory and use sh .shar to expand the files. (Use one sh command per file; sh *.shar will not work in general.) For the .tar file, use tar xvf mesch12a.tar and for the .zip file use unzip mesch12a.zip On a Unix system you can use the configure script to set up the machine-dependent files. The script takes a number of options which are used for installing different subsets of the full Meschach. For the basic system, which requires only meschach[012].shar, use configure make basic make clean For including sparse operations, which requires meschach[0123].shar, use configure --with-sparse make sparse make clean For including complex operations, which requires meschach[0124].shar, use configure --with-complex make complex make clean For including everything, which requires meschach[01234].shar, use configure --with-all make all make clean To compile the complete library in single precision (with Real equivalent to float), add the --with-float option to configure, use configure --with-all --with-float make all make clean Some Unix-like systems may have some problems with this due to bugs or incompatibilities in various parts of the system. To check this use make torture and run torture. In this case use the machine-dependent files from the machines directory. (This is the case for RS/6000 machines, the -O switch results in failure of a routine in schur.c. Compiling without the -O switch results in correct results.) If you have problems using configure, or you use a non-Unix system, check the MACHINES directory (generated by meschach0.shar) for your machine, operating system and/or compiler. Save the machine dependent files makefile, machine.c and machine.h. Copy those files from the directory for your machine to the directory where the source code is. To link into a program prog.c, compile it using cc -o prog_name prog.c ....(source files).... meschach.a -lm This code has been mostly developed on the University of Queensland, Australia's Pyramid 9810 running BSD4.3. Initial development was on a Zilog Zeus Z8000 machine running Zeus, a Unix workalike operating system. Versions have also been successfully used on various Unix machines including Sun 3's, IBM RT's, SPARC's and an IBM RS/6000 running AIX. It has also been compiled on an IBM AT clone using Quick C. It has been designed to compile under either Kernighan and Richie, (Edition 1) C and under ANSI C. (And, indeed, it has been compiled in both ANSI C and non-ANSI C environments.) b) On non-Unix machines First look in the machines directory for your system type. If it is there, then copy the machine dependent files machine.h, makefile (and possibly machine.c) to the Meschach directory. If your machine type is not there, then you will need to either compile ``by hand'', or construct your own makefile and possibly machine.h as well. The machine-dependent files for various systems should be used as a starting point, and the ``vanilla'' version of machine.h should be used. Information on the machine-dependent files follows in the next three subsections. On an IBM PC clone, the source code would be on a floppy disk. Use xcopy a:* meschach to copy it to the meschach directory. Then ``cd meschach'', and then compile the source code. Different compilers on MSDOS machines will require different installation procedures. Check the directory meschach for the appropriate ``makefile'' for your compiler. If your compiler is not listed, then you should try compiling it ``by hand'', modifying the machine-dependent files as necessary. Worst come to worst, for a given C compiler, execute *.c on MS-DOS machines. For example, tcc *.c for Turbo C, and msc *.c for Microsoft C, or if you are using Quick C, qcl *.c and of course cc *.c for the standard Unix compiler. Once the object files have been generated, you will need to combine them into a library. Consult your local compiler's manual for details of how to do this. When compiling programs/routines that use Meschach, you will need to have access the the header files in the INCLUDE directory. The INCLUDE directory's contents can be copied to the directory where the programs/routines are compiled. The files in the DOC directory form a very brief form of documentation on the the library routines in Meschach. See the printed documentation for more comprehensive documentation of the Meschach routines. This can be obtained from the authors via email. The files and directories created by the machines.shar shell archive contain the files machine.c machine.h and makefile for a particular machine/operating system/compiler where they need to be different. Copy the files in the appropriate directory for your machine/operating system/compiler to the directory with the Meschach source before compiling. c) makefile This is setup by using the configure script on a Unix system, based on the makefile.in file. However, if you want to modify how the library is compiled, you are free to change the makefile. The most likely change that you would want to make to this file is to change the line CFLAGS = -O to suit your particular compiler. The code is intended to be compilable by both ANSI and non-ANSI compilers. To achieve this portability without sacrificing the ANSI function prototypes (which are very useful for avoiding problems with passing parameters) there is a token ANSI_C which must be #define'd in order to take full advantage of ANSI C. To do this you should do all compilations with #define ANSI_C 1 This can also be done at the compilation stage with a -DANSI_C flag. Again, you will have to use the -DANSI_C flag or its equivalent whenever you compile, or insert the line #define ANSI_C 1 in machine.h, to make full use of ANSI C with this matrix library. d) machine.h Like makefile this is normally set up by the configure script on Unix machines. However, for non-Unix systems, or if you need to set some things ``by hand'', change machine.h. There are a few quantities in here that should be modified to suit your particular compiler. Firstly, the macros MEM_COPY() and MEM_ZERO() need to be correctly defined here. The original library was compiled on BSD systems, and so it originally relied on bcopy() and bzero(). In machine.h you will find the definitions for using the standard ANSI C library routines: /*--------------------ANSI C--------------------*/ #include #include #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) Delete or comment out the alternative definitions and it should compile correctly. The source files containing memmove() and/or memset() are available by anonymous ftp from some ftp sites (try archie to discover them). The files are usually called memmove.c or memset.c. Some ftp sites which currently (Jan '94) have a version of these files are munnari.oz.au (in Australia), ftp.uu.net, gatekeeper.dec.com (USA), and unix.hensa.ac.uk (in the UK). The directory in which you will find memmove.c and memset.c typically looks like .../bsd-sources/lib/libc/... There are two further machine-dependent quantities that should be set. These are machine epsilon or the unit roundoff for double precision arithmetic, and the maximum value produced by the rand() routine, which is used in rand_vec() and rand_mat(). The current definitions of these are #define MACHEPS 2.2e-16 #define MAX_RAND 2.147483648e9 The value of MACHEPS should be correct for all IEEE standard double precision arithmetic. However, ANSI C's contains #define'd quantities DBL_EPSILON and RAND_MAX, so if you have an ANSI C compiler and headers, replace the above two lines of machine.h with #include /* for Real == float */ #define MACHEPS DBL_EPSILON #define MAX_RAND RAND_MAX The default value given for MAX_RAND is 2^31 , as the Pyramid 9810 and the SPARC 2's both have 32 bit words. There is a program macheps.c which is included in your source files which computes and prints out the value of MACHEPS for your machine. Some other macros control some aspects of Meschach. One of these is SEGMENTED which should be #define'd if you are working with a machine or compiler that does not allow large arrays to be allocated. For example, the most common memory models for MS-DOS compilers do not allow more than 64Kbyte to be allocated in one block. This limits square matrices to be no more than 9090 . Inserting #define SEGMENTED 1 into machine.h will mean that matrices are allocated a row at a time. 4. SAMPLE TESTS There are several programs for checking Meschach called torture (source: torture.c) for the dense routines, sptort (source: sptort.c) for the sparse routines, ztorture (source ztorture.c) for a complex version of torture, memtort (source memtort.c) for memory allocation/deallocation, itertort (source itertort.c) for iterative methods, mfuntort (source mfuntort.c) for computing powers of dense matrices, iotort (source iotort.c) for I/O routines. These can be compiled using make by "make torture", "make sptort", etc. The programs are part of meschach0.shar. 5. OTHER PROBLEMS Meschach is not a commercial package, so we do not guarantee that everything will be perfect or will install smoothly. Inevitably there will be unforeseen problems. If you come across any bugs or inconsistencies, please let us know. If you need to modify the results of the configure script, or need to construct your own machine.h and makefile's, please send them to us. A number of people sent us the machine dependent files for Meschach 1.1, but with the use of configure, and the new information needed for version 1.2, these machine dependent files don't have quite the right information. Hopefully, though, they are redundant. Non-Unix platforms at present require ``manual'' installation. Because of the variety of platforms (MS-DOS, Macintosh, VAX/VMS, Prime, Amiga, Atari, ....) this is left up to the users of these platforms. We hope that you can use the distibutable machine-dependent files as a starting point for this task. If you have programs or routines written using Meschach v.1.1x, you should put the statement #include "oldnames.h" at the beginning of your files. This is because a large number of the names of the routines have been changed (e.g. "get_vec()" has become "v_get()"). This will enable you to use the old names, although all of the error messages etc., will use the new names. Also note that the new iterative routines have a very different calling sequence. If you need the old iterative routines, they are in oldmeschach.shar. If you wish to let us know what you have done, etc., our email addresses are david.stewart@anu.edu.au zbigniew.leyk@anu.edu.au Good luck! ACKNOWLEDGMENTS Many people have helped in various ways with ideas and suggestions. Needless to say, the bugs are all ours! But these people should be thanked for their encouragement etc. These include a number of people at University of Queensland: Graeme Chandler, David De Wit, Martin Sharry, Michael Forbes, Phil Kilby, John Holt, Phil Pollett and Tony Watts. At the Australian National University: Mike Osborne, Steve Roberts, Margaret Kahn and Teresa Leyk. Karen George of the University of Canberra has been a source of both ideas and encouragement. Email has become significant part of work, and many people have pointed out bugs, inconsistencies and improvements to Meschach by email. These people include Ajay Shah of the University of Southern California, Dov Grobgeld of the Weizmann Institute, John Edstrom of the University of Calgary, Eric Grosse, one of the netlib organisers, Ole Saether of Oslo, Norway, Alfred Thiele and Pierre Asselin of Carnegie-Mellon Univeristy, Daniel Polani of the University of Mainz, Marian Slodicka of Slovakia, Kaifu Wu of Pomona, Hidetoshi Shimodaira of the University of Tokyo, Eng Siong of Edinburgh, Hirokawa Rui of the University of Tokyo, Marko Slyz of the University of Michigan, and Brook Milligan of the University of Texas. This list is only partial, and there are many others who have corresponded with us on details about Meschach and the like. Finally our thanks go to all those that have had to struggle with compilers and other things to get Meschach to work. gtk-wave-cleaner-0.22-04/meschach/arnoldi.c0000777000175000017500000001171213120075106021555 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Arnoldi method for finding eigenvalues of large non-symmetric matrices */ #include #include #include "matrix.h" #include "matrix2.h" #include "sparse.h" static char rcsid[] = "$Id: arnoldi.c,v 1.3 1994/01/13 05:45:40 des Exp $"; /* arnoldi -- an implementation of the Arnoldi method */ MAT *arnoldi(A,A_param,x0,m,h_rem,Q,H) VEC *(*A)(); void *A_param; VEC *x0; int m; Real *h_rem; MAT *Q, *H; { STATIC VEC *v=VNULL, *u=VNULL, *r=VNULL, *s=VNULL, *tmp=VNULL; int i; Real h_val; if ( ! A || ! Q || ! x0 ) error(E_NULL,"arnoldi"); if ( m <= 0 ) error(E_BOUNDS,"arnoldi"); if ( Q->n != x0->dim || Q->m != m ) error(E_SIZES,"arnoldi"); m_zero(Q); H = m_resize(H,m,m); m_zero(H); u = v_resize(u,x0->dim); v = v_resize(v,x0->dim); r = v_resize(r,m); s = v_resize(s,m); tmp = v_resize(tmp,x0->dim); MEM_STAT_REG(u,TYPE_VEC); MEM_STAT_REG(v,TYPE_VEC); MEM_STAT_REG(r,TYPE_VEC); MEM_STAT_REG(s,TYPE_VEC); MEM_STAT_REG(tmp,TYPE_VEC); sv_mlt(1.0/v_norm2(x0),x0,v); for ( i = 0; i < m; i++ ) { set_row(Q,i,v); u = (*A)(A_param,v,u); r = mv_mlt(Q,u,r); tmp = vm_mlt(Q,r,tmp); v_sub(u,tmp,u); h_val = v_norm2(u); /* if u == 0 then we have an exact subspace */ if ( h_val == 0.0 ) { *h_rem = h_val; return H; } /* iterative refinement -- ensures near orthogonality */ do { s = mv_mlt(Q,u,s); tmp = vm_mlt(Q,s,tmp); v_sub(u,tmp,u); v_add(r,s,r); } while ( v_norm2(s) > 0.1*(h_val = v_norm2(u)) ); /* now that u is nearly orthogonal to Q, update H */ set_col(H,i,r); if ( i == m-1 ) { *h_rem = h_val; continue; } /* H->me[i+1][i] = h_val; */ m_set_val(H,i+1,i,h_val); sv_mlt(1.0/h_val,u,v); } #ifdef THREADSAFE V_FREE(v); V_FREE(u); V_FREE(r); V_FREE(r); V_FREE(s); V_FREE(tmp); #endif return H; } /* sp_arnoldi -- uses arnoldi() with an explicit representation of A */ MAT *sp_arnoldi(A,x0,m,h_rem,Q,H) SPMAT *A; VEC *x0; int m; Real *h_rem; MAT *Q, *H; { return arnoldi(sp_mv_mlt,A,x0,m,h_rem,Q,H); } /* gmres -- generalised minimum residual algorithm of Saad & Schultz SIAM J. Sci. Stat. Comp. v.7, pp.856--869 (1986) -- y is overwritten with the solution */ VEC *gmres(A,A_param,m,Q,R,b,tol,x) VEC *(*A)(); void *A_param; VEC *b, *x; int m; MAT *Q, *R; double tol; { STATIC VEC *v=VNULL, *u=VNULL, *r=VNULL, *tmp=VNULL, *rhs=VNULL; STATIC VEC *diag=VNULL, *beta=VNULL; int i; Real h_val, norm_b; if ( ! A || ! Q || ! b || ! R ) error(E_NULL,"gmres"); if ( m <= 0 ) error(E_BOUNDS,"gmres"); if ( Q->n != b->dim || Q->m != m ) error(E_SIZES,"gmres"); x = v_copy(b,x); m_zero(Q); R = m_resize(R,m+1,m); m_zero(R); u = v_resize(u,x->dim); v = v_resize(v,x->dim); tmp = v_resize(tmp,x->dim); rhs = v_resize(rhs,m+1); MEM_STAT_REG(u,TYPE_VEC); MEM_STAT_REG(v,TYPE_VEC); MEM_STAT_REG(r,TYPE_VEC); MEM_STAT_REG(tmp,TYPE_VEC); MEM_STAT_REG(rhs,TYPE_VEC); norm_b = v_norm2(x); if ( norm_b == 0.0 ) error(E_RANGE,"gmres"); sv_mlt(1.0/norm_b,x,v); for ( i = 0; i < m; i++ ) { set_row(Q,i,v); tracecatch(u = (*A)(A_param,v,u),"gmres"); r = mv_mlt(Q,u,r); tmp = vm_mlt(Q,r,tmp); v_sub(u,tmp,u); h_val = v_norm2(u); set_col(R,i,r); R->me[i+1][i] = h_val; sv_mlt(1.0/h_val,u,v); } /* use i x i submatrix of R */ R = m_resize(R,i+1,i); rhs = v_resize(rhs,i+1); v_zero(rhs); rhs->ve[0] = norm_b; tmp = v_resize(tmp,i); diag = v_resize(diag,i+1); beta = v_resize(beta,i+1); MEM_STAT_REG(beta,TYPE_VEC); MEM_STAT_REG(diag,TYPE_VEC); QRfactor(R,diag /* ,beta */); tmp = QRsolve(R,diag, /* beta, */ rhs,tmp); v_resize(tmp,m); vm_mlt(Q,tmp,x); #ifdef THREADSAFE V_FREE(v); V_FREE(u); V_FREE(r); V_FREE(tmp); V_FREE(rhs); V_FREE(diag); V_FREE(beta); #endif return x; } gtk-wave-cleaner-0.22-04/meschach/bdfactor.c0000777000175000017500000004367113120075106021722 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Band matrix factorisation routines */ /* bdfactor.c 18/11/93 */ static char rcsid[] = "$Id: "; #include #include #include "matrix2.h" /* generate band matrix for a matrix with n columns, lb subdiagonals and ub superdiagonals; Way of saving a band of a matrix: first we save subdiagonals (from 0 to lb-1); then main diagonal (in the lb row) and then superdiagonals (from lb+1 to lb+ub) in such a way that the elements which were previously in one column are now also in one column */ #ifndef ANSI_C BAND *bd_get(lb,ub,n) int lb, ub, n; #else BAND *bd_get(int lb, int ub, int n) #endif { BAND *A; if (lb < 0 || ub < 0 || n <= 0) error(E_NEG,"bd_get"); if ((A = NEW(BAND)) == (BAND *)NULL) error(E_MEM,"bd_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_BAND,0,sizeof(BAND)); mem_numvar(TYPE_BAND,1); } lb = A->lb = min(n-1,lb); ub = A->ub = min(n-1,ub); A->mat = m_get(lb+ub+1,n); return A; } /* bd_free -- frees BAND matrix -- returns (-1) on error and 0 otherwise */ #ifndef ANSI_C int bd_free(A) BAND *A; #else int bd_free(BAND *A) #endif { if ( A == (BAND *)NULL || A->lb < 0 || A->ub < 0 ) /* don't trust it */ return (-1); if (A->mat) m_free(A->mat); if (mem_info_is_on()) { mem_bytes(TYPE_BAND,sizeof(BAND),0); mem_numvar(TYPE_BAND,-1); } free((char *)A); return 0; } /* resize band matrix */ #ifndef ANSI_C BAND *bd_resize(A,new_lb,new_ub,new_n) BAND *A; int new_lb,new_ub,new_n; #else BAND *bd_resize(BAND *A, int new_lb, int new_ub, int new_n) #endif { int lb,ub,i,j,l,shift,umin; Real **Av; if (new_lb < 0 || new_ub < 0 || new_n <= 0) error(E_NEG,"bd_resize"); if ( ! A ) return bd_get(new_lb,new_ub,new_n); if ( A->lb+A->ub+1 > A->mat->m ) error(E_INTERN,"bd_resize"); if ( A->lb == new_lb && A->ub == new_ub && A->mat->n == new_n ) return A; lb = A->lb; ub = A->ub; Av = A->mat->me; umin = min(ub,new_ub); /* ensure that unused triangles at edges are zero'd */ for ( i = 0; i < lb; i++ ) for ( j = A->mat->n - lb + i; j < A->mat->n; j++ ) Av[i][j] = 0.0; for ( i = lb+1,l=1; l <= umin; i++,l++ ) for ( j = 0; j < l; j++ ) Av[i][j] = 0.0; new_lb = A->lb = min(new_lb,new_n-1); new_ub = A->ub = min(new_ub,new_n-1); A->mat = m_resize(A->mat,new_lb+new_ub+1,new_n); Av = A->mat->me; /* if new_lb != lb then move the rows to get the main diag in the new_lb row */ if (new_lb > lb) { shift = new_lb-lb; for (i=lb+umin, l=i+shift; i >= 0; i--,l--) MEM_COPY(Av[i],Av[l],new_n*sizeof(Real)); for (l=shift-1; l >= 0; l--) __zero__(Av[l],new_n); } else if (new_lb < lb) { shift = lb - new_lb; for (i=shift, l=0; i <= lb+umin; i++,l++) MEM_COPY(Av[i],Av[l],new_n*sizeof(Real)); for (i=lb+umin+1; i <= new_lb+new_ub; i++) __zero__(Av[i],new_n); } return A; } /* bd_copy -- copies band matrix A to B, returning B -- if B is NULL, create -- B is set to the correct size */ #ifndef ANSI_C BAND *bd_copy(A,B) BAND *A,*B; #else BAND *bd_copy(const BAND *A, BAND *B) #endif { int lb,ub,i,j,n; if ( !A ) error(E_NULL,"bd_copy"); if (A == B) return B; n = A->mat->n; if ( !B ) B = bd_get(A->lb,A->ub,n); else if (B->lb != A->lb || B->ub != A->ub || B->mat->n != n ) B = bd_resize(B,A->lb,A->ub,n); if (A->mat == B->mat) return B; ub = B->ub = A->ub; lb = B->lb = A->lb; for ( i=0, j=n-lb; i <= lb; i++, j++ ) MEM_COPY(A->mat->me[i],B->mat->me[i],j*sizeof(Real)); for ( i=lb+1, j=1; i <= lb+ub; i++, j++ ) MEM_COPY(A->mat->me[i]+j,B->mat->me[i]+j,(n - j)*sizeof(Real)); return B; } /* copy band matrix bA to a square matrix A returning A */ #ifndef ANSI_C MAT *band2mat(bA,A) BAND *bA; MAT *A; #else MAT *band2mat(const BAND *bA, MAT *A) #endif { int i,j,l,n,n1; int lb, ub; Real **bmat; if ( !bA ) error(E_NULL,"band2mat"); if ( bA->mat == A ) error(E_INSITU,"band2mat"); ub = bA->ub; lb = bA->lb; n = bA->mat->n; n1 = n-1; bmat = bA->mat->me; A = m_resize(A,n,n); m_zero(A); for (j=0; j < n; j++) for (i=min(n1,j+lb),l=lb+j-i; i >= max(0,j-ub); i--,l++) A->me[i][j] = bmat[l][j]; return A; } /* copy a square matrix to a band matrix with lb subdiagonals and ub superdiagonals */ #ifndef ANSI_C BAND *mat2band(A,lb,ub,bA) BAND *bA; MAT *A; int lb, ub; #else BAND *mat2band(const MAT *A, int lb, int ub,BAND *bA) #endif { int i, j, l, n1; Real **bmat; if (! A ) error(E_NULL,"mat2band"); if (ub < 0 || lb < 0) error(E_SIZES,"mat2band"); if ( bA != (BAND *)NULL && bA->mat == A ) error(E_INSITU,"mat2band"); n1 = A->n-1; lb = min(n1,lb); ub = min(n1,ub); bA = bd_resize(bA,lb,ub,n1+1); bmat = bA->mat->me; for (j=0; j <= n1; j++) for (i=min(n1,j+lb),l=lb+j-i; i >= max(0,j-ub); i--,l++) bmat[l][j] = A->me[i][j]; return bA; } /* transposition of matrix in; out - matrix after transposition; can be done in situ */ #ifndef ANSI_C BAND *bd_transp(in,out) BAND *in, *out; #else BAND *bd_transp(const BAND *in, BAND *out) #endif { int i, j, jj, l, k, lb, ub, lub, n, n1; int in_situ; Real **in_v, **out_v; if ( in == (BAND *)NULL || in->mat == (MAT *)NULL ) error(E_NULL,"bd_transp"); lb = in->lb; ub = in->ub; lub = lb+ub; n = in->mat->n; n1 = n-1; in_situ = ( in == out ); if ( ! in_situ ) out = bd_resize(out,ub,lb,n); else { /* only need to swap lb and ub fields */ out->lb = ub; out->ub = lb; } in_v = in->mat->me; if (! in_situ) { int sh_in,sh_out; out_v = out->mat->me; for (i=0, l=lub, k=lb-i; i <= lub; i++,l--,k--) { sh_in = max(-k,0); sh_out = max(k,0); MEM_COPY(&(in_v[i][sh_in]),&(out_v[l][sh_out]), (n-sh_in-sh_out)*sizeof(Real)); /********************************** for (j=n1-sh_out, jj=n1-sh_in; j >= sh_in; j--,jj--) { out_v[l][jj] = in_v[i][j]; } **********************************/ } } else if (ub == lb) { Real tmp; for (i=0, l=lub, k=lb-i; i < lb; i++,l--,k--) { for (j=n1-k, jj=n1; j >= 0; j--,jj--) { tmp = in_v[l][jj]; in_v[l][jj] = in_v[i][j]; in_v[i][j] = tmp; } } } else if (ub > lb) { /* hence i-ub <= 0 & l-lb >= 0 */ int p,pp,lbi; for (i=0, l=lub; i < (lub+1)/2; i++,l--) { lbi = lb-i; for (j=l-lb, jj=0, p=max(-lbi,0), pp = max(l-ub,0); j <= n1; j++,jj++,p++,pp++) { in_v[l][pp] = in_v[i][p]; in_v[i][jj] = in_v[l][j]; } for ( ; p <= n1-max(lbi,0); p++,pp++) in_v[l][pp] = in_v[i][p]; } if (lub%2 == 0) { /* shift only */ i = lub/2; for (j=max(i-lb,0), jj=0; jj <= n1-ub+i; j++,jj++) in_v[i][jj] = in_v[i][j]; } } else { /* ub < lb, hence ub-l <= 0 & lb-i >= 0 */ int p,pp,ubi; for (i=0, l=lub; i < (lub+1)/2; i++,l--) { ubi = i-ub; for (j=n1-max(lb-l,0), jj=n1-max(-ubi,0), p=n1-lb+i, pp=n1; p >= 0; j--, jj--, pp--, p--) { in_v[i][jj] = in_v[l][j]; in_v[l][pp] = in_v[i][p]; } for ( ; jj >= max(ubi,0); j--, jj--) in_v[i][jj] = in_v[l][j]; } if (lub%2 == 0) { /* shift only */ i = lub/2; for (j=n1-lb+i, jj=n1-max(ub-i,0); j >= 0; j--, jj--) in_v[i][jj] = in_v[i][j]; } } return out; } /* bdv_mltadd -- band matrix-vector multiply and add -- returns out <- x + s.bA.y -- if y is NULL then create y (as zero vector) -- error if either A or x is NULL */ #ifndef ANSI_C VEC *bdv_mltadd(x,y,bA,s,out) BAND *bA; VEC *x, *y; double s; VEC *out; #else VEC *bdv_mltadd(const VEC *x, const VEC *y, const BAND *bA, double s, VEC *out) #endif { int i, j; if ( ! bA || ! x || ! y ) error(E_NULL,"bdv_mltadd"); if ( bA->mat->n != x->dim || y->dim != x->dim ) error(E_SIZES,"bdv_mltadd"); if ( ! out || out->dim != x->dim ) out = v_resize(out,x->dim); out = v_copy(x,out); for ( j = 0; j < x->dim; j++ ) for ( i = max(j-bA->ub,0); i <= j+bA->lb && i < x->dim; i++ ) out->ve[i] += s*bd_get_val(bA,i,j)*y->ve[j]; return out; } /* vbd_mltadd -- band matrix-vector multiply and add -- returns out^T <- x^T + s.y^T.bA -- if out is NULL then create out (as zero vector) -- error if either bA or x is NULL */ #ifndef ANSI_C VEC *vbd_mltadd(x,y,bA,s,out) BAND *bA; VEC *x, *y; double s; VEC *out; #else VEC *vbd_mltadd(const VEC *x, const VEC *y, const BAND *bA, double s, VEC *out) #endif { int i, j; if ( ! bA || ! x || ! y ) error(E_NULL,"vbd_mltadd"); if ( bA->mat->n != x->dim || y->dim != x->dim ) error(E_SIZES,"vbd_mltadd"); if ( ! out || out->dim != x->dim ) out = v_resize(out,x->dim); out = v_copy(x,out); for ( j = 0; j < x->dim; j++ ) for ( i = max(j-bA->ub,0); i <= j+bA->lb && i < x->dim; i++ ) out->ve[j] += s*bd_get_val(bA,i,j)*y->ve[i]; return out; } /* bd_zero -- zeros band matrix A which is returned */ #ifndef ANSI_C BAND *bd_zero(A) BAND *A; #else BAND *bd_zero(BAND *A) #endif { if ( ! A ) error(E_NULL,"bd_zero"); m_zero(A->mat); return A; } /* bds_mltadd -- returns OUT <- A+alpha*B -- OUT is created (as zero) if NULL -- if OUT is not the correct size, it is re-sized before the operation -- if A or B are null, and error is generated */ #ifndef ANSI_C BAND *bds_mltadd(A,B,alpha,OUT) BAND *A, *B, *OUT; Real alpha; #else BAND *bds_mltadd(const BAND *A, const BAND *B, double alpha, BAND *OUT) #endif { int i; if ( ! A || ! B ) error(E_NULL,"bds_mltadd"); if ( A->mat->n != B->mat->n ) error(E_SIZES,"bds_mltadd"); if ( A == OUT || B == OUT ) error(E_INSITU,"bds_mltadd"); OUT = bd_copy(A,OUT); OUT = bd_resize(OUT,max(A->lb,B->lb),max(A->ub,B->ub),A->mat->n); for ( i = 0; i <= B->lb + B->ub; i++ ) __mltadd__(OUT->mat->me[i+OUT->lb-B->lb],B->mat->me[i],alpha,B->mat->n); return OUT; } /* sbd_mlt -- returns OUT <- s.A */ #ifndef ANSI_C BAND *sbd_mlt(Real s, BAND *A, BAND *OUT) #else BAND *sbd_mlt(Real s, const BAND *A, BAND *OUT) #endif { if ( ! A ) error(E_NULL,"sbd_mlt"); OUT = bd_resize(OUT,A->lb,A->ub,A->mat->n); sm_mlt(s,A->mat,OUT->mat); return OUT; } /* bdLUfactor -- gaussian elimination with partial pivoting -- on entry, the matrix A in band storage with elements in rows 0 to lb+ub; The jth column of A is stored in the jth column of band A (bA) as follows: bA->mat->me[lb+j-i][j] = A->me[i][j] for max(0,j-lb) <= i <= min(A->n-1,j+ub); -- on exit: U is stored as an upper triangular matrix with lb+ub superdiagonals in rows lb to 2*lb+ub, and the matrix L is stored in rows 0 to lb-1. Matrix U is permuted, whereas L is not permuted !!! Therefore we save some memory. */ #ifndef ANSI_C BAND *bdLUfactor(bA,pivot) BAND *bA; PERM *pivot; #else BAND *bdLUfactor(BAND *bA, PERM *pivot) #endif { int i, j, k, l, n, n1, lb, ub, lub, k_end, k_lub; int i_max, shift; Real **bA_v; Real max1, temp; if ( bA==(BAND *)NULL || pivot==(PERM *)NULL ) error(E_NULL,"bdLUfactor"); lb = bA->lb; ub = bA->ub; lub = lb+ub; n = bA->mat->n; n1 = n-1; lub = lb+ub; if ( pivot->size != n ) error(E_SIZES,"bdLUfactor"); /* initialise pivot with identity permutation */ for ( i=0; i < n; i++ ) pivot->pe[i] = i; /* extend band matrix */ /* extended part is filled with zeros */ bA = bd_resize(bA,lb,min(n1,lub),n); bA_v = bA->mat->me; /* main loop */ for ( k=0; k < n1; k++ ) { k_end = max(0,lb+k-n1); k_lub = min(k+lub,n1); /* find the best pivot row */ max1 = 0.0; i_max = -1; for ( i=lb; i >= k_end; i-- ) { temp = fabs(bA_v[i][k]); if ( temp > max1 ) { max1 = temp; i_max = i; } } /* if no pivot then ignore column k... */ if ( i_max == -1 ) continue; /* do we pivot ? */ if ( i_max != lb ) /* yes we do... */ { /* save transposition using non-shifted indices */ shift = lb-i_max; px_transp(pivot,k+shift,k); for ( i=lb, j=k; j <= k_lub; i++,j++ ) { temp = bA_v[i][j]; bA_v[i][j] = bA_v[i-shift][j]; bA_v[i-shift][j] = temp; } } /* row operations */ for ( i=lb-1; i >= k_end; i-- ) { temp = bA_v[i][k] /= bA_v[lb][k]; shift = lb-i; for ( j=k+1,l=i+1; j <= k_lub; l++,j++ ) bA_v[l][j] -= temp*bA_v[l+shift][j]; } } return bA; } /* bdLUsolve -- given an LU factorisation in bA, solve bA*x=b */ /* pivot is changed upon return */ #ifndef ANSI_C VEC *bdLUsolve(bA,pivot,b,x) BAND *bA; PERM *pivot; VEC *b,*x; #else VEC *bdLUsolve(const BAND *bA, PERM *pivot, const VEC *b, VEC *x) #endif { int i,j,l,n,n1,pi,lb,ub,jmin, maxj; Real c; Real **bA_v; if ( bA==(BAND *)NULL || b==(VEC *)NULL || pivot==(PERM *)NULL ) error(E_NULL,"bdLUsolve"); if ( bA->mat->n != b->dim || bA->mat->n != pivot->size) error(E_SIZES,"bdLUsolve"); lb = bA->lb; ub = bA->ub; n = b->dim; n1 = n-1; bA_v = bA->mat->me; x = v_resize(x,b->dim); px_vec(pivot,b,x); /* solve Lx = b; implicit diagonal = 1 L is not permuted, therefore it must be permuted now */ px_inv(pivot,pivot); for (j=0; j < n; j++) { jmin = j+1; c = x->ve[j]; maxj = max(0,j+lb-n1); for (i=jmin,l=lb-1; l >= maxj; i++,l--) { if ( (pi = pivot->pe[i]) < jmin) pi = pivot->pe[i] = pivot->pe[pi]; x->ve[pi] -= bA_v[l][j]*c; } } /* solve Ux = b; explicit diagonal */ x->ve[n1] /= bA_v[lb][n1]; for (i=n-2; i >= 0; i--) { c = x->ve[i]; for (j=min(n1,i+ub), l=lb+j-i; j > i; j--,l--) c -= bA_v[l][j]*x->ve[j]; x->ve[i] = c/bA_v[lb][i]; } return (x); } /* LDLfactor -- L.D.L' factorisation of A in-situ; A is a band matrix it works using only lower bandwidth & main diagonal so it is possible to set A->ub = 0 */ #ifndef ANSI_C BAND *bdLDLfactor(A) BAND *A; #else BAND *bdLDLfactor(BAND *A) #endif { int i,j,k,n,n1,lb,ki,jk,ji,lbkm,lbkp; Real **Av; Real c, cc; if ( ! A ) error(E_NULL,"bdLDLfactor"); if (A->lb == 0) return A; lb = A->lb; n = A->mat->n; n1 = n-1; Av = A->mat->me; for (k=0; k < n; k++) { lbkm = lb-k; lbkp = lb+k; /* matrix D */ c = Av[lb][k]; for (j=max(0,-lbkm), jk=lbkm+j; j < k; j++, jk++) { cc = Av[jk][j]; c -= Av[lb][j]*cc*cc; } if (c == 0.0) error(E_SING,"bdLDLfactor"); Av[lb][k] = c; /* matrix L */ for (i=min(n1,lbkp), ki=lbkp-i; i > k; i--,ki++) { c = Av[ki][k]; for (j=max(0,i-lb), ji=lb+j-i, jk=lbkm+j; j < k; j++, ji++, jk++) c -= Av[lb][j]*Av[ji][j]*Av[jk][j]; Av[ki][k] = c/Av[lb][k]; } } return A; } /* solve A*x = b, where A is factorized by Choleski LDL^T factorization */ #ifndef ANSI_C VEC *bdLDLsolve(A,b,x) BAND *A; VEC *b, *x; #else VEC *bdLDLsolve(const BAND *A, const VEC *b, VEC *x) #endif { int i,j,l,n,n1,lb,ilb; Real **Av, *Avlb; Real c; if ( ! A || ! b ) error(E_NULL,"bdLDLsolve"); if ( A->mat->n != b->dim ) error(E_SIZES,"bdLDLsolve"); n = A->mat->n; n1 = n-1; x = v_resize(x,n); lb = A->lb; Av = A->mat->me; Avlb = Av[lb]; /* solve L*y = b */ x->ve[0] = b->ve[0]; for (i=1; i < n; i++) { ilb = i-lb; c = b->ve[i]; for (j=max(0,ilb), l=j-ilb; j < i; j++,l++) c -= Av[l][j]*x->ve[j]; x->ve[i] = c; } /* solve D*z = y */ for (i=0; i < n; i++) x->ve[i] /= Avlb[i]; /* solve L^T*x = z */ for (i=n-2; i >= 0; i--) { ilb = i+lb; c = x->ve[i]; for (j=min(n1,ilb), l=ilb-j; j > i; j--,l++) c -= Av[l][i]*x->ve[j]; x->ve[i] = c; } return x; } /* ****************************************************** This function is a contribution from Ruediger Franke. His e-mail addres is: Ruediger.Franke@rz.tu-ilmenau.de ****************************************************** */ /* bd_mv_mlt -- * computes out = A * x * may not work in situ (x != out) */ VEC *bd_mv_mlt(A, x, out) BAND *A; VEC *x, *out; { int i, j, j_end, k; int start_idx, end_idx; int n, m, lb, ub; Real **A_me; Real *x_ve; Real sum; if (!A || !x) error(E_NULL,"bd_mv_mlt"); if (x->dim != A->mat->n) error(E_SIZES,"bd_mv_mlt"); if (!out || out->dim != A->mat->n) out = v_resize(out, A->mat->n); if (out == x) error(E_INSITU,"bd_mv_mlt"); n = A->mat->n; m = A->mat->m; lb = A->lb; ub = A->ub; A_me = A->mat->me; start_idx = lb; end_idx = m + n-1 - ub; for (i=0; ive + k; sum = 0.0; for (; j < j_end; j++, k++) sum += A_me[j][k] * *x_ve++; out->ve[i] = sum; } return out; } gtk-wave-cleaner-0.22-04/meschach/bkpfacto.c0000777000175000017500000002075213120075106021722 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Matrix factorisation routines to work with the other matrix files. */ static char rcsid[] = "$Id: bkpfacto.c,v 1.7 1994/01/13 05:45:50 des Exp $"; #include #include #include "matrix.h" #include "matrix2.h" #define btos(x) ((x) ? "TRUE" : "FALSE") /* Most matrix factorisation routines are in-situ unless otherwise specified */ #define alpha 0.6403882032022076 /* = (1+sqrt(17))/8 */ /* sqr -- returns square of x -- utility function */ double sqr(x) double x; { return x*x; } /* interchange -- a row/column swap routine */ static void interchange(A,i,j) MAT *A; /* assumed != NULL & also SQUARE */ int i, j; /* assumed in range */ { Real **A_me, tmp; int k, n; A_me = A->me; n = A->n; if ( i == j ) return; if ( i > j ) { k = i; i = j; j = k; } for ( k = 0; k < i; k++ ) { /* tmp = A_me[k][i]; */ tmp = m_entry(A,k,i); /* A_me[k][i] = A_me[k][j]; */ m_set_val(A,k,i,m_entry(A,k,j)); /* A_me[k][j] = tmp; */ m_set_val(A,k,j,tmp); } for ( k = j+1; k < n; k++ ) { /* tmp = A_me[j][k]; */ tmp = m_entry(A,j,k); /* A_me[j][k] = A_me[i][k]; */ m_set_val(A,j,k,m_entry(A,i,k)); /* A_me[i][k] = tmp; */ m_set_val(A,i,k,tmp); } for ( k = i+1; k < j; k++ ) { /* tmp = A_me[k][j]; */ tmp = m_entry(A,k,j); /* A_me[k][j] = A_me[i][k]; */ m_set_val(A,k,j,m_entry(A,i,k)); /* A_me[i][k] = tmp; */ m_set_val(A,i,k,tmp); } /* tmp = A_me[i][i]; */ tmp = m_entry(A,i,i); /* A_me[i][i] = A_me[j][j]; */ m_set_val(A,i,i,m_entry(A,j,j)); /* A_me[j][j] = tmp; */ m_set_val(A,j,j,tmp); } /* BKPfactor -- Bunch-Kaufman-Parlett factorisation of A in-situ -- A is factored into the form P'AP = MDM' where P is a permutation matrix, M lower triangular and D is block diagonal with blocks of size 1 or 2 -- P is stored in pivot; blocks[i]==i iff D[i][i] is a block */ #ifndef ANSI_C MAT *BKPfactor(A,pivot,blocks) MAT *A; PERM *pivot, *blocks; #else MAT *BKPfactor(MAT *A, PERM *pivot, PERM *blocks) #endif { int i, j, k, n, onebyone, r; Real **A_me, aii, aip1, aip1i, lambda, sigma, tmp; Real det, s, t; if ( ! A || ! pivot || ! blocks ) error(E_NULL,"BKPfactor"); if ( A->m != A->n ) error(E_SQUARE,"BKPfactor"); if ( A->m != pivot->size || pivot->size != blocks->size ) error(E_SIZES,"BKPfactor"); n = A->n; A_me = A->me; px_ident(pivot); px_ident(blocks); for ( i = 0; i < n; i = onebyone ? i+1 : i+2 ) { /* printf("# Stage: %d\n",i); */ aii = fabs(m_entry(A,i,i)); lambda = 0.0; r = (i+1 < n) ? i+1 : i; for ( k = i+1; k < n; k++ ) { tmp = fabs(m_entry(A,i,k)); if ( tmp >= lambda ) { lambda = tmp; r = k; } } /* printf("# lambda = %g, r = %d\n", lambda, r); */ /* printf("# |A[%d][%d]| = %g\n",r,r,fabs(m_entry(A,r,r))); */ /* determine if 1x1 or 2x2 block, and do pivoting if needed */ if ( aii >= alpha*lambda ) { onebyone = TRUE; goto dopivot; } /* compute sigma */ sigma = 0.0; for ( k = i; k < n; k++ ) { if ( k == r ) continue; tmp = ( k > r ) ? fabs(m_entry(A,r,k)) : fabs(m_entry(A,k,r)); if ( tmp > sigma ) sigma = tmp; } if ( aii*sigma >= alpha*sqr(lambda) ) onebyone = TRUE; else if ( fabs(m_entry(A,r,r)) >= alpha*sigma ) { /* printf("# Swapping rows/cols %d and %d\n",i,r); */ interchange(A,i,r); px_transp(pivot,i,r); onebyone = TRUE; } else { /* printf("# Swapping rows/cols %d and %d\n",i+1,r); */ interchange(A,i+1,r); px_transp(pivot,i+1,r); px_transp(blocks,i,i+1); onebyone = FALSE; } /* printf("onebyone = %s\n",btos(onebyone)); */ /* printf("# Matrix so far (@checkpoint A) =\n"); */ /* m_output(A); */ /* printf("# pivot =\n"); px_output(pivot); */ /* printf("# blocks =\n"); px_output(blocks); */ dopivot: if ( onebyone ) { /* do one by one block */ if ( m_entry(A,i,i) != 0.0 ) { aii = m_entry(A,i,i); for ( j = i+1; j < n; j++ ) { tmp = m_entry(A,i,j)/aii; for ( k = j; k < n; k++ ) m_sub_val(A,j,k,tmp*m_entry(A,i,k)); m_set_val(A,i,j,tmp); } } } else /* onebyone == FALSE */ { /* do two by two block */ det = m_entry(A,i,i)*m_entry(A,i+1,i+1)-sqr(m_entry(A,i,i+1)); /* Must have det < 0 */ /* printf("# det = %g\n",det); */ aip1i = m_entry(A,i,i+1)/det; aii = m_entry(A,i,i)/det; aip1 = m_entry(A,i+1,i+1)/det; for ( j = i+2; j < n; j++ ) { s = - aip1i*m_entry(A,i+1,j) + aip1*m_entry(A,i,j); t = - aip1i*m_entry(A,i,j) + aii*m_entry(A,i+1,j); for ( k = j; k < n; k++ ) m_sub_val(A,j,k,m_entry(A,i,k)*s + m_entry(A,i+1,k)*t); m_set_val(A,i,j,s); m_set_val(A,i+1,j,t); } } /* printf("# Matrix so far (@checkpoint B) =\n"); */ /* m_output(A); */ /* printf("# pivot =\n"); px_output(pivot); */ /* printf("# blocks =\n"); px_output(blocks); */ } /* set lower triangular half */ for ( i = 0; i < A->m; i++ ) for ( j = 0; j < i; j++ ) m_set_val(A,i,j,m_entry(A,j,i)); return A; } /* BKPsolve -- solves A.x = b where A has been factored a la BKPfactor() -- returns x, which is created if NULL */ #ifndef ANSI_C VEC *BKPsolve(A,pivot,block,b,x) MAT *A; PERM *pivot, *block; VEC *b, *x; #else VEC *BKPsolve(const MAT *A, PERM *pivot, const PERM *block, const VEC *b, VEC *x) #endif { STATIC VEC *tmp=VNULL; /* dummy storage needed */ int i, j, n, onebyone; Real **A_me, a11, a12, a22, b1, b2, det, sum, *tmp_ve, tmp_diag; if ( ! A || ! pivot || ! block || ! b ) error(E_NULL,"BKPsolve"); if ( A->m != A->n ) error(E_SQUARE,"BKPsolve"); n = A->n; if ( b->dim != n || pivot->size != n || block->size != n ) error(E_SIZES,"BKPsolve"); x = v_resize(x,n); tmp = v_resize(tmp,n); MEM_STAT_REG(tmp,TYPE_VEC); A_me = A->me; tmp_ve = tmp->ve; px_vec(pivot,b,tmp); /* solve for lower triangular part */ for ( i = 0; i < n; i++ ) { sum = v_entry(tmp,i); if ( block->pe[i] < i ) for ( j = 0; j < i-1; j++ ) sum -= m_entry(A,i,j)*v_entry(tmp,j); else for ( j = 0; j < i; j++ ) sum -= m_entry(A,i,j)*v_entry(tmp,j); v_set_val(tmp,i,sum); } /* printf("# BKPsolve: solving L part: tmp =\n"); v_output(tmp); */ /* solve for diagonal part */ for ( i = 0; i < n; i = onebyone ? i+1 : i+2 ) { onebyone = ( block->pe[i] == i ); if ( onebyone ) { tmp_diag = m_entry(A,i,i); if ( tmp_diag == 0.0 ) error(E_SING,"BKPsolve"); /* tmp_ve[i] /= tmp_diag; */ v_set_val(tmp,i,v_entry(tmp,i) / tmp_diag); } else { a11 = m_entry(A,i,i); a22 = m_entry(A,i+1,i+1); a12 = m_entry(A,i+1,i); b1 = v_entry(tmp,i); b2 = v_entry(tmp,i+1); det = a11*a22-a12*a12; /* < 0 : see BKPfactor() */ if ( det == 0.0 ) error(E_SING,"BKPsolve"); det = 1/det; v_set_val(tmp,i,det*(a22*b1-a12*b2)); v_set_val(tmp,i+1,det*(a11*b2-a12*b1)); } } /* printf("# BKPsolve: solving D part: tmp =\n"); v_output(tmp); */ /* solve for transpose of lower traingular part */ for ( i = n-1; i >= 0; i-- ) { /* use symmetry of factored form to get stride 1 */ sum = v_entry(tmp,i); if ( block->pe[i] > i ) for ( j = i+2; j < n; j++ ) sum -= m_entry(A,i,j)*v_entry(tmp,j); else for ( j = i+1; j < n; j++ ) sum -= m_entry(A,i,j)*v_entry(tmp,j); v_set_val(tmp,i,sum); } /* printf("# BKPsolve: solving L^T part: tmp =\n");v_output(tmp); */ /* and do final permutation */ x = pxinv_vec(pivot,tmp,x); #ifdef THREADSAFE V_FREE(tmp); #endif return x; } gtk-wave-cleaner-0.22-04/meschach/chfactor.c0000777000175000017500000001262413120075106021721 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Matrix factorisation routines to work with the other matrix files. */ /* CHfactor.c 1.2 11/25/87 */ static char rcsid[] = "$Id: chfactor.c,v 1.2 1994/01/13 05:36:36 des Exp $"; #include #include #include "matrix.h" #include "matrix2.h" /* Most matrix factorisation routines are in-situ unless otherwise specified */ /* CHfactor -- Cholesky L.L' factorisation of A in-situ */ #ifndef ANSI_C MAT *CHfactor(A) MAT *A; #else MAT *CHfactor(MAT *A) #endif { unsigned int i, j, k, n; Real **A_ent, *A_piv, *A_row, sum, tmp; if ( A==(MAT *)NULL ) error(E_NULL,"CHfactor"); if ( A->m != A->n ) error(E_SQUARE,"CHfactor"); n = A->n; A_ent = A->me; for ( k=0; km != A->n || A->n != b->dim ) error(E_SIZES,"CHsolve"); x = v_resize(x,b->dim); Lsolve(A,b,x,0.0); Usolve(A,x,x,0.0); return (x); } /* LDLfactor -- L.D.L' factorisation of A in-situ */ #ifndef ANSI_C MAT *LDLfactor(A) MAT *A; #else MAT *LDLfactor(MAT *A) #endif { unsigned int i, k, n, p; Real **A_ent; Real d, sum; STATIC VEC *r = VNULL; if ( ! A ) error(E_NULL,"LDLfactor"); if ( A->m != A->n ) error(E_SQUARE,"LDLfactor"); n = A->n; A_ent = A->me; r = v_resize(r,n); MEM_STAT_REG(r,TYPE_VEC); for ( k = 0; k < n; k++ ) { sum = 0.0; for ( p = 0; p < k; p++ ) { r->ve[p] = A_ent[p][p]*A_ent[k][p]; sum += r->ve[p]*A_ent[k][p]; } d = A_ent[k][k] -= sum; if ( d == 0.0 ) error(E_SING,"LDLfactor"); for ( i = k+1; i < n; i++ ) { sum = __ip__(A_ent[i],r->ve,(int)k); /**************************************** sum = 0.0; for ( p = 0; p < k; p++ ) sum += A_ent[i][p]*r->ve[p]; ****************************************/ A_ent[i][k] = (A_ent[i][k] - sum)/d; } } #ifdef THREADSAFE V_FREE(r); #endif return A; } /* LDLsolve -- solves linear system A.x = b with A factored by LDLfactor() -- returns x, which is created if it is NULL on entry */ #ifndef ANSI_C VEC *LDLsolve(LDL,b,x) MAT *LDL; VEC *b, *x; #else VEC *LDLsolve(const MAT *LDL, const VEC *b, VEC *x) #endif { if ( ! LDL || ! b ) error(E_NULL,"LDLsolve"); if ( LDL->m != LDL->n ) error(E_SQUARE,"LDLsolve"); if ( LDL->m != b->dim ) error(E_SIZES,"LDLsolve"); x = v_resize(x,b->dim); Lsolve(LDL,b,x,1.0); Dsolve(LDL,x,x); LTsolve(LDL,x,x,1.0); return x; } /* MCHfactor -- Modified Cholesky L.L' factorisation of A in-situ */ #ifndef ANSI_C MAT *MCHfactor(A,tol) MAT *A; double tol; #else MAT *MCHfactor(MAT *A, double tol) #endif { unsigned int i, j, k, n; Real **A_ent, *A_piv, *A_row, sum, tmp; if ( A==(MAT *)NULL ) error(E_NULL,"MCHfactor"); if ( A->m != A->n ) error(E_SQUARE,"MCHfactor"); if ( tol <= 0.0 ) error(E_RANGE,"MCHfactor"); n = A->n; A_ent = A->me; for ( k=0; k&2; exit 1 fi eval "with_`echo $package|sed s/-/_/g`=1" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb | --ver | --ve | --v) verbose=yes ;; *) ;; esac fi done trap 'rm -f conftest* core; exit 1' 1 3 15 # Needed for some versions of `tr' so that character classes in `[]' work. if test "${LANG+set}" = "set" ; then LANG=C fi rm -f conftest* compile='${CC-cc} $CFLAGS $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1' # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. unique_file=err.c # Find the source files, if location was not specified. if test -z "$srcdir"; then srcdirdefaulted=yes # Try the directory containing this script, then `..'. prog=$0 confdir=`echo $prog|sed 's%/[^/][^/]*$%%'` test "X$confdir" = "X$prog" && confdir=. srcdir=$confdir if test ! -r $srcdir/$unique_file; then srcdir=.. fi fi if test ! -r $srcdir/$unique_file; then if test x$srcdirdefaulted = xyes; then echo "configure: Can not find sources in \`${confdir}' or \`..'." 1>&2 else echo "configure: Can not find sources in \`${srcdir}'." 1>&2 fi exit 1 fi # Preserve a srcdir of `.' to avoid automounter screwups with pwd. # But we can't avoid them for `..', to make subdirectories work. case $srcdir in .|/*|~*) ;; *) srcdir=`cd $srcdir; pwd` ;; # Make relative path absolute. esac PROGS="" if test -z "$CC"; then # Extract the first word of `acc', so it can be a program name with args. set dummy acc; word=$2 echo checking for $word IFS="${IFS= }"; saveifs="$IFS"; IFS="${IFS}:" for dir in $PATH; do test -z "$dir" && dir=. if test -f $dir/$word; then CC="acc" break fi done IFS="$saveifs" fi test -z "$CC" && CC="""" test -n "$CC" -a -n "$verbose" && echo " setting CC to $CC" if test -z "$CC"; then # Extract the first word of `cc', so it can be a program name with args. set dummy cc; word=$2 echo checking for $word IFS="${IFS= }"; saveifs="$IFS"; IFS="${IFS}:" for dir in $PATH; do test -z "$dir" && dir=. if test -f $dir/$word; then CC="cc" break fi done IFS="$saveifs" fi test -z "$CC" && CC="gcc" test -n "$CC" -a -n "$verbose" && echo " setting CC to $CC" echo checking how to run the C preprocessor if test -z "$CPP"; then CPP='${CC-cc} -E' cat > conftest.c < EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then : else CPP=/lib/cpp fi rm -f conftest* fi echo checking for AIX cat > conftest.c < conftest.out 2>&1" if egrep "yes" conftest.out >/dev/null 2>&1; then { test -n "$verbose" && \ echo ' defining' _ALL_SOURCE DEFS="$DEFS -D_ALL_SOURCE=1" SEDDEFS="${SEDDEFS}\${SEDdA}_ALL_SOURCE\${SEDdB}_ALL_SOURCE\${SEDdC}1\${SEDdD} \${SEDuA}_ALL_SOURCE\${SEDuB}_ALL_SOURCE\${SEDuC}1\${SEDuD} \${SEDeA}_ALL_SOURCE\${SEDeB}_ALL_SOURCE\${SEDeC}1\${SEDeD} " } fi rm -f conftest* echo checking for minix/config.h cat > conftest.c < EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then MINIX=1 fi rm -f conftest* # The Minix shell can't assign to the same variable on the same line! if test -n "$MINIX"; then { test -n "$verbose" && \ echo ' defining' _POSIX_SOURCE DEFS="$DEFS -D_POSIX_SOURCE=1" SEDDEFS="${SEDDEFS}\${SEDdA}_POSIX_SOURCE\${SEDdB}_POSIX_SOURCE\${SEDdC}1\${SEDdD} \${SEDuA}_POSIX_SOURCE\${SEDuB}_POSIX_SOURCE\${SEDuC}1\${SEDuD} \${SEDeA}_POSIX_SOURCE\${SEDeB}_POSIX_SOURCE\${SEDeC}1\${SEDeD} " } { test -n "$verbose" && \ echo ' defining' _POSIX_1_SOURCE to be '2' DEFS="$DEFS -D_POSIX_1_SOURCE=2" SEDDEFS="${SEDDEFS}\${SEDdA}_POSIX_1_SOURCE\${SEDdB}_POSIX_1_SOURCE\${SEDdC}2\${SEDdD} \${SEDuA}_POSIX_1_SOURCE\${SEDuB}_POSIX_1_SOURCE\${SEDuC}2\${SEDuD} \${SEDeA}_POSIX_1_SOURCE\${SEDeB}_POSIX_1_SOURCE\${SEDeC}2\${SEDeD} " } { test -n "$verbose" && \ echo ' defining' _MINIX DEFS="$DEFS -D_MINIX=1" SEDDEFS="${SEDDEFS}\${SEDdA}_MINIX\${SEDdB}_MINIX\${SEDdC}1\${SEDdD} \${SEDuA}_MINIX\${SEDuB}_MINIX\${SEDuC}1\${SEDuD} \${SEDeA}_MINIX\${SEDeB}_MINIX\${SEDeC}1\${SEDeD} " } fi echo checking for POSIXized ISC if test -d /etc/conf/kconfig.d && grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 then ISC=1 # If later tests want to check for ISC. { test -n "$verbose" && \ echo ' defining' _POSIX_SOURCE DEFS="$DEFS -D_POSIX_SOURCE=1" SEDDEFS="${SEDDEFS}\${SEDdA}_POSIX_SOURCE\${SEDdB}_POSIX_SOURCE\${SEDdC}1\${SEDdD} \${SEDuA}_POSIX_SOURCE\${SEDuB}_POSIX_SOURCE\${SEDuC}1\${SEDuD} \${SEDeA}_POSIX_SOURCE\${SEDeB}_POSIX_SOURCE\${SEDeC}1\${SEDeD} " } if test -n "$GCC"; then CC="$CC -posix" else CC="$CC -Xp" fi fi if test -z "$RANLIB"; then # Extract the first word of `ranlib', so it can be a program name with args. set dummy ranlib; word=$2 echo checking for $word IFS="${IFS= }"; saveifs="$IFS"; IFS="${IFS}:" for dir in $PATH; do test -z "$dir" && dir=. if test -f $dir/$word; then RANLIB="ranlib" break fi done IFS="$saveifs" fi test -z "$RANLIB" && RANLIB=":" test -n "$RANLIB" -a -n "$verbose" && echo " setting RANLIB to $RANLIB" for hdr in memory.h do trhdr=HAVE_`echo $hdr | tr '[a-z]./' '[A-Z]__'` echo checking for ${hdr} cat > conftest.c < EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then { test -n "$verbose" && \ echo ' defining' ${trhdr} DEFS="$DEFS -D${trhdr}=1" SEDDEFS="${SEDDEFS}\${SEDdA}${trhdr}\${SEDdB}${trhdr}\${SEDdC}1\${SEDdD} \${SEDuA}${trhdr}\${SEDuB}${trhdr}\${SEDuC}1\${SEDuD} \${SEDeA}${trhdr}\${SEDeB}${trhdr}\${SEDeC}1\${SEDeD} " } fi rm -f conftest* done echo checking for ANSI C header files cat > conftest.c < #include #include #include EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. echo '#include ' > conftest.c eval "$CPP \$DEFS conftest.c > conftest.out 2>&1" if egrep "memchr" conftest.out >/dev/null 2>&1; then # SGI's /bin/cc from Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. cat > conftest.c < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e,f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF eval $compile if test -s conftest && (./conftest; exit) 2>/dev/null; then { test -n "$verbose" && \ echo ' defining' STDC_HEADERS DEFS="$DEFS -DSTDC_HEADERS=1" SEDDEFS="${SEDDEFS}\${SEDdA}STDC_HEADERS\${SEDdB}STDC_HEADERS\${SEDdC}1\${SEDdD} \${SEDuA}STDC_HEADERS\${SEDuB}STDC_HEADERS\${SEDuC}1\${SEDuD} \${SEDeA}STDC_HEADERS\${SEDeB}STDC_HEADERS\${SEDeC}1\${SEDeD} " } fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* # No no no no no! Meschach does NOT support complex.h, # which uses a completely different definition of complex numbers # and has a different meaning for keyword "complex"! Drew Parsons, 2001. # # echo checking for complex.h # cat > conftest.c < # EOF # err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` # if test -z "$err"; then # { # test -n "$verbose" && \ # echo ' defining' HAVE_COMPLEX_H # DEFS="$DEFS -DHAVE_COMPLEX_H=1" # SEDDEFS="${SEDDEFS}\${SEDdA}HAVE_COMPLEX_H\${SEDdB}HAVE_COMPLEX_H\${SEDdC}1\${SEDdD} # \${SEDuA}HAVE_COMPLEX_H\${SEDuB}HAVE_COMPLEX_H\${SEDuC}1\${SEDuD} # \${SEDeA}HAVE_COMPLEX_H\${SEDeB}HAVE_COMPLEX_H\${SEDeC}1\${SEDeD} # " # } # # fi # rm -f conftest* echo checking for malloc.h cat > conftest.c < EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then { test -n "$verbose" && \ echo ' defining' HAVE_MALLOC_H DEFS="$DEFS -DHAVE_MALLOC_H=1" SEDDEFS="${SEDDEFS}\${SEDdA}HAVE_MALLOC_H\${SEDdB}HAVE_MALLOC_H\${SEDdC}1\${SEDdD} \${SEDuA}HAVE_MALLOC_H\${SEDuB}HAVE_MALLOC_H\${SEDuC}1\${SEDuD} \${SEDeA}HAVE_MALLOC_H\${SEDeB}HAVE_MALLOC_H\${SEDeC}1\${SEDeD} " } fi rm -f conftest* echo checking for varargs.h cat > conftest.c < EOF err=`eval "($CPP \$DEFS conftest.c >/dev/null) 2>&1"` if test -z "$err"; then { test -n "$verbose" && \ echo ' defining' VARARGS DEFS="$DEFS -DVARARGS=1" SEDDEFS="${SEDDEFS}\${SEDdA}VARARGS\${SEDdB}VARARGS\${SEDdC}1\${SEDdD} \${SEDuA}VARARGS\${SEDuB}VARARGS\${SEDuC}1\${SEDuD} \${SEDeA}VARARGS\${SEDeB}VARARGS\${SEDeC}1\${SEDeD} " } fi rm -f conftest* { test -n "$verbose" && \ echo ' defining' NOT_SEGMENTED DEFS="$DEFS -DNOT_SEGMENTED=1" SEDDEFS="${SEDDEFS}\${SEDdA}NOT_SEGMENTED\${SEDdB}NOT_SEGMENTED\${SEDdC}1\${SEDdD} \${SEDuA}NOT_SEGMENTED\${SEDuB}NOT_SEGMENTED\${SEDuC}1\${SEDuD} \${SEDeA}NOT_SEGMENTED\${SEDeB}NOT_SEGMENTED\${SEDeC}1\${SEDeD} " } echo checking for size_t in sys/types.h echo '#include ' > conftest.c eval "$CPP \$DEFS conftest.c > conftest.out 2>&1" if egrep "size_t" conftest.out >/dev/null 2>&1; then : else { test -n "$verbose" && \ echo ' defining' size_t to be 'unsigned' DEFS="$DEFS -Dsize_t=unsigned" SEDDEFS="${SEDDEFS}\${SEDdA}size_t\${SEDdB}size_t\${SEDdC}unsigned\${SEDdD} \${SEDuA}size_t\${SEDuB}size_t\${SEDuC}unsigned\${SEDuD} \${SEDeA}size_t\${SEDeB}size_t\${SEDeC}unsigned\${SEDeD} " } fi rm -f conftest* prog='/* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset x; /* SunOS 4.1.1 cc rejects this. */ char const *const *ccp; char **p; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; p = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++ccp; p = (char**) ccp; ccp = (char const *const *) p; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25,17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; }' echo checking for working const cat > conftest.c < conftest.c </dev/null; then : else { test -n "$verbose" && \ echo ' defining' WORDS_BIGENDIAN DEFS="$DEFS -DWORDS_BIGENDIAN=1" SEDDEFS="${SEDDEFS}\${SEDdA}WORDS_BIGENDIAN\${SEDdB}WORDS_BIGENDIAN\${SEDdC}1\${SEDdD} \${SEDuA}WORDS_BIGENDIAN\${SEDuB}WORDS_BIGENDIAN\${SEDuC}1\${SEDuD} \${SEDeA}WORDS_BIGENDIAN\${SEDeB}WORDS_BIGENDIAN\${SEDeC}1\${SEDeD} " } fi rm -f conftest* # check whether --with-complex was given if test -n "$with_complex"; then { test -n "$verbose" && \ echo ' defining' COMPLEX DEFS="$DEFS -DCOMPLEX=1" SEDDEFS="${SEDDEFS}\${SEDdA}COMPLEX\${SEDdB}COMPLEX\${SEDdC}1\${SEDdD} \${SEDuA}COMPLEX\${SEDuB}COMPLEX\${SEDuC}1\${SEDuD} \${SEDeA}COMPLEX\${SEDeB}COMPLEX\${SEDeC}1\${SEDeD} " } fi # check whether --with-sparse was given if test -n "$with_sparse"; then { test -n "$verbose" && \ echo ' defining' SPARSE DEFS="$DEFS -DSPARSE=1" SEDDEFS="${SEDDEFS}\${SEDdA}SPARSE\${SEDdB}SPARSE\${SEDdC}1\${SEDdD} \${SEDuA}SPARSE\${SEDuB}SPARSE\${SEDuC}1\${SEDuD} \${SEDeA}SPARSE\${SEDeB}SPARSE\${SEDeC}1\${SEDeD} " } fi # check whether --with-all was given if test -n "$with_all"; then { test -n "$verbose" && \ echo ' defining' COMPLEX DEFS="$DEFS -DCOMPLEX=1" SEDDEFS="${SEDDEFS}\${SEDdA}COMPLEX\${SEDdB}COMPLEX\${SEDdC}1\${SEDdD} \${SEDuA}COMPLEX\${SEDuB}COMPLEX\${SEDuC}1\${SEDuD} \${SEDeA}COMPLEX\${SEDeB}COMPLEX\${SEDeC}1\${SEDeD} " } fi # check whether --with-all was given if test -n "$with_all"; then { test -n "$verbose" && \ echo ' defining' SPARSE DEFS="$DEFS -DSPARSE=1" SEDDEFS="${SEDDEFS}\${SEDdA}SPARSE\${SEDdB}SPARSE\${SEDdC}1\${SEDdD} \${SEDuA}SPARSE\${SEDuB}SPARSE\${SEDuC}1\${SEDuD} \${SEDeA}SPARSE\${SEDeB}SPARSE\${SEDeC}1\${SEDeD} " } fi # check whether --with-unroll was given if test -n "$with_unroll"; then { test -n "$verbose" && \ echo ' defining' VUNROLL DEFS="$DEFS -DVUNROLL=1" SEDDEFS="${SEDDEFS}\${SEDdA}VUNROLL\${SEDdB}VUNROLL\${SEDdC}1\${SEDdD} \${SEDuA}VUNROLL\${SEDuB}VUNROLL\${SEDuC}1\${SEDuD} \${SEDeA}VUNROLL\${SEDeB}VUNROLL\${SEDeC}1\${SEDeD} " } fi # check whether --with-munroll was given if test -n "$with_munroll"; then { test -n "$verbose" && \ echo ' defining' MUNROLL DEFS="$DEFS -DMUNROLL=1" SEDDEFS="${SEDDEFS}\${SEDdA}MUNROLL\${SEDdB}MUNROLL\${SEDdC}1\${SEDdD} \${SEDuA}MUNROLL\${SEDuB}MUNROLL\${SEDuC}1\${SEDuD} \${SEDeA}MUNROLL\${SEDeB}MUNROLL\${SEDeC}1\${SEDeD} " } fi # check whether --with-segmem was given if test -n "$with_segmem"; then { test -n "$verbose" && \ echo ' defining' SEGMENTED DEFS="$DEFS -DSEGMENTED=1" SEDDEFS="${SEDDEFS}\${SEDdA}SEGMENTED\${SEDdB}SEGMENTED\${SEDdC}1\${SEDdD} \${SEDuA}SEGMENTED\${SEDuB}SEGMENTED\${SEDuC}1\${SEDuD} \${SEDeA}SEGMENTED\${SEDeB}SEGMENTED\${SEDeC}1\${SEDeD} " } fi # check whether --with-float was given if test -n "$with_float"; then { test -n "$verbose" && \ echo ' defining' REAL_FLT DEFS="$DEFS -DREAL_FLT=1" SEDDEFS="${SEDDEFS}\${SEDdA}REAL_FLT\${SEDdB}REAL_FLT\${SEDdC}1\${SEDdD} \${SEDuA}REAL_FLT\${SEDuB}REAL_FLT\${SEDuC}1\${SEDuD} \${SEDeA}REAL_FLT\${SEDeB}REAL_FLT\${SEDeC}1\${SEDeD} " } fi # check whether --with-double was given if test -n "$with_double"; then { test -n "$verbose" && \ echo ' defining' REAL_DBL DEFS="$DEFS -DREAL_DBL=1" SEDDEFS="${SEDDEFS}\${SEDdA}REAL_DBL\${SEDdB}REAL_DBL\${SEDdC}1\${SEDdD} \${SEDuA}REAL_DBL\${SEDuB}REAL_DBL\${SEDuC}1\${SEDuD} \${SEDeA}REAL_DBL\${SEDeB}REAL_DBL\${SEDeC}1\${SEDeD} " } fi LIBS="$LIBS -lm" echo checking for u_int cat > conftest.c < #ifdef __STDC__ #include #endif int main() { exit(0); } int t() { u_int i; i = 1; } EOF if eval $compile; then { test -n "$verbose" && \ echo ' defining' U_INT_DEF DEFS="$DEFS -DU_INT_DEF=1" SEDDEFS="${SEDDEFS}\${SEDdA}U_INT_DEF\${SEDdB}U_INT_DEF\${SEDdC}1\${SEDdD} \${SEDuA}U_INT_DEF\${SEDuB}U_INT_DEF\${SEDuC}1\${SEDuD} \${SEDeA}U_INT_DEF\${SEDeB}U_INT_DEF\${SEDeC}1\${SEDeD} " } fi rm -f conftest* echo 'computing machine epsilon(s)' echo $CC -o macheps dmacheps.c $CC -o macheps dmacheps.c { test -n "$verbose" && \ echo ' defining' D_MACHEPS to be '`./macheps`' DEFS="$DEFS -DD_MACHEPS=`./macheps`" SEDDEFS="${SEDDEFS}\${SEDdA}D_MACHEPS\${SEDdB}D_MACHEPS\${SEDdC}`./macheps`\${SEDdD} \${SEDuA}D_MACHEPS\${SEDuB}D_MACHEPS\${SEDuC}`./macheps`\${SEDuD} \${SEDeA}D_MACHEPS\${SEDeB}D_MACHEPS\${SEDeC}`./macheps`\${SEDeD} " } echo $CC -o macheps fmacheps.c $CC -o macheps fmacheps.c { test -n "$verbose" && \ echo ' defining' F_MACHEPS to be '`./macheps`' DEFS="$DEFS -DF_MACHEPS=`./macheps`" SEDDEFS="${SEDDEFS}\${SEDdA}F_MACHEPS\${SEDdB}F_MACHEPS\${SEDdC}`./macheps`\${SEDdD} \${SEDuA}F_MACHEPS\${SEDuB}F_MACHEPS\${SEDuC}`./macheps`\${SEDuD} \${SEDeA}F_MACHEPS\${SEDeB}F_MACHEPS\${SEDeC}`./macheps`\${SEDeD} " } echo computing M_MAX_INT echo $CC -o maxint maxint.c $CC -o maxint maxint.c { test -n "$verbose" && \ echo ' defining' M_MAX_INT to be '`./maxint`' DEFS="$DEFS -DM_MAX_INT=`./maxint`" SEDDEFS="${SEDDEFS}\${SEDdA}M_MAX_INT\${SEDdB}M_MAX_INT\${SEDdC}`./maxint`\${SEDdD} \${SEDuA}M_MAX_INT\${SEDuB}M_MAX_INT\${SEDuC}`./maxint`\${SEDuD} \${SEDeA}M_MAX_INT\${SEDeB}M_MAX_INT\${SEDeC}`./maxint`\${SEDeD} " } echo checking char '\\0' vs. float zeros cat > conftest.c < conftest.out 2>&1" if egrep "yes" conftest.out >/dev/null 2>&1; then { test -n "$verbose" && \ echo ' defining' CHAR0ISDBL0 DEFS="$DEFS -DCHAR0ISDBL0=1" SEDDEFS="${SEDDEFS}\${SEDdA}CHAR0ISDBL0\${SEDdB}CHAR0ISDBL0\${SEDdC}1\${SEDdD} \${SEDuA}CHAR0ISDBL0\${SEDuB}CHAR0ISDBL0\${SEDuC}1\${SEDuD} \${SEDeA}CHAR0ISDBL0\${SEDeB}CHAR0ISDBL0\${SEDeC}1\${SEDeD} " } fi rm -f conftest* for func in bcopy bzero do trfunc=HAVE_`echo $func | tr '[a-z]' '[A-Z]'` echo checking for ${func} cat > conftest.c < int main() { exit(0); } int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined (__stub_${func}) || defined (__stub___${func}) choke me #else /* Override any gcc2 internal prototype to avoid an error. */ extern char ${func}(); ${func}(); #endif } EOF if eval $compile; then { test -n "$verbose" && \ echo ' defining' ${trfunc} DEFS="$DEFS -D${trfunc}=1" SEDDEFS="${SEDDEFS}\${SEDdA}${trfunc}\${SEDdB}${trfunc}\${SEDdC}1\${SEDdD} \${SEDuA}${trfunc}\${SEDuB}${trfunc}\${SEDuC}1\${SEDuD} \${SEDeA}${trfunc}\${SEDeB}${trfunc}\${SEDeC}1\${SEDeD} " } fi rm -f conftest* done echo checking for function prototypes cat > conftest.c < config.status </dev/null | sed 1q`: # # $0 $* for arg do case "\$arg" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) exec /bin/sh $0 $* ;; *) echo "Usage: config.status --recheck" 2>&1; exit 1 ;; esac done trap 'rm -f makefile machine.h conftest*; exit 1' 1 3 15 PROGS='$PROGS' CC='$CC' CPP='$CPP' RANLIB='$RANLIB' LIBS='$LIBS' srcdir='$srcdir' prefix='$prefix' exec_prefix='$exec_prefix' prsub='$prsub' EOF cat >> config.status <<\EOF top_srcdir=$srcdir # Allow make-time overrides of the generated file list. test -n "$gen_files" || gen_files="makefile" for file in .. $gen_files; do if [ "x$file" != "x.." ]; then srcdir=$top_srcdir # Remove last slash and all that follows it. Not all systems have dirname. dir=`echo $file|sed 's%/[^/][^/]*$%%'` if test "$dir" != "$file"; then test "$top_srcdir" != . && srcdir=$top_srcdir/$dir test ! -d $dir && mkdir $dir fi echo creating $file rm -f $file echo "# Generated automatically from `echo $file|sed 's|.*/||'`.in by configure." > $file sed -e " $prsub s%@PROGS@%$PROGS%g s%@CC@%$CC%g s%@CPP@%$CPP%g s%@RANLIB@%$RANLIB%g s%@LIBS@%$LIBS%g s%@srcdir@%$srcdir%g s%@DEFS@%-DHAVE_CONFIG_H%" $top_srcdir/${file}.in >> $file fi; done test -n "$gen_config" || gen_config=machine.h echo creating $gen_config # These sed commands are put into SEDDEFS when defining a macro. # They are broken into pieces to make the sed script easier to manage. # They are passed to sed as "A NAME B NAME C VALUE D", where NAME # is the cpp macro being defined and VALUE is the value it is being given. # Each defining turns into a single global substitution command. # # SEDd sets the value in "#define NAME VALUE" lines. SEDdA='s@^\([ ]*\)#\([ ]*define[ ][ ]*\)' SEDdB='\([ ][ ]*\)[^ ]*@\1#\2' SEDdC='\3' SEDdD='@g' # SEDu turns "#undef NAME" with trailing blanks into "#define NAME VALUE". SEDuA='s@^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' SEDuB='\([ ]\)@\1#\2define\3' SEDuC=' ' SEDuD='\4@g' # SEDe turns "#undef NAME" without trailing blanks into "#define NAME VALUE". SEDeA='s@^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' SEDeB='$@\1#\2define\3' SEDeC=' ' SEDeD='@g' rm -f conftest.sed EOF # Turn off quoting long enough to insert the sed commands. rm -f conftest.sh cat > conftest.sh < conftest.s1 # Like head -20. sed 1,${maxshlines}d conftest.sh > conftest.s2 # Like tail +21. # Write a limited-size here document to append to conftest.sed. echo 'cat >> conftest.sed <> config.status cat conftest.s1 >> config.status echo 'CONFEOF' >> config.status rm -f conftest.s1 conftest.sh mv conftest.s2 conftest.sh done rm -f conftest.sh # Now back to your regularly scheduled config.status. cat >> config.status <<\EOF # This sed command replaces #undef's with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it in # machine.h. cat >> conftest.sed <<\CONFEOF s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, CONFEOF rm -f conftest.h # Break up the sed commands because old seds have small limits. maxsedlines=20 cp $top_srcdir/$gen_config.in conftest.h1 while : do lines=`grep -c . conftest.sed` if test -z "$lines" || test "$lines" -eq 0; then break; fi rm -f conftest.s1 conftest.s2 conftest.h2 sed ${maxsedlines}q conftest.sed > conftest.s1 # Like head -20. sed 1,${maxsedlines}d conftest.sed > conftest.s2 # Like tail +21. sed -f conftest.s1 < conftest.h1 > conftest.h2 rm -f conftest.s1 conftest.h1 conftest.sed mv conftest.h2 conftest.h1 mv conftest.s2 conftest.sed done rm -f conftest.sed conftest.h echo "/* $gen_config. Generated automatically by configure. */" > conftest.h cat conftest.h1 >> conftest.h rm -f conftest.h1 if cmp -s $gen_config conftest.h 2>/dev/null; then # The file exists and we would not be changing it. rm -f conftest.h else rm -f $gen_config mv conftest.h $gen_config fi exit 0 EOF chmod +x config.status test -n "$no_create" || ./config.status echo "Extensions to basic version: use configure --with-opt1 --with-opt2" echo " Option:" echo " --with-complex incorporate complex functions" echo " --with-sparse incorporate sparse matrix functions" echo " --with-all both of the above" echo " --with-unroll unroll low level loops on vectors" echo " --with-munroll unroll low level loops on matrices" echo " --with-float single precision" echo " --with-double double precision (default)" echo "Re-run configure with these options if you want them" # configure.in copyright (C) Brook Milligan and David Stewart, 1993 gtk-wave-cleaner-0.22-04/meschach/conjgrad.c0000777000175000017500000002012613120075106021713 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Conjugate gradient routines file Uses sparse matrix input & sparse Cholesky factorisation in pccg(). All the following routines use routines to define a matrix rather than use any explicit representation (with the exeception of the pccg() pre-conditioner) The matrix A is defined by VEC *(*A)(void *params, VEC *x, VEC *y) where y = A.x on exit, and y is returned. The params argument is intended to make it easier to re-use & modify such routines. If we have a sparse matrix data structure SPMAT *A_mat; then these can be used by passing sp_mv_mlt as the function, and A_mat as the param. */ #include #include #include "matrix.h" #include "sparse.h" static char rcsid[] = "$Id: conjgrad.c,v 1.4 1994/01/13 05:36:45 des Exp $"; /* #define MAX_ITER 10000 */ static int max_iter = 10000; int cg_num_iters; /* matrix-as-routine type definition */ /* #ifdef ANSI_C */ /* typedef VEC *(*MTX_FN)(void *params, VEC *x, VEC *out); */ /* #else */ typedef VEC *(*MTX_FN)(); /* #endif */ #ifdef ANSI_C VEC *spCHsolve(SPMAT *,VEC *,VEC *); #else VEC *spCHsolve(); #endif /* cg_set_maxiter -- sets maximum number of iterations if numiter > 1 -- just returns current max_iter otherwise -- returns old maximum */ int cg_set_maxiter(numiter) int numiter; { int temp; if ( numiter < 2 ) return max_iter; temp = max_iter; max_iter = numiter; return temp; } /* pccg -- solves A.x = b using pre-conditioner M (assumed factored a la spCHfctr()) -- results are stored in x (if x != NULL), which is returned */ VEC *pccg(A,A_params,M_inv,M_params,b,eps,x) MTX_FN A, M_inv; VEC *b, *x; double eps; void *A_params, *M_params; { VEC *r = VNULL, *p = VNULL, *q = VNULL, *z = VNULL; int k; Real alpha, beta, ip, old_ip, norm_b; if ( ! A || ! b ) error(E_NULL,"pccg"); if ( x == b ) error(E_INSITU,"pccg"); x = v_resize(x,b->dim); if ( eps <= 0.0 ) eps = MACHEPS; r = v_get(b->dim); p = v_get(b->dim); q = v_get(b->dim); z = v_get(b->dim); norm_b = v_norm2(b); v_zero(x); r = v_copy(b,r); old_ip = 0.0; for ( k = 0; ; k++ ) { if ( v_norm2(r) < eps*norm_b ) break; if ( k > max_iter ) error(E_ITER,"pccg"); if ( M_inv ) (*M_inv)(M_params,r,z); else v_copy(r,z); /* M == identity */ ip = in_prod(z,r); if ( k ) /* if ( k > 0 ) ... */ { beta = ip/old_ip; p = v_mltadd(z,p,beta,p); } else /* if ( k == 0 ) ... */ { beta = 0.0; p = v_copy(z,p); old_ip = 0.0; } q = (*A)(A_params,p,q); alpha = ip/in_prod(p,q); x = v_mltadd(x,p,alpha,x); r = v_mltadd(r,q,-alpha,r); old_ip = ip; } cg_num_iters = k; V_FREE(p); V_FREE(q); V_FREE(r); V_FREE(z); return x; } /* sp_pccg -- a simple interface to pccg() which uses sparse matrix data structures -- assumes that LLT contains the Cholesky factorisation of the actual pre-conditioner */ VEC *sp_pccg(A,LLT,b,eps,x) SPMAT *A, *LLT; VEC *b, *x; double eps; { return pccg(sp_mv_mlt,A,spCHsolve,LLT,b,eps,x); } /* Routines for performing the CGS (Conjugate Gradient Squared) algorithm of P. Sonneveld: "CGS, a fast Lanczos-type solver for nonsymmetric linear systems", SIAM J. Sci. & Stat. Comp. v. 10, pp. 36--52 */ /* cgs -- uses CGS to compute a solution x to A.x=b -- the matrix A is not passed explicitly, rather a routine A is passed where A(x,Ax,params) computes Ax = A.x -- the computed solution is passed */ VEC *cgs(A,A_params,b,r0,tol,x) MTX_FN A; VEC *x, *b; VEC *r0; /* tilde r0 parameter -- should be random??? */ double tol; /* error tolerance used */ void *A_params; { VEC *p, *q, *r, *u, *v, *tmp1, *tmp2; Real alpha, beta, norm_b, rho, old_rho, sigma; int iter; if ( ! A || ! x || ! b || ! r0 ) error(E_NULL,"cgs"); if ( x->dim != b->dim || r0->dim != x->dim ) error(E_SIZES,"cgs"); if ( tol <= 0.0 ) tol = MACHEPS; p = v_get(x->dim); q = v_get(x->dim); r = v_get(x->dim); u = v_get(x->dim); v = v_get(x->dim); tmp1 = v_get(x->dim); tmp2 = v_get(x->dim); norm_b = v_norm2(b); (*A)(A_params,x,tmp1); v_sub(b,tmp1,r); v_zero(p); v_zero(q); old_rho = 1.0; iter = 0; while ( v_norm2(r) > tol*norm_b ) { if ( ++iter > max_iter ) break; /* error(E_ITER,"cgs"); */ rho = in_prod(r0,r); if ( old_rho == 0.0 ) error(E_SING,"cgs"); beta = rho/old_rho; v_mltadd(r,q,beta,u); v_mltadd(q,p,beta,tmp1); v_mltadd(u,tmp1,beta,p); (*A)(A_params,p,v); sigma = in_prod(r0,v); if ( sigma == 0.0 ) error(E_SING,"cgs"); alpha = rho/sigma; v_mltadd(u,v,-alpha,q); v_add(u,q,tmp1); (*A)(A_params,tmp1,tmp2); v_mltadd(r,tmp2,-alpha,r); v_mltadd(x,tmp1,alpha,x); old_rho = rho; } cg_num_iters = iter; V_FREE(p); V_FREE(q); V_FREE(r); V_FREE(u); V_FREE(v); V_FREE(tmp1); V_FREE(tmp2); return x; } /* sp_cgs -- simple interface for SPMAT data structures */ VEC *sp_cgs(A,b,r0,tol,x) SPMAT *A; VEC *b, *r0, *x; double tol; { return cgs(sp_mv_mlt,A,b,r0,tol,x); } /* Routine for performing LSQR -- the least squares QR algorithm of Paige and Saunders: "LSQR: an algorithm for sparse linear equations and sparse least squares", ACM Trans. Math. Soft., v. 8 pp. 43--71 (1982) */ /* lsqr -- sparse CG-like least squares routine: -- finds min_x ||A.x-b||_2 using A defined through A & AT -- returns x (if x != NULL) */ VEC *lsqr(A,AT,A_params,b,tol,x) MTX_FN A, AT; /* AT is A transposed */ VEC *x, *b; double tol; /* error tolerance used */ void *A_params; { VEC *u, *v, *w, *tmp; Real alpha, beta, norm_b, phi, phi_bar, rho, rho_bar, rho_max, theta; Real s, c; /* for Givens' rotations */ int iter, m, n; if ( ! b || ! x ) error(E_NULL,"lsqr"); if ( tol <= 0.0 ) tol = MACHEPS; m = b->dim; n = x->dim; u = v_get((unsigned int)m); v = v_get((unsigned int)n); w = v_get((unsigned int)n); tmp = v_get((unsigned int)n); norm_b = v_norm2(b); v_zero(x); beta = v_norm2(b); if ( beta == 0.0 ) return x; sv_mlt(1.0/beta,b,u); tracecatch((*AT)(A_params,u,v),"lsqr"); alpha = v_norm2(v); if ( alpha == 0.0 ) return x; sv_mlt(1.0/alpha,v,v); v_copy(v,w); phi_bar = beta; rho_bar = alpha; rho_max = 1.0; iter = 0; do { if ( ++iter > max_iter ) error(E_ITER,"lsqr"); tmp = v_resize(tmp,m); tracecatch((*A) (A_params,v,tmp),"lsqr"); v_mltadd(tmp,u,-alpha,u); beta = v_norm2(u); sv_mlt(1.0/beta,u,u); tmp = v_resize(tmp,n); tracecatch((*AT)(A_params,u,tmp),"lsqr"); v_mltadd(tmp,v,-beta,v); alpha = v_norm2(v); sv_mlt(1.0/alpha,v,v); rho = sqrt(rho_bar*rho_bar+beta*beta); if ( rho > rho_max ) rho_max = rho; c = rho_bar/rho; s = beta/rho; theta = s*alpha; rho_bar = -c*alpha; phi = c*phi_bar; phi_bar = s*phi_bar; /* update x & w */ if ( rho == 0.0 ) error(E_SING,"lsqr"); v_mltadd(x,w,phi/rho,x); v_mltadd(v,w,-theta/rho,w); } while ( fabs(phi_bar*alpha*c) > tol*norm_b/rho_max ); cg_num_iters = iter; V_FREE(tmp); V_FREE(u); V_FREE(v); V_FREE(w); return x; } /* sp_lsqr -- simple interface for SPMAT data structures */ VEC *sp_lsqr(A,b,tol,x) SPMAT *A; VEC *b, *x; double tol; { return lsqr(sp_mv_mlt,sp_vm_mlt,A,b,tol,x); } gtk-wave-cleaner-0.22-04/meschach/copy.c0000777000175000017500000001430213120075106021075 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ static char rcsid[] = "$Id: copy.c,v 1.2 1994/01/13 05:37:14 des Exp $"; #include #include "matrix.h" /* _m_copy -- copies matrix into new area -- out(i0:m,j0:n) <- in(i0:m,j0:n) */ #ifndef ANSI_C MAT *_m_copy(in,out,i0,j0) MAT *in,*out; unsigned int i0,j0; #else MAT *_m_copy(const MAT *in, MAT *out, unsigned int i0, unsigned int j0) #endif { unsigned int i /* ,j */; if ( in==MNULL ) error(E_NULL,"_m_copy"); if ( in==out ) return (out); if ( out==MNULL || out->m < in->m || out->n < in->n ) out = m_resize(out,in->m,in->n); for ( i=i0; i < in->m; i++ ) MEM_COPY(&(in->me[i][j0]),&(out->me[i][j0]), (in->n - j0)*sizeof(Real)); /* for ( j=j0; j < in->n; j++ ) out->me[i][j] = in->me[i][j]; */ return (out); } /* _v_copy -- copies vector into new area -- out(i0:dim) <- in(i0:dim) */ #ifndef ANSI_C VEC *_v_copy(in,out,i0) VEC *in,*out; unsigned int i0; #else VEC *_v_copy(const VEC *in, VEC *out, unsigned int i0) #endif { /* unsigned int i,j; */ if ( in==VNULL ) error(E_NULL,"_v_copy"); if ( in==out ) return (out); if ( out==VNULL || out->dim < in->dim ) out = v_resize(out,in->dim); MEM_COPY(&(in->ve[i0]),&(out->ve[i0]),(in->dim - i0)*sizeof(Real)); /* for ( i=i0; i < in->dim; i++ ) out->ve[i] = in->ve[i]; */ return (out); } /* px_copy -- copies permutation 'in' to 'out' -- out is resized to in->size */ #ifndef ANSI_C PERM *px_copy(in,out) PERM *in,*out; #else PERM *px_copy(const PERM *in, PERM *out) #endif { /* int i; */ if ( in == PNULL ) error(E_NULL,"px_copy"); if ( in == out ) return out; if ( out == PNULL || out->size != in->size ) out = px_resize(out,in->size); MEM_COPY(in->pe,out->pe,in->size*sizeof(unsigned int)); /* for ( i = 0; i < in->size; i++ ) out->pe[i] = in->pe[i]; */ return out; } /* The .._move() routines are for moving blocks of memory around within Meschach data structures and for re-arranging matrices, vectors etc. */ /* m_move -- copies selected pieces of a matrix -- moves the m0 x n0 submatrix with top-left cor-ordinates (i0,j0) to the corresponding submatrix of out with top-left co-ordinates (i1,j1) -- out is resized (& created) if necessary */ #ifndef ANSI_C MAT *m_move(in,i0,j0,m0,n0,out,i1,j1) MAT *in, *out; int i0, j0, m0, n0, i1, j1; #else MAT *m_move(const MAT *in, int i0,int j0, int m0,int n0, MAT *out, int i1, int j1) #endif { int i; if ( ! in ) error(E_NULL,"m_move"); if ( i0 < 0 || j0 < 0 || i1 < 0 || j1 < 0 || m0 < 0 || n0 < 0 || i0+m0 > in->m || j0+n0 > in->n ) error(E_BOUNDS,"m_move"); if ( ! out ) out = m_resize(out,i1+m0,j1+n0); else if ( i1+m0 > out->m || j1+n0 > out->n ) out = m_resize(out,max(out->m,i1+m0),max(out->n,j1+n0)); for ( i = 0; i < m0; i++ ) MEM_COPY(&(in->me[i0+i][j0]),&(out->me[i1+i][j1]), n0*sizeof(Real)); return out; } /* v_move -- copies selected pieces of a vector -- moves the length dim0 subvector with initial index i0 to the corresponding subvector of out with initial index i1 -- out is resized if necessary */ #ifndef ANSI_C VEC *v_move(in,i0,dim0,out,i1) VEC *in, *out; int i0, dim0, i1; #else VEC *v_move(const VEC *in, int i0, int dim0, VEC *out, int i1) #endif { if ( ! in ) error(E_NULL,"v_move"); if ( i0 < 0 || dim0 < 0 || i1 < 0 || i0+dim0 > in->dim ) error(E_BOUNDS,"v_move"); if ( (! out) || i1+dim0 > out->dim ) out = v_resize(out,i1+dim0); MEM_COPY(&(in->ve[i0]),&(out->ve[i1]),dim0*sizeof(Real)); return out; } /* mv_move -- copies selected piece of matrix to a vector -- moves the m0 x n0 submatrix with top-left co-ordinate (i0,j0) to the subvector with initial index i1 (and length m0*n0) -- rows are copied contiguously -- out is resized if necessary */ #ifndef ANSI_C VEC *mv_move(in,i0,j0,m0,n0,out,i1) MAT *in; VEC *out; int i0, j0, m0, n0, i1; #else VEC *mv_move(const MAT *in, int i0,int j0, int m0, int n0, VEC *out, int i1) #endif { int dim1, i; if ( ! in ) error(E_NULL,"mv_move"); if ( i0 < 0 || j0 < 0 || m0 < 0 || n0 < 0 || i1 < 0 || i0+m0 > in->m || j0+n0 > in->n ) error(E_BOUNDS,"mv_move"); dim1 = m0*n0; if ( (! out) || i1+dim1 > out->dim ) out = v_resize(out,i1+dim1); for ( i = 0; i < m0; i++ ) MEM_COPY(&(in->me[i0+i][j0]),&(out->ve[i1+i*n0]),n0*sizeof(Real)); return out; } /* vm_move -- copies selected piece of vector to a matrix -- moves the subvector with initial index i0 and length m1*n1 to the m1 x n1 submatrix with top-left co-ordinate (i1,j1) -- copying is done by rows -- out is resized if necessary */ #ifndef ANSI_C MAT *vm_move(in,i0,out,i1,j1,m1,n1) VEC *in; MAT *out; int i0, i1, j1, m1, n1; #else MAT *vm_move(const VEC *in, int i0, MAT *out, int i1, int j1, int m1, int n1) #endif { int dim0, i; if ( ! in ) error(E_NULL,"vm_move"); if ( i0 < 0 || i1 < 0 || j1 < 0 || m1 < 0 || n1 < 0 || i0+m1*n1 > in->dim ) error(E_BOUNDS,"vm_move"); if ( ! out ) out = m_resize(out,i1+m1,j1+n1); else out = m_resize(out,max(i1+m1,out->m),max(j1+n1,out->n)); dim0 = m1*n1; for ( i = 0; i < m1; i++ ) MEM_COPY(&(in->ve[i0+i*n1]),&(out->me[i1+i][j1]),n1*sizeof(Real)); return out; } gtk-wave-cleaner-0.22-04/meschach/copyright0000777000175000017500000000214413120075106021713 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ gtk-wave-cleaner-0.22-04/meschach/dmacheps.c0000777000175000017500000000257213120075106021715 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ #include double dclean(x) double x; { static double y; y = x; return y; /* prevents optimisation */ } main() { static double deps, deps1, dtmp; deps = 1.0; while ( dclean(1.0+deps) > 1.0 ) deps = 0.5*deps; printf("%g\n", 2.0*deps); } gtk-wave-cleaner-0.22-04/meschach/err.c0000777000175000017500000002411713120075106020720 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Stewart & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* File with basic error-handling operations */ static char rcsid[] = "$Id: err.c,v 1.6 1995/01/30 14:49:14 des Exp $"; #include #include #include #include "err.h" #ifdef SYSV /* AT&T System V */ #include #else /* something else -- assume BSD or ANSI C */ #include #endif #define FALSE 0 #define TRUE 1 #define EF_EXIT 0 #define EF_ABORT 1 #define EF_JUMP 2 #define EF_SILENT 3 /* The only error caught in this file! */ #define E_SIGNAL 16 static char *err_mesg[] = { "unknown error", /* 0 */ "sizes of objects don't match", /* 1 */ "index out of bounds", /* 2 */ "can't allocate memory", /* 3 */ "singular matrix", /* 4 */ "matrix not positive definite", /* 5 */ "incorrect format input", /* 6 */ "bad input file/device", /* 7 */ "NULL objects passed", /* 8 */ "matrix not square", /* 9 */ "object out of range", /* 10 */ "can't do operation in situ for non-square matrix", /* 11 */ "can't do operation in situ", /* 12 */ "excessive number of iterations", /* 13 */ "convergence criterion failed", /* 14 */ "bad starting value", /* 15 */ "floating exception", /* 16 */ "internal inconsistency (data structure)",/* 17 */ "unexpected end-of-file", /* 18 */ "shared vectors (cannot release them)", /* 19 */ "negative argument", /* 20 */ "cannot overwrite object", /* 21 */ "breakdown in iterative method" /* 22 */ }; #define MAXERR (sizeof(err_mesg)/sizeof(char *)) static char *warn_mesg[] = { "unknown warning", /* 0 */ "wrong type number (use macro TYPE_*)", /* 1 */ "no corresponding mem_stat_mark", /* 2 */ "computed norm of a residual is less than 0", /* 3 */ "resizing a shared vector" /* 4 */ }; #define MAXWARN (sizeof(warn_mesg)/sizeof(char *)) #define MAX_ERRS 100 jmp_buf restart; /* array of pointers to lists of errors */ typedef struct { char **listp; /* pointer to a list of errors */ unsigned len; /* length of the list */ unsigned warn; /* =FALSE - errors, =TRUE - warnings */ } Err_list; static Err_list err_list[ERR_LIST_MAX_LEN] = { {err_mesg,MAXERR,FALSE}, /* basic errors list */ {warn_mesg,MAXWARN,TRUE} /* basic warnings list */ }; static int err_list_end = 2; /* number of elements in err_list */ /* attach a new list of errors pointed by err_ptr or change a previous one; list_len is the number of elements in the list; list_num is the list number; warn == FALSE - errors (stop the program), warn == TRUE - warnings (continue the program); Note: lists numbered 0 and 1 are attached automatically, you do not need to do it */ #ifndef ANSI_C int err_list_attach(list_num, list_len,err_ptr,warn) int list_num, list_len, warn; char **err_ptr; #else int err_list_attach(int list_num, int list_len, char **err_ptr, int warn) #endif { if (list_num < 0 || list_len <= 0 || err_ptr == (char **)NULL) return -1; if (list_num >= ERR_LIST_MAX_LEN) { fprintf(stderr,"\n file \"%s\": %s %s\n", "err.c","increase the value of ERR_LIST_MAX_LEN", "in matrix.h and zmatdef.h"); if ( ! isatty(fileno(stdout)) ) fprintf(stderr,"\n file \"%s\": %s %s\n", "err.c","increase the value of ERR_LIST_MAX_LEN", "in matrix.h and zmatdef.h"); printf("Exiting program\n"); exit(0); } if (err_list[list_num].listp != (char **)NULL && err_list[list_num].listp != err_ptr) free((char *)err_list[list_num].listp); err_list[list_num].listp = err_ptr; err_list[list_num].len = list_len; err_list[list_num].warn = warn; err_list_end = list_num+1; return list_num; } /* release the error list numbered list_num */ #ifndef ANSI_C int err_list_free(list_num) int list_num; #else int err_list_free(int list_num) #endif { if (list_num < 0 || list_num >= err_list_end) return -1; if (err_list[list_num].listp != (char **)NULL) { err_list[list_num].listp = (char **)NULL; err_list[list_num].len = 0; err_list[list_num].warn = 0; } return 0; } /* check if list_num is attached; return FALSE if not; return TRUE if yes */ #ifndef ANSI_C int err_is_list_attached(list_num) int list_num; #else int err_is_list_attached(int list_num) #endif { if (list_num < 0 || list_num >= err_list_end) return FALSE; if (err_list[list_num].listp != (char **)NULL) return TRUE; return FALSE; } /* other local variables */ static int err_flag = EF_EXIT, num_errs = 0, cnt_errs = 1; /* set_err_flag -- sets err_flag -- returns old err_flag */ #ifndef ANSI_C int set_err_flag(flag) int flag; #else int set_err_flag(int flag) #endif { int tmp; tmp = err_flag; err_flag = flag; return tmp; } /* count_errs -- sets cnt_errs (TRUE/FALSE) & returns old value */ #ifndef ANSI_C int count_errs(flag) int flag; #else int count_errs(int flag) #endif { int tmp; tmp = cnt_errs; cnt_errs = flag; return tmp; } /* ev_err -- reports error (err_num) in file "file" at line "line_num" and returns to user error handler; list_num is an error list number (0 is the basic list pointed by err_mesg, 1 is the basic list of warnings) */ #ifndef ANSI_C int ev_err(file,err_num,line_num,fn_name,list_num) char *file, *fn_name; int err_num, line_num,list_num; #else int ev_err(const char *file, int err_num, int line_num, const char *fn_name, int list_num) #endif { int num; if ( err_num < 0 ) err_num = 0; if (list_num < 0 || list_num >= err_list_end || err_list[list_num].listp == (char **)NULL) { fprintf(stderr, "\n Not (properly) attached list of errors: list_num = %d\n", list_num); fprintf(stderr," Call \"err_list_attach\" in your program\n"); if ( ! isatty(fileno(stdout)) ) { fprintf(stderr, "\n Not (properly) attached list of errors: list_num = %d\n", list_num); fprintf(stderr," Call \"err_list_attach\" in your program\n"); } printf("\nExiting program\n"); exit(0); } num = err_num; if ( num >= err_list[list_num].len ) num = 0; if ( cnt_errs && ++num_errs >= MAX_ERRS ) /* too many errors */ { fprintf(stderr,"\n\"%s\", line %d: %s in function %s()\n", file,line_num,err_list[list_num].listp[num], isascii(*fn_name) ? fn_name : "???"); if ( ! isatty(fileno(stdout)) ) fprintf(stdout,"\n\"%s\", line %d: %s in function %s()\n", file,line_num,err_list[list_num].listp[num], isascii(*fn_name) ? fn_name : "???"); printf("Sorry, too many errors: %d\n",num_errs); printf("Exiting program\n"); exit(0); } if ( err_list[list_num].warn ) switch ( err_flag ) { case EF_SILENT: break; default: fprintf(stderr,"\n\"%s\", line %d: %s in function %s()\n\n", file,line_num,err_list[list_num].listp[num], isascii(*fn_name) ? fn_name : "???"); if ( ! isatty(fileno(stdout)) ) fprintf(stdout,"\n\"%s\", line %d: %s in function %s()\n\n", file,line_num,err_list[list_num].listp[num], isascii(*fn_name) ? fn_name : "???"); break; } else switch ( err_flag ) { case EF_SILENT: longjmp(restart,(err_num==0)? -1 : err_num); break; case EF_ABORT: fprintf(stderr,"\n\"%s\", line %d: %s in function %s()\n", file,line_num,err_list[list_num].listp[num], isascii(*fn_name) ? fn_name : "???"); if ( ! isatty(fileno(stdout)) ) fprintf(stdout,"\n\"%s\", line %d: %s in function %s()\n", file,line_num,err_list[list_num].listp[num], isascii(*fn_name) ? fn_name : "???"); abort(); break; case EF_JUMP: fprintf(stderr,"\n\"%s\", line %d: %s in function %s()\n", file,line_num,err_list[list_num].listp[num], isascii(*fn_name) ? fn_name : "???"); if ( ! isatty(fileno(stdout)) ) fprintf(stdout,"\n\"%s\", line %d: %s in function %s()\n", file,line_num,err_list[list_num].listp[num], isascii(*fn_name) ? fn_name : "???"); longjmp(restart,(err_num==0)? -1 : err_num); break; default: fprintf(stderr,"\n\"%s\", line %d: %s in function %s()\n\n", file,line_num,err_list[list_num].listp[num], isascii(*fn_name) ? fn_name : "???"); if ( ! isatty(fileno(stdout)) ) fprintf(stdout,"\n\"%s\", line %d: %s in function %s()\n\n", file,line_num,err_list[list_num].listp[num], isascii(*fn_name) ? fn_name : "???"); break; } /* ensure exit if fall through */ if ( ! err_list[list_num].warn ) exit(0); return 0; } /* float_error -- catches floating arithmetic signals */ #ifndef ANSI_C static void float_error(num) int num; #else static void float_error(int num) #endif { signal(SIGFPE,float_error); /* fprintf(stderr,"SIGFPE: signal #%d\n",num); */ /* fprintf(stderr,"errno = %d\n",errno); */ ev_err("???.c",E_SIGNAL,0,"???",0); } /* catch_signal -- sets up float_error() to catch SIGFPE's */ void catch_FPE() { signal(SIGFPE,float_error); } gtk-wave-cleaner-0.22-04/meschach/err.h0000777000175000017500000001345213120075106020725 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Stewart & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* err.h 28/09/1993 */ /* RCS id: $Id: err.h,v 1.2 1995/01/30 14:48:05 des Exp $ */ #ifndef ERRHEADER #define ERRHEADER #include #include "machine.h" /* Error recovery */ extern jmp_buf restart; /* max. # of error lists */ #define ERR_LIST_MAX_LEN 10 /* main error functions */ #ifndef ANSI_C extern int ev_err(); /* main error handler */ extern int set_err_flag(); /* for different ways of handling errors, returns old value */ extern int count_errs(); /* to avoid "too many errors" */ extern int err_list_attach(); /* for attaching a list of errors */ extern int err_is_list_attached(); /* checking if a list is attached */ extern int err_list_free(); /* freeing a list of errors */ #else /* ANSI_C */ /* Alister: Looks like Jeff changed both cases of "const car" here to "char" */ /* in the err.h that was in the top gwc directory. */ /* I've removed that file, but making that change here breaks compilation. */ extern int ev_err(const char *,int,int,const char *,int); /* main error handler */ extern int set_err_flag(int flag); /* for different ways of handling errors, returns old value */ extern int count_errs(int true_false); /* to avoid "too many errors" */ extern int err_list_attach(int list_num, int list_len, char **err_ptr,int warn); /* for attaching a list of errors */ extern int err_is_list_attached(int list_num); /* checking if a list is attached */ extern int err_list_free(int list_num); /* freeing a list of errors */ #endif /* error(E_TYPE,"myfunc") raises error type E_TYPE for function my_func() */ #define error(err_num,fn_name) ev_err(__FILE__,err_num,__LINE__,fn_name,0) /* warning(WARN_TYPE,"myfunc") raises warning type WARN_TYPE for function my_func() */ #define warning(err_num,fn_name) ev_err(__FILE__,err_num,__LINE__,fn_name,1) /* error flags */ #define EF_EXIT 0 /* exit on error */ #define EF_ABORT 1 /* abort (dump core) on error */ #define EF_JUMP 2 /* jump on error */ #define EF_SILENT 3 /* jump, but don't print message */ #define ERREXIT() set_err_flag(EF_EXIT) #define ERRABORT() set_err_flag(EF_ABORT) /* don't print message */ #define SILENTERR() if ( ! setjmp(restart) ) set_err_flag(EF_SILENT) /* return here on error */ #define ON_ERROR() if ( ! setjmp(restart) ) set_err_flag(EF_JUMP) /* error types */ #define E_UNKNOWN 0 #define E_SIZES 1 #define E_BOUNDS 2 #define E_MEM 3 #define E_SING 4 #define E_POSDEF 5 #define E_FORMAT 6 #define E_INPUT 7 #define E_NULL 8 #define E_SQUARE 9 #define E_RANGE 10 #define E_INSITU2 11 #define E_INSITU 12 #define E_ITER 13 #define E_CONV 14 #define E_START 15 #define E_SIGNAL 16 #define E_INTERN 17 #define E_EOF 18 #define E_SHARED_VECS 19 #define E_NEG 20 #define E_OVERWRITE 21 #define E_BREAKDOWN 22 /* warning types */ #define WARN_UNKNOWN 0 #define WARN_WRONG_TYPE 1 #define WARN_NO_MARK 2 #define WARN_RES_LESS_0 3 #define WARN_SHARED_VEC 4 /* error catching macros */ /* execute err_part if error errnum is raised while executing ok_part */ #define catch(errnum,ok_part,err_part) \ { jmp_buf _save; int _err_num, _old_flag; \ _old_flag = set_err_flag(EF_SILENT); \ MEM_COPY(restart,_save,sizeof(jmp_buf)); \ if ( (_err_num=setjmp(restart)) == 0 ) \ { ok_part; \ set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); } \ else if ( _err_num == errnum ) \ { set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); \ err_part; } \ else { set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); \ error(_err_num,"catch"); \ } \ } /* execute err_part if any error raised while executing ok_part */ #define catchall(ok_part,err_part) \ { jmp_buf _save; int _err_num, _old_flag; \ _old_flag = set_err_flag(EF_SILENT); \ MEM_COPY(restart,_save,sizeof(jmp_buf)); \ if ( (_err_num=setjmp(restart)) == 0 ) \ { ok_part; \ set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); } \ else \ { set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); \ err_part; } \ } /* print message if error raised while executing ok_part, then re-raise error to trace calls */ #define tracecatch(ok_part,function) \ { jmp_buf _save; int _err_num, _old_flag; \ _old_flag = set_err_flag(EF_JUMP); \ MEM_COPY(restart,_save,sizeof(jmp_buf)); \ if ( (_err_num=setjmp(restart)) == 0 ) \ { ok_part; \ set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); } \ else \ { set_err_flag(_old_flag); \ MEM_COPY(_save,restart,sizeof(jmp_buf)); \ error(_err_num,function); } \ } #endif /* ERRHEADER */ gtk-wave-cleaner-0.22-04/meschach/extras.c0000777000175000017500000002526313120075106021441 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Memory port routines: MEM_COPY and MEM_ZERO */ /* For BSD 4.[23] environments: using bcopy() and bzero() */ #include "machine.h" #ifndef MEM_COPY void MEM_COPY(from,to,len) char *from, *to; int len; { int i; if ( from < to ) { for ( i = 0; i < len; i++ ) *to++ = *from++; } else { from += len; to += len; for ( i = 0; i < len; i++ ) *(--to) = *(--from); } } #endif #ifndef MEM_ZERO void MEM_ZERO(ptr,len) char *ptr; int len; { int i; for ( i = 0; i < len; i++ ) *(ptr++) = '\0'; } #endif /* This file contains versions of something approximating the well-known BLAS routines in C, suitable for Meschach (hence the `m'). These are "vanilla" implementations, at least with some consideration of the effects of caching and paging, and maybe some loop unrolling for register-rich machines */ /* Organisation of matrices: it is assumed that matrices are represented by Real **'s. To keep flexibility, there is also an "initial column" parameter j0, so that the actual elements used are A[0][j0], A[0][j0+1], ..., A[0][j0+n-1] A[1][j0], A[1][j0+1], ..., A[1][j0+n-1] .. .. ... .. A[m-1][j0], A[m-1][j0+1], ..., A[m-1][j0+n-1] */ static char rcsid[] = "$Id: extras.c,v 1.4 1995/06/08 15:13:15 des Exp $"; #include #define REGISTER_RICH 1 /* mblar-1 routines */ /* Mscale -- sets x <- alpha.x */ void Mscale(len,alpha,x) int len; double alpha; Real *x; { register int i; for ( i = 0; i < len; i++ ) x[i] *= alpha; } /* Mswap -- swaps x and y */ void Mswap(len,x,y) int len; Real *x, *y; { register int i; register Real tmp; for ( i = 0; i < len; i++ ) { tmp = x[i]; x[i] = y[i]; y[i] = tmp; } } /* Mcopy -- copies x to y */ void Mcopy(len,x,y) int len; Real *x, *y; { register int i; for ( i = 0; i < len; i++ ) y[i] = x[i]; } /* Maxpy -- y <- y + alpha.x */ void Maxpy(len,alpha,x,y) int len; double alpha; Real *x, *y; { register int i, len4; /**************************************** for ( i = 0; i < len; i++ ) y[i] += alpha*x[i]; ****************************************/ #ifdef REGISTER_RICH len4 = len / 4; len = len % 4; for ( i = 0; i < len4; i++ ) { y[4*i] += alpha*x[4*i]; y[4*i+1] += alpha*x[4*i+1]; y[4*i+2] += alpha*x[4*i+2]; y[4*i+3] += alpha*x[4*i+3]; } x += 4*len4; y += 4*len4; #endif for ( i = 0; i < len; i++ ) y[i] += alpha*x[i]; } /* Mdot -- returns x'.y */ double Mdot(len,x,y) int len; Real *x, *y; { register int i, len4; register Real sum; #ifndef REGISTER_RICH sum = 0.0; #endif #ifdef REGISTER_RICH register Real sum0, sum1, sum2, sum3; sum0 = sum1 = sum2 = sum3 = 0.0; len4 = len / 4; len = len % 4; for ( i = 0; i < len4; i++ ) { sum0 += x[4*i ]*y[4*i ]; sum1 += x[4*i+1]*y[4*i+1]; sum2 += x[4*i+2]*y[4*i+2]; sum3 += x[4*i+3]*y[4*i+3]; } sum = sum0 + sum1 + sum2 + sum3; x += 4*len4; y += 4*len4; #endif for ( i = 0; i < len; i++ ) sum += x[i]*y[i]; return sum; } #ifndef ABS #define ABS(x) ((x) >= 0 ? (x) : -(x)) #endif /* Mnorminf -- returns ||x||_inf */ double Mnorminf(len,x) int len; Real *x; { register int i; register Real tmp, max_val; max_val = 0.0; for ( i = 0; i < len; i++ ) { tmp = ABS(x[i]); if ( max_val < tmp ) max_val = tmp; } return max_val; } /* Mnorm1 -- returns ||x||_1 */ double Mnorm1(len,x) int len; Real *x; { register int i; register Real sum; sum = 0.0; for ( i = 0; i < len; i++ ) sum += ABS(x[i]); return sum; } /* Mnorm2 -- returns ||x||_2 */ double Mnorm2(len,x) int len; Real *x; { register int i; register Real norm, invnorm, sum, tmp; norm = Mnorminf(len,x); if ( norm == 0.0 ) return 0.0; invnorm = 1.0/norm; sum = 0.0; for ( i = 0; i < len; i++ ) { tmp = x[i]*invnorm; sum += tmp*tmp; } return sum/invnorm; } /* mblar-2 routines */ /* Mmv -- y <- alpha.A.x + beta.y */ void Mmv(m,n,alpha,A,j0,x,beta,y) int m, n, j0; double alpha, beta; Real **A, *x, *y; { register int i, j, m4, n4; register Real sum0, sum1, sum2, sum3, tmp0, tmp1, tmp2, tmp3; register Real *dp0, *dp1, *dp2, *dp3; /**************************************** for ( i = 0; i < m; i++ ) y[i] += alpha*Mdot(n,&(A[i][j0]),x); ****************************************/ m4 = n4 = 0; #ifdef REGISTER_RICH m4 = m / 4; m = m % 4; n4 = n / 4; n = n % 4; for ( i = 0; i < m4; i++ ) { sum0 = sum1 = sum2 = sum3 = 0.0; dp0 = &(A[4*i ][j0]); dp1 = &(A[4*i+1][j0]); dp2 = &(A[4*i+2][j0]); dp3 = &(A[4*i+3][j0]); for ( j = 0; j < n4; j++ ) { tmp0 = x[4*j ]; tmp1 = x[4*j+1]; tmp2 = x[4*j+2]; tmp3 = x[4*j+3]; sum0 = sum0 + dp0[j]*tmp0 + dp0[j+1]*tmp1 + dp0[j+2]*tmp2 + dp0[j+3]*tmp3; sum1 = sum1 + dp1[j]*tmp0 + dp1[j+1]*tmp1 + dp1[j+2]*tmp2 + dp1[j+3]*tmp3; sum2 = sum2 + dp2[j]*tmp0 + dp2[j+1]*tmp1 + dp2[j+2]*tmp2 + dp2[j+3]*tmp3; sum3 = sum3 + dp3[j]*tmp0 + dp3[j+1]*tmp2 + dp3[j+2]*tmp2 + dp3[j+3]*tmp3; } for ( j = 0; j < n; j++ ) { sum0 += dp0[4*n4+j]*x[4*n4+j]; sum1 += dp1[4*n4+j]*x[4*n4+j]; sum2 += dp2[4*n4+j]*x[4*n4+j]; sum3 += dp3[4*n4+j]*x[4*n4+j]; } y[4*i ] = beta*y[4*i ] + alpha*sum0; y[4*i+1] = beta*y[4*i+1] + alpha*sum1; y[4*i+2] = beta*y[4*i+2] + alpha*sum2; y[4*i+3] = beta*y[4*i+3] + alpha*sum3; } #endif for ( i = 0; i < m; i++ ) y[4*m4+i] = beta*y[i] + alpha*Mdot(4*n4+n,&(A[4*m4+i][j0]),x); } /* Mvm -- y <- alpha.A^T.x + beta.y */ void Mvm(m,n,alpha,A,j0,x,beta,y) int m, n, j0; double alpha, beta; Real **A, *x, *y; { register int i, j, m4, n2; register Real *Aref; register Real tmp; #ifdef REGISTER_RICH register Real *Aref0, *Aref1; register Real tmp0, tmp1; register Real yval0, yval1, yval2, yval3; #endif if ( beta != 1.0 ) Mscale(m,beta,y); /**************************************** for ( j = 0; j < n; j++ ) Maxpy(m,alpha*x[j],&(A[j][j0]),y); ****************************************/ m4 = n2 = 0; m4 = m / 4; m = m % 4; #ifdef REGISTER_RICH n2 = n / 2; n = n % 2; for ( j = 0; j < n2; j++ ) { tmp0 = alpha*x[2*j]; tmp1 = alpha*x[2*j+1]; Aref0 = &(A[2*j ][j0]); Aref1 = &(A[2*j+1][j0]); for ( i = 0; i < m4; i++ ) { yval0 = y[4*i ] + tmp0*Aref0[4*i ]; yval1 = y[4*i+1] + tmp0*Aref0[4*i+1]; yval2 = y[4*i+2] + tmp0*Aref0[4*i+2]; yval3 = y[4*i+3] + tmp0*Aref0[4*i+3]; y[4*i ] = yval0 + tmp1*Aref1[4*i ]; y[4*i+1] = yval1 + tmp1*Aref1[4*i+1]; y[4*i+2] = yval2 + tmp1*Aref1[4*i+2]; y[4*i+3] = yval3 + tmp1*Aref1[4*i+3]; } y += 4*m4; Aref0 += 4*m4; Aref1 += 4*m4; for ( i = 0; i < m; i++ ) y[i] += tmp0*Aref0[i] + tmp1*Aref1[i]; } #endif for ( j = 0; j < n; j++ ) { tmp = alpha*x[2*n2+j]; Aref = &(A[2*n2+j][j0]); for ( i = 0; i < m4; i++ ) { y[4*i ] += tmp*Aref[4*i ]; y[4*i+1] += tmp*Aref[4*i+1]; y[4*i+2] += tmp*Aref[4*i+2]; y[4*i+3] += tmp*Aref[4*i+3]; } y += 4*m4; Aref += 4*m4; for ( i = 0; i < m; i++ ) y[i] += tmp*Aref[i]; } } /* Mupdate -- A <- A + alpha.x.y^T */ void Mupdate(m,n,alpha,x,y,A,j0) int m, n, j0; double alpha; Real **A, *x, *y; { register int i, j, n4; register Real *Aref; register Real tmp; /**************************************** for ( i = 0; i < m; i++ ) Maxpy(n,alpha*x[i],y,&(A[i][j0])); ****************************************/ n4 = n / 4; n = n % 4; for ( i = 0; i < m; i++ ) { tmp = alpha*x[i]; Aref = &(A[i][j0]); for ( j = 0; j < n4; j++ ) { Aref[4*j ] += tmp*y[4*j ]; Aref[4*j+1] += tmp*y[4*j+1]; Aref[4*j+2] += tmp*y[4*j+2]; Aref[4*j+3] += tmp*y[4*j+3]; } Aref += 4*n4; y += 4*n4; for ( j = 0; j < n; j++ ) Aref[j] += tmp*y[j]; } } /* mblar-3 routines */ /* Mmm -- C <- C + alpha.A.B */ void Mmm(m,n,p,alpha,A,Aj0,B,Bj0,C,Cj0) int m, n, p; /* C is m x n */ double alpha; Real **A, **B, **C; int Aj0, Bj0, Cj0; { register int i, j, k; /* register Real tmp, sum; */ /**************************************** for ( i = 0; i < m; i++ ) for ( k = 0; k < p; k++ ) Maxpy(n,alpha*A[i][Aj0+k],&(B[k][Bj0]),&(C[i][Cj0])); ****************************************/ for ( i = 0; i < m; i++ ) Mvm(p,n,alpha,B,Bj0,&(A[i][Aj0]),1.0,&(C[i][Cj0])); } /* Mmtrm -- C <- C + alpha.A^T.B */ void Mmtrm(m,n,p,alpha,A,Aj0,B,Bj0,C,Cj0) int m, n, p; /* C is m x n */ double alpha; Real **A, **B, **C; int Aj0, Bj0, Cj0; { register int i, j, k; /**************************************** for ( i = 0; i < m; i++ ) for ( k = 0; k < p; k++ ) Maxpy(n,alpha*A[k][Aj0+i],&(B[k][Bj0]),&(C[i][Cj0])); ****************************************/ for ( k = 0; k < p; k++ ) Mupdate(m,n,alpha,&(A[k][Aj0]),&(B[k][Bj0]),C,Cj0); } /* Mmmtr -- C <- C + alpha.A.B^T */ void Mmmtr(m,n,p,alpha,A,Aj0,B,Bj0,C,Cj0) int m, n, p; /* C is m x n */ double alpha; Real **A, **B, **C; int Aj0, Bj0, Cj0; { register int i, j, k; /**************************************** for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j++ ) C[i][Cj0+j] += alpha*Mdot(p,&(A[i][Aj0]),&(B[j][Bj0])); ****************************************/ for ( i = 0; i < m; i++ ) Mmv(n,p,alpha,B,Bj0,&(A[i][Aj0]),1.0,&(C[i][Cj0])); } /* Mmtrmtr -- C <- C + alpha.A^T.B^T */ void Mmtrmtr(m,n,p,alpha,A,Aj0,B,Bj0,C,Cj0) int m, n, p; /* C is m x n */ double alpha; Real **A, **B, **C; int Aj0, Bj0, Cj0; { register int i, j, k; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j++ ) for ( k = 0; k < p; k++ ) C[i][Cj0+j] += A[i][Aj0+k]*B[k][Bj0+j]; } gtk-wave-cleaner-0.22-04/meschach/fft.c0000777000175000017500000000776213120075106020716 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Fast Fourier Transform routine Loosely based on the Fortran routine in Rabiner & Gold's "Digital Signal Processing" */ static char rcsid[] = "$Id: fft.c,v 1.4 1996/08/20 14:21:05 stewart Exp $"; #include #include #include "matrix.h" #include "matrix2.h" /* fft -- d.i.t. fast Fourier transform -- radix-2 FFT only -- vector extended to a power of 2 */ #ifndef ANSI_C void fft(x_re,x_im) VEC *x_re, *x_im; #else void fft(VEC *x_re, VEC *x_im) #endif { int i, ip, j, k, li, n, length; Real *xr, *xi; Real theta, pi = 3.1415926535897932384; Real w_re, w_im, u_re, u_im, t_re, t_im; Real tmp, tmpr, tmpi; if ( ! x_re || ! x_im ) error(E_NULL,"fft"); if ( x_re->dim != x_im->dim ) error(E_SIZES,"fft"); n = 1; while ( x_re->dim > n ) n *= 2; x_re = v_resize(x_re,n); x_im = v_resize(x_im,n); /* printf("# fft: x_re =\n"); v_output(x_re); */ /* printf("# fft: x_im =\n"); v_output(x_im); */ xr = x_re->ve; xi = x_im->ve; /* Decimation in time (DIT) algorithm */ j = 0; for ( i = 0; i < n-1; i++ ) { if ( i < j ) { tmp = xr[i]; xr[i] = xr[j]; xr[j] = tmp; tmp = xi[i]; xi[i] = xi[j]; xi[j] = tmp; } k = n / 2; while ( k <= j ) { j -= k; k /= 2; } j += k; } /* Actual FFT */ for ( li = 1; li < n; li *= 2 ) { length = 2*li; theta = pi/li; u_re = 1.0; u_im = 0.0; if ( li == 1 ) { w_re = -1.0; w_im = 0.0; } else if ( li == 2 ) { w_re = 0.0; w_im = 1.0; } else { w_re = cos(theta); w_im = sin(theta); } for ( j = 0; j < li; j++ ) { for ( i = j; i < n; i += length ) { ip = i + li; /* step 1 */ t_re = xr[ip]*u_re - xi[ip]*u_im; t_im = xr[ip]*u_im + xi[ip]*u_re; /* step 2 */ xr[ip] = xr[i] - t_re; xi[ip] = xi[i] - t_im; /* step 3 */ xr[i] += t_re; xi[i] += t_im; } tmpr = u_re*w_re - u_im*w_im; tmpi = u_im*w_re + u_re*w_im; u_re = tmpr; u_im = tmpi; } } } /* ifft -- inverse FFT using the same interface as fft() */ #ifndef ANSI_C void ifft(x_re,x_im) VEC *x_re, *x_im; #else void ifft(VEC *x_re, VEC *x_im) #endif { /* we just use complex conjugates */ sv_mlt(-1.0,x_im,x_im); fft(x_re,x_im); sv_mlt(-1.0/((double)(x_re->dim)),x_im,x_im); sv_mlt( 1.0/((double)(x_re->dim)),x_re,x_re); } gtk-wave-cleaner-0.22-04/meschach/fmacheps.c0000777000175000017500000000257013120075106021715 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ #include double fclean(x) double x; { static float y; y = x; return y; /* prevents optimisation */ } main() { static float feps, feps1, ftmp; feps = 1.0; while ( fclean(1.0+feps) > 1.0 ) feps = 0.5*feps; printf("%g\n", 2.0*feps); } gtk-wave-cleaner-0.22-04/meschach/givens.c0000777000175000017500000001010713120075106021415 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Files for matrix computations Givens operations file. Contains routines for calculating and applying givens rotations for/to vectors and also to matrices by row and by column. */ /* givens.c 1.2 11/25/87 */ static char rcsid[] = "$Id: givens.c,v 1.3 1995/03/27 15:41:15 des Exp $"; #include #include #include "matrix.h" #include "matrix2.h" /* givens -- returns c,s parameters for Givens rotation to eliminate y in the vector [ x y ]' */ #ifndef ANSI_C void givens(x,y,c,s) double x,y; Real *c,*s; #else void givens(double x, double y, Real *c, Real *s) #endif { Real norm; norm = sqrt(x*x+y*y); if ( norm == 0.0 ) { *c = 1.0; *s = 0.0; } /* identity */ else { *c = x/norm; *s = y/norm; } } /* rot_vec -- apply Givens rotation to x's i & k components */ #ifndef ANSI_C VEC *rot_vec(x,i,k,c,s,out) VEC *x,*out; unsigned int i,k; double c,s; #else VEC *rot_vec(const VEC *x,unsigned int i,unsigned int k, double c,double s, VEC *out) #endif { Real temp; if ( x==VNULL ) error(E_NULL,"rot_vec"); if ( i >= x->dim || k >= x->dim ) error(E_RANGE,"rot_vec"); out = v_copy(x,out); /* temp = c*out->ve[i] + s*out->ve[k]; */ temp = c*v_entry(out,i) + s*v_entry(out,k); /* out->ve[k] = -s*out->ve[i] + c*out->ve[k]; */ v_set_val(out,k,-s*v_entry(out,i)+c*v_entry(out,k)); /* out->ve[i] = temp; */ v_set_val(out,i,temp); return (out); } /* rot_rows -- premultiply mat by givens rotation described by c,s */ #ifndef ANSI_C MAT *rot_rows(mat,i,k,c,s,out) MAT *mat,*out; unsigned int i,k; double c,s; #else MAT *rot_rows(const MAT *mat, unsigned int i, unsigned int k, double c, double s, MAT *out) #endif { unsigned int j; Real temp; if ( mat==(MAT *)NULL ) error(E_NULL,"rot_rows"); if ( i >= mat->m || k >= mat->m ) error(E_RANGE,"rot_rows"); if ( mat != out ) out = m_copy(mat,m_resize(out,mat->m,mat->n)); for ( j=0; jn; j++ ) { /* temp = c*out->me[i][j] + s*out->me[k][j]; */ temp = c*m_entry(out,i,j) + s*m_entry(out,k,j); /* out->me[k][j] = -s*out->me[i][j] + c*out->me[k][j]; */ m_set_val(out,k,j, -s*m_entry(out,i,j) + c*m_entry(out,k,j)); /* out->me[i][j] = temp; */ m_set_val(out,i,j, temp); } return (out); } /* rot_cols -- postmultiply mat by givens rotation described by c,s */ #ifndef ANSI_C MAT *rot_cols(mat,i,k,c,s,out) MAT *mat,*out; unsigned int i,k; double c,s; #else MAT *rot_cols(const MAT *mat,unsigned int i,unsigned int k, double c, double s, MAT *out) #endif { unsigned int j; Real temp; if ( mat==(MAT *)NULL ) error(E_NULL,"rot_cols"); if ( i >= mat->n || k >= mat->n ) error(E_RANGE,"rot_cols"); if ( mat != out ) out = m_copy(mat,m_resize(out,mat->m,mat->n)); for ( j=0; jm; j++ ) { /* temp = c*out->me[j][i] + s*out->me[j][k]; */ temp = c*m_entry(out,j,i) + s*m_entry(out,j,k); /* out->me[j][k] = -s*out->me[j][i] + c*out->me[j][k]; */ m_set_val(out,j,k, -s*m_entry(out,j,i) + c*m_entry(out,j,k)); /* out->me[j][i] = temp; */ m_set_val(out,j,i,temp); } return (out); } gtk-wave-cleaner-0.22-04/meschach/hessen.c0000777000175000017500000001061613120075106021414 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* File containing routines for determining Hessenberg factorisations. */ static char rcsid[] = "$Id: hessen.c,v 1.2 1994/01/13 05:36:24 des Exp $"; #include #include "matrix.h" #include "matrix2.h" /* Hfactor -- compute Hessenberg factorisation in compact form. -- factorisation performed in situ -- for details of the compact form see QRfactor.c and matrix2.doc */ #ifndef ANSI_C MAT *Hfactor(A, diag, beta) MAT *A; VEC *diag, *beta; #else MAT *Hfactor(MAT *A, VEC *diag, VEC *beta) #endif { STATIC VEC *hh = VNULL, *w = VNULL; int k, limit; if ( ! A || ! diag || ! beta ) error(E_NULL,"Hfactor"); if ( diag->dim < A->m - 1 || beta->dim < A->m - 1 ) error(E_SIZES,"Hfactor"); if ( A->m != A->n ) error(E_SQUARE,"Hfactor"); limit = A->m - 1; hh = v_resize(hh,A->m); w = v_resize(w,A->n); MEM_STAT_REG(hh,TYPE_VEC); MEM_STAT_REG(w, TYPE_VEC); for ( k = 0; k < limit; k++ ) { /* compute the Householder vector hh */ get_col(A,(unsigned int)k,hh); /* printf("the %d'th column = "); v_output(hh); */ hhvec(hh,k+1,&beta->ve[k],hh,&A->me[k+1][k]); /* diag->ve[k] = hh->ve[k+1]; */ v_set_val(diag,k,v_entry(hh,k+1)); /* printf("H/h vector = "); v_output(hh); */ /* printf("from the %d'th entry\n",k+1); */ /* printf("beta = %g\n",beta->ve[k]); */ /* apply Householder operation symmetrically to A */ _hhtrcols(A,k+1,k+1,hh,v_entry(beta,k),w); hhtrrows(A,0 ,k+1,hh,v_entry(beta,k)); /* printf("A = "); m_output(A); */ } #ifdef THREADSAFE V_FREE(hh); V_FREE(w); #endif return (A); } /* makeHQ -- construct the Hessenberg orthogonalising matrix Q; -- i.e. Hess M = Q.M.Q' */ #ifndef ANSI_C MAT *makeHQ(H, diag, beta, Qout) MAT *H, *Qout; VEC *diag, *beta; #else MAT *makeHQ(MAT *H, VEC *diag, VEC *beta, MAT *Qout) #endif { int i, j, limit; STATIC VEC *tmp1 = VNULL, *tmp2 = VNULL; if ( H==(MAT *)NULL || diag==(VEC *)NULL || beta==(VEC *)NULL ) error(E_NULL,"makeHQ"); limit = H->m - 1; if ( diag->dim < limit || beta->dim < limit ) error(E_SIZES,"makeHQ"); if ( H->m != H->n ) error(E_SQUARE,"makeHQ"); Qout = m_resize(Qout,H->m,H->m); tmp1 = v_resize(tmp1,H->m); tmp2 = v_resize(tmp2,H->m); MEM_STAT_REG(tmp1,TYPE_VEC); MEM_STAT_REG(tmp2,TYPE_VEC); for ( i = 0; i < H->m; i++ ) { /* tmp1 = i'th basis vector */ for ( j = 0; j < H->m; j++ ) /* tmp1->ve[j] = 0.0; */ v_set_val(tmp1,j,0.0); /* tmp1->ve[i] = 1.0; */ v_set_val(tmp1,i,1.0); /* apply H/h transforms in reverse order */ for ( j = limit-1; j >= 0; j-- ) { get_col(H,(unsigned int)j,tmp2); /* tmp2->ve[j+1] = diag->ve[j]; */ v_set_val(tmp2,j+1,v_entry(diag,j)); hhtrvec(tmp2,beta->ve[j],j+1,tmp1,tmp1); } /* insert into Qout */ set_col(Qout,(unsigned int)i,tmp1); } #ifdef THREADSAFE V_FREE(tmp1); V_FREE(tmp2); #endif return (Qout); } /* makeH -- construct actual Hessenberg matrix */ #ifndef ANSI_C MAT *makeH(H,Hout) MAT *H, *Hout; #else MAT *makeH(const MAT *H, MAT *Hout) #endif { int i, j, limit; if ( H==(MAT *)NULL ) error(E_NULL,"makeH"); if ( H->m != H->n ) error(E_SQUARE,"makeH"); Hout = m_resize(Hout,H->m,H->m); Hout = m_copy(H,Hout); limit = H->m; for ( i = 1; i < limit; i++ ) for ( j = 0; j < i-1; j++ ) /* Hout->me[i][j] = 0.0;*/ m_set_val(Hout,i,j,0.0); return (Hout); } gtk-wave-cleaner-0.22-04/meschach/hsehldr.c0000777000175000017500000001453113120075106021560 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Files for matrix computations Householder transformation file. Contains routines for calculating householder transformations, applying them to vectors and matrices by both row & column. */ /* hsehldr.c 1.3 10/8/87 */ static char rcsid[] = "$Id: hsehldr.c,v 1.2 1994/01/13 05:36:29 des Exp $"; #include #include #include "matrix.h" #include "matrix2.h" /* hhvec -- calulates Householder vector to eliminate all entries after the i0 entry of the vector vec. It is returned as out. May be in-situ */ #ifndef ANSI_C VEC *hhvec(vec,i0,beta,out,newval) VEC *vec,*out; unsigned int i0; Real *beta,*newval; #else VEC *hhvec(const VEC *vec, unsigned int i0, Real *beta, VEC *out, Real *newval) #endif { Real norm; out = _v_copy(vec,out,i0); norm = sqrt(_in_prod(out,out,i0)); if ( norm <= 0.0 ) { *beta = 0.0; return (out); } *beta = 1.0/(norm * (norm+fabs(out->ve[i0]))); if ( out->ve[i0] > 0.0 ) *newval = -norm; else *newval = norm; out->ve[i0] -= *newval; return (out); } /* hhtrvec -- apply Householder transformation to vector -- that is, out <- (I-beta.hh(i0:n).hh(i0:n)^T).in -- may be in-situ */ #ifndef ANSI_C VEC *hhtrvec(hh,beta,i0,in,out) VEC *hh,*in,*out; /* hh = Householder vector */ unsigned int i0; double beta; #else VEC *hhtrvec(const VEC *hh, double beta, unsigned int i0, const VEC *in, VEC *out) #endif { Real scale; /* unsigned int i; */ if ( hh==VNULL || in==VNULL ) error(E_NULL,"hhtrvec"); if ( in->dim != hh->dim ) error(E_SIZES,"hhtrvec"); if ( i0 > in->dim ) error(E_BOUNDS,"hhtrvec"); scale = beta*_in_prod(hh,in,i0); out = v_copy(in,out); __mltadd__(&(out->ve[i0]),&(hh->ve[i0]),-scale,(int)(in->dim-i0)); /************************************************************ for ( i=i0; idim; i++ ) out->ve[i] = in->ve[i] - scale*hh->ve[i]; ************************************************************/ return (out); } /* hhtrrows -- transform a matrix by a Householder vector by rows starting at row i0 from column j0 -- in-situ -- that is, M(i0:m,j0:n) <- M(i0:m,j0:n)(I-beta.hh(j0:n).hh(j0:n)^T) */ #ifndef ANSI_C MAT *hhtrrows(M,i0,j0,hh,beta) MAT *M; unsigned int i0, j0; VEC *hh; double beta; #else MAT *hhtrrows(MAT *M, unsigned int i0, unsigned int j0, const VEC *hh, double beta) #endif { Real ip, scale; int i /*, j */; if ( M==MNULL || hh==VNULL ) error(E_NULL,"hhtrrows"); if ( M->n != hh->dim ) error(E_RANGE,"hhtrrows"); if ( i0 > M->m || j0 > M->n ) error(E_BOUNDS,"hhtrrows"); if ( beta == 0.0 ) return (M); /* for each row ... */ for ( i = i0; i < M->m; i++ ) { /* compute inner product */ ip = __ip__(&(M->me[i][j0]),&(hh->ve[j0]),(int)(M->n-j0)); /************************************************** ip = 0.0; for ( j = j0; j < M->n; j++ ) ip += M->me[i][j]*hh->ve[j]; **************************************************/ scale = beta*ip; if ( scale == 0.0 ) continue; /* do operation */ __mltadd__(&(M->me[i][j0]),&(hh->ve[j0]),-scale, (int)(M->n-j0)); /************************************************** for ( j = j0; j < M->n; j++ ) M->me[i][j] -= scale*hh->ve[j]; **************************************************/ } return (M); } /* hhtrcols -- transform a matrix by a Householder vector by columns starting at row i0 from column j0 -- that is, M(i0:m,j0:n) <- (I-beta.hh(i0:m).hh(i0:m)^T)M(i0:m,j0:n) -- in-situ -- calls _hhtrcols() with the scratch vector w -- Meschach internal routines should call _hhtrcols() to avoid excessive memory allocation/de-allocation */ #ifndef ANSI_C MAT *hhtrcols(M,i0,j0,hh,beta) MAT *M; unsigned int i0, j0; VEC *hh; double beta; #else MAT *hhtrcols(MAT *M, unsigned int i0, unsigned int j0, const VEC *hh, double beta) #endif { STATIC VEC *w = VNULL; if ( M == MNULL || hh == VNULL || w == VNULL ) error(E_NULL,"hhtrcols"); if ( M->m != hh->dim ) error(E_SIZES,"hhtrcols"); if ( i0 > M->m || j0 > M->n ) error(E_BOUNDS,"hhtrcols"); if ( ! w || w->dim < M->n ) w = v_resize(w,M->n); MEM_STAT_REG(w,TYPE_VEC); M = _hhtrcols(M,i0,j0,hh,beta,w); #ifdef THREADSAFE V_FREE(w); #endif return M; } /* _hhtrcols -- transform a matrix by a Householder vector by columns starting at row i0 from column j0 -- that is, M(i0:m,j0:n) <- (I-beta.hh(i0:m).hh(i0:m)^T)M(i0:m,j0:n) -- in-situ -- scratch vector w passed as argument -- raises error if w == NULL */ #ifndef ANSI_C MAT *_hhtrcols(M,i0,j0,hh,beta,w) MAT *M; unsigned int i0, j0; VEC *hh; double beta; VEC *w; #else MAT *_hhtrcols(MAT *M, unsigned int i0, unsigned int j0, const VEC *hh, double beta, VEC *w) #endif { /* Real ip, scale; */ int i /*, k */; /* STATIC VEC *w = VNULL; */ if ( M == MNULL || hh == VNULL || w == VNULL ) error(E_NULL,"_hhtrcols"); if ( M->m != hh->dim ) error(E_SIZES,"_hhtrcols"); if ( i0 > M->m || j0 > M->n ) error(E_BOUNDS,"_hhtrcols"); if ( beta == 0.0 ) return (M); if ( w->dim < M->n ) w = v_resize(w,M->n); /* MEM_STAT_REG(w,TYPE_VEC); */ v_zero(w); for ( i = i0; i < M->m; i++ ) if ( hh->ve[i] != 0.0 ) __mltadd__(&(w->ve[j0]),&(M->me[i][j0]),hh->ve[i], (int)(M->n-j0)); for ( i = i0; i < M->m; i++ ) if ( hh->ve[i] != 0.0 ) __mltadd__(&(M->me[i][j0]),&(w->ve[j0]),-beta*hh->ve[i], (int)(M->n-j0)); return (M); } gtk-wave-cleaner-0.22-04/meschach/init.c0000777000175000017500000001454313120075106021075 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This is a file of routines for zero-ing, and initialising vectors, matrices and permutations. This is to be included in the matrix.a library */ static char rcsid[] = "$Id: init.c,v 1.6 1994/01/13 05:36:58 des Exp $"; #include #include "matrix.h" /* v_zero -- zero the vector x */ #ifndef ANSI_C VEC *v_zero(x) VEC *x; #else VEC *v_zero(VEC *x) #endif { if ( x == VNULL ) error(E_NULL,"v_zero"); __zero__(x->ve,x->dim); /* for ( i = 0; i < x->dim; i++ ) x->ve[i] = 0.0; */ return x; } /* iv_zero -- zero the vector ix */ #ifndef ANSI_C IVEC *iv_zero(ix) IVEC *ix; #else IVEC *iv_zero(IVEC *ix) #endif { int i; if ( ix == IVNULL ) error(E_NULL,"iv_zero"); for ( i = 0; i < ix->dim; i++ ) ix->ive[i] = 0; return ix; } /* m_zero -- zero the matrix A */ #ifndef ANSI_C MAT *m_zero(A) MAT *A; #else MAT *m_zero(MAT *A) #endif { int i, A_m, A_n; Real **A_me; if ( A == MNULL ) error(E_NULL,"m_zero"); A_m = A->m; A_n = A->n; A_me = A->me; for ( i = 0; i < A_m; i++ ) __zero__(A_me[i],A_n); /* for ( j = 0; j < A_n; j++ ) A_me[i][j] = 0.0; */ return A; } /* mat_id -- set A to being closest to identity matrix as possible -- i.e. A[i][j] == 1 if i == j and 0 otherwise */ #ifndef ANSI_C MAT *m_ident(A) MAT *A; #else MAT *m_ident(MAT *A) #endif { int i, size; if ( A == MNULL ) error(E_NULL,"m_ident"); m_zero(A); size = min(A->m,A->n); for ( i = 0; i < size; i++ ) A->me[i][i] = 1.0; return A; } /* px_ident -- set px to identity permutation */ #ifndef ANSI_C PERM *px_ident(px) PERM *px; #else PERM *px_ident(PERM *px) #endif { int i, px_size; unsigned int *px_pe; if ( px == PNULL ) error(E_NULL,"px_ident"); px_size = px->size; px_pe = px->pe; for ( i = 0; i < px_size; i++ ) px_pe[i] = i; return px; } /* Pseudo random number generator data structures */ /* Knuth's lagged Fibonacci-based generator: See "Seminumerical Algorithms: The Art of Computer Programming" sections 3.2-3.3 */ #ifdef ANSI_C #ifndef LONG_MAX #include #endif #endif #ifdef LONG_MAX #define MODULUS LONG_MAX #else #define MODULUS 1000000000L /* assuming long's at least 32 bits long */ #endif #define MZ 0L static long mrand_list[56]; static int started = FALSE; static int inext = 0, inextp = 31; /* mrand -- pseudo-random number generator */ #ifdef ANSI_C double mrand(void) #else double mrand() #endif { long lval; static Real factor = 1.0/((Real)MODULUS); if ( ! started ) smrand(3127); inext = (inext >= 54) ? 0 : inext+1; inextp = (inextp >= 54) ? 0 : inextp+1; lval = mrand_list[inext]-mrand_list[inextp]; if ( lval < 0L ) lval += MODULUS; mrand_list[inext] = lval; return (double)lval*factor; } /* mrandlist -- fills the array a[] with len random numbers */ #ifndef ANSI_C void mrandlist(a, len) Real a[]; int len; #else void mrandlist(Real a[], int len) #endif { int i; long lval; static Real factor = 1.0/((Real)MODULUS); if ( ! started ) smrand(3127); for ( i = 0; i < len; i++ ) { inext = (inext >= 54) ? 0 : inext+1; inextp = (inextp >= 54) ? 0 : inextp+1; lval = mrand_list[inext]-mrand_list[inextp]; if ( lval < 0L ) lval += MODULUS; mrand_list[inext] = lval; a[i] = (Real)lval*factor; } } /* smrand -- set seed for mrand() */ #ifndef ANSI_C void smrand(seed) int seed; #else void smrand(int seed) #endif { int i; mrand_list[0] = (123413*seed) % MODULUS; for ( i = 1; i < 55; i++ ) mrand_list[i] = (123413*mrand_list[i-1]) % MODULUS; started = TRUE; /* run mrand() through the list sufficient times to thoroughly randomise the array */ for ( i = 0; i < 55*55; i++ ) mrand(); } #undef MODULUS #undef MZ #undef FAC /* v_rand -- initialises x to be a random vector, components independently & uniformly ditributed between 0 and 1 */ #ifndef ANSI_C VEC *v_rand(x) VEC *x; #else VEC *v_rand(VEC *x) #endif { /* int i; */ if ( ! x ) error(E_NULL,"v_rand"); /* for ( i = 0; i < x->dim; i++ ) */ /* x->ve[i] = rand()/((Real)MAX_RAND); */ /* x->ve[i] = mrand(); */ mrandlist(x->ve,x->dim); return x; } /* m_rand -- initialises A to be a random vector, components independently & uniformly distributed between 0 and 1 */ #ifndef ANSI_C MAT *m_rand(A) MAT *A; #else MAT *m_rand(MAT *A) #endif { int i /* , j */; if ( ! A ) error(E_NULL,"m_rand"); for ( i = 0; i < A->m; i++ ) /* for ( j = 0; j < A->n; j++ ) */ /* A->me[i][j] = rand()/((Real)MAX_RAND); */ /* A->me[i][j] = mrand(); */ mrandlist(A->me[i],A->n); return A; } /* v_ones -- fills x with one's */ #ifndef ANSI_C VEC *v_ones(x) VEC *x; #else VEC *v_ones(VEC *x) #endif { int i; if ( ! x ) error(E_NULL,"v_ones"); for ( i = 0; i < x->dim; i++ ) x->ve[i] = 1.0; return x; } /* m_ones -- fills matrix with one's */ #ifndef ANSI_C MAT *m_ones(A) MAT *A; #else MAT *m_ones(MAT *A) #endif { int i, j; if ( ! A ) error(E_NULL,"m_ones"); for ( i = 0; i < A->m; i++ ) for ( j = 0; j < A->n; j++ ) A->me[i][j] = 1.0; return A; } /* v_count -- initialises x so that x->ve[i] == i */ #ifndef ANSI_C VEC *v_count(x) VEC *x; #else VEC *v_count(VEC *x) #endif { int i; if ( ! x ) error(E_NULL,"v_count"); for ( i = 0; i < x->dim; i++ ) x->ve[i] = (Real)i; return x; } gtk-wave-cleaner-0.22-04/meschach/iotort.c0000777000175000017500000000650413120075106021450 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* iotort.c 10/11/93 */ /* test of I/O functions */ static char rcsid[] = "$Id: $"; #include "sparse.h" #include "zmatrix.h" #define errmesg(mesg) printf("Error: %s error: line %d\n",mesg,__LINE__) #define notice(mesg) printf("# Testing %s...\n",mesg); void main() { VEC *x; MAT *A; PERM *pivot; IVEC *ix; SPMAT *spA; ZVEC *zx; ZMAT *ZA; char yes; int i; FILE *fp; mem_info_on(TRUE); if ((fp = fopen("iotort.dat","w")) == NULL) { printf(" !!! Cannot open file %s for writing\n\n","iotort.dat"); exit(1); } x = v_get(10); A = m_get(3,3); zx = zv_get(10); ZA = zm_get(3,3); pivot = px_get(10); ix = iv_get(10); spA = sp_get(3,3,2); v_rand(x); m_rand(A); zv_rand(zx); zm_rand(ZA); px_ident(pivot); for (i=0; i < 10; i++) ix->ive[i] = i+1; for (i=0; i < spA->m; i++) { sp_set_val(spA,i,i,1.0); if (i > 0) sp_set_val(spA,i-1,i,-1.0); } notice(" VEC output"); v_foutput(fp,x); notice(" MAT output"); m_foutput(fp,A); notice(" ZVEC output"); zv_foutput(fp,zx); notice(" ZMAT output"); zm_foutput(fp,ZA); notice(" PERM output"); px_foutput(fp,pivot); notice(" IVEC output"); iv_foutput(fp,ix); notice(" SPMAT output"); sp_foutput(fp,spA); fprintf(fp,"Y"); fclose(fp); printf("\nENTER SOME VALUES:\n\n"); if ((fp = fopen("iotort.dat","r")) == NULL) { printf(" !!! Cannot open file %s for reading\n\n","iotort.dat"); exit(1); } notice(" VEC input/output"); x = v_finput(fp,x); v_output(x); notice(" MAT input/output"); A = m_finput(fp,A); m_output(A); notice(" ZVEC input/output"); zx = zv_finput(fp,zx); zv_output(zx); notice(" ZMAT input/output"); ZA = zm_finput(fp,ZA); zm_output(ZA); notice(" PERM input/output"); pivot = px_finput(fp,pivot); px_output(pivot); notice(" IVEC input/output"); ix = iv_finput(fp,ix); iv_output(ix); notice(" SPMAT input/output"); SP_FREE(spA); spA = sp_finput(fp); sp_output(spA); notice(" general input"); finput(fp," finish the test? ","%c",&yes); if (yes == 'y' || yes == 'Y' ) printf(" YES\n"); else printf(" NO\n"); fclose(fp); mem_info(); } gtk-wave-cleaner-0.22-04/meschach/iter.h0000777000175000017500000001574713120075106021111 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* iter.h 14/09/93 */ /* Structures for iterative methods */ #ifndef ITERHH #define ITERHH /* RCS id: $Id: iter.h,v 1.2 1994/03/08 05:48:27 des Exp $ */ #include "sparse.h" /* basic structure for iterative methods */ /* type Fun_Ax for functions to get y = A*x */ #ifdef ANSI_C typedef VEC *(*Fun_Ax)(void *,VEC *,VEC *); #else typedef VEC *(*Fun_Ax)(); #endif /* type ITER */ typedef struct Iter_data { int shared_x; /* if TRUE then x is shared and it will not be free'd */ int shared_b; /* if TRUE then b is shared and it will not be free'd */ unsigned k; /* no. of direction (search) vectors; =0 - none */ int limit; /* upper bound on the no. of iter. steps */ int steps; /* no. of iter. steps done */ Real eps; /* accuracy required */ VEC *x; /* input: initial guess; output: approximate solution */ VEC *b; /* right hand side of the equation A*x = b */ Fun_Ax Ax; /* function computing y = A*x */ void *A_par; /* parameters for Ax */ Fun_Ax ATx; /* function computing y = A^T*x; T = transpose */ void *AT_par; /* parameters for ATx */ Fun_Ax Bx; /* function computing y = B*x; B - preconditioner */ void *B_par; /* parameters for Bx */ Fun_Ax BTx; /* function computing y = B^T*x; B - preconditioner */ void *BT_par; /* parameters for BTx */ #ifdef ANSI_C #ifdef PROTOTYPES_IN_STRUCT void (*info)(struct Iter_data *, double, VEC *,VEC *); /* function giving some information for a user; nres - a norm of a residual res */ int (*stop_crit)(struct Iter_data *, double, VEC *,VEC *); /* stopping criterion: nres - a norm of res; res - residual; if returned value == TRUE then stop; if returned value == FALSE then continue; */ #else void (*info)(); int (*stop_crit)(); #endif /* PROTOTYPES_IN_STRUCT */ #else void (*info)(); /* function giving some information for a user */ int (*stop_crit)(); /* stopping criterion: if returned value == TRUE then stop; if returned value == FALSE then continue; */ #endif /* ANSI_C */ Real init_res; /* the norm of the initial residual */ } ITER; #define INULL (ITER *)NULL /* type Fun_info */ #ifdef ANSI_C typedef void (*Fun_info)(ITER *, double, VEC *,VEC *); #else typedef void (*Fun_info)(); #endif /* type Fun_stp_crt */ #ifdef ANSI_C typedef int (*Fun_stp_crt)(ITER *, double, VEC *,VEC *); #else typedef int (*Fun_stp_crt)(); #endif /* macros */ /* default values */ #define ITER_LIMIT_DEF 1000 #define ITER_EPS_DEF 1e-6 /* other macros */ /* set ip->Ax=fun and ip->A_par=fun_par */ #define iter_Ax(ip,fun,fun_par) \ (ip->Ax=(Fun_Ax)(fun),ip->A_par=(void *)(fun_par),0) #define iter_ATx(ip,fun,fun_par) \ (ip->ATx=(Fun_Ax)(fun),ip->AT_par=(void *)(fun_par),0) #define iter_Bx(ip,fun,fun_par) \ (ip->Bx=(Fun_Ax)(fun),ip->B_par=(void *)(fun_par),0) #define iter_BTx(ip,fun,fun_par) \ (ip->BTx=(Fun_Ax)(fun),ip->BT_par=(void *)(fun_par),0) /* save free macro */ #define ITER_FREE(ip) (iter_free(ip), (ip)=(ITER *)NULL) /* prototypes from iter0.c */ #ifdef ANSI_C /* standard information */ void iter_std_info(const ITER *ip,double nres,VEC *res,VEC *Bres); /* standard stopping criterion */ int iter_std_stop_crit(const ITER *ip, double nres, VEC *res,VEC *Bres); /* get, resize and free ITER variable */ ITER *iter_get(int lenb, int lenx); ITER *iter_resize(ITER *ip,int lenb,int lenx); int iter_free(ITER *ip); void iter_dump(FILE *fp,ITER *ip); /* copy ip1 to ip2 copying also elements of x and b */ ITER *iter_copy(const ITER *ip1, ITER *ip2); /* copy ip1 to ip2 without copying elements of x and b */ ITER *iter_copy2(ITER *ip1,ITER *ip2); /* functions for generating sparse matrices with random elements */ SPMAT *iter_gen_sym(int n, int nrow); SPMAT *iter_gen_nonsym(int m,int n,int nrow,double diag); SPMAT *iter_gen_nonsym_posdef(int n,int nrow); #else void iter_std_info(); int iter_std_stop_crit(); ITER *iter_get(); int iter_free(); ITER *iter_resize(); void iter_dump(); ITER *iter_copy(); ITER *iter_copy2(); SPMAT *iter_gen_sym(); SPMAT *iter_gen_nonsym(); SPMAT *iter_gen_nonsym_posdef(); #endif /* prototypes from iter.c */ /* different iterative procedures */ #ifdef ANSI_C VEC *iter_cg(ITER *ip); VEC *iter_cg1(ITER *ip); VEC *iter_spcg(SPMAT *A,SPMAT *LLT,VEC *b,double eps,VEC *x,int limit, int *steps); VEC *iter_cgs(ITER *ip,VEC *r0); VEC *iter_spcgs(SPMAT *A,SPMAT *B,VEC *b,VEC *r0,double eps,VEC *x, int limit, int *steps); VEC *iter_lsqr(ITER *ip); VEC *iter_splsqr(SPMAT *A,VEC *b,double tol,VEC *x, int limit,int *steps); VEC *iter_gmres(ITER *ip); VEC *iter_spgmres(SPMAT *A,SPMAT *B,VEC *b,double tol,VEC *x,int k, int limit, int *steps); MAT *iter_arnoldi_iref(ITER *ip,Real *h,MAT *Q,MAT *H); MAT *iter_arnoldi(ITER *ip,Real *h,MAT *Q,MAT *H); MAT *iter_sparnoldi(SPMAT *A,VEC *x0,int k,Real *h,MAT *Q,MAT *H); VEC *iter_mgcr(ITER *ip); VEC *iter_spmgcr(SPMAT *A,SPMAT *B,VEC *b,double tol,VEC *x,int k, int limit, int *steps); void iter_lanczos(ITER *ip,VEC *a,VEC *b,Real *beta2,MAT *Q); void iter_splanczos(SPMAT *A,int m,VEC *x0,VEC *a,VEC *b,Real *beta2, MAT *Q); VEC *iter_lanczos2(ITER *ip,VEC *evals,VEC *err_est); VEC *iter_splanczos2(SPMAT *A,int m,VEC *x0,VEC *evals,VEC *err_est); VEC *iter_cgne(ITER *ip); VEC *iter_spcgne(SPMAT *A,SPMAT *B,VEC *b,double eps,VEC *x, int limit,int *steps); #else VEC *iter_cg(); VEC *iter_cg1(); VEC *iter_spcg(); VEC *iter_cgs(); VEC *iter_spcgs(); VEC *iter_lsqr(); VEC *iter_splsqr(); VEC *iter_gmres(); VEC *iter_spgmres(); MAT *iter_arnoldi_iref(); MAT *iter_arnoldi(); MAT *iter_sparnoldi(); VEC *iter_mgcr(); VEC *iter_spmgcr(); void iter_lanczos(); void iter_splanczos(); VEC *iter_lanczos2(); VEC *iter_splanczos2(); VEC *iter_cgne(); VEC *iter_spcgne(); #endif #endif /* ITERHH */ gtk-wave-cleaner-0.22-04/meschach/iter0.c0000777000175000017500000002324613120075106021155 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Stewart & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* iter0.c 14/09/93 */ /* ITERATIVE METHODS - service functions */ /* functions for creating and releasing ITER structures; for memory information; for getting some values from an ITER variable; for changing values in an ITER variable; see also iter.c */ #include #include #include "iter.h" static char rcsid[] = "$Id: iter0.c,v 1.3 1995/01/30 14:50:56 des Exp $"; /* standard functions */ /* standard information */ #ifndef ANSI_C void iter_std_info(ip,nres,res,Bres) ITER *ip; double nres; VEC *res, *Bres; #else void iter_std_info(const ITER *ip, double nres, VEC *res, VEC *Bres) #endif { if (nres >= 0.0) #ifndef MEX printf(" %d. residual = %g\n",ip->steps,nres); #else mexPrintf(" %d. residual = %g\n",ip->steps,nres); #endif else #ifndef MEX printf(" %d. residual = %g (WARNING !!! should be >= 0) \n", ip->steps,nres); #else mexPrintf(" %d. residual = %g (WARNING !!! should be >= 0) \n", ip->steps,nres); #endif } /* standard stopping criterion */ #ifndef ANSI_C int iter_std_stop_crit(ip, nres, res, Bres) ITER *ip; double nres; VEC *res, *Bres; #else int iter_std_stop_crit(const ITER *ip, double nres, VEC *res, VEC *Bres) #endif { /* standard stopping criterium */ if (nres <= ip->init_res*ip->eps) return TRUE; return FALSE; } /* iter_get - create a new structure pointing to ITER */ #ifndef ANSI_C ITER *iter_get(lenb, lenx) int lenb, lenx; #else ITER *iter_get(int lenb, int lenx) #endif { ITER *ip; if ((ip = NEW(ITER)) == (ITER *) NULL) error(E_MEM,"iter_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_ITER,0,sizeof(ITER)); mem_numvar(TYPE_ITER,1); } /* default values */ ip->shared_x = FALSE; ip->shared_b = FALSE; ip->k = 0; ip->limit = ITER_LIMIT_DEF; ip->eps = ITER_EPS_DEF; ip->steps = 0; if (lenb > 0) ip->b = v_get(lenb); else ip->b = (VEC *)NULL; if (lenx > 0) ip->x = v_get(lenx); else ip->x = (VEC *)NULL; ip->Ax = (Fun_Ax) NULL; ip->A_par = NULL; ip->ATx = (Fun_Ax) NULL; ip->AT_par = NULL; ip->Bx = (Fun_Ax) NULL; ip->B_par = NULL; ip->info = iter_std_info; ip->stop_crit = iter_std_stop_crit; ip->init_res = 0.0; return ip; } /* iter_free - release memory */ #ifndef ANSI_C int iter_free(ip) ITER *ip; #else int iter_free(ITER *ip) #endif { if (ip == (ITER *)NULL) return -1; if (mem_info_is_on()) { mem_bytes(TYPE_ITER,sizeof(ITER),0); mem_numvar(TYPE_ITER,-1); } if ( !ip->shared_x && ip->x != NULL ) v_free(ip->x); if ( !ip->shared_b && ip->b != NULL ) v_free(ip->b); free((char *)ip); return 0; } #ifndef ANSI_C ITER *iter_resize(ip,new_lenb,new_lenx) ITER *ip; int new_lenb, new_lenx; #else ITER *iter_resize(ITER *ip, int new_lenb, int new_lenx) #endif { VEC *old; if ( ip == (ITER *) NULL) error(E_NULL,"iter_resize"); old = ip->x; ip->x = v_resize(ip->x,new_lenx); if ( ip->shared_x && old != ip->x ) warning(WARN_SHARED_VEC,"iter_resize"); old = ip->b; ip->b = v_resize(ip->b,new_lenb); if ( ip->shared_b && old != ip->b ) warning(WARN_SHARED_VEC,"iter_resize"); return ip; } #ifndef MEX /* print out ip structure - for diagnostic purposes mainly */ #ifndef ANSI_C void iter_dump(fp,ip) ITER *ip; FILE *fp; #else void iter_dump(FILE *fp, ITER *ip) #endif { if (ip == NULL) { fprintf(fp," ITER structure: NULL\n"); return; } fprintf(fp,"\n ITER structure:\n"); fprintf(fp," ip->shared_x = %s, ip->shared_b = %s\n", (ip->shared_x ? "TRUE" : "FALSE"), (ip->shared_b ? "TRUE" : "FALSE") ); fprintf(fp," ip->k = %d, ip->limit = %d, ip->steps = %d, ip->eps = %g\n", ip->k,ip->limit,ip->steps,ip->eps); fprintf(fp," ip->x = 0x%p, ip->b = 0x%p\n",ip->x,ip->b); fprintf(fp," ip->Ax = 0x%p, ip->A_par = 0x%p\n",ip->Ax,ip->A_par); fprintf(fp," ip->ATx = 0x%p, ip->AT_par = 0x%p\n",ip->ATx,ip->AT_par); fprintf(fp," ip->Bx = 0x%p, ip->B_par = 0x%p\n",ip->Bx,ip->B_par); fprintf(fp," ip->info = 0x%p, ip->stop_crit = 0x%p, ip->init_res = %g\n", ip->info,ip->stop_crit,ip->init_res); fprintf(fp,"\n"); } #endif /* copy the structure ip1 to ip2 preserving vectors x and b of ip2 (vectors x and b in ip2 are the same before and after iter_copy2) if ip2 == NULL then a new structure is created with x and b being NULL and other members are taken from ip1 */ #ifndef ANSI_C ITER *iter_copy2(ip1,ip2) ITER *ip1, *ip2; #else ITER *iter_copy2(ITER *ip1, ITER *ip2) #endif { VEC *x, *b; int shx, shb; if (ip1 == (ITER *)NULL) error(E_NULL,"iter_copy2"); if (ip2 == (ITER *)NULL) { if ((ip2 = NEW(ITER)) == (ITER *) NULL) error(E_MEM,"iter_copy2"); else if (mem_info_is_on()) { mem_bytes(TYPE_ITER,0,sizeof(ITER)); mem_numvar(TYPE_ITER,1); } ip2->x = ip2->b = NULL; ip2->shared_x = ip2->shared_x = FALSE; } x = ip2->x; b = ip2->b; shb = ip2->shared_b; shx = ip2->shared_x; MEM_COPY(ip1,ip2,sizeof(ITER)); ip2->x = x; ip2->b = b; ip2->shared_x = shx; ip2->shared_b = shb; return ip2; } /* copy the structure ip1 to ip2 copying also the vectors x and b */ #ifndef ANSI_C ITER *iter_copy(ip1,ip2) ITER *ip1, *ip2; #else ITER *iter_copy(const ITER *ip1, ITER *ip2) #endif { VEC *x, *b; if (ip1 == (ITER *)NULL) error(E_NULL,"iter_copy"); if (ip2 == (ITER *)NULL) { if ((ip2 = NEW(ITER)) == (ITER *) NULL) error(E_MEM,"iter_copy2"); else if (mem_info_is_on()) { mem_bytes(TYPE_ITER,0,sizeof(ITER)); mem_numvar(TYPE_ITER,1); } } x = ip2->x; b = ip2->b; MEM_COPY(ip1,ip2,sizeof(ITER)); if (ip1->x) ip2->x = v_copy(ip1->x,x); if (ip1->b) ip2->b = v_copy(ip1->b,b); ip2->shared_x = ip2->shared_b = FALSE; return ip2; } /*** functions to generate sparse matrices with random entries ***/ /* iter_gen_sym -- generate symmetric positive definite n x n matrix, nrow - number of nonzero entries in a row */ #ifndef ANSI_C SPMAT *iter_gen_sym(n,nrow) int n, nrow; #else SPMAT *iter_gen_sym(int n, int nrow) #endif { SPMAT *A; VEC *u; Real s1; int i, j, k, k_max; if (nrow <= 1) nrow = 2; /* nrow should be even */ if ((nrow & 1)) nrow -= 1; A = sp_get(n,n,nrow); u = v_get(A->m); v_zero(u); for ( i = 0; i < A->m; i++ ) { k_max = ((rand() >> 8) % (nrow/2)); for ( k = 0; k <= k_max; k++ ) { j = (rand() >> 8) % A->n; s1 = mrand(); sp_set_val(A,i,j,s1); sp_set_val(A,j,i,s1); u->ve[i] += fabs(s1); u->ve[j] += fabs(s1); } } /* ensure that A is positive definite */ for ( i = 0; i < A->m; i++ ) sp_set_val(A,i,i,u->ve[i] + 1.0); V_FREE(u); return A; } /* iter_gen_nonsym -- generate non-symmetric m x n sparse matrix, m >= n nrow - number of entries in a row; diag - number which is put in diagonal entries and then permuted (if diag is zero then 1.0 is there) */ #ifndef ANSI_C SPMAT *iter_gen_nonsym(m,n,nrow,diag) int m, n, nrow; double diag; #else SPMAT *iter_gen_nonsym(int m, int n, int nrow, double diag) #endif { SPMAT *A; PERM *px; int i, j, k, k_max; Real s1; if (nrow <= 1) nrow = 2; if (diag == 0.0) diag = 1.0; A = sp_get(m,n,nrow); px = px_get(n); for ( i = 0; i < A->m; i++ ) { k_max = (rand() >> 8) % (nrow-1); for ( k = 0; k <= k_max; k++ ) { j = (rand() >> 8) % A->n; s1 = mrand(); sp_set_val(A,i,j,-s1); } } /* to make it likely that A is nonsingular, use pivot... */ for ( i = 0; i < 2*A->n; i++ ) { j = (rand() >> 8) % A->n; k = (rand() >> 8) % A->n; px_transp(px,j,k); } for ( i = 0; i < A->n; i++ ) sp_set_val(A,i,px->pe[i],diag); PX_FREE(px); return A; } #if ( 0 ) /* iter_gen_nonsym -- generate non-symmetric positive definite n x n sparse matrix; nrow - number of entries in a row */ #ifndef ANSI_C SPMAT *iter_gen_nonsym_posdef(n,nrow) int n, nrow; #else SPMAT *iter_gen_nonsym(int m, int n, int nrow, double diag) #endif { SPMAT *A; PERM *px; VEC *u; int i, j, k, k_max; Real s1; if (nrow <= 1) nrow = 2; A = sp_get(n,n,nrow); px = px_get(n); u = v_get(A->m); v_zero(u); for ( i = 0; i < A->m; i++ ) { k_max = (rand() >> 8) % (nrow-1); for ( k = 0; k <= k_max; k++ ) { j = (rand() >> 8) % A->n; s1 = mrand(); sp_set_val(A,i,j,-s1); u->ve[i] += fabs(s1); } } /* ensure that A is positive definite */ for ( i = 0; i < A->m; i++ ) sp_set_val(A,i,i,u->ve[i] + 1.0); PX_FREE(px); V_FREE(u); return A; } #endif gtk-wave-cleaner-0.22-04/meschach/iternsym.c0000777000175000017500000010103413120075106021774 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Stewart & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* iter.c 17/09/93 */ /* ITERATIVE METHODS - implementation of several iterative methods; see also iter0.c */ #include #include #include "matrix.h" #include "matrix2.h" #include "sparse.h" #include "iter.h" static char rcsid[] = "$Header: iternsym.c,v 1.6 1995/01/30 14:53:01 des Exp $"; #ifdef ANSI_C VEC *spCHsolve(SPMAT *,VEC *,VEC *); #else VEC *spCHsolve(); #endif /* iter_cgs -- uses CGS to compute a solution x to A.x=b */ #ifndef ANSI_C VEC *iter_cgs(ip,r0) ITER *ip; VEC *r0; #else VEC *iter_cgs(ITER *ip, VEC *r0) #endif { STATIC VEC *p = VNULL, *q = VNULL, *r = VNULL, *u = VNULL; STATIC VEC *v = VNULL, *z = VNULL; VEC *tmp; Real alpha, beta, nres, rho, old_rho, sigma, inner; if (ip == INULL) error(E_NULL,"iter_cgs"); if (!ip->Ax || !ip->b || !r0) error(E_NULL,"iter_cgs"); if ( ip->x == ip->b ) error(E_INSITU,"iter_cgs"); if (!ip->stop_crit) error(E_NULL,"iter_cgs"); if ( r0->dim != ip->b->dim ) error(E_SIZES,"iter_cgs"); if ( ip->eps <= 0.0 ) ip->eps = MACHEPS; p = v_resize(p,ip->b->dim); q = v_resize(q,ip->b->dim); r = v_resize(r,ip->b->dim); u = v_resize(u,ip->b->dim); v = v_resize(v,ip->b->dim); MEM_STAT_REG(p,TYPE_VEC); MEM_STAT_REG(q,TYPE_VEC); MEM_STAT_REG(r,TYPE_VEC); MEM_STAT_REG(u,TYPE_VEC); MEM_STAT_REG(v,TYPE_VEC); if (ip->Bx) { z = v_resize(z,ip->b->dim); MEM_STAT_REG(z,TYPE_VEC); } if (ip->x != VNULL) { if (ip->x->dim != ip->b->dim) error(E_SIZES,"iter_cgs"); ip->Ax(ip->A_par,ip->x,v); /* v = A*x */ if (ip->Bx) { v_sub(ip->b,v,v); /* v = b - A*x */ (ip->Bx)(ip->B_par,v,r); /* r = B*(b-A*x) */ } else v_sub(ip->b,v,r); /* r = b-A*x */ } else { /* ip->x == 0 */ ip->x = v_get(ip->b->dim); /* x == 0 */ ip->shared_x = FALSE; if (ip->Bx) (ip->Bx)(ip->B_par,ip->b,r); /* r = B*b */ else v_copy(ip->b,r); /* r = b */ } v_zero(p); v_zero(q); old_rho = 1.0; for (ip->steps = 0; ip->steps <= ip->limit; ip->steps++) { inner = in_prod(r,r); nres = sqrt(fabs(inner)); if (ip->steps == 0) ip->init_res = nres; if (ip->info) ip->info(ip,nres,r,VNULL); if ( ip->stop_crit(ip,nres,r,VNULL) ) break; rho = in_prod(r0,r); if ( old_rho == 0.0 ) error(E_BREAKDOWN,"iter_cgs"); beta = rho/old_rho; v_mltadd(r,q,beta,u); v_mltadd(q,p,beta,v); v_mltadd(u,v,beta,p); (ip->Ax)(ip->A_par,p,q); if (ip->Bx) { (ip->Bx)(ip->B_par,q,z); tmp = z; } else tmp = q; sigma = in_prod(r0,tmp); if ( sigma == 0.0 ) error(E_BREAKDOWN,"iter_cgs"); alpha = rho/sigma; v_mltadd(u,tmp,-alpha,q); v_add(u,q,v); (ip->Ax)(ip->A_par,v,u); if (ip->Bx) { (ip->Bx)(ip->B_par,u,z); tmp = z; } else tmp = u; v_mltadd(r,tmp,-alpha,r); v_mltadd(ip->x,v,alpha,ip->x); old_rho = rho; } #ifdef THREADSAFE V_FREE(p); V_FREE(q); V_FREE(r); V_FREE(u); V_FREE(v); V_FREE(z); #endif return ip->x; } /* iter_spcgs -- simple interface for SPMAT data structures use always as follows: x = iter_spcgs(A,B,b,r0,tol,x,limit,steps); or x = iter_spcgs(A,B,b,r0,tol,VNULL,limit,steps); In the second case the solution vector is created. If B is not NULL then it is a preconditioner. */ #ifndef ANSI_C VEC *iter_spcgs(A,B,b,r0,tol,x,limit,steps) SPMAT *A, *B; VEC *b, *r0, *x; double tol; int *steps,limit; #else VEC *iter_spcgs(SPMAT *A, SPMAT *B, VEC *b, VEC *r0, double tol, VEC *x, int limit, int *steps) #endif { ITER *ip; ip = iter_get(0,0); ip->Ax = (Fun_Ax) sp_mv_mlt; ip->A_par = (void *) A; if (B) { ip->Bx = (Fun_Ax) sp_mv_mlt; ip->B_par = (void *) B; } else { ip->Bx = (Fun_Ax) NULL; ip->B_par = NULL; } ip->info = (Fun_info) NULL; ip->limit = limit; ip->b = b; ip->eps = tol; ip->x = x; iter_cgs(ip,r0); x = ip->x; if (steps) *steps = ip->steps; ip->shared_x = ip->shared_b = TRUE; iter_free(ip); /* release only ITER structure */ return x; } /* Routine for performing LSQR -- the least squares QR algorithm of Paige and Saunders: "LSQR: an algorithm for sparse linear equations and sparse least squares", ACM Trans. Math. Soft., v. 8 pp. 43--71 (1982) */ /* iter_lsqr -- sparse CG-like least squares routine: -- finds min_x ||A.x-b||_2 using A defined through A & AT -- returns x (if x != NULL) */ #ifndef ANSI_C VEC *iter_lsqr(ip) ITER *ip; #else VEC *iter_lsqr(ITER *ip) #endif { STATIC VEC *u = VNULL, *v = VNULL, *w = VNULL, *tmp = VNULL; Real alpha, beta, phi, phi_bar; Real rho, rho_bar, rho_max, theta, nres; Real s, c; /* for Givens' rotations */ int m, n; if ( ! ip || ! ip->b || !ip->Ax || !ip->ATx ) error(E_NULL,"iter_lsqr"); if ( ip->x == ip->b ) error(E_INSITU,"iter_lsqr"); if (!ip->stop_crit || !ip->x) error(E_NULL,"iter_lsqr"); if ( ip->eps <= 0.0 ) ip->eps = MACHEPS; m = ip->b->dim; n = ip->x->dim; u = v_resize(u,(unsigned int)m); v = v_resize(v,(unsigned int)n); w = v_resize(w,(unsigned int)n); tmp = v_resize(tmp,(unsigned int)n); MEM_STAT_REG(u,TYPE_VEC); MEM_STAT_REG(v,TYPE_VEC); MEM_STAT_REG(w,TYPE_VEC); MEM_STAT_REG(tmp,TYPE_VEC); if (ip->x != VNULL) { ip->Ax(ip->A_par,ip->x,u); /* u = A*x */ v_sub(ip->b,u,u); /* u = b-A*x */ } else { /* ip->x == 0 */ ip->x = v_get(ip->b->dim); ip->shared_x = FALSE; v_copy(ip->b,u); /* u = b */ } beta = v_norm2(u); if ( beta == 0.0 ) return ip->x; sv_mlt(1.0/beta,u,u); (ip->ATx)(ip->AT_par,u,v); alpha = v_norm2(v); if ( alpha == 0.0 ) return ip->x; sv_mlt(1.0/alpha,v,v); v_copy(v,w); phi_bar = beta; rho_bar = alpha; rho_max = 1.0; for (ip->steps = 0; ip->steps <= ip->limit; ip->steps++) { tmp = v_resize(tmp,m); (ip->Ax)(ip->A_par,v,tmp); v_mltadd(tmp,u,-alpha,u); beta = v_norm2(u); sv_mlt(1.0/beta,u,u); tmp = v_resize(tmp,n); (ip->ATx)(ip->AT_par,u,tmp); v_mltadd(tmp,v,-beta,v); alpha = v_norm2(v); sv_mlt(1.0/alpha,v,v); rho = sqrt(rho_bar*rho_bar+beta*beta); if ( rho > rho_max ) rho_max = rho; c = rho_bar/rho; s = beta/rho; theta = s*alpha; rho_bar = -c*alpha; phi = c*phi_bar; phi_bar = s*phi_bar; /* update ip->x & w */ if ( rho == 0.0 ) error(E_BREAKDOWN,"iter_lsqr"); v_mltadd(ip->x,w,phi/rho,ip->x); v_mltadd(v,w,-theta/rho,w); nres = fabs(phi_bar*alpha*c)*rho_max; if (ip->info) ip->info(ip,nres,w,VNULL); if (ip->steps == 0) ip->init_res = nres; if ( ip->stop_crit(ip,nres,w,VNULL) ) break; } #ifdef THREADSAFE V_FREE(u); V_FREE(v); V_FREE(w); V_FREE(tmp); #endif return ip->x; } /* iter_splsqr -- simple interface for SPMAT data structures */ #ifndef ANSI_C VEC *iter_splsqr(A,b,tol,x,limit,steps) SPMAT *A; VEC *b, *x; double tol; int *steps,limit; #else VEC *iter_splsqr(SPMAT *A, VEC *b, double tol, VEC *x, int limit, int *steps) #endif { ITER *ip; ip = iter_get(0,0); ip->Ax = (Fun_Ax) sp_mv_mlt; ip->A_par = (void *) A; ip->ATx = (Fun_Ax) sp_vm_mlt; ip->AT_par = (void *) A; ip->Bx = (Fun_Ax) NULL; ip->B_par = NULL; ip->info = (Fun_info) NULL; ip->limit = limit; ip->b = b; ip->eps = tol; ip->x = x; iter_lsqr(ip); x = ip->x; if (steps) *steps = ip->steps; ip->shared_x = ip->shared_b = TRUE; iter_free(ip); /* release only ITER structure */ return x; } /* iter_arnoldi -- an implementation of the Arnoldi method; iterative refinement is applied. */ #ifndef ANSI_C MAT *iter_arnoldi_iref(ip,h_rem,Q,H) ITER *ip; Real *h_rem; MAT *Q, *H; #else MAT *iter_arnoldi_iref(ITER *ip, Real *h_rem, MAT *Q, MAT *H) #endif { STATIC VEC *u=VNULL, *r=VNULL, *s=VNULL, *tmp=VNULL; VEC v; /* auxiliary vector */ int i,j; Real h_val, c; if (ip == INULL) error(E_NULL,"iter_arnoldi_iref"); if ( ! ip->Ax || ! Q || ! ip->x ) error(E_NULL,"iter_arnoldi_iref"); if ( ip->k <= 0 ) error(E_BOUNDS,"iter_arnoldi_iref"); if ( Q->n != ip->x->dim || Q->m != ip->k ) error(E_SIZES,"iter_arnoldi_iref"); m_zero(Q); H = m_resize(H,ip->k,ip->k); m_zero(H); u = v_resize(u,ip->x->dim); r = v_resize(r,ip->k); s = v_resize(s,ip->k); tmp = v_resize(tmp,ip->x->dim); MEM_STAT_REG(u,TYPE_VEC); MEM_STAT_REG(r,TYPE_VEC); MEM_STAT_REG(s,TYPE_VEC); MEM_STAT_REG(tmp,TYPE_VEC); v.dim = v.max_dim = ip->x->dim; c = v_norm2(ip->x); if ( c <= 0.0) return H; else { v.ve = Q->me[0]; sv_mlt(1.0/c,ip->x,&v); } v_zero(r); v_zero(s); for ( i = 0; i < ip->k; i++ ) { v.ve = Q->me[i]; u = (ip->Ax)(ip->A_par,&v,u); for (j = 0; j <= i; j++) { v.ve = Q->me[j]; /* modified Gram-Schmidt */ r->ve[j] = in_prod(&v,u); v_mltadd(u,&v,-r->ve[j],u); } h_val = v_norm2(u); /* if u == 0 then we have an exact subspace */ if ( h_val <= 0.0 ) { *h_rem = h_val; return H; } /* iterative refinement -- ensures near orthogonality */ do { v_zero(tmp); for (j = 0; j <= i; j++) { v.ve = Q->me[j]; s->ve[j] = in_prod(&v,u); v_mltadd(tmp,&v,s->ve[j],tmp); } v_sub(u,tmp,u); v_add(r,s,r); } while ( v_norm2(s) > 0.1*(h_val = v_norm2(u)) ); /* now that u is nearly orthogonal to Q, update H */ set_col(H,i,r); /* check once again if h_val is zero */ if ( h_val <= 0.0 ) { *h_rem = h_val; return H; } if ( i == ip->k-1 ) { *h_rem = h_val; continue; } /* H->me[i+1][i] = h_val; */ m_set_val(H,i+1,i,h_val); v.ve = Q->me[i+1]; sv_mlt(1.0/h_val,u,&v); } #ifdef THREADSAFE V_FREE(u); V_FREE(r); V_FREE(s); V_FREE(tmp); #endif return H; } /* iter_arnoldi -- an implementation of the Arnoldi method; modified Gram-Schmidt algorithm */ #ifndef ANSI_C MAT *iter_arnoldi(ip,h_rem,Q,H) ITER *ip; Real *h_rem; MAT *Q, *H; #else MAT *iter_arnoldi(ITER *ip, Real *h_rem, MAT *Q, MAT *H) #endif { STATIC VEC *u=VNULL, *r=VNULL; VEC v; /* auxiliary vector */ int i,j; Real h_val, c; if (ip == INULL) error(E_NULL,"iter_arnoldi"); if ( ! ip->Ax || ! Q || ! ip->x ) error(E_NULL,"iter_arnoldi"); if ( ip->k <= 0 ) error(E_BOUNDS,"iter_arnoldi"); if ( Q->n != ip->x->dim || Q->m != ip->k ) error(E_SIZES,"iter_arnoldi"); m_zero(Q); H = m_resize(H,ip->k,ip->k); m_zero(H); u = v_resize(u,ip->x->dim); r = v_resize(r,ip->k); MEM_STAT_REG(u,TYPE_VEC); MEM_STAT_REG(r,TYPE_VEC); v.dim = v.max_dim = ip->x->dim; c = v_norm2(ip->x); if ( c <= 0.0) return H; else { v.ve = Q->me[0]; sv_mlt(1.0/c,ip->x,&v); } v_zero(r); for ( i = 0; i < ip->k; i++ ) { v.ve = Q->me[i]; u = (ip->Ax)(ip->A_par,&v,u); for (j = 0; j <= i; j++) { v.ve = Q->me[j]; /* modified Gram-Schmidt */ r->ve[j] = in_prod(&v,u); v_mltadd(u,&v,-r->ve[j],u); } h_val = v_norm2(u); /* if u == 0 then we have an exact subspace */ if ( h_val <= 0.0 ) { *h_rem = h_val; return H; } set_col(H,i,r); if ( i == ip->k-1 ) { *h_rem = h_val; continue; } /* H->me[i+1][i] = h_val; */ m_set_val(H,i+1,i,h_val); v.ve = Q->me[i+1]; sv_mlt(1.0/h_val,u,&v); } #ifdef THREADSAFE V_FREE(u); V_FREE(r); #endif return H; } /* iter_sparnoldi -- uses arnoldi() with an explicit representation of A */ #ifndef ANSI_C MAT *iter_sparnoldi(A,x0,m,h_rem,Q,H) SPMAT *A; VEC *x0; int m; Real *h_rem; MAT *Q, *H; #else MAT *iter_sparnoldi(SPMAT *A, VEC *x0, int m, Real *h_rem, MAT *Q, MAT *H) #endif { ITER *ip; ip = iter_get(0,0); ip->Ax = (Fun_Ax) sp_mv_mlt; ip->A_par = (void *) A; ip->x = x0; ip->k = m; iter_arnoldi_iref(ip,h_rem,Q,H); ip->shared_x = ip->shared_b = TRUE; iter_free(ip); /* release only ITER structure */ return H; } /* for testing gmres */ #ifndef ANSI_C static void test_gmres(ip,i,Q,R,givc,givs,h_val) ITER *ip; int i; MAT *Q, *R; VEC *givc, *givs; double h_val; #else static void test_gmres(ITER *ip, int i, MAT *Q, MAT *R, VEC *givc, VEC *givs, double h_val) #endif { VEC vt, vt1; STATIC MAT *Q1=MNULL, *R1=MNULL; int j; /* test Q*A*Q^T = R */ Q = m_resize(Q,i+1,ip->b->dim); Q1 = m_resize(Q1,i+1,ip->b->dim); R1 = m_resize(R1,i+1,i+1); MEM_STAT_REG(Q1,TYPE_MAT); MEM_STAT_REG(R1,TYPE_MAT); vt.dim = vt.max_dim = ip->b->dim; vt1.dim = vt1.max_dim = ip->b->dim; for (j=0; j <= i; j++) { vt.ve = Q->me[j]; vt1.ve = Q1->me[j]; ip->Ax(ip->A_par,&vt,&vt1); } mmtr_mlt(Q,Q1,R1); R1 = m_resize(R1,i+2,i+1); for (j=0; j < i; j++) R1->me[i+1][j] = 0.0; R1->me[i+1][i] = h_val; for (j = 0; j <= i; j++) { rot_rows(R1,j,j+1,givc->ve[j],givs->ve[j],R1); } R1 = m_resize(R1,i+1,i+1); m_sub(R,R1,R1); /* if (m_norm_inf(R1) > MACHEPS*ip->b->dim) */ #ifndef MEX printf(" %d. ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n", ip->steps,m_norm_inf(R1),MACHEPS); #endif /* check Q*Q^T = I */ Q = m_resize(Q,i+1,ip->b->dim); mmtr_mlt(Q,Q,R1); for (j=0; j <= i; j++) R1->me[j][j] -= 1.0; #ifndef MEX if (m_norm_inf(R1) > MACHEPS*ip->b->dim) printf(" ! m_norm_inf(Q*Q^T) = %g\n",m_norm_inf(R1)); #endif #ifdef THREADSAFE M_FREE(Q1); M_FREE(R1); #endif } /* gmres -- generalised minimum residual algorithm of Saad & Schultz SIAM J. Sci. Stat. Comp. v.7, pp.856--869 (1986) */ #ifndef ANSI_C VEC *iter_gmres(ip) ITER *ip; #else VEC *iter_gmres(ITER *ip) #endif { STATIC VEC *u=VNULL, *r=VNULL, *rhs = VNULL; STATIC VEC *givs=VNULL, *givc=VNULL, *z = VNULL; STATIC MAT *Q = MNULL, *R = MNULL; VEC *rr, v, v1; /* additional pointers (not real vectors) */ int i,j, done; Real nres; /* Real last_h; */ if (ip == INULL) error(E_NULL,"iter_gmres"); if ( ! ip->Ax || ! ip->b ) error(E_NULL,"iter_gmres"); if ( ! ip->stop_crit ) error(E_NULL,"iter_gmres"); if ( ip->k <= 0 ) error(E_BOUNDS,"iter_gmres"); if (ip->x != VNULL && ip->x->dim != ip->b->dim) error(E_SIZES,"iter_gmres"); if (ip->eps <= 0.0) ip->eps = MACHEPS; r = v_resize(r,ip->k+1); u = v_resize(u,ip->b->dim); rhs = v_resize(rhs,ip->k+1); givs = v_resize(givs,ip->k); /* Givens rotations */ givc = v_resize(givc,ip->k); MEM_STAT_REG(r,TYPE_VEC); MEM_STAT_REG(u,TYPE_VEC); MEM_STAT_REG(rhs,TYPE_VEC); MEM_STAT_REG(givs,TYPE_VEC); MEM_STAT_REG(givc,TYPE_VEC); R = m_resize(R,ip->k+1,ip->k); Q = m_resize(Q,ip->k,ip->b->dim); MEM_STAT_REG(R,TYPE_MAT); MEM_STAT_REG(Q,TYPE_MAT); if (ip->x == VNULL) { /* ip->x == 0 */ ip->x = v_get(ip->b->dim); ip->shared_x = FALSE; } v.dim = v.max_dim = ip->b->dim; /* v and v1 are pointers to rows */ v1.dim = v1.max_dim = ip->b->dim; /* of matrix Q */ if (ip->Bx != (Fun_Ax)NULL) { /* if precondition is defined */ z = v_resize(z,ip->b->dim); MEM_STAT_REG(z,TYPE_VEC); } done = FALSE; for (ip->steps = 0; ip->steps < ip->limit; ) { /* restart */ ip->Ax(ip->A_par,ip->x,u); /* u = A*x */ v_sub(ip->b,u,u); /* u = b - A*x */ rr = u; /* rr is a pointer only */ if (ip->Bx) { (ip->Bx)(ip->B_par,u,z); /* tmp = B*(b-A*x) */ rr = z; } nres = v_norm2(rr); if (ip->steps == 0) { if (ip->info) ip->info(ip,nres,VNULL,VNULL); ip->init_res = nres; } if ( nres == 0.0 ) { done = TRUE; break; } v.ve = Q->me[0]; sv_mlt(1.0/nres,rr,&v); v_zero(r); v_zero(rhs); rhs->ve[0] = nres; for ( i = 0; i < ip->k && ip->steps < ip->limit; i++ ) { ip->steps++; v.ve = Q->me[i]; (ip->Ax)(ip->A_par,&v,u); rr = u; if (ip->Bx) { (ip->Bx)(ip->B_par,u,z); rr = z; } if (i < ip->k - 1) { v1.ve = Q->me[i+1]; v_copy(rr,&v1); for (j = 0; j <= i; j++) { v.ve = Q->me[j]; /* r->ve[j] = in_prod(&v,rr); */ /* modified Gram-Schmidt algorithm */ r->ve[j] = in_prod(&v,&v1); v_mltadd(&v1,&v,-r->ve[j],&v1); } r->ve[i+1] = nres = v_norm2(&v1); if (nres <= MACHEPS*ip->init_res) { for (j = 0; j < i; j++) rot_vec(r,j,j+1,givc->ve[j],givs->ve[j],r); set_col(R,i,r); done = TRUE; break; } sv_mlt(1.0/nres,&v1,&v1); } else { /* i == ip->k - 1 */ /* Q->me[ip->k] need not be computed */ for (j = 0; j <= i; j++) { v.ve = Q->me[j]; r->ve[j] = in_prod(&v,rr); } nres = in_prod(rr,rr) - in_prod(r,r); if (sqrt(fabs(nres)) <= MACHEPS*ip->init_res) { for (j = 0; j < i; j++) rot_vec(r,j,j+1,givc->ve[j],givs->ve[j],r); set_col(R,i,r); done = TRUE; break; } if (nres < 0.0) { /* do restart */ i--; ip->steps--; break; } r->ve[i+1] = sqrt(nres); } /* QR update */ /* last_h = r->ve[i+1]; */ /* for test only */ for (j = 0; j < i; j++) rot_vec(r,j,j+1,givc->ve[j],givs->ve[j],r); givens(r->ve[i],r->ve[i+1],&givc->ve[i],&givs->ve[i]); rot_vec(r,i,i+1,givc->ve[i],givs->ve[i],r); rot_vec(rhs,i,i+1,givc->ve[i],givs->ve[i],rhs); set_col(R,i,r); nres = fabs((double) rhs->ve[i+1]); if (ip->info) ip->info(ip,nres,VNULL,VNULL); if ( ip->stop_crit(ip,nres,VNULL,VNULL) ) { done = TRUE; break; } } /* use ixi submatrix of R */ if (i >= ip->k) i = ip->k - 1; R = m_resize(R,i+1,i+1); rhs = v_resize(rhs,i+1); /* test only */ /* test_gmres(ip,i,Q,R,givc,givs,last_h); */ Usolve(R,rhs,rhs,0.0); /* solve a system: R*x = rhs */ /* new approximation */ for (j = 0; j <= i; j++) { v.ve = Q->me[j]; v_mltadd(ip->x,&v,rhs->ve[j],ip->x); } if (done) break; /* back to old dimensions */ rhs = v_resize(rhs,ip->k+1); R = m_resize(R,ip->k+1,ip->k); } #ifdef THREADSAFE V_FREE(u); V_FREE(r); V_FREE(rhs); V_FREE(givs); V_FREE(givc); V_FREE(z); M_FREE(Q); M_FREE(R); #endif return ip->x; } /* iter_spgmres - a simple interface to iter_gmres */ #ifndef ANSI_C VEC *iter_spgmres(A,B,b,tol,x,k,limit,steps) SPMAT *A, *B; VEC *b, *x; double tol; int *steps,k,limit; #else VEC *iter_spgmres(SPMAT *A, SPMAT *B, VEC *b, double tol, VEC *x, int k, int limit, int *steps) #endif { ITER *ip; ip = iter_get(0,0); ip->Ax = (Fun_Ax) sp_mv_mlt; ip->A_par = (void *) A; if (B) { ip->Bx = (Fun_Ax) sp_mv_mlt; ip->B_par = (void *) B; } else { ip->Bx = (Fun_Ax) NULL; ip->B_par = NULL; } ip->k = k; ip->limit = limit; ip->info = (Fun_info) NULL; ip->b = b; ip->eps = tol; ip->x = x; iter_gmres(ip); x = ip->x; if (steps) *steps = ip->steps; ip->shared_x = ip->shared_b = TRUE; iter_free(ip); /* release only ITER structure */ return x; } /* for testing mgcr */ #ifndef ANSI_C static void test_mgcr(ip,i,Q,R) ITER *ip; int i; MAT *Q, *R; #else static void test_mgcr(ITER *ip, int i, MAT *Q, MAT *R) #endif { VEC vt, vt1; static MAT *R1=MNULL; static VEC *r=VNULL, *r1=VNULL; VEC *rr; int k,j; Real sm; /* check Q*Q^T = I */ vt.dim = vt.max_dim = ip->b->dim; vt1.dim = vt1.max_dim = ip->b->dim; Q = m_resize(Q,i+1,ip->b->dim); R1 = m_resize(R1,i+1,i+1); r = v_resize(r,ip->b->dim); r1 = v_resize(r1,ip->b->dim); MEM_STAT_REG(R1,TYPE_MAT); MEM_STAT_REG(r,TYPE_VEC); MEM_STAT_REG(r1,TYPE_VEC); m_zero(R1); for (k=1; k <= i; k++) for (j=1; j <= i; j++) { vt.ve = Q->me[k]; vt1.ve = Q->me[j]; R1->me[k][j] = in_prod(&vt,&vt1); } for (j=1; j <= i; j++) R1->me[j][j] -= 1.0; #ifndef MEX if (m_norm_inf(R1) > MACHEPS*ip->b->dim) printf(" ! (mgcr:) m_norm_inf(Q*Q^T) = %g\n",m_norm_inf(R1)); #endif /* check (r_i,Ap_j) = 0 for j <= i */ ip->Ax(ip->A_par,ip->x,r); v_sub(ip->b,r,r); rr = r; if (ip->Bx) { ip->Bx(ip->B_par,r,r1); rr = r1; } #ifndef MEX printf(" ||r|| = %g\n",v_norm2(rr)); #endif sm = 0.0; for (j = 1; j <= i; j++) { vt.ve = Q->me[j]; sm = max(sm,in_prod(&vt,rr)); } #ifndef MEX if (sm >= MACHEPS*ip->b->dim) printf(" ! (mgcr:) max_j (r,Ap_j) = %g\n",sm); #endif } /* iter_mgcr -- modified generalized conjugate residual algorithm; fast version of GCR; */ #ifndef ANSI_C VEC *iter_mgcr(ip) ITER *ip; #else VEC *iter_mgcr(ITER *ip) #endif { STATIC VEC *As=VNULL, *beta=VNULL, *alpha=VNULL, *z=VNULL; STATIC MAT *N=MNULL, *H=MNULL; VEC *rr, v, s; /* additional pointer and structures */ Real nres; /* norm of a residual */ Real dd; /* coefficient d_i */ int i,j; int done; /* if TRUE then stop the iterative process */ int dim; /* dimension of the problem */ /* ip cannot be NULL */ if (ip == INULL) error(E_NULL,"mgcr"); /* Ax, b and stopping criterion must be given */ if (! ip->Ax || ! ip->b || ! ip->stop_crit) error(E_NULL,"mgcr"); /* at least one direction vector must exist */ if ( ip->k <= 0) error(E_BOUNDS,"mgcr"); /* if the vector x is given then b and x must have the same dimension */ if ( ip->x && ip->x->dim != ip->b->dim) error(E_SIZES,"mgcr"); if (ip->eps <= 0.0) ip->eps = MACHEPS; dim = ip->b->dim; As = v_resize(As,dim); alpha = v_resize(alpha,ip->k); beta = v_resize(beta,ip->k); MEM_STAT_REG(As,TYPE_VEC); MEM_STAT_REG(alpha,TYPE_VEC); MEM_STAT_REG(beta,TYPE_VEC); H = m_resize(H,ip->k,ip->k); N = m_resize(N,ip->k,dim); MEM_STAT_REG(H,TYPE_MAT); MEM_STAT_REG(N,TYPE_MAT); /* if a preconditioner is defined */ if (ip->Bx) { z = v_resize(z,dim); MEM_STAT_REG(z,TYPE_VEC); } /* if x is NULL then it is assumed that x has entries with value zero */ if ( ! ip->x ) { ip->x = v_get(ip->b->dim); ip->shared_x = FALSE; } /* v and s are additional pointers to rows of N */ /* they must have the same dimension as rows of N */ v.dim = v.max_dim = s.dim = s.max_dim = dim; done = FALSE; for (ip->steps = 0; ip->steps < ip->limit; ) { (*ip->Ax)(ip->A_par,ip->x,As); /* As = A*x */ v_sub(ip->b,As,As); /* As = b - A*x */ rr = As; /* rr is an additional pointer */ /* if a preconditioner is defined */ if (ip->Bx) { (*ip->Bx)(ip->B_par,As,z); /* z = B*(b-A*x) */ rr = z; } /* norm of the residual */ nres = v_norm2(rr); dd = nres; /* dd = ||r_i|| */ /* check if the norm of the residual is zero */ if (ip->steps == 0) { /* information for a user */ if (ip->info) (*ip->info)(ip,nres,As,rr); ip->init_res = fabs(nres); } if (nres == 0.0) { /* iterative process is finished */ done = TRUE; break; } /* save this residual in the first row of N */ v.ve = N->me[0]; v_copy(rr,&v); for (i = 0; i < ip->k && ip->steps < ip->limit; i++) { ip->steps++; v.ve = N->me[i]; /* pointer to a row of N (=s_i) */ /* note that we must use here &v, not v */ (*ip->Ax)(ip->A_par,&v,As); rr = As; /* As = A*s_i */ if (ip->Bx) { (*ip->Bx)(ip->B_par,As,z); /* z = B*A*s_i */ rr = z; } if (i < ip->k - 1) { s.ve = N->me[i+1]; /* pointer to a row of N (=s_{i+1}) */ v_copy(rr,&s); /* s_{i+1} = B*A*s_i */ for (j = 0; j <= i-1; j++) { v.ve = N->me[j+1]; /* pointer to a row of N (=s_{j+1}) */ /* beta->ve[j] = in_prod(&v,rr); */ /* beta_{j,i} */ /* modified Gram-Schmidt algorithm */ beta->ve[j] = in_prod(&v,&s); /* beta_{j,i} */ /* s_{i+1} -= beta_{j,i}*s_{j+1} */ v_mltadd(&s,&v,- beta->ve[j],&s); } /* beta_{i,i} = ||s_{i+1}||_2 */ beta->ve[i] = nres = v_norm2(&s); if ( nres <= MACHEPS*ip->init_res) { /* s_{i+1} == 0 */ i--; done = TRUE; break; } sv_mlt(1.0/nres,&s,&s); /* normalize s_{i+1} */ v.ve = N->me[0]; alpha->ve[i] = in_prod(&v,&s); /* alpha_i = (s_0 , s_{i+1}) */ } else { for (j = 0; j <= i-1; j++) { v.ve = N->me[j+1]; /* pointer to a row of N (=s_{j+1}) */ beta->ve[j] = in_prod(&v,rr); /* beta_{j,i} */ } nres = in_prod(rr,rr); /* rr = B*A*s_{k-1} */ for (j = 0; j <= i-1; j++) nres -= beta->ve[j]*beta->ve[j]; if (sqrt(fabs(nres)) <= MACHEPS*ip->init_res) { /* s_k is zero */ i--; done = TRUE; break; } if (nres < 0.0) { /* do restart */ i--; ip->steps--; break; } beta->ve[i] = sqrt(nres); /* beta_{k-1,k-1} */ v.ve = N->me[0]; alpha->ve[i] = in_prod(&v,rr); for (j = 0; j <= i-1; j++) alpha->ve[i] -= beta->ve[j]*alpha->ve[j]; alpha->ve[i] /= beta->ve[i]; /* alpha_{k-1} */ } set_col(H,i,beta); /* other method of computing dd */ /* if (fabs((double)alpha->ve[i]) > dd) { nres = - dd*dd + alpha->ve[i]*alpha->ve[i]; nres = sqrt((double) nres); if (ip->info) (*ip->info)(ip,-nres,VNULL,VNULL); break; } */ /* to avoid overflow/underflow in computing dd */ /* dd *= cos(asin((double)(alpha->ve[i]/dd))); */ nres = alpha->ve[i]/dd; if (fabs(nres-1.0) <= MACHEPS*ip->init_res) dd = 0.0; else { nres = 1.0 - nres*nres; if (nres < 0.0) { nres = sqrt((double) -nres); if (ip->info) (*ip->info)(ip,-dd*nres,VNULL,VNULL); break; } dd *= sqrt((double) nres); } if (ip->info) (*ip->info)(ip,dd,VNULL,VNULL); if ( ip->stop_crit(ip,dd,VNULL,VNULL) ) { /* stopping criterion is satisfied */ done = TRUE; break; } } /* end of for */ if (i >= ip->k) i = ip->k - 1; /* use (i+1) by (i+1) submatrix of H */ H = m_resize(H,i+1,i+1); alpha = v_resize(alpha,i+1); Usolve(H,alpha,alpha,0.0); /* c_i is saved in alpha */ for (j = 0; j <= i; j++) { v.ve = N->me[j]; v_mltadd(ip->x,&v,alpha->ve[j],ip->x); } if (done) break; /* stop the iterative process */ alpha = v_resize(alpha,ip->k); H = m_resize(H,ip->k,ip->k); } /* end of while */ #ifdef THREADSAFE V_FREE(As); V_FREE(beta); V_FREE(alpha); V_FREE(z); M_FREE(N); M_FREE(H); #endif return ip->x; /* return the solution */ } /* iter_spmgcr - a simple interface to iter_mgcr */ /* no preconditioner */ #ifndef ANSI_C VEC *iter_spmgcr(A,B,b,tol,x,k,limit,steps) SPMAT *A, *B; VEC *b, *x; double tol; int *steps,k,limit; #else VEC *iter_spmgcr(SPMAT *A, SPMAT *B, VEC *b, double tol, VEC *x, int k, int limit, int *steps) #endif { ITER *ip; ip = iter_get(0,0); ip->Ax = (Fun_Ax) sp_mv_mlt; ip->A_par = (void *) A; if (B) { ip->Bx = (Fun_Ax) sp_mv_mlt; ip->B_par = (void *) B; } else { ip->Bx = (Fun_Ax) NULL; ip->B_par = NULL; } ip->k = k; ip->limit = limit; ip->info = (Fun_info) NULL; ip->b = b; ip->eps = tol; ip->x = x; iter_mgcr(ip); x = ip->x; if (steps) *steps = ip->steps; ip->shared_x = ip->shared_b = TRUE; iter_free(ip); /* release only ITER structure */ return x; } /* Conjugate gradients method for a normal equation a preconditioner B must be symmetric !! */ #ifndef ANSI_C VEC *iter_cgne(ip) ITER *ip; #else VEC *iter_cgne(ITER *ip) #endif { STATIC VEC *r = VNULL, *p = VNULL, *q = VNULL, *z = VNULL; Real alpha, beta, inner, old_inner, nres; VEC *rr1; /* pointer only */ if (ip == INULL) error(E_NULL,"iter_cgne"); if (!ip->Ax || ! ip->ATx || !ip->b) error(E_NULL,"iter_cgne"); if ( ip->x == ip->b ) error(E_INSITU,"iter_cgne"); if (!ip->stop_crit) error(E_NULL,"iter_cgne"); if ( ip->eps <= 0.0 ) ip->eps = MACHEPS; r = v_resize(r,ip->b->dim); p = v_resize(p,ip->b->dim); q = v_resize(q,ip->b->dim); MEM_STAT_REG(r,TYPE_VEC); MEM_STAT_REG(p,TYPE_VEC); MEM_STAT_REG(q,TYPE_VEC); z = v_resize(z,ip->b->dim); MEM_STAT_REG(z,TYPE_VEC); if (ip->x) { if (ip->x->dim != ip->b->dim) error(E_SIZES,"iter_cgne"); ip->Ax(ip->A_par,ip->x,p); /* p = A*x */ v_sub(ip->b,p,z); /* z = b - A*x */ } else { /* ip->x == 0 */ ip->x = v_get(ip->b->dim); ip->shared_x = FALSE; v_copy(ip->b,z); } rr1 = z; if (ip->Bx) { (ip->Bx)(ip->B_par,rr1,p); rr1 = p; } (ip->ATx)(ip->AT_par,rr1,r); /* r = A^T*B*(b-A*x) */ old_inner = 0.0; for ( ip->steps = 0; ip->steps <= ip->limit; ip->steps++ ) { rr1 = r; if ( ip->Bx ) { (ip->Bx)(ip->B_par,r,z); /* rr = B*r */ rr1 = z; } inner = in_prod(r,rr1); nres = sqrt(fabs(inner)); if (ip->info) ip->info(ip,nres,r,rr1); if (ip->steps == 0) ip->init_res = nres; if ( ip->stop_crit(ip,nres,r,rr1) ) break; if ( ip->steps ) /* if ( ip->steps > 0 ) ... */ { beta = inner/old_inner; p = v_mltadd(rr1,p,beta,p); } else /* if ( ip->steps == 0 ) ... */ { beta = 0.0; p = v_copy(rr1,p); old_inner = 0.0; } (ip->Ax)(ip->A_par,p,q); /* q = A*p */ if (ip->Bx) { (ip->Bx)(ip->B_par,q,z); (ip->ATx)(ip->AT_par,z,q); rr1 = q; /* q = A^T*B*A*p */ } else { (ip->ATx)(ip->AT_par,q,z); /* z = A^T*A*p */ rr1 = z; } alpha = inner/in_prod(rr1,p); v_mltadd(ip->x,p,alpha,ip->x); v_mltadd(r,rr1,-alpha,r); old_inner = inner; } #ifdef THREADSAFE V_FREE(r); V_FREE(p); V_FREE(q); V_FREE(z); #endif return ip->x; } /* iter_spcgne -- a simple interface to iter_cgne() which uses sparse matrix data structures -- assumes that B contains an actual preconditioner (or NULL) use always as follows: x = iter_spcgne(A,B,b,eps,x,limit,steps); or x = iter_spcgne(A,B,b,eps,VNULL,limit,steps); In the second case the solution vector is created. */ #ifndef ANSI_C VEC *iter_spcgne(A,B,b,eps,x,limit,steps) SPMAT *A, *B; VEC *b, *x; double eps; int *steps, limit; #else VEC *iter_spcgne(SPMAT *A,SPMAT *B, VEC *b, double eps, VEC *x, int limit, int *steps) #endif { ITER *ip; ip = iter_get(0,0); ip->Ax = (Fun_Ax) sp_mv_mlt; ip->A_par = (void *)A; ip->ATx = (Fun_Ax) sp_vm_mlt; ip->AT_par = (void *)A; if (B) { ip->Bx = (Fun_Ax) sp_mv_mlt; ip->B_par = (void *)B; } else { ip->Bx = (Fun_Ax) NULL; ip->B_par = NULL; } ip->info = (Fun_info) NULL; ip->b = b; ip->eps = eps; ip->limit = limit; ip->x = x; iter_cgne(ip); x = ip->x; if (steps) *steps = ip->steps; ip->shared_x = ip->shared_b = TRUE; iter_free(ip); /* release only ITER structure */ return x; } gtk-wave-cleaner-0.22-04/meschach/itersym.c0000777000175000017500000003573213120075106021631 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Stewart & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* itersym.c 17/09/93 */ /* ITERATIVE METHODS - implementation of several iterative methods; see also iter0.c */ #include #include #include "matrix.h" #include "matrix2.h" #include "sparse.h" #include "iter.h" static char rcsid[] = "$Id: itersym.c,v 1.2 1995/01/30 14:55:54 des Exp $"; #ifdef ANSI_C VEC *spCHsolve(const SPMAT *,VEC *,VEC *); VEC *trieig(VEC *,VEC *,MAT *); #else VEC *spCHsolve(); VEC *trieig(); #endif /* iter_spcg -- a simple interface to iter_cg() which uses sparse matrix data structures -- assumes that LLT contains the Cholesky factorisation of the actual preconditioner; use always as follows: x = iter_spcg(A,LLT,b,eps,x,limit,steps); or x = iter_spcg(A,LLT,b,eps,VNULL,limit,steps); In the second case the solution vector is created. */ #ifndef ANSI_C VEC *iter_spcg(A,LLT,b,eps,x,limit,steps) SPMAT *A, *LLT; VEC *b, *x; double eps; int *steps, limit; #else VEC *iter_spcg(SPMAT *A, SPMAT *LLT, VEC *b, double eps, VEC *x, int limit, int *steps) #endif { ITER *ip; ip = iter_get(0,0); ip->Ax = (Fun_Ax) sp_mv_mlt; ip->A_par = (void *)A; ip->Bx = (Fun_Ax) spCHsolve; ip->B_par = (void *)LLT; ip->info = (Fun_info) NULL; ip->b = b; ip->eps = eps; ip->limit = limit; ip->x = x; iter_cg(ip); x = ip->x; if (steps) *steps = ip->steps; ip->shared_x = ip->shared_b = TRUE; iter_free(ip); /* release only ITER structure */ return x; } /* Conjugate gradients method; */ #ifndef ANSI_C VEC *iter_cg(ip) ITER *ip; #else VEC *iter_cg(ITER *ip) #endif { STATIC VEC *r = VNULL, *p = VNULL, *q = VNULL, *z = VNULL; Real alpha, beta, inner, old_inner, nres; VEC *rr; /* rr == r or rr == z */ if (ip == INULL) error(E_NULL,"iter_cg"); if (!ip->Ax || !ip->b) error(E_NULL,"iter_cg"); if ( ip->x == ip->b ) error(E_INSITU,"iter_cg"); if (!ip->stop_crit) error(E_NULL,"iter_cg"); if ( ip->eps <= 0.0 ) ip->eps = MACHEPS; r = v_resize(r,ip->b->dim); p = v_resize(p,ip->b->dim); q = v_resize(q,ip->b->dim); MEM_STAT_REG(r,TYPE_VEC); MEM_STAT_REG(p,TYPE_VEC); MEM_STAT_REG(q,TYPE_VEC); if (ip->Bx != (Fun_Ax)NULL) { z = v_resize(z,ip->b->dim); MEM_STAT_REG(z,TYPE_VEC); rr = z; } else rr = r; if (ip->x != VNULL) { if (ip->x->dim != ip->b->dim) error(E_SIZES,"iter_cg"); ip->Ax(ip->A_par,ip->x,p); /* p = A*x */ v_sub(ip->b,p,r); /* r = b - A*x */ } else { /* ip->x == 0 */ ip->x = v_get(ip->b->dim); ip->shared_x = FALSE; v_copy(ip->b,r); } old_inner = 0.0; for ( ip->steps = 0; ip->steps <= ip->limit; ip->steps++ ) { if ( ip->Bx ) (ip->Bx)(ip->B_par,r,rr); /* rr = B*r */ inner = in_prod(rr,r); nres = sqrt(fabs(inner)); if (ip->info) ip->info(ip,nres,r,rr); if (ip->steps == 0) ip->init_res = nres; if ( ip->stop_crit(ip,nres,r,rr) ) break; if ( ip->steps ) /* if ( ip->steps > 0 ) ... */ { beta = inner/old_inner; p = v_mltadd(rr,p,beta,p); } else /* if ( ip->steps == 0 ) ... */ { beta = 0.0; p = v_copy(rr,p); old_inner = 0.0; } (ip->Ax)(ip->A_par,p,q); /* q = A*p */ alpha = in_prod(p,q); if (sqrt(fabs(alpha)) <= MACHEPS*ip->init_res) error(E_BREAKDOWN,"iter_cg"); alpha = inner/alpha; v_mltadd(ip->x,p,alpha,ip->x); v_mltadd(r,q,-alpha,r); old_inner = inner; } #ifdef THREADSAFE V_FREE(r); V_FREE(p); V_FREE(q); V_FREE(z); #endif return ip->x; } /* iter_lanczos -- raw lanczos algorithm -- no re-orthogonalisation -- creates T matrix of size == m, but no larger than before beta_k == 0 -- uses passed routine to do matrix-vector multiplies */ #ifndef ANSI_C void iter_lanczos(ip,a,b,beta2,Q) ITER *ip; VEC *a, *b; Real *beta2; MAT *Q; #else void iter_lanczos(ITER *ip, VEC *a, VEC *b, Real *beta2, MAT *Q) #endif { int j; STATIC VEC *v = VNULL, *w = VNULL, *tmp = VNULL; Real alpha, beta, c; if ( ! ip ) error(E_NULL,"iter_lanczos"); if ( ! ip->Ax || ! ip->x || ! a || ! b ) error(E_NULL,"iter_lanczos"); if ( ip->k <= 0 ) error(E_BOUNDS,"iter_lanczos"); if ( Q && ( Q->n < ip->x->dim || Q->m < ip->k ) ) error(E_SIZES,"iter_lanczos"); a = v_resize(a,(unsigned int)ip->k); b = v_resize(b,(unsigned int)(ip->k-1)); v = v_resize(v,ip->x->dim); w = v_resize(w,ip->x->dim); tmp = v_resize(tmp,ip->x->dim); MEM_STAT_REG(v,TYPE_VEC); MEM_STAT_REG(w,TYPE_VEC); MEM_STAT_REG(tmp,TYPE_VEC); beta = 1.0; v_zero(a); v_zero(b); if (Q) m_zero(Q); /* normalise x as w */ c = v_norm2(ip->x); if (c <= MACHEPS) { /* ip->x == 0 */ *beta2 = 0.0; return; } else sv_mlt(1.0/c,ip->x,w); (ip->Ax)(ip->A_par,w,v); for ( j = 0; j < ip->k; j++ ) { /* store w in Q if Q not NULL */ if ( Q ) set_row(Q,j,w); alpha = in_prod(w,v); a->ve[j] = alpha; v_mltadd(v,w,-alpha,v); beta = v_norm2(v); if ( beta == 0.0 ) { *beta2 = 0.0; return; } if ( j < ip->k-1 ) b->ve[j] = beta; v_copy(w,tmp); sv_mlt(1/beta,v,w); sv_mlt(-beta,tmp,v); (ip->Ax)(ip->A_par,w,tmp); v_add(v,tmp,v); } *beta2 = beta; #ifdef THREADSAFE V_FREE(v); V_FREE(w); V_FREE(tmp); #endif } /* iter_splanczos -- version that uses sparse matrix data structure */ #ifndef ANSI_C void iter_splanczos(A,m,x0,a,b,beta2,Q) SPMAT *A; int m; VEC *x0, *a, *b; Real *beta2; MAT *Q; #else void iter_splanczos(SPMAT *A, int m, VEC *x0, VEC *a, VEC *b, Real *beta2, MAT *Q) #endif { ITER *ip; ip = iter_get(0,0); ip->shared_x = ip->shared_b = TRUE; ip->Ax = (Fun_Ax) sp_mv_mlt; ip->A_par = (void *) A; ip->x = x0; ip->k = m; iter_lanczos(ip,a,b,beta2,Q); iter_free(ip); /* release only ITER structure */ } #ifndef ANSI_C extern double frexp(), ldexp(); #else extern double frexp(double num, int *exponent), ldexp(double num, int exponent); #endif /* product -- returns the product of a long list of numbers -- answer stored in mant (mantissa) and expt (exponent) */ #ifndef ANSI_C static double product(a,offset,expt) VEC *a; double offset; int *expt; #else static double product(VEC *a, double offset, int *expt) #endif { Real mant, tmp_fctr; int i, tmp_expt; if ( ! a ) error(E_NULL,"product"); mant = 1.0; *expt = 0; if ( offset == 0.0 ) for ( i = 0; i < a->dim; i++ ) { mant *= frexp(a->ve[i],&tmp_expt); *expt += tmp_expt; if ( ! (i % 10) ) { mant = frexp(mant,&tmp_expt); *expt += tmp_expt; } } else for ( i = 0; i < a->dim; i++ ) { tmp_fctr = a->ve[i] - offset; tmp_fctr += (tmp_fctr > 0.0 ) ? -MACHEPS*offset : MACHEPS*offset; mant *= frexp(tmp_fctr,&tmp_expt); *expt += tmp_expt; if ( ! (i % 10) ) { mant = frexp(mant,&tmp_expt); *expt += tmp_expt; } } mant = frexp(mant,&tmp_expt); *expt += tmp_expt; return mant; } /* product2 -- returns the product of a long list of numbers (except the k'th) -- answer stored in mant (mantissa) and expt (exponent) */ #ifndef ANSI_C static double product2(a,k,expt) VEC *a; int k; /* entry of a to leave out */ int *expt; #else static double product2(VEC *a, int k, int *expt) #endif { Real mant, mu, tmp_fctr; int i, tmp_expt; if ( ! a ) error(E_NULL,"product2"); if ( k < 0 || k >= a->dim ) error(E_BOUNDS,"product2"); mant = 1.0; *expt = 0; mu = a->ve[k]; for ( i = 0; i < a->dim; i++ ) { if ( i == k ) continue; tmp_fctr = a->ve[i] - mu; tmp_fctr += ( tmp_fctr > 0.0 ) ? -MACHEPS*mu : MACHEPS*mu; mant *= frexp(tmp_fctr,&tmp_expt); *expt += tmp_expt; if ( ! (i % 10) ) { mant = frexp(mant,&tmp_expt); *expt += tmp_expt; } } mant = frexp(mant,&tmp_expt); *expt += tmp_expt; return mant; } /* dbl_cmp -- comparison function to pass to qsort() */ #ifndef ANSI_C static int dbl_cmp(x,y) Real *x, *y; #else static int dbl_cmp(Real *x, Real *y) #endif { Real tmp; tmp = *x - *y; return (tmp > 0 ? 1 : tmp < 0 ? -1: 0); } /* iter_lanczos2 -- lanczos + error estimate for every e-val -- uses Cullum & Willoughby approach, Sparse Matrix Proc. 1978 -- returns multiple e-vals where multiple e-vals may not exist -- returns evals vector */ #ifndef ANSI_C VEC *iter_lanczos2(ip,evals,err_est) ITER *ip; /* ITER structure */ VEC *evals; /* eigenvalue vector */ VEC *err_est; /* error estimates of eigenvalues */ #else VEC *iter_lanczos2(ITER *ip, VEC *evals, VEC *err_est) #endif { VEC *a; STATIC VEC *b=VNULL, *a2=VNULL, *b2=VNULL; Real beta, pb_mant, det_mant, det_mant1, det_mant2; int i, pb_expt, det_expt, det_expt1, det_expt2; if ( ! ip ) error(E_NULL,"iter_lanczos2"); if ( ! ip->Ax || ! ip->x ) error(E_NULL,"iter_lanczos2"); if ( ip->k <= 0 ) error(E_RANGE,"iter_lanczos2"); a = evals; a = v_resize(a,(unsigned int)ip->k); b = v_resize(b,(unsigned int)(ip->k-1)); MEM_STAT_REG(b,TYPE_VEC); iter_lanczos(ip,a,b,&beta,MNULL); /* printf("# beta =%g\n",beta); */ pb_mant = 0.0; if ( err_est ) { pb_mant = product(b,(double)0.0,&pb_expt); /* printf("# pb_mant = %g, pb_expt = %d\n",pb_mant, pb_expt); */ } /* printf("# diags =\n"); v_output(a); */ /* printf("# off diags =\n"); v_output(b); */ a2 = v_resize(a2,a->dim - 1); b2 = v_resize(b2,b->dim - 1); MEM_STAT_REG(a2,TYPE_VEC); MEM_STAT_REG(b2,TYPE_VEC); for ( i = 0; i < a2->dim - 1; i++ ) { a2->ve[i] = a->ve[i+1]; b2->ve[i] = b->ve[i+1]; } a2->ve[a2->dim-1] = a->ve[a2->dim]; trieig(a,b,MNULL); /* sort evals as a courtesy */ qsort((void *)(a->ve),(int)(a->dim),sizeof(Real),(int (*)())dbl_cmp); /* error estimates */ if ( err_est ) { err_est = v_resize(err_est,(unsigned int)ip->k); trieig(a2,b2,MNULL); /* printf("# a =\n"); v_output(a); */ /* printf("# a2 =\n"); v_output(a2); */ for ( i = 0; i < a->dim; i++ ) { det_mant1 = product2(a,i,&det_expt1); det_mant2 = product(a2,(double)a->ve[i],&det_expt2); /* printf("# det_mant1=%g, det_expt1=%d\n", det_mant1,det_expt1); */ /* printf("# det_mant2=%g, det_expt2=%d\n", det_mant2,det_expt2); */ if ( det_mant1 == 0.0 ) { /* multiple e-val of T */ err_est->ve[i] = 0.0; continue; } else if ( det_mant2 == 0.0 ) { err_est->ve[i] = HUGE_VAL; continue; } if ( (det_expt1 + det_expt2) % 2 ) /* if odd... */ det_mant = sqrt(2.0*fabs(det_mant1*det_mant2)); else /* if even... */ det_mant = sqrt(fabs(det_mant1*det_mant2)); det_expt = (det_expt1+det_expt2)/2; err_est->ve[i] = fabs(beta* ldexp(pb_mant/det_mant,pb_expt-det_expt)); } } #ifdef THREADSAFE V_FREE(b); V_FREE(a2); V_FREE(b2); #endif return a; } /* iter_splanczos2 -- version of iter_lanczos2() that uses sparse matrix data structure */ #ifndef ANSI_C VEC *iter_splanczos2(A,m,x0,evals,err_est) SPMAT *A; int m; VEC *x0; /* initial vector */ VEC *evals; /* eigenvalue vector */ VEC *err_est; /* error estimates of eigenvalues */ #else VEC *iter_splanczos2(SPMAT *A, int m, VEC *x0, VEC *evals, VEC *err_est) #endif { ITER *ip; VEC *a; ip = iter_get(0,0); ip->Ax = (Fun_Ax) sp_mv_mlt; ip->A_par = (void *) A; ip->x = x0; ip->k = m; a = iter_lanczos2(ip,evals,err_est); ip->shared_x = ip->shared_b = TRUE; iter_free(ip); /* release only ITER structure */ return a; } /* Conjugate gradient method Another variant - mainly for testing */ #ifndef ANSI_C VEC *iter_cg1(ip) ITER *ip; #else VEC *iter_cg1(ITER *ip) #endif { STATIC VEC *r = VNULL, *p = VNULL, *q = VNULL, *z = VNULL; Real alpha; double inner,nres; VEC *rr; /* rr == r or rr == z */ if (ip == INULL) error(E_NULL,"iter_cg"); if (!ip->Ax || !ip->b) error(E_NULL,"iter_cg"); if ( ip->x == ip->b ) error(E_INSITU,"iter_cg"); if (!ip->stop_crit) error(E_NULL,"iter_cg"); if ( ip->eps <= 0.0 ) ip->eps = MACHEPS; r = v_resize(r,ip->b->dim); p = v_resize(p,ip->b->dim); q = v_resize(q,ip->b->dim); MEM_STAT_REG(r,TYPE_VEC); MEM_STAT_REG(p,TYPE_VEC); MEM_STAT_REG(q,TYPE_VEC); if (ip->Bx != (Fun_Ax)NULL) { z = v_resize(z,ip->b->dim); MEM_STAT_REG(z,TYPE_VEC); rr = z; } else rr = r; if (ip->x != VNULL) { if (ip->x->dim != ip->b->dim) error(E_SIZES,"iter_cg"); ip->Ax(ip->A_par,ip->x,p); /* p = A*x */ v_sub(ip->b,p,r); /* r = b - A*x */ } else { /* ip->x == 0 */ ip->x = v_get(ip->b->dim); ip->shared_x = FALSE; v_copy(ip->b,r); } if (ip->Bx) (ip->Bx)(ip->B_par,r,p); else v_copy(r,p); inner = in_prod(p,r); nres = sqrt(fabs(inner)); if (ip->info) ip->info(ip,nres,r,p); if ( nres == 0.0) return ip->x; for ( ip->steps = 0; ip->steps <= ip->limit; ip->steps++ ) { ip->Ax(ip->A_par,p,q); inner = in_prod(q,p); if (sqrt(fabs(inner)) <= MACHEPS*ip->init_res) error(E_BREAKDOWN,"iter_cg1"); alpha = in_prod(p,r)/inner; v_mltadd(ip->x,p,alpha,ip->x); v_mltadd(r,q,-alpha,r); rr = r; if (ip->Bx) { ip->Bx(ip->B_par,r,z); rr = z; } nres = in_prod(r,rr); if (nres < 0.0) { warning(WARN_RES_LESS_0,"iter_cg"); break; } nres = sqrt(fabs(nres)); if (ip->info) ip->info(ip,nres,r,z); if (ip->steps == 0) ip->init_res = nres; if ( ip->stop_crit(ip,nres,r,z) ) break; alpha = -in_prod(rr,q)/inner; v_mltadd(rr,p,alpha,p); } #ifdef THREADSAFE V_FREE(r); V_FREE(p); V_FREE(q); V_FREE(z); #endif return ip->x; } gtk-wave-cleaner-0.22-04/meschach/itertort.c0000777000175000017500000003746213120075106022013 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* iter_tort.c 16/09/93 */ /* This file contains tests for the iterative part of Meschach */ #include #include "matrix2.h" #include "sparse2.h" #include "iter.h" #include #define errmesg(mesg) printf("Error: %s error: line %d\n",mesg,__LINE__) #define notice(mesg) printf("# Testing %s...\n",mesg); /* for iterative methods */ #if REAL == DOUBLE #define EPS 1e-7 #define KK 20 #elif REAL == FLOAT #define EPS 1e-5 #define KK 8 #endif #define ANON 513 #define ASYM ANON static VEC *ex_sol = VNULL; /* new iter information */ void iter_mod_info(ip,nres,res,Bres) ITER *ip; double nres; VEC *res, *Bres; { static VEC *tmp; if (ip->b == VNULL) return; tmp = v_resize(tmp,ip->b->dim); MEM_STAT_REG(tmp,TYPE_VEC); if (nres >= 0.0) { printf(" %d. residual = %g\n",ip->steps,nres); } else printf(" %d. residual = %g (WARNING !!! should be >= 0) \n", ip->steps,nres); if (ex_sol != VNULL) printf(" ||u_ex - u_approx||_2 = %g\n", v_norm2(v_sub(ip->x,ex_sol,tmp))); } /* out = A^T*A*x */ VEC *norm_equ(A,x,out) SPMAT *A; VEC *x, *out; { static VEC * tmp; tmp = v_resize(tmp,x->dim); MEM_STAT_REG(tmp,TYPE_VEC); sp_mv_mlt(A,x,tmp); sp_vm_mlt(A,tmp,out); return out; } /* make symmetric preconditioner for nonsymmetric matrix A; B = 0.5*(A+A^T) and then B is factorized using incomplete Choleski factorization */ SPMAT *gen_sym_precond(A) SPMAT *A; { SPMAT *B; SPROW *row; int i,j,k; Real val; B = sp_get(A->m,A->n,A->row[0].maxlen); for (i=0; i < A->m; i++) { row = &(A->row[i]); for (j = 0; j < row->len; j++) { k = row->elt[j].col; if (i != k) { val = 0.5*(sp_get_val(A,i,k) + sp_get_val(A,k,i)); sp_set_val(B,i,k,val); sp_set_val(B,k,i,val); } else { /* i == k */ val = sp_get_val(A,i,i); sp_set_val(B,i,i,val); } } } spICHfactor(B); return B; } /* Dv_mlt -- diagonal by vector multiply; the diagonal matrix is represented by a vector d */ VEC *Dv_mlt(d, x, out) VEC *d, *x, *out; { int i; if ( ! d || ! x ) error(E_NULL,"Dv_mlt"); if ( d->dim != x->dim ) error(E_SIZES,"Dv_mlt"); out = v_resize(out,x->dim); for ( i = 0; i < x->dim; i++ ) out->ve[i] = d->ve[i]*x->ve[i]; return out; } /************************************************/ void main(argc, argv) int argc; char *argv[]; { VEC *x, *y, *z, *u, *v, *xn, *yn; SPMAT *A = NULL, *B = NULL; SPMAT *An = NULL, *Bn = NULL; int i, k, kk, j; ITER *ips, *ips1, *ipns, *ipns1; MAT *Q, *H, *Q1, *H1; VEC vt, vt1; Real hh; mem_info_on(TRUE); notice("allocating sparse matrices"); printf(" dim of A = %dx%d\n",ASYM,ASYM); A = iter_gen_sym(ASYM,8); B = sp_copy(A); spICHfactor(B); u = v_get(A->n); x = v_get(A->n); y = v_get(A->n); v = v_get(A->n); v_rand(x); sp_mv_mlt(A,x,y); ex_sol = x; notice(" initialize ITER variables"); /* ips for symmetric matrices with precondition */ ips = iter_get(A->m,A->n); /* printf(" ips:\n"); iter_dump(stdout,ips); */ ips->limit = 500; ips->eps = EPS; iter_Ax(ips,sp_mv_mlt,A); iter_Bx(ips,spCHsolve,B); ips->b = v_copy(y,ips->b); v_rand(ips->x); /* test of iter_resize */ ips = iter_resize(ips,2*A->m,2*A->n); ips = iter_resize(ips,A->m,A->n); /* printf(" ips:\n"); iter_dump(stdout,ips); */ /* ips1 for symmetric matrices without precondition */ ips1 = iter_get(0,0); /* printf(" ips1:\n"); iter_dump(stdout,ips1); */ ITER_FREE(ips1); ips1 = iter_copy2(ips,ips1); iter_Bx(ips1,NULL,NULL); ips1->b = ips->b; ips1->shared_b = TRUE; /* printf(" ips1:\n"); iter_dump(stdout,ips1); */ /* ipns for nonsymetric matrices with precondition */ ipns = iter_copy(ips,INULL); ipns->k = KK; ipns->limit = 500; ipns->info = NULL; An = iter_gen_nonsym_posdef(ANON,8); Bn = gen_sym_precond(An); xn = v_get(An->n); yn = v_get(An->n); v_rand(xn); sp_mv_mlt(An,xn,yn); ipns->b = v_copy(yn,ipns->b); iter_Ax(ipns, sp_mv_mlt,An); iter_ATx(ipns, sp_vm_mlt,An); iter_Bx(ipns, spCHsolve,Bn); /* printf(" ipns:\n"); iter_dump(stdout,ipns); */ /* ipns1 for nonsymmetric matrices without precondition */ ipns1 = iter_copy2(ipns,INULL); ipns1->b = ipns->b; ipns1->shared_b = TRUE; iter_Bx(ipns1,NULL,NULL); /* printf(" ipns1:\n"); iter_dump(stdout,ipns1); */ /******* CG ********/ notice(" CG method without preconditioning"); ips1->info = NULL; mem_stat_mark(1); iter_cg(ips1); k = ips1->steps; z = ips1->x; printf(" cg: no. of iter.steps = %d\n",k); v_sub(z,x,u); printf(" (cg:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(u),EPS); notice(" CG method with ICH preconditioning"); ips->info = NULL; v_zero(ips->x); iter_cg(ips); k = ips->steps; printf(" cg: no. of iter.steps = %d\n",k); v_sub(ips->x,x,u); printf(" (cg:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(u),EPS); V_FREE(v); if ((v = iter_spcg(A,B,y,EPS,VNULL,1000,&k)) == VNULL) errmesg("CG method with precond.: NULL solution"); v_sub(ips->x,v,u); if (v_norm2(u) >= EPS) { errmesg("CG method with precond.: different solutions"); printf(" diff. = %g\n",v_norm2(u)); } mem_stat_free(1); printf(" spcg: # of iter. steps = %d\n",k); v_sub(v,x,u); printf(" (spcg:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(u),EPS); /*** CG FOR NORMAL EQUATION *****/ notice("CGNE method with ICH preconditioning (nonsymmetric case)"); /* ipns->info = iter_std_info; */ ipns->info = NULL; v_zero(ipns->x); mem_stat_mark(1); iter_cgne(ipns); k = ipns->steps; z = ipns->x; printf(" cgne: no. of iter.steps = %d\n",k); v_sub(z,xn,u); printf(" (cgne:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(u),EPS); notice("CGNE method without preconditioning (nonsymmetric case)"); v_rand(u); u = iter_spcgne(An,NULL,yn,EPS,u,1000,&k); mem_stat_free(1); printf(" spcgne: no. of iter.steps = %d\n",k); v_sub(u,xn,u); printf(" (spcgne:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(u),EPS); /*** CGS *****/ notice("CGS method with ICH preconditioning (nonsymmetric case)"); v_zero(ipns->x); /* new init guess == 0 */ mem_stat_mark(1); ipns->info = NULL; v_rand(u); iter_cgs(ipns,u); k = ipns->steps; z = ipns->x; printf(" cgs: no. of iter.steps = %d\n",k); v_sub(z,xn,u); printf(" (cgs:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(u),EPS); notice("CGS method without preconditioning (nonsymmetric case)"); v_rand(u); v_rand(v); v = iter_spcgs(An,NULL,yn,u,EPS,v,1000,&k); mem_stat_free(1); printf(" cgs: no. of iter.steps = %d\n",k); v_sub(v,xn,u); printf(" (cgs:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(u),EPS); /*** LSQR ***/ notice("LSQR method (without preconditioning)"); v_rand(u); v_free(ipns1->x); ipns1->x = u; ipns1->shared_x = TRUE; ipns1->info = NULL; mem_stat_mark(2); z = iter_lsqr(ipns1); v_sub(xn,z,v); k = ipns1->steps; printf(" lsqr: # of iter. steps = %d\n",k); printf(" (lsqr:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(v),EPS); v_rand(u); u = iter_splsqr(An,yn,EPS,u,1000,&k); mem_stat_free(2); v_sub(xn,u,v); printf(" splsqr: # of iter. steps = %d\n",k); printf(" (splsqr:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(v),EPS); /***** GMRES ********/ notice("GMRES method with ICH preconditioning (nonsymmetric case)"); v_zero(ipns->x); /* ipns->info = iter_std_info; */ ipns->info = NULL; mem_stat_mark(2); z = iter_gmres(ipns); v_sub(xn,z,v); k = ipns->steps; printf(" gmres: # of iter. steps = %d\n",k); printf(" (gmres:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(v),EPS); notice("GMRES method without preconditioning (nonsymmetric case)"); V_FREE(v); v = iter_spgmres(An,NULL,yn,EPS,VNULL,10,1004,&k); mem_stat_free(2); v_sub(xn,v,v); printf(" spgmres: # of iter. steps = %d\n",k); printf(" (spgmres:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(v),EPS); /**** MGCR *****/ notice("MGCR method with ICH preconditioning (nonsymmetric case)"); v_zero(ipns->x); mem_stat_mark(2); z = iter_mgcr(ipns); v_sub(xn,z,v); k = ipns->steps; printf(" mgcr: # of iter. steps = %d\n",k); printf(" (mgcr:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(v),EPS); notice("MGCR method without preconditioning (nonsymmetric case)"); V_FREE(v); v = iter_spmgcr(An,NULL,yn,EPS,VNULL,10,1004,&k); mem_stat_free(2); v_sub(xn,v,v); printf(" spmgcr: # of iter. steps = %d\n",k); printf(" (spmgcr:) ||u_ex - u_approx||_2 = %g [EPS = %g]\n", v_norm2(v),EPS); /***** ARNOLDI METHOD ********/ notice("arnoldi method"); kk = ipns1->k = KK; Q = m_get(kk,x->dim); Q1 = m_get(kk,x->dim); H = m_get(kk,kk); v_rand(u); ipns1->x = u; ipns1->shared_x = TRUE; mem_stat_mark(3); iter_arnoldi_iref(ipns1,&hh,Q,H); mem_stat_free(3); /* check the equality: Q*A*Q^T = H; */ vt.dim = vt.max_dim = x->dim; vt1.dim = vt1.max_dim = x->dim; for (j=0; j < kk; j++) { vt.ve = Q->me[j]; vt1.ve = Q1->me[j]; sp_mv_mlt(An,&vt,&vt1); } H1 = m_get(kk,kk); mmtr_mlt(Q,Q1,H1); m_sub(H,H1,H1); if (m_norm_inf(H1) > MACHEPS*x->dim) printf(" (arnoldi_iref) ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n", m_norm_inf(H1),MACHEPS); /* check Q*Q^T = I */ mmtr_mlt(Q,Q,H1); for (j=0; j < kk; j++) H1->me[j][j] -= 1.0; if (m_norm_inf(H1) > MACHEPS*x->dim) printf(" (arnoldi_iref) ||Q*Q^T - I|| = %g [cf. MACHEPS = %g]\n", m_norm_inf(H1),MACHEPS); ipns1->x = u; ipns1->shared_x = TRUE; mem_stat_mark(3); iter_arnoldi(ipns1,&hh,Q,H); mem_stat_free(3); /* check the equality: Q*A*Q^T = H; */ vt.dim = vt.max_dim = x->dim; vt1.dim = vt1.max_dim = x->dim; for (j=0; j < kk; j++) { vt.ve = Q->me[j]; vt1.ve = Q1->me[j]; sp_mv_mlt(An,&vt,&vt1); } mmtr_mlt(Q,Q1,H1); m_sub(H,H1,H1); if (m_norm_inf(H1) > MACHEPS*x->dim) printf(" (arnoldi) ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n", m_norm_inf(H1),MACHEPS); /* check Q*Q^T = I */ mmtr_mlt(Q,Q,H1); for (j=0; j < kk; j++) H1->me[j][j] -= 1.0; if (m_norm_inf(H1) > MACHEPS*x->dim) printf(" (arnoldi) ||Q*Q^T - I|| = %g [cf. MACHEPS = %g]\n", m_norm_inf(H1),MACHEPS); v_rand(u); mem_stat_mark(3); iter_sparnoldi(An,u,kk,&hh,Q,H); mem_stat_free(3); /* check the equality: Q*A*Q^T = H; */ vt.dim = vt.max_dim = x->dim; vt1.dim = vt1.max_dim = x->dim; for (j=0; j < kk; j++) { vt.ve = Q->me[j]; vt1.ve = Q1->me[j]; sp_mv_mlt(An,&vt,&vt1); } mmtr_mlt(Q,Q1,H1); m_sub(H,H1,H1); if (m_norm_inf(H1) > MACHEPS*x->dim) printf(" (sparnoldi) ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n", m_norm_inf(H1),MACHEPS); /* check Q*Q^T = I */ mmtr_mlt(Q,Q,H1); for (j=0; j < kk; j++) H1->me[j][j] -= 1.0; if (m_norm_inf(H1) > MACHEPS*x->dim) printf(" (sparnoldi) ||Q*Q^T - I|| = %g [cf. MACHEPS = %g]\n", m_norm_inf(H1),MACHEPS); /****** LANCZOS METHOD ******/ notice("lanczos method"); kk = ipns1->k; Q = m_resize(Q,kk,x->dim); Q1 = m_resize(Q1,kk,x->dim); H = m_resize(H,kk,kk); ips1->k = kk; v_rand(u); v_free(ips1->x); ips1->x = u; ips1->shared_x = TRUE; mem_stat_mark(3); iter_lanczos(ips1,x,y,&hh,Q); mem_stat_free(3); /* check the equality: Q*A*Q^T = H; */ vt.dim = vt1.dim = Q->n; vt.max_dim = vt1.max_dim = Q->max_n; Q1 = m_resize(Q1,Q->m,Q->n); for (j=0; j < Q->m; j++) { vt.ve = Q->me[j]; vt1.ve = Q1->me[j]; sp_mv_mlt(A,&vt,&vt1); } H1 = m_resize(H1,Q->m,Q->m); H = m_resize(H,Q->m,Q->m); mmtr_mlt(Q,Q1,H1); m_zero(H); for (j=0; j < Q->m-1; j++) { H->me[j][j] = x->ve[j]; H->me[j][j+1] = H->me[j+1][j] = y->ve[j]; } H->me[Q->m-1][Q->m-1] = x->ve[Q->m-1]; m_sub(H,H1,H1); if (m_norm_inf(H1) > MACHEPS*x->dim) printf(" (lanczos) ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n", m_norm_inf(H1),MACHEPS); /* check Q*Q^T = I */ mmtr_mlt(Q,Q,H1); for (j=0; j < Q->m; j++) H1->me[j][j] -= 1.0; if (m_norm_inf(H1) > MACHEPS*x->dim) printf(" (lanczos) ||Q*Q^T - I|| = %g [cf. MACHEPS = %g]\n", m_norm_inf(H1),MACHEPS); mem_stat_mark(3); v_rand(u); iter_splanczos(A,kk,u,x,y,&hh,Q); mem_stat_free(3); /* check the equality: Q*A*Q^T = H; */ vt.dim = vt1.dim = Q->n; vt.max_dim = vt1.max_dim = Q->max_n; Q1 = m_resize(Q1,Q->m,Q->n); for (j=0; j < Q->m; j++) { vt.ve = Q->me[j]; vt1.ve = Q1->me[j]; sp_mv_mlt(A,&vt,&vt1); } H1 = m_resize(H1,Q->m,Q->m); H = m_resize(H,Q->m,Q->m); mmtr_mlt(Q,Q1,H1); for (j=0; j < Q->m-1; j++) { H->me[j][j] = x->ve[j]; H->me[j][j+1] = H->me[j+1][j] = y->ve[j]; } H->me[Q->m-1][Q->m-1] = x->ve[Q->m-1]; m_sub(H,H1,H1); if (m_norm_inf(H1) > MACHEPS*x->dim) printf(" (splanczos) ||Q*A*Q^T - H|| = %g [cf. MACHEPS = %g]\n", m_norm_inf(H1),MACHEPS); /* check Q*Q^T = I */ mmtr_mlt(Q,Q,H1); for (j=0; j < Q->m; j++) H1->me[j][j] -= 1.0; if (m_norm_inf(H1) > MACHEPS*x->dim) printf(" (splanczos) ||Q*Q^T - I|| = %g [cf. MACHEPS = %g]\n", m_norm_inf(H1),MACHEPS); /***** LANCZOS2 ****/ notice("lanczos2 method"); kk = 50; /* # of dir. vectors */ ips1->k = kk; v_rand(u); ips1->x = u; ips1->shared_x = TRUE; for ( i = 0; i < xn->dim; i++ ) xn->ve[i] = i; iter_Ax(ips1,Dv_mlt,xn); mem_stat_mark(3); iter_lanczos2(ips1,y,v); mem_stat_free(3); printf("# Number of steps of Lanczos algorithm = %d\n", kk); printf("# Exact eigenvalues are 0, 1, 2, ..., %d\n",ANON-1); printf("# Extreme eigenvalues should be accurate; \n"); printf("# interior values usually are not.\n"); printf("# approx e-vals =\n"); v_output(y); printf("# Error in estimate of bottom e-vec (Lanczos) = %g\n", fabs(v->ve[0])); mem_stat_mark(3); v_rand(u); iter_splanczos2(A,kk,u,y,v); mem_stat_free(3); /***** FINISHING *******/ notice("release ITER variables"); M_FREE(Q); M_FREE(Q1); M_FREE(H); M_FREE(H1); ITER_FREE(ipns); ITER_FREE(ips); ITER_FREE(ipns1); ITER_FREE(ips1); SP_FREE(A); SP_FREE(B); SP_FREE(An); SP_FREE(Bn); V_FREE(x); V_FREE(y); V_FREE(u); V_FREE(v); V_FREE(xn); V_FREE(yn); printf("# Done testing (%s)\n",argv[0]); mem_info(); } gtk-wave-cleaner-0.22-04/meschach/ivecop.c0000777000175000017500000001656113120075106021421 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* ivecop.c */ #include #include "matrix.h" static char rcsid[] = "$Id: ivecop.c,v 1.6 1996/08/20 18:19:21 stewart Exp $"; static char line[MAXLINE]; /* iv_get -- get integer vector -- see also memory.c */ #ifndef ANSI_C IVEC *iv_get(dim) int dim; #else IVEC *iv_get(int dim) #endif { IVEC *iv; /* unsigned int i; */ if (dim < 0) error(E_NEG,"iv_get"); if ((iv=NEW(IVEC)) == IVNULL ) error(E_MEM,"iv_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_IVEC,0,sizeof(IVEC)); mem_numvar(TYPE_IVEC,1); } iv->dim = iv->max_dim = dim; if ((iv->ive = NEW_A(dim,int)) == (int *)NULL ) error(E_MEM,"iv_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_IVEC,0,dim*sizeof(int)); } return (iv); } /* iv_free -- returns iv & asoociated memory back to memory heap */ #ifndef ANSI_C int iv_free(iv) IVEC *iv; #else int iv_free(IVEC *iv) #endif { if ( iv==IVNULL || iv->dim > MAXDIM ) /* don't trust it */ return (-1); if ( iv->ive == (int *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_IVEC,sizeof(IVEC),0); mem_numvar(TYPE_IVEC,-1); } free((char *)iv); } else { if (mem_info_is_on()) { mem_bytes(TYPE_IVEC,sizeof(IVEC)+iv->max_dim*sizeof(int),0); mem_numvar(TYPE_IVEC,-1); } free((char *)iv->ive); free((char *)iv); } return (0); } /* iv_resize -- returns the IVEC with dimension new_dim -- iv is set to the zero vector */ #ifndef ANSI_C IVEC *iv_resize(iv,new_dim) IVEC *iv; int new_dim; #else IVEC *iv_resize(IVEC *iv, int new_dim) #endif { int i; if (new_dim < 0) error(E_NEG,"iv_resize"); if ( ! iv ) return iv_get(new_dim); if (new_dim == iv->dim) return iv; if ( new_dim > iv->max_dim ) { if (mem_info_is_on()) { mem_bytes(TYPE_IVEC,iv->max_dim*sizeof(int), new_dim*sizeof(int)); } iv->ive = RENEW(iv->ive,new_dim,int); if ( ! iv->ive ) error(E_MEM,"iv_resize"); iv->max_dim = new_dim; } if ( iv->dim <= new_dim ) for ( i = iv->dim; i < new_dim; i++ ) iv->ive[i] = 0; iv->dim = new_dim; return iv; } /* iv_copy -- copy integer vector in to out -- out created/resized if necessary */ #ifndef ANSI_C IVEC *iv_copy(in,out) IVEC *in, *out; #else IVEC *iv_copy(const IVEC *in, IVEC *out) #endif { int i; if ( ! in ) error(E_NULL,"iv_copy"); out = iv_resize(out,in->dim); for ( i = 0; i < in->dim; i++ ) out->ive[i] = in->ive[i]; return out; } /* iv_move -- move selected pieces of an IVEC -- moves the length dim0 subvector with initial index i0 to the corresponding subvector of out with initial index i1 -- out is resized if necessary */ #ifndef ANSI_C IVEC *iv_move(in,i0,dim0,out,i1) IVEC *in, *out; int i0, dim0, i1; #else IVEC *iv_move(const IVEC *in, int i0, int dim0, IVEC *out, int i1) #endif { if ( ! in ) error(E_NULL,"iv_move"); if ( i0 < 0 || dim0 < 0 || i1 < 0 || i0+dim0 > in->dim ) error(E_BOUNDS,"iv_move"); if ( (! out) || i1+dim0 > out->dim ) out = iv_resize(out,i1+dim0); MEM_COPY(&(in->ive[i0]),&(out->ive[i1]),dim0*sizeof(int)); return out; } /* iv_add -- integer vector addition -- may be in-situ */ #ifndef ANSI_C IVEC *iv_add(iv1,iv2,out) IVEC *iv1,*iv2,*out; #else IVEC *iv_add(const IVEC *iv1, const IVEC *iv2, IVEC *out) #endif { unsigned int i; int *out_ive, *iv1_ive, *iv2_ive; if ( iv1==IVNULL || iv2==IVNULL ) error(E_NULL,"iv_add"); if ( iv1->dim != iv2->dim ) error(E_SIZES,"iv_add"); if ( out==IVNULL || out->dim != iv1->dim ) out = iv_resize(out,iv1->dim); out_ive = out->ive; iv1_ive = iv1->ive; iv2_ive = iv2->ive; for ( i = 0; i < iv1->dim; i++ ) out_ive[i] = iv1_ive[i] + iv2_ive[i]; return (out); } /* iv_sub -- integer vector addition -- may be in-situ */ #ifndef ANSI_C IVEC *iv_sub(iv1,iv2,out) IVEC *iv1,*iv2,*out; #else IVEC *iv_sub(const IVEC *iv1, const IVEC *iv2, IVEC *out) #endif { unsigned int i; int *out_ive, *iv1_ive, *iv2_ive; if ( iv1==IVNULL || iv2==IVNULL ) error(E_NULL,"iv_sub"); if ( iv1->dim != iv2->dim ) error(E_SIZES,"iv_sub"); if ( out==IVNULL || out->dim != iv1->dim ) out = iv_resize(out,iv1->dim); out_ive = out->ive; iv1_ive = iv1->ive; iv2_ive = iv2->ive; for ( i = 0; i < iv1->dim; i++ ) out_ive[i] = iv1_ive[i] - iv2_ive[i]; return (out); } #define MAX_STACK 60 /* iv_sort -- sorts vector x, and generates permutation that gives the order of the components; x = [1.3, 3.7, 0.5] -> [0.5, 1.3, 3.7] and the permutation is order = [2, 0, 1]. -- if order is NULL on entry then it is ignored -- the sorted vector x is returned */ #ifndef ANSI_C IVEC *iv_sort(x, order) IVEC *x; PERM *order; #else IVEC *iv_sort(IVEC *x, PERM *order) #endif { int *x_ive, tmp, v; /* int *order_pe; */ int dim, i, j, l, r, tmp_i; int stack[MAX_STACK], sp; if ( ! x ) error(E_NULL,"iv_sort"); if ( order != PNULL && order->size != x->dim ) order = px_resize(order, x->dim); x_ive = x->ive; dim = x->dim; if ( order != PNULL ) px_ident(order); if ( dim <= 1 ) return x; /* using quicksort algorithm in Sedgewick, "Algorithms in C", Ch. 9, pp. 118--122 (1990) */ sp = 0; l = 0; r = dim-1; v = x_ive[0]; for ( ; ; ) { while ( r > l ) { /* "i = partition(x_ive,l,r);" */ v = x_ive[r]; i = l-1; j = r; for ( ; ; ) { while ( x_ive[++i] < v ) ; --j; while ( x_ive[j] > v && j != 0 ) --j; if ( i >= j ) break; tmp = x_ive[i]; x_ive[i] = x_ive[j]; x_ive[j] = tmp; if ( order != PNULL ) { tmp_i = order->pe[i]; order->pe[i] = order->pe[j]; order->pe[j] = tmp_i; } } tmp = x_ive[i]; x_ive[i] = x_ive[r]; x_ive[r] = tmp; if ( order != PNULL ) { tmp_i = order->pe[i]; order->pe[i] = order->pe[r]; order->pe[r] = tmp_i; } if ( i-l > r-i ) { stack[sp++] = l; stack[sp++] = i-1; l = i+1; } else { stack[sp++] = i+1; stack[sp++] = r; r = i-1; } } /* recursion elimination */ if ( sp == 0 ) break; r = stack[--sp]; l = stack[--sp]; } return x; } gtk-wave-cleaner-0.22-04/meschach/lanczos.c0000777000175000017500000001725113120075106021602 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* File containing Lanczos type routines for finding eigenvalues of large, sparse, symmetic matrices */ #include #include #include "matrix.h" #include "sparse.h" static char rcsid[] = "$Id: lanczos.c,v 1.4 1994/01/13 05:28:24 des Exp $"; #ifdef ANSI_C extern VEC *trieig(VEC *,VEC *,MAT *); #else extern VEC *trieig(); #endif /* lanczos -- raw lanczos algorithm -- no re-orthogonalisation -- creates T matrix of size == m, but no larger than before beta_k == 0 -- uses passed routine to do matrix-vector multiplies */ void lanczos(A_fn,A_params,m,x0,a,b,beta2,Q) VEC *(*A_fn)(); /* VEC *(*A_fn)(void *A_params,VEC *in, VEC *out) */ void *A_params; int m; VEC *x0, *a, *b; Real *beta2; MAT *Q; { int j; VEC *v, *w, *tmp; Real alpha, beta; if ( ! A_fn || ! x0 || ! a || ! b ) error(E_NULL,"lanczos"); if ( m <= 0 ) error(E_BOUNDS,"lanczos"); if ( Q && ( Q->m < x0->dim || Q->n < m ) ) error(E_SIZES,"lanczos"); a = v_resize(a,(unsigned int)m); b = v_resize(b,(unsigned int)(m-1)); v = v_get(x0->dim); w = v_get(x0->dim); tmp = v_get(x0->dim); beta = 1.0; /* normalise x0 as w */ sv_mlt(1.0/v_norm2(x0),x0,w); (*A_fn)(A_params,w,v); for ( j = 0; j < m; j++ ) { /* store w in Q if Q not NULL */ if ( Q ) set_col(Q,j,w); alpha = in_prod(w,v); a->ve[j] = alpha; v_mltadd(v,w,-alpha,v); beta = v_norm2(v); if ( beta == 0.0 ) { v_resize(a,(unsigned int)j+1); v_resize(b,(unsigned int)j); *beta2 = 0.0; if ( Q ) Q = m_resize(Q,Q->m,j+1); return; } if ( j < m-1 ) b->ve[j] = beta; v_copy(w,tmp); sv_mlt(1/beta,v,w); sv_mlt(-beta,tmp,v); (*A_fn)(A_params,w,tmp); v_add(v,tmp,v); } *beta2 = beta; V_FREE(v); V_FREE(w); V_FREE(tmp); } extern double frexp(), ldexp(); /* product -- returns the product of a long list of numbers -- answer stored in mant (mantissa) and expt (exponent) */ static double product(a,offset,expt) VEC *a; double offset; int *expt; { Real mant, tmp_fctr; int i, tmp_expt; if ( ! a ) error(E_NULL,"product"); mant = 1.0; *expt = 0; if ( offset == 0.0 ) for ( i = 0; i < a->dim; i++ ) { mant *= frexp(a->ve[i],&tmp_expt); *expt += tmp_expt; if ( ! (i % 10) ) { mant = frexp(mant,&tmp_expt); *expt += tmp_expt; } } else for ( i = 0; i < a->dim; i++ ) { tmp_fctr = a->ve[i] - offset; tmp_fctr += (tmp_fctr > 0.0 ) ? -MACHEPS*offset : MACHEPS*offset; mant *= frexp(tmp_fctr,&tmp_expt); *expt += tmp_expt; if ( ! (i % 10) ) { mant = frexp(mant,&tmp_expt); *expt += tmp_expt; } } mant = frexp(mant,&tmp_expt); *expt += tmp_expt; return mant; } /* product2 -- returns the product of a long list of numbers -- answer stored in mant (mantissa) and expt (exponent) */ static double product2(a,k,expt) VEC *a; int k; /* entry of a to leave out */ int *expt; { Real mant, mu, tmp_fctr; int i, tmp_expt; if ( ! a ) error(E_NULL,"product2"); if ( k < 0 || k >= a->dim ) error(E_BOUNDS,"product2"); mant = 1.0; *expt = 0; mu = a->ve[k]; for ( i = 0; i < a->dim; i++ ) { if ( i == k ) continue; tmp_fctr = a->ve[i] - mu; tmp_fctr += ( tmp_fctr > 0.0 ) ? -MACHEPS*mu : MACHEPS*mu; mant *= frexp(tmp_fctr,&tmp_expt); *expt += tmp_expt; if ( ! (i % 10) ) { mant = frexp(mant,&tmp_expt); *expt += tmp_expt; } } mant = frexp(mant,&tmp_expt); *expt += tmp_expt; return mant; } /* dbl_cmp -- comparison function to pass to qsort() */ static int dbl_cmp(x,y) Real *x, *y; { Real tmp; tmp = *x - *y; return (tmp > 0 ? 1 : tmp < 0 ? -1: 0); } /* lanczos2 -- lanczos + error estimate for every e-val -- uses Cullum & Willoughby approach, Sparse Matrix Proc. 1978 -- returns multiple e-vals where multiple e-vals may not exist -- returns evals vector */ VEC *lanczos2(A_fn,A_params,m,x0,evals,err_est) VEC *(*A_fn)(); void *A_params; int m; VEC *x0; /* initial vector */ VEC *evals; /* eigenvalue vector */ VEC *err_est; /* error estimates of eigenvalues */ { VEC *a; STATIC VEC *b=VNULL, *a2=VNULL, *b2=VNULL; Real beta, pb_mant, det_mant, det_mant1, det_mant2; int i, pb_expt, det_expt, det_expt1, det_expt2; if ( ! A_fn || ! x0 ) error(E_NULL,"lanczos2"); if ( m <= 0 ) error(E_RANGE,"lanczos2"); a = evals; a = v_resize(a,(unsigned int)m); b = v_resize(b,(unsigned int)(m-1)); MEM_STAT_REG(b,TYPE_VEC); lanczos(A_fn,A_params,m,x0,a,b,&beta,MNULL); /* printf("# beta =%g\n",beta); */ pb_mant = 0.0; if ( err_est ) { pb_mant = product(b,(double)0.0,&pb_expt); /* printf("# pb_mant = %g, pb_expt = %d\n",pb_mant, pb_expt); */ } /* printf("# diags =\n"); out_vec(a); */ /* printf("# off diags =\n"); out_vec(b); */ a2 = v_resize(a2,a->dim - 1); b2 = v_resize(b2,b->dim - 1); MEM_STAT_REG(a2,TYPE_VEC); MEM_STAT_REG(b2,TYPE_VEC); for ( i = 0; i < a2->dim - 1; i++ ) { a2->ve[i] = a->ve[i+1]; b2->ve[i] = b->ve[i+1]; } a2->ve[a2->dim-1] = a->ve[a2->dim]; trieig(a,b,MNULL); /* sort evals as a courtesy */ qsort((void *)(a->ve),(int)(a->dim),sizeof(Real),(int (*)())dbl_cmp); /* error estimates */ if ( err_est ) { err_est = v_resize(err_est,(unsigned int)m); trieig(a2,b2,MNULL); /* printf("# a =\n"); out_vec(a); */ /* printf("# a2 =\n"); out_vec(a2); */ for ( i = 0; i < a->dim; i++ ) { det_mant1 = product2(a,i,&det_expt1); det_mant2 = product(a2,(double)a->ve[i],&det_expt2); /* printf("# det_mant1=%g, det_expt1=%d\n", det_mant1,det_expt1); */ /* printf("# det_mant2=%g, det_expt2=%d\n", det_mant2,det_expt2); */ if ( det_mant1 == 0.0 ) { /* multiple e-val of T */ err_est->ve[i] = 0.0; continue; } else if ( det_mant2 == 0.0 ) { err_est->ve[i] = HUGE_VAL; continue; } if ( (det_expt1 + det_expt2) % 2 ) /* if odd... */ det_mant = sqrt(2.0*fabs(det_mant1*det_mant2)); else /* if even... */ det_mant = sqrt(fabs(det_mant1*det_mant2)); det_expt = (det_expt1+det_expt2)/2; err_est->ve[i] = fabs(beta* ldexp(pb_mant/det_mant,pb_expt-det_expt)); } } #ifdef THREADSAFE V_FREE(b); V_FREE(a2); V_FREE(b2); #endif return a; } /* sp_lanczos -- version that uses sparse matrix data structure */ void sp_lanczos(A,m,x0,a,b,beta2,Q) SPMAT *A; int m; VEC *x0, *a, *b; Real *beta2; MAT *Q; { lanczos(sp_mv_mlt,A,m,x0,a,b,beta2,Q); } /* sp_lanczos2 -- version of lanczos2() that uses sparse matrix data structure */ VEC *sp_lanczos2(A,m,x0,evals,err_est) SPMAT *A; int m; VEC *x0; /* initial vector */ VEC *evals; /* eigenvalue vector */ VEC *err_est; /* error estimates of eigenvalues */ { return lanczos2(sp_mv_mlt,A,m,x0,evals,err_est); } gtk-wave-cleaner-0.22-04/meschach/ls.dat0000777000175000017500000000061513120075106021071 0ustar00alisteralister00000000000000# No. of a problem 2 # A = Matrix: 5 by 3 row 0: 3 -1 2 row 1: 2 -1 1.2 row 2: 2.5 1 -1.5 row 3: 3 1 1 row 4: -1 1 -2.2 # b = Vector: dim: 5 5 3 2 4 6 gtk-wave-cleaner-0.22-04/meschach/lufactor.c0000777000175000017500000001641213120075106021746 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Matrix factorisation routines to work with the other matrix files. */ /* LUfactor.c 1.5 11/25/87 */ static char rcsid[] = "$Id: lufactor.c,v 1.10 1995/05/16 17:26:44 des Exp $"; #include #include #include "matrix.h" #include "matrix2.h" /* Most matrix factorisation routines are in-situ unless otherwise specified */ /* LUfactor -- gaussian elimination with scaled partial pivoting -- Note: returns LU matrix which is A */ #ifndef ANSI_C MAT *LUfactor(A,pivot) MAT *A; PERM *pivot; #else MAT *LUfactor(MAT *A, PERM *pivot) #endif { unsigned int i, j, m, n; int i_max, k, k_max; Real **A_v, *A_piv, *A_row; Real max1, temp, tiny; STATIC VEC *scale = VNULL; if ( A==(MAT *)NULL || pivot==(PERM *)NULL ) error(E_NULL,"LUfactor"); if ( pivot->size != A->m ) error(E_SIZES,"LUfactor"); m = A->m; n = A->n; scale = v_resize(scale,A->m); MEM_STAT_REG(scale,TYPE_VEC); A_v = A->me; tiny = 10.0/HUGE_VAL; /* initialise pivot with identity permutation */ for ( i=0; ipe[i] = i; /* set scale parameters */ for ( i=0; ive[i] = max1; } /* main loop */ k_max = min(m,n)-1; for ( k=0; kve[i]) >= tiny*fabs(A_v[i][k]) ) { temp = fabs(A_v[i][k])/scale->ve[i]; if ( temp > max1 ) { max1 = temp; i_max = i; } } /* if no pivot then ignore column k... */ if ( i_max == -1 ) { /* set pivot entry A[k][k] exactly to zero, rather than just "small" */ A_v[k][k] = 0.0; continue; } /* do we pivot ? */ if ( i_max != k ) /* yes we do... */ { px_transp(pivot,i_max,k); for ( j=0; jm != LU->n || LU->n != b->dim ) error(E_SIZES,"LUsolve"); x = v_resize(x,b->dim); px_vec(pivot,b,x); /* x := P.b */ Lsolve(LU,x,x,1.0); /* implicit diagonal = 1 */ Usolve(LU,x,x,0.0); /* explicit diagonal */ return (x); } /* LUTsolve -- given an LU factorisation in A, solve A^T.x=b */ #ifndef ANSI_C VEC *LUTsolve(LU,pivot,b,x) MAT *LU; PERM *pivot; VEC *b,*x; #else VEC *LUTsolve(const MAT *LU, PERM *pivot, const VEC *b, VEC *x) #endif { if ( ! LU || ! b || ! pivot ) error(E_NULL,"LUTsolve"); if ( LU->m != LU->n || LU->n != b->dim ) error(E_SIZES,"LUTsolve"); x = v_copy(b,x); UTsolve(LU,x,x,0.0); /* explicit diagonal */ LTsolve(LU,x,x,1.0); /* implicit diagonal = 1 */ pxinv_vec(pivot,x,x); /* x := P^T.tmp */ return (x); } /* m_inverse -- returns inverse of A, provided A is not too rank deficient -- uses LU factorisation */ #ifndef ANSI_C MAT *m_inverse(A,out) MAT *A, *out; #else MAT *m_inverse(const MAT *A, MAT *out) #endif { int i; STATIC VEC *tmp = VNULL, *tmp2 = VNULL; STATIC MAT *A_cp = MNULL; STATIC PERM *pivot = PNULL; if ( ! A ) error(E_NULL,"m_inverse"); if ( A->m != A->n ) error(E_SQUARE,"m_inverse"); if ( ! out || out->m < A->m || out->n < A->n ) out = m_resize(out,A->m,A->n); A_cp = m_resize(A_cp,A->m,A->n); A_cp = m_copy(A,A_cp); tmp = v_resize(tmp,A->m); tmp2 = v_resize(tmp2,A->m); pivot = px_resize(pivot,A->m); MEM_STAT_REG(A_cp,TYPE_MAT); MEM_STAT_REG(tmp, TYPE_VEC); MEM_STAT_REG(tmp2,TYPE_VEC); MEM_STAT_REG(pivot,TYPE_PERM); tracecatch(LUfactor(A_cp,pivot),"m_inverse"); for ( i = 0; i < A->n; i++ ) { v_zero(tmp); tmp->ve[i] = 1.0; tracecatch(LUsolve(A_cp,pivot,tmp,tmp2),"m_inverse"); set_col(out,i,tmp2); } #ifdef THREADSAFE V_FREE(tmp); V_FREE(tmp2); M_FREE(A_cp); PX_FREE(pivot); #endif return out; } /* LUcondest -- returns an estimate of the condition number of LU given the LU factorisation in compact form */ #ifndef ANSI_C double LUcondest(LU,pivot) MAT *LU; PERM *pivot; #else double LUcondest(const MAT *LU, PERM *pivot) #endif { STATIC VEC *y = VNULL, *z = VNULL; Real cond_est, L_norm, U_norm, sum, tiny; int i, j, n; if ( ! LU || ! pivot ) error(E_NULL,"LUcondest"); if ( LU->m != LU->n ) error(E_SQUARE,"LUcondest"); if ( LU->n != pivot->size ) error(E_SIZES,"LUcondest"); tiny = 10.0/HUGE_VAL; n = LU->n; y = v_resize(y,n); z = v_resize(z,n); MEM_STAT_REG(y,TYPE_VEC); MEM_STAT_REG(z,TYPE_VEC); for ( i = 0; i < n; i++ ) { sum = 0.0; for ( j = 0; j < i; j++ ) sum -= LU->me[j][i]*y->ve[j]; sum -= (sum < 0.0) ? 1.0 : -1.0; if ( fabs(LU->me[i][i]) <= tiny*fabs(sum) ) return HUGE_VAL; y->ve[i] = sum / LU->me[i][i]; } catch(E_SING, LTsolve(LU,y,y,1.0); LUsolve(LU,pivot,y,z); , return HUGE_VAL); /* now estimate norm of A (even though it is not directly available) */ /* actually computes ||L||_inf.||U||_inf */ U_norm = 0.0; for ( i = 0; i < n; i++ ) { sum = 0.0; for ( j = i; j < n; j++ ) sum += fabs(LU->me[i][j]); if ( sum > U_norm ) U_norm = sum; } L_norm = 0.0; for ( i = 0; i < n; i++ ) { sum = 1.0; for ( j = 0; j < i; j++ ) sum += fabs(LU->me[i][j]); if ( sum > L_norm ) L_norm = sum; } tracecatch(cond_est = U_norm*L_norm*v_norm_inf(z)/v_norm_inf(y), "LUcondest"); #ifdef THREADSAFE V_FREE(y); V_FREE(z); #endif return cond_est; } gtk-wave-cleaner-0.22-04/meschach/machine.c0000777000175000017500000001013013120075106021522 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Stewart & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains basic routines which are used by the functions in meschach.a etc. These are the routines that should be modified in order to take full advantage of specialised architectures (pipelining, vector processors etc). */ static char *rcsid = "$Id: machine.c,v 1.4 1994/01/13 05:28:56 des Exp $"; #include "machine.h" /* __ip__ -- inner product */ #ifndef ANSI_C double __ip__(dp1,dp2,len) register Real *dp1, *dp2; int len; #else double __ip__(const Real *dp1, const Real *dp2, int len) #endif { #ifdef VUNROLL register int len4; register Real sum1, sum2, sum3; #endif register int i; register Real sum; sum = 0.0; #ifdef VUNROLL sum1 = sum2 = sum3 = 0.0; len4 = len / 4; len = len % 4; for ( i = 0; i < len4; i++ ) { sum += dp1[4*i]*dp2[4*i]; sum1 += dp1[4*i+1]*dp2[4*i+1]; sum2 += dp1[4*i+2]*dp2[4*i+2]; sum3 += dp1[4*i+3]*dp2[4*i+3]; } sum += sum1 + sum2 + sum3; dp1 += 4*len4; dp2 += 4*len4; #endif for ( i = 0; i < len; i++ ) sum += dp1[i]*dp2[i]; return sum; } /* __mltadd__ -- scalar multiply and add c.f. v_mltadd() */ #ifndef ANSI_C void __mltadd__(dp1,dp2,s,len) register Real *dp1, *dp2; register double s; register int len; #else void __mltadd__(Real *dp1, const Real *dp2, double s, int len) #endif { register int i; #ifdef VUNROLL register int len4; len4 = len / 4; len = len % 4; for ( i = 0; i < len4; i++ ) { dp1[4*i] += s*dp2[4*i]; dp1[4*i+1] += s*dp2[4*i+1]; dp1[4*i+2] += s*dp2[4*i+2]; dp1[4*i+3] += s*dp2[4*i+3]; } dp1 += 4*len4; dp2 += 4*len4; #endif for ( i = 0; i < len; i++ ) dp1[i] += s*dp2[i]; } /* __smlt__ scalar multiply array c.f. sv_mlt() */ #ifndef ANSI_C void __smlt__(dp,s,out,len) register Real *dp, *out; register double s; register int len; #else void __smlt__(const Real *dp, double s, Real *out, int len) #endif { register int i; for ( i = 0; i < len; i++ ) out[i] = s*dp[i]; } /* __add__ -- add arrays c.f. v_add() */ #ifndef ANSI_C void __add__(dp1,dp2,out,len) register Real *dp1, *dp2, *out; register int len; #else void __add__(const Real *dp1, const Real *dp2, Real *out, int len) #endif { register int i; for ( i = 0; i < len; i++ ) out[i] = dp1[i] + dp2[i]; } /* __sub__ -- subtract arrays c.f. v_sub() */ #ifndef ANSI_C void __sub__(dp1,dp2,out,len) register Real *dp1, *dp2, *out; register int len; #else void __sub__(const Real *dp1, const Real *dp2, Real *out, int len) #endif { register int i; for ( i = 0; i < len; i++ ) out[i] = dp1[i] - dp2[i]; } /* __zero__ -- zeros an array of floating point numbers */ #ifndef ANSI_C void __zero__(dp,len) register Real *dp; register int len; #else void __zero__(Real *dp, int len) #endif { #ifdef CHAR0ISDBL0 /* if a floating point zero is equivalent to a string of nulls */ MEM_ZERO((char *)dp,len*sizeof(Real)); #else /* else, need to zero the array entry by entry */ int i; for ( i = 0; i < len; i++ ) dp[i] = 0.0; #endif } gtk-wave-cleaner-0.22-04/meschach/machine.h.in0000777000175000017500000001060513120075106022143 0ustar00alisteralister00000000000000/* Any machine specific stuff goes here */ /* Add details necessary for your own installation here! */ /* RCS id: $Id: machine.h.in,v 1.3 1995/03/27 15:36:21 des Exp $ */ /* This is for use with "configure" -- if you are not using configure then use machine.van for the "vanilla" version of machine.h */ /* Note special macros: ANSI_C (ANSI C syntax) SEGMENTED (segmented memory machine e.g. MS-DOS) MALLOCDECL (declared if malloc() etc have been declared) */ #ifndef _MACHINE_H #define _MACHINE_H 1 #undef const #undef MALLOCDECL #undef NOT_SEGMENTED #undef HAVE_MEMORY_H #undef HAVE_COMPLEX_H #undef HAVE_MALLOC_H #undef STDC_HEADERS #undef HAVE_BCOPY #undef HAVE_BZERO #undef CHAR0ISDBL0 #undef WORDS_BIGENDIAN #undef U_INT_DEF #undef VARARGS #undef HAVE_PROTOTYPES #undef HAVE_PROTOTYPES_IN_STRUCT /* for inclusion into C++ files */ #ifdef __cplusplus #define ANSI_C 1 #ifndef HAVE_PROTOTYPES #define HAVE_PROTOTYPES 1 #endif #ifndef HAVE_PROTOTYPES_IN_STRUCT #define HAVE_PROTOTYPES_IN_STRUCT 1 #endif #endif /* __cplusplus */ /* example usage: VEC *PROTO(v_get,(int dim)); */ #ifdef HAVE_PROTOTYPES #define PROTO(name,args) name args #else #define PROTO(name,args) name() #endif /* HAVE_PROTOTYPES */ #ifdef HAVE_PROTOTYPES_IN_STRUCT /* PROTO_() is to be used instead of PROTO() in struct's and typedef's */ #define PROTO_(name,args) name args #else #define PROTO_(name,args) name() #endif /* HAVE_PROTOTYPES_IN_STRUCT */ /* for basic or larger versions */ #undef COMPLEX #undef SPARSE /* for loop unrolling */ #undef VUNROLL #undef MUNROLL /* for segmented memory */ #ifndef NOT_SEGMENTED #define SEGMENTED #endif /* if the system has malloc.h */ #ifdef HAVE_MALLOC_H #define MALLOCDECL 1 #include #endif /* any compiler should have this header */ /* if not, change it */ #include /* Check for ANSI C memmove and memset */ #ifdef STDC_HEADERS /* standard copy & zero functions */ #define MEM_COPY(from,to,size) memmove((to),(from),(size)) #define MEM_ZERO(where,size) memset((where),'\0',(size)) #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* standard headers */ #ifdef ANSI_C #include #include #include #include #endif /* if have bcopy & bzero and no alternatives yet known, use them */ #ifdef HAVE_BCOPY #ifndef MEM_COPY /* nonstandard copy function */ #define MEM_COPY(from,to,size) bcopy((char *)(from),(char *)(to),(int)(size)) #endif #endif #ifdef HAVE_BZERO #ifndef MEM_ZERO /* nonstandard zero function */ #define MEM_ZERO(where,size) bzero((char *)(where),(int)(size)) #endif #endif /* if the system has complex.h */ #ifdef HAVE_COMPLEX_H #include #endif /* If prototypes are available & ANSI_C not yet defined, then define it, but don't include any header files as the proper ANSI C headers aren't here */ #ifdef HAVE_PROTOTYPES #ifndef ANSI_C #define ANSI_C 1 #endif #endif /* floating point precision */ /* you can choose single, double or long double (if available) precision */ #define FLOAT 1 #define DOUBLE 2 #define LONG_DOUBLE 3 #undef REAL_FLT #undef REAL_DBL /* if nothing is defined, choose double precision */ #ifndef REAL_DBL #ifndef REAL_FLT #define REAL_DBL 1 #endif #endif /* single precision */ #ifdef REAL_FLT #define Real float #define LongReal float #define REAL FLOAT #define LONGREAL FLOAT #endif /* double precision */ #ifdef REAL_DBL #define Real double #define LongReal double #define REAL DOUBLE #define LONGREAL DOUBLE #endif /* machine epsilon or unit roundoff error */ /* This is correct on most IEEE Real precision systems */ #ifdef DBL_EPSILON #if REAL == DOUBLE #define MACHEPS DBL_EPSILON #elif REAL == FLOAT #define MACHEPS FLT_EPSILON #elif REAL == LONGDOUBLE #define MACHEPS LDBL_EPSILON #endif #endif #undef F_MACHEPS #undef D_MACHEPS #ifndef MACHEPS #if REAL == DOUBLE #define MACHEPS D_MACHEPS #elif REAL == FLOAT #define MACHEPS F_MACHEPS #elif REAL == LONGDOUBLE #define MACHEPS D_MACHEPS #endif #endif #undef M_MACHEPS /******************** #ifdef DBL_EPSILON #define MACHEPS DBL_EPSILON #endif #ifdef M_MACHEPS #ifndef MACHEPS #define MACHEPS M_MACHEPS #endif #endif ********************/ #undef M_MAX_INT #ifdef M_MAX_INT #ifndef MAX_RAND #define MAX_RAND ((double)(M_MAX_INT)) #endif #endif /* for non-ANSI systems */ #ifndef HUGE_VAL #define HUGE_VAL HUGE #else #ifndef HUGE #define HUGE HUGE_VAL #endif #endif #ifdef ANSI_C extern int isatty(int); #endif #endif gtk-wave-cleaner-0.22-04/meschach/makefile.in0000777000175000017500000001342513120075106022071 0ustar00alisteralister00000000000000# # Makefile for Meschach via autoconf # # Copyright (C) David Stewart & Zbigniew Leyk 1993 # # $Id: makefile.in,v 1.4 1994/03/14 01:24:06 des Exp $ # srcdir = @srcdir@ VPATH = @srcdir@ CC = @CC@ DEFS = @DEFS@ LIBS = @LIBS@ RANLIB = @RANLIB@ CFLAGS = $(OPT_CFLAGS) .c.o: $(CC) -c $(CFLAGS) $(DEFS) $< SHELL = /bin/sh MES_PAK = mesch12b TAR = tar SHAR = stree -u ZIP = zip -r -l FLIST = FILELIST ############################### LIST1 = copy.o err.o matrixio.o memory.o vecop.o matop.o pxop.o \ submat.o init.o otherio.o machine.o matlab.o ivecop.o version.o \ meminfo.o memstat.o LIST2 = lufactor.o bkpfacto.o chfactor.o qrfactor.o solve.o hsehldr.o \ givens.o update.o norm.o hessen.o symmeig.o schur.o svd.o fft.o \ mfunc.o bdfactor.o LIST3 = sparse.o sprow.o sparseio.o spchfctr.o splufctr.o \ spbkp.o spswap.o iter0.o itersym.o iternsym.o ZLIST1 = zmachine.o zcopy.o zmatio.o zmemory.o zvecop.o zmatop.o znorm.o \ zfunc.o ZLIST2 = zlufctr.o zsolve.o zmatlab.o zhsehldr.o zqrfctr.o \ zgivens.o zhessen.o zschur.o # they are no longer supported # if you use them add oldpart to all and sparse OLDLIST = conjgrad.o lanczos.o arnoldi.o ALL_LISTS = $(LIST1) $(LIST2) $(LIST3) $(ZLIST1) $(ZLIST2) $(OLDLIST) HBASE = err.h meminfo.h machine.h matrix.h HLIST = $(HBASE) iter.h matlab.h matrix2.h oldnames.h sparse.h \ sparse2.h zmatrix.h zmatrix2.h TORTURE = torture.o sptort.o ztorture.o memtort.o itertort.o \ mfuntort.o iotort.o OTHERS = dmacheps.c extras.c fmacheps.c maxint.c makefile.in \ README configure configure.in machine.h.in copyright \ tutorial.c tutadv.c rk4.dat ls.dat makefile $(FLIST) # Different configurations # the dependencies **between** the parts are for dmake all: @PROGS@ part1 part2 part3 zpart1 zpart2 part2: part1 part3: part2 basic: part1 part2 sparse: part1 part2 part3 zpart2: zpart1 complex: part1 part2 zpart1 zpart2 $(LIST1): $(HBASE) part1: $(LIST1) ar ru meschach.a $(LIST1) $(RANLIB) meschach.a $(LIST2): $(HBASE) matrix2.h part2: $(LIST2) ar ru meschach.a $(LIST2) $(RANLIB) meschach.a $(LIST3): $(HBASE) sparse.h sparse2.h part3: $(LIST3) ar ru meschach.a $(LIST3) $(RANLIB) meschach.a $(ZLIST1): $(HBASDE) zmatrix.h zpart1: $(ZLIST1) ar ru meschach.a $(ZLIST1) $(RANLIB) meschach.a $(ZLIST2): $(HBASE) zmatrix.h zmatrix2.h zpart2: $(ZLIST2) ar ru meschach.a $(ZLIST2) $(RANLIB) meschach.a $(OLDLIST): $(HBASE) sparse.h sparse2.h oldpart: $(OLDLIST) ar ru meschach.a $(OLDLIST) $(RANLIB) meschach.a ####################################### tar: - /bin/rm -f $(MES_PAK).tar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(TAR) cvf $(MES_PAK).tar \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC # use this only for PC machines msdos-zip: - /bin/rm -f $(MES_PAK).zip chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(ZIP) $(MES_PAK).zip \ `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC fullshar: - /bin/rm -f $(MES_PAK).shar; chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ MACHINES DOC > $(MES_PAK).shar shar: - /bin/rm -f meschach1.shar meschach2.shar meschach3.shar \ meschach4.shar oldmeschach.shar meschach0.shar chmod 644 `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ $(OTHERS) $(HLIST) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` chmod 755 configure $(MAKE) list $(SHAR) `echo $(LIST1) | sed -e 's/\.o/.c/g'` > meschach1.shar $(SHAR) `echo $(LIST2) | sed -e 's/\.o/.c/g'` > meschach2.shar $(SHAR) `echo $(LIST3) | sed -e 's/\.o/.c/g'` > meschach3.shar $(SHAR) `echo $(ZLIST1) | sed -e 's/\.o/.c/g'` \ `echo $(ZLIST2) | sed -e 's/\.o/.c/g'` > meschach4.shar $(SHAR) `echo $(OLDLIST) | sed -e 's/\.o/.c/g'` > oldmeschach.shar $(SHAR) $(OTHERS) `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) DOC MACHINES > meschach0.shar list: /bin/rm -f $(FLIST) ls -lR `echo $(ALL_LISTS) | sed -e 's/\.o/.c/g'` \ `echo $(TORTURE) | sed -e 's/\.o/.c/g'` \ $(HLIST) $(OTHERS) MACHINES DOC \ |awk '/^$$/ {print};/^[-d]/ {printf("%s %s %10d %s %s %s %s\n", \ $$1,$$2,$$5,$$6,$$7,$$8,$$9)}; /^[^-d]/ {print}' \ > $(FLIST) clean: /bin/rm -f *.o core asx5213a.mat iotort.dat cleanup: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a realclean: /bin/rm -f *.o core asx5213a.mat iotort.dat *.a /bin/rm -f torture sptort ztorture memtort itertort mfuntort iotort /bin/rm -f makefile machine.h config.status maxint macheps alltorture: torture sptort ztorture memtort itertort mfuntort iotort torture:torture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o torture torture.o \ meschach.a $(LIBS) sptort:sptort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o sptort sptort.o \ meschach.a $(LIBS) memtort: memtort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o memtort memtort.o \ meschach.a $(LIBS) ztorture:ztorture.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o ztorture ztorture.o \ meschach.a $(LIBS) itertort: itertort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o itertort itertort.o \ meschach.a $(LIBS) iotort: iotort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o iotort iotort.o \ meschach.a $(LIBS) mfuntort: mfuntort.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o mfuntort mfuntort.o \ meschach.a $(LIBS) tstmove: tstmove.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstmove tstmove.o \ meschach.a $(LIBS) tstpxvec: tstpxvec.o meschach.a $(CC) $(CFLAGS) $(DEFS) -o tstpxvec tstpxvec.o \ meschach.a $(LIBS) gtk-wave-cleaner-0.22-04/meschach/matlab.c0000777000175000017500000001267313120075106021374 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains routines for import/exporting data to/from MATLAB. The main routines are: MAT *m_save(FILE *fp,MAT *A,char *name) VEC *v_save(FILE *fp,VEC *x,char *name) MAT *m_load(FILE *fp,char **name) */ #include #include "matrix.h" #include "matlab.h" static char rcsid[] = "$Id: matlab.c,v 1.8 1995/02/14 20:12:36 des Exp $"; /* m_save -- save matrix in ".mat" file for MATLAB -- returns matrix to be saved */ #ifndef ANSI_C MAT *m_save(fp,A,name) FILE *fp; MAT *A; char *name; #else MAT *m_save(FILE *fp, MAT *A, const char *name) #endif { int i, j; matlab mat; if ( ! A ) error(E_NULL,"m_save"); mat.type = 1000*MACH_ID + 100*ORDER + 10*PRECISION + 0; mat.m = A->m; mat.n = A->n; mat.imag = FALSE; mat.namlen = (name == (char *)NULL) ? 1 : strlen(name)+1; /* write header */ fwrite(&mat,sizeof(matlab),1,fp); /* write name */ if ( name == (char *)NULL ) fwrite("",sizeof(char),1,fp); else fwrite(name,sizeof(char),(int)(mat.namlen),fp); /* write actual data */ #if ORDER == ROW_ORDER for ( i = 0; i < A->m; i++ ) fwrite(A->me[i],sizeof(Real),(int)(A->n),fp); #else /* column major order: ORDER == COL_ORDER */ for ( j = 0; j < A->n; j++ ) for ( i = 0; i < A->m; i++ ) fwrite(&(A->me[i][j]),sizeof(Real),1,fp); #endif return A; } /* v_save -- save vector in ".mat" file for MATLAB -- saves it as a row vector -- returns vector to be saved */ #ifndef ANSI_C VEC *v_save(fp,x,name) FILE *fp; VEC *x; char *name; #else VEC *v_save(FILE *fp, VEC *x, const char *name) #endif { matlab mat; if ( ! x ) error(E_NULL,"v_save"); mat.type = 1000*MACH_ID + 100*ORDER + 10*PRECISION + 0; mat.m = x->dim; mat.n = 1; mat.imag = FALSE; mat.namlen = (name == (char *)NULL) ? 1 : strlen(name)+1; /* write header */ fwrite(&mat,sizeof(matlab),1,fp); /* write name */ if ( name == (char *)NULL ) fwrite("",sizeof(char),1,fp); else fwrite(name,sizeof(char),(int)(mat.namlen),fp); /* write actual data */ fwrite(x->ve,sizeof(Real),(int)(x->dim),fp); return x; } /* d_save -- save double in ".mat" file for MATLAB -- saves it as a row vector -- returns vector to be saved */ #ifndef ANSI_C double d_save(fp,x,name) FILE *fp; double x; char *name; #else double d_save(FILE *fp, double x, const char *name) #endif { matlab mat; Real x1 = x; mat.type = 1000*MACH_ID + 100*ORDER + 10*PRECISION + 0; mat.m = 1; mat.n = 1; mat.imag = FALSE; mat.namlen = (name == (char *)NULL) ? 1 : strlen(name)+1; /* write header */ fwrite(&mat,sizeof(matlab),1,fp); /* write name */ if ( name == (char *)NULL ) fwrite("",sizeof(char),1,fp); else fwrite(name,sizeof(char),(int)(mat.namlen),fp); /* write actual data */ fwrite(&x1,sizeof(Real),1,fp); return x; } /* m_load -- loads in a ".mat" file variable as produced by MATLAB -- matrix returned; imaginary parts ignored */ #ifndef ANSI_C MAT *m_load(fp,name) FILE *fp; char **name; #else MAT *m_load(FILE *fp, char **name) #endif { MAT *A; int i; int m_flag, o_flag, p_flag, t_flag; float f_temp; Real d_temp; matlab mat; if ( fread(&mat,sizeof(matlab),1,fp) != 1 ) error(E_FORMAT,"m_load"); if ( mat.type >= 10000 ) /* don't load a sparse matrix! */ error(E_FORMAT,"m_load"); m_flag = (mat.type/1000) % 10; o_flag = (mat.type/100) % 10; p_flag = (mat.type/10) % 10; t_flag = (mat.type) % 10; if ( m_flag != MACH_ID ) error(E_FORMAT,"m_load"); if ( t_flag != 0 ) error(E_FORMAT,"m_load"); if ( p_flag != DOUBLE_PREC && p_flag != SINGLE_PREC ) error(E_FORMAT,"m_load"); *name = (char *)malloc((unsigned)(mat.namlen)+1); if ( fread(*name,sizeof(char),(unsigned)(mat.namlen),fp) == 0 ) error(E_FORMAT,"m_load"); A = m_get((unsigned)(mat.m),(unsigned)(mat.n)); for ( i = 0; i < A->m*A->n; i++ ) { if ( p_flag == DOUBLE_PREC ) fread(&d_temp,sizeof(double),1,fp); else { fread(&f_temp,sizeof(float),1,fp); d_temp = f_temp; } if ( o_flag == ROW_ORDER ) A->me[i / A->n][i % A->n] = d_temp; else if ( o_flag == COL_ORDER ) A->me[i % A->m][i / A->m] = d_temp; else error(E_FORMAT,"m_load"); } if ( mat.imag ) /* skip imaginary part */ for ( i = 0; i < A->m*A->n; i++ ) { if ( p_flag == DOUBLE_PREC ) fread(&d_temp,sizeof(double),1,fp); else fread(&f_temp,sizeof(float),1,fp); } return A; } gtk-wave-cleaner-0.22-04/meschach/matlab.h0000777000175000017500000000572613120075106021402 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* matlab.h -- Header file for matlab.c, spmatlab.c and zmatlab.c for save/load formats */ #ifndef MATLAB_DEF #define MATLAB_DEF /* structure required by MATLAB */ typedef struct { long type; /* matrix type */ long m; /* # rows */ long n; /* # cols */ long imag; /* is complex? */ long namlen; /* length of variable name */ } matlab; /* macros for matrix storage type */ #define INTEL 0 /* for 80x87 format */ #define PC INTEL #define MOTOROLA 1 /* 6888x format */ #define SUN MOTOROLA #define APOLLO MOTOROLA #define MAC MOTOROLA #define VAX_D 2 #define VAX_G 3 #define COL_ORDER 0 #define ROW_ORDER 1 #define DOUBLE_PREC 0 /* double precision */ #define SINGLE_PREC 1 /* single precision */ #define INT_32 2 /* 32 bit integers (signed) */ #define INT_16 3 /* 16 bit integers (signed) */ #define INT_16u 4 /* 16 bit integers (unsigned) */ /* end of macros for matrix storage type */ #ifndef MACH_ID #define MACH_ID MOTOROLA #endif #define ORDER COL_ORDER #if REAL == DOUBLE #define PRECISION DOUBLE_PREC #elif REAL == FLOAT #define PRECISION SINGLE_PREC #endif /* prototypes */ #ifdef ANSI_C MAT *m_save(FILE *,MAT *,const char *); MAT *m_load(FILE *,char **); VEC *v_save(FILE *,VEC *,const char *); double d_save(FILE *,double,const char *); #else extern MAT *m_save(), *m_load(); extern VEC *v_save(); extern double d_save(); #endif /* complex variant */ #ifdef COMPLEX #include "zmatrix.h" #ifdef ANSI_C extern ZMAT *zm_save(FILE *fp,ZMAT *A,char *name); extern ZVEC *zv_save(FILE *fp,ZVEC *x,char *name); extern complex z_save(FILE *fp,complex z,char *name); extern ZMAT *zm_load(FILE *fp,char **name); #else extern ZMAT *zm_save(); extern ZVEC *zv_save(); extern complex z_save(); extern ZMAT *zm_load(); #endif #endif #endif gtk-wave-cleaner-0.22-04/meschach/matop.c0000777000175000017500000003203013120075106021241 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* matop.c 1.3 11/25/87 */ #include #include "matrix.h" static char rcsid[] = "$Id: matop.c,v 1.4 1995/03/27 15:43:57 des Exp $"; /* m_add -- matrix addition -- may be in-situ */ #ifndef ANSI_C MAT *m_add(mat1,mat2,out) MAT *mat1,*mat2,*out; #else MAT *m_add(const MAT *mat1, const MAT *mat2, MAT *out) #endif { unsigned int m,n,i; if ( mat1==(MAT *)NULL || mat2==(MAT *)NULL ) error(E_NULL,"m_add"); if ( mat1->m != mat2->m || mat1->n != mat2->n ) error(E_SIZES,"m_add"); if ( out==(MAT *)NULL || out->m != mat1->m || out->n != mat1->n ) out = m_resize(out,mat1->m,mat1->n); m = mat1->m; n = mat1->n; for ( i=0; ime[i],mat2->me[i],out->me[i],(int)n); /************************************************** for ( j=0; jme[i][j] = mat1->me[i][j]+mat2->me[i][j]; **************************************************/ } return (out); } /* m_sub -- matrix subtraction -- may be in-situ */ #ifndef ANSI_C MAT *m_sub(mat1,mat2,out) MAT *mat1,*mat2,*out; #else MAT *m_sub(const MAT *mat1, const MAT *mat2, MAT *out) #endif { unsigned int m,n,i; if ( mat1==(MAT *)NULL || mat2==(MAT *)NULL ) error(E_NULL,"m_sub"); if ( mat1->m != mat2->m || mat1->n != mat2->n ) error(E_SIZES,"m_sub"); if ( out==(MAT *)NULL || out->m != mat1->m || out->n != mat1->n ) out = m_resize(out,mat1->m,mat1->n); m = mat1->m; n = mat1->n; for ( i=0; ime[i],mat2->me[i],out->me[i],(int)n); /************************************************** for ( j=0; jme[i][j] = mat1->me[i][j]-mat2->me[i][j]; **************************************************/ } return (out); } /* m_mlt -- matrix-matrix multiplication */ #ifndef ANSI_C MAT *m_mlt(A,B,OUT) MAT *A,*B,*OUT; #else MAT *m_mlt(const MAT *A, const MAT *B, MAT *OUT) #endif { unsigned int i, /* j, */ k, m, n, p; Real **A_v, **B_v /*, *B_row, *OUT_row, sum, tmp */; if ( A==(MAT *)NULL || B==(MAT *)NULL ) error(E_NULL,"m_mlt"); if ( A->n != B->m ) error(E_SIZES,"m_mlt"); if ( A == OUT || B == OUT ) error(E_INSITU,"m_mlt"); m = A->m; n = A->n; p = B->n; A_v = A->me; B_v = B->me; if ( OUT==(MAT *)NULL || OUT->m != A->m || OUT->n != B->n ) OUT = m_resize(OUT,A->m,B->n); /**************************************************************** for ( i=0; ime[i][j] = sum; } ****************************************************************/ m_zero(OUT); for ( i=0; ime[i],B_v[k],A_v[i][k],(int)p); /************************************************** B_row = B_v[k]; OUT_row = OUT->me[i]; for ( j=0; jn != B->n ) error(E_SIZES,"mmtr_mlt"); if ( ! OUT || OUT->m != A->m || OUT->n != B->m ) OUT = m_resize(OUT,A->m,B->m); limit = A->n; for ( i = 0; i < A->m; i++ ) for ( j = 0; j < B->m; j++ ) { OUT->me[i][j] = __ip__(A->me[i],B->me[j],(int)limit); /************************************************** sum = 0.0; A_row = A->me[i]; B_row = B->me[j]; for ( k = 0; k < limit; k++ ) sum += (*A_row++)*(*B_row++); OUT->me[i][j] = sum; **************************************************/ } return OUT; } /* mtrm_mlt -- matrix transposed-matrix multiplication -- A^T.B is returned, result stored in OUT */ #ifndef ANSI_C MAT *mtrm_mlt(A,B,OUT) MAT *A, *B, *OUT; #else MAT *mtrm_mlt(const MAT *A, const MAT *B, MAT *OUT) #endif { int i, k, limit; /* Real *B_row, *OUT_row, multiplier; */ if ( ! A || ! B ) error(E_NULL,"mmtr_mlt"); if ( A == OUT || B == OUT ) error(E_INSITU,"mtrm_mlt"); if ( A->m != B->m ) error(E_SIZES,"mmtr_mlt"); if ( ! OUT || OUT->m != A->n || OUT->n != B->n ) OUT = m_resize(OUT,A->n,B->n); limit = B->n; m_zero(OUT); for ( k = 0; k < A->m; k++ ) for ( i = 0; i < A->n; i++ ) { if ( A->me[k][i] != 0.0 ) __mltadd__(OUT->me[i],B->me[k],A->me[k][i],(int)limit); /************************************************** multiplier = A->me[k][i]; OUT_row = OUT->me[i]; B_row = B->me[k]; for ( j = 0; j < limit; j++ ) *(OUT_row++) += multiplier*(*B_row++); **************************************************/ } return OUT; } /* mv_mlt -- matrix-vector multiplication -- Note: b is treated as a column vector */ #ifndef ANSI_C VEC *mv_mlt(A,b,out) MAT *A; VEC *b,*out; #else VEC *mv_mlt(const MAT *A, const VEC *b, VEC *out) #endif { unsigned int i, m, n; Real **A_v, *b_v /*, *A_row */; /* register Real sum; */ if ( A==(MAT *)NULL || b==(VEC *)NULL ) error(E_NULL,"mv_mlt"); if ( A->n != b->dim ) error(E_SIZES,"mv_mlt"); if ( b == out ) error(E_INSITU,"mv_mlt"); if ( out == (VEC *)NULL || out->dim != A->m ) out = v_resize(out,A->m); m = A->m; n = A->n; A_v = A->me; b_v = b->ve; for ( i=0; ive[i] = __ip__(A_v[i],b_v,(int)n); /************************************************** A_row = A_v[i]; b_v = b->ve; for ( j=0; jve[i] = sum; **************************************************/ } return out; } /* sm_mlt -- scalar-matrix multiply -- may be in-situ */ #ifndef ANSI_C MAT *sm_mlt(scalar,matrix,out) double scalar; MAT *matrix,*out; #else MAT *sm_mlt(double scalar, const MAT *matrix, MAT *out) #endif { unsigned int m,n,i; if ( matrix==(MAT *)NULL ) error(E_NULL,"sm_mlt"); if ( out==(MAT *)NULL || out->m != matrix->m || out->n != matrix->n ) out = m_resize(out,matrix->m,matrix->n); m = matrix->m; n = matrix->n; for ( i=0; ime[i],(double)scalar,out->me[i],(int)n); /************************************************** for ( j=0; jme[i][j] = scalar*matrix->me[i][j]; **************************************************/ return (out); } /* vm_mlt -- vector-matrix multiplication -- Note: b is treated as a row vector */ #ifndef ANSI_C VEC *vm_mlt(A,b,out) MAT *A; VEC *b,*out; #else VEC *vm_mlt(const MAT *A, const VEC *b, VEC *out) #endif { unsigned int j,m,n; /* Real sum,**A_v,*b_v; */ if ( A==(MAT *)NULL || b==(VEC *)NULL ) error(E_NULL,"vm_mlt"); if ( A->m != b->dim ) error(E_SIZES,"vm_mlt"); if ( b == out ) error(E_INSITU,"vm_mlt"); if ( out == (VEC *)NULL || out->dim != A->n ) out = v_resize(out,A->n); m = A->m; n = A->n; v_zero(out); for ( j = 0; j < m; j++ ) if ( b->ve[j] != 0.0 ) __mltadd__(out->ve,A->me[j],b->ve[j],(int)n); /************************************************** A_v = A->me; b_v = b->ve; for ( j=0; jve[j] = sum; } **************************************************/ return out; } /* m_transp -- transpose matrix */ #ifndef ANSI_C MAT *m_transp(in,out) MAT *in, *out; #else MAT *m_transp(const MAT *in, MAT *out) #endif { int i, j; int in_situ; Real tmp; if ( in == (MAT *)NULL ) error(E_NULL,"m_transp"); if ( in == out && in->n != in->m ) error(E_INSITU2,"m_transp"); in_situ = ( in == out ); if ( out == (MAT *)NULL || out->m != in->n || out->n != in->m ) out = m_resize(out,in->n,in->m); if ( ! in_situ ) for ( i = 0; i < in->m; i++ ) for ( j = 0; j < in->n; j++ ) out->me[j][i] = in->me[i][j]; else for ( i = 1; i < in->m; i++ ) for ( j = 0; j < i; j++ ) { tmp = in->me[i][j]; in->me[i][j] = in->me[j][i]; in->me[j][i] = tmp; } return out; } /* swap_rows -- swaps rows i and j of matrix A for cols lo through hi */ #ifndef ANSI_C MAT *swap_rows(A,i,j,lo,hi) MAT *A; int i, j, lo, hi; #else MAT *swap_rows(MAT *A, int i, int j, int lo, int hi) #endif { int k; Real **A_me, tmp; if ( ! A ) error(E_NULL,"swap_rows"); if ( i < 0 || j < 0 || i >= A->m || j >= A->m ) error(E_SIZES,"swap_rows"); lo = max(0,lo); hi = min(hi,A->n-1); A_me = A->me; for ( k = lo; k <= hi; k++ ) { tmp = A_me[k][i]; A_me[k][i] = A_me[k][j]; A_me[k][j] = tmp; } return A; } /* swap_cols -- swap columns i and j of matrix A for cols lo through hi */ #ifndef ANSI_C MAT *swap_cols(A,i,j,lo,hi) MAT *A; int i, j, lo, hi; #else MAT *swap_cols(MAT *A, int i, int j, int lo, int hi) #endif { int k; Real **A_me, tmp; if ( ! A ) error(E_NULL,"swap_cols"); if ( i < 0 || j < 0 || i >= A->n || j >= A->n ) error(E_SIZES,"swap_cols"); lo = max(0,lo); hi = min(hi,A->m-1); A_me = A->me; for ( k = lo; k <= hi; k++ ) { tmp = A_me[i][k]; A_me[i][k] = A_me[j][k]; A_me[j][k] = tmp; } return A; } /* ms_mltadd -- matrix-scalar multiply and add -- may be in situ -- returns out == A1 + s*A2 */ #ifndef ANSI_C MAT *ms_mltadd(A1,A2,s,out) MAT *A1, *A2, *out; double s; #else MAT *ms_mltadd(const MAT *A1, const MAT *A2, double s, MAT *out) #endif { /* register Real *A1_e, *A2_e, *out_e; */ /* register int j; */ int i, m, n; if ( ! A1 || ! A2 ) error(E_NULL,"ms_mltadd"); if ( A1->m != A2->m || A1->n != A2->n ) error(E_SIZES,"ms_mltadd"); if ( out != A1 && out != A2 ) out = m_resize(out,A1->m,A1->n); if ( s == 0.0 ) return m_copy(A1,out); if ( s == 1.0 ) return m_add(A1,A2,out); tracecatch(out = m_copy(A1,out),"ms_mltadd"); m = A1->m; n = A1->n; for ( i = 0; i < m; i++ ) { __mltadd__(out->me[i],A2->me[i],s,(int)n); /************************************************** A1_e = A1->me[i]; A2_e = A2->me[i]; out_e = out->me[i]; for ( j = 0; j < n; j++ ) out_e[j] = A1_e[j] + s*A2_e[j]; **************************************************/ } return out; } /* mv_mltadd -- matrix-vector multiply and add -- may not be in situ -- returns out == v1 + alpha*A*v2 */ #ifndef ANSI_C VEC *mv_mltadd(v1,v2,A,alpha,out) VEC *v1, *v2, *out; MAT *A; double alpha; #else VEC *mv_mltadd(const VEC *v1, const VEC *v2, const MAT *A, double alpha, VEC *out) #endif { /* register int j; */ int i, m, n; Real *v2_ve, *out_ve; if ( ! v1 || ! v2 || ! A ) error(E_NULL,"mv_mltadd"); if ( out == v2 ) error(E_INSITU,"mv_mltadd"); if ( v1->dim != A->m || v2->dim != A->n ) error(E_SIZES,"mv_mltadd"); tracecatch(out = v_copy(v1,out),"mv_mltadd"); v2_ve = v2->ve; out_ve = out->ve; m = A->m; n = A->n; if ( alpha == 0.0 ) return out; for ( i = 0; i < m; i++ ) { out_ve[i] += alpha*__ip__(A->me[i],v2_ve,(int)n); /************************************************** A_e = A->me[i]; sum = 0.0; for ( j = 0; j < n; j++ ) sum += A_e[j]*v2_ve[j]; out_ve[i] = v1->ve[i] + alpha*sum; **************************************************/ } return out; } /* vm_mltadd -- vector-matrix multiply and add -- may not be in situ -- returns out' == v1' + v2'*A */ #ifndef ANSI_C VEC *vm_mltadd(v1,v2,A,alpha,out) VEC *v1, *v2, *out; MAT *A; double alpha; #else VEC *vm_mltadd(const VEC *v1, const VEC *v2, const MAT *A, double alpha, VEC *out) #endif { int /* i, */ j, m, n; Real tmp, /* *A_e, */ *out_ve; if ( ! v1 || ! v2 || ! A ) error(E_NULL,"vm_mltadd"); if ( v2 == out ) error(E_INSITU,"vm_mltadd"); if ( v1->dim != A->n || A->m != v2->dim ) error(E_SIZES,"vm_mltadd"); tracecatch(out = v_copy(v1,out),"vm_mltadd"); out_ve = out->ve; m = A->m; n = A->n; for ( j = 0; j < m; j++ ) { tmp = v2->ve[j]*alpha; if ( tmp != 0.0 ) __mltadd__(out_ve,A->me[j],tmp,(int)n); /************************************************** A_e = A->me[j]; for ( i = 0; i < n; i++ ) out_ve[i] += A_e[i]*tmp; **************************************************/ } return out; } gtk-wave-cleaner-0.22-04/meschach/matrix.h0000777000175000017500000005257213120075106021447 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Type definitions for general purpose maths package */ #ifndef MATRIXH /* RCS id: $Id: matrix.h,v 1.18 1994/04/16 00:33:37 des Exp $ */ #define MATRIXH #include "machine.h" #include "err.h" #include "meminfo.h" /* unsigned integer type */ /************************************************************ #ifndef U_INT_DEF typedef unsigned int u_int; #define U_INT_DEF #endif ************************************************************/ /* vector definition */ typedef struct { unsigned int dim, max_dim; Real *ve; } VEC; /* matrix definition */ typedef struct { unsigned int m, n; unsigned int max_m, max_n, max_size; Real **me,*base; /* base is base of alloc'd mem */ } MAT; /* band matrix definition */ typedef struct { MAT *mat; /* matrix */ int lb,ub; /* lower and upper bandwidth */ } BAND; /* permutation definition */ typedef struct { unsigned int size, max_size, *pe; } PERM; /* integer vector definition */ typedef struct { unsigned int dim, max_dim; int *ive; } IVEC; #ifndef MALLOCDECL #ifndef ANSI_C extern char *malloc(), *calloc(), *realloc(); #else extern void *malloc(size_t), *calloc(size_t,size_t), *realloc(void *,size_t); #endif #endif /* MALLOCDECL */ /* For creating MEX files (for use with Matlab) using Meschach See also: mexmesch.h */ #ifdef MEX #include "mex.h" #define malloc(len) mxMalloc(len) #define calloc(n,len) mxCalloc(n,len) #define realloc(ptr,len) mxRealloc(ptr,len) #define free(ptr) mxFree(ptr) #define printf mexPrintf #ifndef THREADSAFE /* for use as a shared library */ #define THREADSAFE 1 #endif #endif /* MEX */ #ifdef THREADSAFE #define STATIC #else #define STATIC static #endif /* THREADSAFE */ #ifndef ANSI_C extern void m_version(); #else void m_version( void ); #endif #ifndef ANSI_C /* allocate one object of given type */ #define NEW(type) ((type *)calloc((size_t)1,sizeof(type))) /* allocate num objects of given type */ #define NEW_A(num,type) ((type *)calloc((size_t)(num),sizeof(type))) /* re-allocate arry to have num objects of the given type */ #define RENEW(var,num,type) \ ((var)=(type *)((var) ? \ realloc((char *)(var),(size_t)(num)*sizeof(type)) : \ calloc((size_t)(num),sizeof(type)))) #define MEMCOPY(from,to,n_items,type) \ MEM_COPY((char *)(from),(char *)(to),(size_t)(n_items)*sizeof(type)) #else /* allocate one object of given type */ #define NEW(type) ((type *)calloc((size_t)1,(size_t)sizeof(type))) /* allocate num objects of given type */ #define NEW_A(num,type) ((type *)calloc((size_t)(num),(size_t)sizeof(type))) /* re-allocate arry to have num objects of the given type */ #define RENEW(var,num,type) \ ((var)=(type *)((var) ? \ realloc((char *)(var),(size_t)((num)*sizeof(type))) : \ calloc((size_t)(num),(size_t)sizeof(type)))) #define MEMCOPY(from,to,n_items,type) \ MEM_COPY((char *)(from),(char *)(to),(unsigned)(n_items)*sizeof(type)) #endif /* ANSI_C */ /* type independent min and max operations */ #ifndef max #define max(a,b) ((a) > (b) ? (a) : (b)) #endif /* max */ #ifndef min #define min(a,b) ((a) > (b) ? (b) : (a)) #endif /* min */ #undef TRUE #define TRUE 1 #undef FALSE #define FALSE 0 /* for input routines */ #define MAXLINE 81 /* Dynamic memory allocation */ /* Should use M_FREE/V_FREE/PX_FREE in programs instead of m/v/px_free() as this is considerably safer -- also provides a simple type check ! */ #ifndef ANSI_C extern VEC *v_get(), *v_resize(); extern MAT *m_get(), *m_resize(); extern PERM *px_get(), *px_resize(); extern IVEC *iv_get(), *iv_resize(); extern int m_free(),v_free(); extern int px_free(); extern int iv_free(); extern BAND *bd_get(), *bd_resize(); extern int bd_free(); #else /* get/resize vector to given dimension */ extern VEC *v_get(int), *v_resize(VEC *,int); /* get/resize matrix to be m x n */ extern MAT *m_get(int,int), *m_resize(MAT *,int,int); /* get/resize permutation to have the given size */ extern PERM *px_get(int), *px_resize(PERM *,int); /* get/resize an integer vector to given dimension */ extern IVEC *iv_get(int), *iv_resize(IVEC *,int); /* get/resize a band matrix to given dimension */ extern BAND *bd_get(int,int,int), *bd_resize(BAND *,int,int,int); /* free (de-allocate) (band) matrices, vectors, permutations and integer vectors */ extern int iv_free(IVEC *); extern int m_free(MAT *),v_free(VEC *),px_free(PERM *); /* changed to extern "int", Jeff Welty, Feb 3, 2005 */ extern int bd_free(BAND *); #endif /* ANSI_C */ /* MACROS */ /* macros that also check types and sets pointers to NULL */ #define M_FREE(mat) ( m_free(mat), (mat)=(MAT *)NULL ) #define V_FREE(vec) ( v_free(vec), (vec)=(VEC *)NULL ) #define PX_FREE(px) ( px_free(px), (px)=(PERM *)NULL ) #define IV_FREE(iv) ( iv_free(iv), (iv)=(IVEC *)NULL ) #define MAXDIM 10000001 /* Entry level access to data structures */ /* routines to check indexes */ #define m_chk_idx(A,i,j) ((i)>=0 && (i)<(A)->m && (j)>=0 && (j)<=(A)->n) #define v_chk_idx(x,i) ((i)>=0 && (i)<(x)->dim) #define bd_chk_idx(A,i,j) ((i)>=max(0,(j)-(A)->ub) && \ (j)>=max(0,(i)-(A)->lb) && (i)<(A)->mat->n && (j)<(A)->mat->n) #define m_entry(A,i,j) m_get_val(A,i,j) #define v_entry(x,i) v_get_val(x,i) #define bd_entry(A,i,j) bd_get_val(A,i,j) #ifdef DEBUG #define m_set_val(A,i,j,val) ( m_chk_idx(A,i,j) ? \ (A)->me[(i)][(j)] = (val) : (error(E_BOUNDS,"m_set_val"), 0.0)) #define m_add_val(A,i,j,val) ( m_chk_idx(A,i,j) ? \ (A)->me[(i)][(j)] += (val) : (error(E_BOUNDS,"m_add_val"), 0.0)) #define m_sub_val(A,i,j,val) ( m_chk_idx(A,i,j) ? \ (A)->me[(i)][(j)] -= (val) : (error(E_BOUNDS,"m_sub_val"), 0.0)) #define m_get_val(A,i,j) ( m_chk_idx(A,i,j) ? \ (A)->me[(i)][(j)] : (error(E_BOUNDS,"m_get_val"), 0.0)) #define v_set_val(x,i,val) ( v_chk_idx(x,i) ? (x)->ve[(i)] = (val) : \ (error(E_BOUNDS,"v_set_val"), 0.0)) #define v_add_val(x,i,val) ( v_chk_idx(x,i) ? (x)->ve[(i)] += (val) : \ (error(E_BOUNDS,"v_set_val"), 0.0)) #define v_sub_val(x,i,val) ( v_chk_idx(x,i) ? (x)->ve[(i)] -= (val) : \ (error(E_BOUNDS,"v_set_val"), 0.0)) #define v_get_val(x,i) ( v_chk_idx(x,i) ? (x)->ve[(i)] : \ (error(E_BOUNDS,"v_get_val"), 0.0)) #define bd_set_val(A,i,j,val) ( bd_chk_idx(A,i,j) ? \ (A)->mat->me[(A)->lb+(j)-(i)][(j)] = (val) : \ (error(E_BOUNDS,"bd_set_val"), 0.0)) #define bd_add_val(A,i,j,val) ( bd_chk_idx(A,i,j) ? \ (A)->mat->me[(A)->lb+(j)-(i)][(j)] += (val) : \ (error(E_BOUNDS,"bd_set_val"), 0.0)) #define bd_get_val(A,i,j) ( bd_chk_idx(A,i,j) ? \ (A)->mat->me[(A)->lb+(j)-(i)][(j)] : \ (error(E_BOUNDS,"bd_get_val"), 0.0)) #else /* no DEBUG */ #define m_set_val(A,i,j,val) ((A)->me[(i)][(j)] = (val)) #define m_add_val(A,i,j,val) ((A)->me[(i)][(j)] += (val)) #define m_sub_val(A,i,j,val) ((A)->me[(i)][(j)] -= (val)) #define m_get_val(A,i,j) ((A)->me[(i)][(j)]) #define v_set_val(x,i,val) ((x)->ve[(i)] = (val)) #define v_add_val(x,i,val) ((x)->ve[(i)] += (val)) #define v_sub_val(x,i,val) ((x)->ve[(i)] -= (val)) #define v_get_val(x,i) ((x)->ve[(i)]) #define bd_set_val(A,i,j,val) ((A)->mat->me[(A)->lb+(j)-(i)][(j)] = (val)) #define bd_add_val(A,i,j,val) ((A)->mat->me[(A)->lb+(j)-(i)][(j)] += (val)) #define bd_get_val(A,i,j) ((A)->mat->me[(A)->lb+(j)-(i)][(j)]) #endif /* DEBUG */ /* I/O routines */ #ifndef ANSI_C extern void v_foutput(),m_foutput(),px_foutput(); extern void iv_foutput(); extern VEC *v_finput(); extern MAT *m_finput(); extern PERM *px_finput(); extern IVEC *iv_finput(); extern int fy_or_n(), fin_int(), yn_dflt(), skipjunk(); extern double fin_double(); #else /* print x on file fp */ void v_foutput(FILE *fp,const VEC *x), /* print A on file fp */ m_foutput(FILE *fp,const MAT *A), /* print px on file fp */ px_foutput(FILE *fp,const PERM *px); /* print ix on file fp */ void iv_foutput(FILE *fp,const IVEC *ix); /* Note: if out is NULL, then returned object is newly allocated; Also: if out is not NULL, then that size is assumed */ /* read in vector from fp */ VEC *v_finput(FILE *fp,VEC *out); /* read in matrix from fp */ MAT *m_finput(FILE *fp,MAT *out); /* read in permutation from fp */ PERM *px_finput(FILE *fp,PERM *out); /* read in int vector from fp */ IVEC *iv_finput(FILE *fp,IVEC *out); /* fy_or_n -- yes-or-no to question in string s -- question written to stderr, input from fp -- if fp is NOT a tty then return y_n_dflt */ int fy_or_n(FILE *fp, const char *s); /* yn_dflt -- sets the value of y_n_dflt to val */ int yn_dflt(int val); /* fin_int -- return integer read from file/stream fp -- prompt s on stderr if fp is a tty -- check that x lies between low and high: re-prompt if fp is a tty, error exit otherwise -- ignore check if low > high */ int fin_int(FILE *fp,const char *s,int low,int high); /* fin_double -- return double read from file/stream fp -- prompt s on stderr if fp is a tty -- check that x lies between low and high: re-prompt if fp is a tty, error exit otherwise -- ignore check if low > high */ double fin_double(FILE *fp,const char *s,double low,double high); /* it skips white spaces and strings of the form #....\n Here .... is a comment string */ int skipjunk(FILE *fp); #endif /* ANSI_C */ /* MACROS */ /* macros to use stdout and stdin instead of explicit fp */ #define v_output(vec) v_foutput(stdout,vec) #define v_input(vec) v_finput(stdin,vec) #define m_output(mat) m_foutput(stdout,mat) #define m_input(mat) m_finput(stdin,mat) #define px_output(px) px_foutput(stdout,px) #define px_input(px) px_finput(stdin,px) #define iv_output(iv) iv_foutput(stdout,iv) #define iv_input(iv) iv_finput(stdin,iv) /* general purpose input routine; skips comments # ... \n */ #define finput(fp,prompt,fmt,var) \ ( ( isatty(fileno(fp)) ? fprintf(stderr,prompt) : skipjunk(fp) ), \ fscanf(fp,fmt,var) ) #define input(prompt,fmt,var) finput(stdin,prompt,fmt,var) #define fprompter(fp,prompt) \ ( isatty(fileno(fp)) ? fprintf(stderr,prompt) : skipjunk(fp) ) #define prompter(prompt) fprompter(stdin,prompt) #define y_or_n(s) fy_or_n(stdin,s) #define in_int(s,lo,hi) fin_int(stdin,s,lo,hi) #define in_double(s,lo,hi) fin_double(stdin,s,lo,hi) /* special purpose access routines */ /* Copying routines */ #ifndef ANSI_C extern MAT *_m_copy(), *m_move(), *vm_move(); extern VEC *_v_copy(), *v_move(), *mv_move(); extern PERM *px_copy(); extern IVEC *iv_copy(), *iv_move(); extern BAND *bd_copy(); #else /* copy in to out starting at out[i0][j0] */ extern MAT *_m_copy(const MAT *in,MAT *out,unsigned int i0,unsigned int j0), * m_move(const MAT *in, int, int, int, int, MAT *out, int, int), *vm_move(const VEC *in, int, MAT *out, int, int, int, int); /* copy in to out starting at out[i0] */ extern VEC *_v_copy(const VEC *in,VEC *out,unsigned int i0), * v_move(const VEC *in, int, int, VEC *out, int), *mv_move(const MAT *in, int, int, int, int, VEC *out, int); extern PERM *px_copy(const PERM *in,PERM *out); extern IVEC *iv_copy(const IVEC *in,IVEC *out), *iv_move(const IVEC *in, int, int, IVEC *out, int); extern BAND *bd_copy(const BAND *in,BAND *out); #endif /* ANSI_C */ /* MACROS */ #define m_copy(in,out) _m_copy(in,out,0,0) #define v_copy(in,out) _v_copy(in,out,0) /* Initialisation routines -- to be zero, ones, random or identity */ #ifndef ANSI_C extern VEC *v_zero(), *v_rand(), *v_ones(); extern MAT *m_zero(), *m_ident(), *m_rand(), *m_ones(); extern PERM *px_ident(); extern IVEC *iv_zero(); #else extern VEC *v_zero(VEC *), *v_rand(VEC *), *v_ones(VEC *); extern MAT *m_zero(MAT *), *m_ident(MAT *), *m_rand(MAT *), *m_ones(MAT *); extern PERM *px_ident(PERM *); extern IVEC *iv_zero(IVEC *); #endif /* ANSI_C */ /* Basic vector operations */ #ifndef ANSI_C extern VEC *sv_mlt(), *mv_mlt(), *vm_mlt(), *v_add(), *v_sub(), *px_vec(), *pxinv_vec(), *v_mltadd(), *v_map(), *_v_map(), *v_lincomb(), *v_linlist(); extern double v_min(), v_max(), v_sum(); extern VEC *v_star(), *v_slash(), *v_sort(); extern double _in_prod(), __ip__(); extern void __mltadd__(), __add__(), __sub__(), __smlt__(), __zero__(); #else extern VEC *sv_mlt(double s,const VEC *x,VEC *out), /* out <- s.x */ *mv_mlt(const MAT *A,const VEC *s,VEC *out), /* out <- A.x */ *vm_mlt(const MAT *A,const VEC *x,VEC *out), /* out^T <- x^T.A */ *v_add(const VEC *x,const VEC *y,VEC *out), /* out <- x + y */ *v_sub(const VEC *x,const VEC *y,VEC *out), /* out <- x - y */ *px_vec(PERM *px,const VEC *x,VEC *out), /* out <- P.x */ *pxinv_vec(PERM *px,const VEC *x,VEC *out), /* out <- P^{-1}.x */ *v_mltadd(const VEC *x,const VEC *y,double s,VEC *out), /* out <- x + s.y */ #ifdef PROTOTYPES_IN_STRUCT *v_map(double (*f)(double),const VEC *x,VEC *y), /* out[i] <- f(x[i]) */ *_v_map(double (*f)(void *,double),void *p,const VEC *x,VEC *y), #else *v_map(double (*f)(),const VEC *,VEC *), /* out[i] <- f(x[i]) */ *_v_map(double (*f)(),void *,const VEC *,VEC *), #endif /* PROTOTYPES_IN_STRUCT */ *v_lincomb(int,const VEC **,const Real *,VEC *), /* out <- sum_i s[i].x[i] */ *v_linlist(VEC *out,VEC *v1,double a1,...); /* out <- s1.x1 + s2.x2 + ... */ /* returns min_j x[j] (== x[i]) */ extern double v_min(const VEC *, int *), /* returns max_j x[j] (== x[i]) */ v_max(const VEC *, int *), /* returns sum_i x[i] */ v_sum(const VEC *); /* Hadamard product: out[i] <- x[i].y[i] */ extern VEC *v_star(const VEC *, const VEC *, VEC *), /* out[i] <- x[i] / y[i] */ *v_slash(const VEC *, const VEC *, VEC *), /* sorts x, and sets order so that sorted x[i] = x[order[i]] */ *v_sort(VEC *, PERM *); /* returns inner product starting at component i0 */ extern double _in_prod(const VEC *x, const VEC *y,unsigned int i0), /* returns sum_{i=0}^{len-1} x[i].y[i] */ __ip__(const Real *,const Real *,int); /* see v_mltadd(), v_add(), v_sub() and v_zero() */ extern void __mltadd__(Real *,const Real *,double,int), __add__(const Real *,const Real *,Real *,int), __sub__(const Real *,const Real *,Real *,int), __smlt__(const Real *,double,Real *,int), __zero__(Real *,int); #endif /* ANSI_C */ /* MACRO */ /* usual way of computing the inner product */ #define in_prod(a,b) _in_prod(a,b,0) /* Norms */ /* scaled vector norms -- scale == NULL implies unscaled */ #ifndef ANSI_C extern double _v_norm1(), _v_norm2(), _v_norm_inf(), m_norm1(), m_norm_inf(), m_norm_frob(); #else /* returns sum_i |x[i]/scale[i]| */ extern double _v_norm1(const VEC *x,const VEC *scale), /* returns (scaled) Euclidean norm */ _v_norm2(const VEC *x,const VEC *scale), /* returns max_i |x[i]/scale[i]| */ _v_norm_inf(const VEC *x,const VEC *scale); /* unscaled matrix norms */ extern double m_norm1(const MAT *A), m_norm_inf(const MAT *A), m_norm_frob(const MAT *A); #endif /* ANSI_C */ /* MACROS */ /* unscaled vector norms */ #define v_norm1(x) _v_norm1(x,VNULL) #define v_norm2(x) _v_norm2(x,VNULL) #define v_norm_inf(x) _v_norm_inf(x,VNULL) /* Basic matrix operations */ #ifndef ANSI_C extern MAT *sm_mlt(), *m_mlt(), *mmtr_mlt(), *mtrm_mlt(), *m_add(), *m_sub(), *sub_mat(), *m_transp(), *ms_mltadd(); extern BAND *bd_transp(), *sbd_mlt(), *bds_mltadd(), *bd_zero(); extern MAT *px_rows(), *px_cols(), *swap_rows(), *swap_cols(), *_set_row(), *_set_col(); extern VEC *get_row(), *get_col(), *sub_vec(), *mv_mltadd(), *vm_mltadd(), *bdv_mltadd(); #else extern MAT *sm_mlt(double s, const MAT *A,MAT *out), /* out <- s.A */ *m_mlt(const MAT *A,const MAT *B,MAT *out), /* out <- A.B */ *mmtr_mlt(const MAT *A,const MAT *B,MAT *out), /* out <- A.B^T */ *mtrm_mlt(const MAT *A,const MAT *B,MAT *out), /* out <- A^T.B */ *m_add(const MAT *A,const MAT *B,MAT *out), /* out <- A + B */ *m_sub(const MAT *A,const MAT *B,MAT *out), /* out <- A - B */ *sub_mat(const MAT *A,unsigned int,unsigned int,unsigned int, unsigned int,MAT *out), *m_transp(const MAT *A,MAT *out), /* out <- A^T */ /* out <- A + s.B */ *ms_mltadd(const MAT *A,const MAT *B,double s,MAT *out); extern BAND *bd_transp(const BAND *in, BAND *out), /* out <- A^T */ *sbd_mlt(Real s, const BAND *A, BAND *OUT), /* OUT <- s.A */ *bds_mltadd(const BAND *A, const BAND *B,double alpha, BAND *OUT), /* OUT <- A+alpha.B */ *bd_zero(BAND *A); /* A <- 0 */ extern MAT *px_rows(const PERM *px,const MAT *A,MAT *out), /* out <- P.A */ *px_cols(const PERM *px,const MAT *A,MAT *out), /* out <- A.P^T */ *swap_rows(MAT *,int,int,int,int), *swap_cols(MAT *,int,int,int,int), /* A[i][j] <- out[j], j >= j0 */ *_set_col(MAT *A,unsigned int i,const VEC *col,unsigned int j0), /* A[i][j] <- out[i], i >= i0 */ *_set_row(MAT *A,unsigned int j,const VEC *row,unsigned int i0); extern VEC *get_row(const MAT *,unsigned int,VEC *), *get_col(const MAT *,unsigned int,VEC *), *sub_vec(const VEC *,int,int,VEC *), /* mv_mltadd: out <- x + s.A.y */ *mv_mltadd(const VEC *x,const VEC *y,const MAT *A, double s,VEC *out), /* vm_mltadd: out^T <- x^T + s.y^T.A */ *vm_mltadd(const VEC *x,const VEC *y,const MAT *A, double s,VEC *out), /* bdv_mltadd: out <- x + s.A.y */ *bdv_mltadd(const VEC *x,const VEC *y,const BAND *A, double s,VEC *out); #endif /* ANSI_C */ /* MACROS */ /* row i of A <- vec */ #define set_row(mat,row,vec) _set_row(mat,row,vec,0) /* col j of A <- vec */ #define set_col(mat,col,vec) _set_col(mat,col,vec,0) /* Basic permutation operations */ #ifndef ANSI_C extern PERM *px_mlt(), *px_inv(), *px_transp(); extern int px_sign(); #else extern PERM *px_mlt(const PERM *px1,const PERM *px2,PERM *out), /* out <- px1.px2 */ *px_inv(const PERM *px,PERM *out), /* out <- px^{-1} */ /* swap px[i] and px[j] */ *px_transp(PERM *px,unsigned int i,unsigned int j); /* returns sign(px) = +1 if px product of even # transpositions -1 if ps product of odd # transpositions */ extern int px_sign(const PERM *); #endif /* ANSI_C */ /* Basic integer vector operations */ #ifndef ANSI_C extern IVEC *iv_add(), *iv_sub(), *iv_sort(); #else extern IVEC *iv_add(const IVEC *ix,const IVEC *iy,IVEC *out), /* out <- ix + iy */ *iv_sub(const IVEC *ix,const IVEC *iy,IVEC *out), /* out <- ix - iy */ /* sorts ix & sets order so that sorted ix[i] = old ix[order[i]] */ *iv_sort(IVEC *ix, PERM *order); #endif /* ANSI_C */ /* miscellaneous functions */ #ifndef ANSI_C extern double square(), cube(), mrand(); extern void smrand(), mrandlist(); extern void m_dump(), px_dump(), v_dump(), iv_dump(); extern MAT *band2mat(); extern BAND *mat2band(); #else double square(double x), /* returns x^2 */ cube(double x), /* returns x^3 */ mrand(void); /* returns random # in [0,1) */ void smrand(int seed), /* seeds mrand() */ mrandlist(Real *x, int len); /* generates len random numbers */ void m_dump(FILE *fp,const MAT *a), px_dump(FILE *fp, const PERM *px), v_dump(FILE *fp,const VEC *x), iv_dump(FILE *fp, const IVEC *ix); MAT *band2mat(const BAND *bA, MAT *A); BAND *mat2band(const MAT *A, int lb,int ub, BAND *bA); #endif /* ANSI_C */ /* miscellaneous constants */ #define VNULL ((VEC *)NULL) #define MNULL ((MAT *)NULL) #define PNULL ((PERM *)NULL) #define IVNULL ((IVEC *)NULL) #define BDNULL ((BAND *)NULL) /* varying number of arguments */ #ifdef ANSI_C #include /* prototypes */ int v_get_vars(int dim,...); int iv_get_vars(int dim,...); int m_get_vars(int m,int n,...); int px_get_vars(int dim,...); int v_resize_vars(int new_dim,...); int iv_resize_vars(int new_dim,...); int m_resize_vars(int m,int n,...); int px_resize_vars(int new_dim,...); int v_free_vars(VEC **,...); int iv_free_vars(IVEC **,...); int px_free_vars(PERM **,...); int m_free_vars(MAT **,...); #elif VARARGS /* old varargs is used */ #include /* prototypes */ int v_get_vars(); int iv_get_vars(); int m_get_vars(); int px_get_vars(); int v_resize_vars(); int iv_resize_vars(); int m_resize_vars(); int px_resize_vars(); int v_free_vars(); int iv_free_vars(); int px_free_vars(); int m_free_vars(); #endif /* ANSI_C */ #endif /* MATRIXH */ gtk-wave-cleaner-0.22-04/meschach/matrix2.h0000777000175000017500000002132713120075106021523 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Header file for ``matrix2.a'' library file */ #ifndef MATRIX2H #define MATRIX2H #include "matrix.h" /* Unless otherwise specified, factorisation routines overwrite the matrix that is being factorised */ #ifndef ANSI_C extern MAT *BKPfactor(), *CHfactor(), *LUfactor(), *QRfactor(), *QRCPfactor(), *LDLfactor(), *Hfactor(), *MCHfactor(), *m_inverse(); extern double LUcondest(), QRcondest(); extern MAT *makeQ(), *makeR(), *makeHQ(), *makeH(); extern MAT *LDLupdate(), *QRupdate(); extern VEC *BKPsolve(), *CHsolve(), *LUsolve(), *_Qsolve(), *QRsolve(), *LDLsolve(), *Usolve(), *Lsolve(), *Dsolve(), *LTsolve(), *UTsolve(), *LUTsolve(), *QRCPsolve(); extern BAND *bdLUfactor(), *bdLDLfactor(); extern VEC *bdLUsolve(), *bdLDLsolve(); extern VEC *hhvec(); extern VEC *hhtrvec(); extern MAT *hhtrrows(); extern MAT *hhtrcols(), *_hhtrcols(); extern void givens(); extern VEC *rot_vec(); /* in situ */ extern MAT *rot_rows(); /* in situ */ extern MAT *rot_cols(); /* in situ */ /* eigenvalue routines */ extern VEC *trieig(), *symmeig(); extern MAT *schur(); extern void schur_evals(); extern MAT *schur_vecs(); /* singular value decomposition */ extern VEC *bisvd(), *svd(); /* matrix powers and exponent */ MAT *_m_pow(); MAT *m_pow(); MAT *m_exp(), *_m_exp(); MAT *m_poly(); /* FFT */ void fft(); void ifft(); #else /* forms Bunch-Kaufman-Parlett factorisation for symmetric indefinite matrices */ extern MAT *BKPfactor(MAT *A,PERM *pivot,PERM *blocks), /* Cholesky factorisation of A (symmetric, positive definite) */ *CHfactor(MAT *A), /* LU factorisation of A (with partial pivoting) */ *LUfactor(MAT *A,PERM *pivot), /* QR factorisation of A; need dim(diag) >= # rows of A */ *QRfactor(MAT *A,VEC *diag), /* QR factorisation of A with column pivoting */ *QRCPfactor(MAT *A,VEC *diag,PERM *pivot), /* L.D.L^T factorisation of A */ *LDLfactor(MAT *A), /* Hessenberg factorisation of A -- for schur() */ *Hfactor(MAT *A,VEC *diag1,VEC *diag2), /* modified Cholesky factorisation of A; actually factors A+D, D diagonal with no diagonal entry in the factor < sqrt(tol) */ *MCHfactor(MAT *A,double tol), *m_inverse(const MAT *A,MAT *out); /* returns condition estimate for A after LUfactor() */ extern double LUcondest(const MAT *A, PERM *pivot), /* returns condition estimate for Q after QRfactor() */ QRcondest(const MAT *A); /* Note: The make..() and ..update() routines assume that the factorisation has already been carried out */ /* Qout is the "Q" (orthongonal) matrix from QR factorisation */ extern MAT *makeQ(const MAT *QR,const VEC *diag,MAT *Qout), /* Rout is the "R" (upper triangular) matrix from QR factorisation */ *makeR(const MAT *A,MAT *Rout), /* Qout is orthogonal matrix in Hessenberg factorisation */ *makeHQ(MAT *A,VEC *diag1,VEC *diag2,MAT *Qout), /* Hout is the Hessenberg matrix in Hessenberg factorisation */ *makeH(const MAT *A,MAT *Hout); /* updates L.D.L^T factorisation for A <- A + alpha.u.u^T */ extern MAT *LDLupdate(MAT *A,VEC *u,double alpha), /* updates QR factorisation for QR <- Q.(R+u.v^T) Note: we need explicit Q & R matrices, from makeQ() and makeR() */ *QRupdate(MAT *Q,MAT *R,VEC *u,VEC *v); /* Solve routines assume that the corresponding factorisation routine has already been applied to the matrix along with auxiliary objects (such as pivot permutations) These solve the system A.x = b, except for LUTsolve and QRTsolve which solve the transposed system A^T.x. = b. If x is NULL on entry, then it is created. */ extern VEC *BKPsolve(const MAT *A,PERM *pivot,const PERM *blocks, const VEC *b,VEC *x), *CHsolve(const MAT *A,const VEC *b,VEC *x), *LDLsolve(const MAT *A,const VEC *b,VEC *x), *LUsolve(const MAT *A, PERM *pivot, const VEC *b,VEC *x), *_Qsolve(const MAT *A, const VEC *diag, const VEC *b, VEC *x, VEC *tmp), *QRsolve(const MAT *A, const VEC *diag, const VEC *b,VEC *x), *QRTsolve(const MAT *A,const VEC *,const VEC *b,VEC *x), /* Triangular equations solve routines; U for upper triangular, L for lower traingular, D for diagonal if diag_val == 0.0 use that values in the matrix */ *Usolve(const MAT *A,const VEC *b,VEC *x,double diag_val), *Lsolve(const MAT *A,const VEC *b,VEC *x,double diag_val), *Dsolve(const MAT *A,const VEC *b,VEC *x), *LTsolve(const MAT *A,const VEC *b,VEC *x,double diag_val), *UTsolve(const MAT *A,const VEC *b,VEC *x,double diag_val), *LUTsolve(const MAT *A,PERM *pivot,const VEC *b, VEC *x), *QRCPsolve(const MAT *QR,const VEC *diag,PERM *pivot, const VEC *b,VEC *x); extern BAND *bdLUfactor(BAND *A,PERM *pivot), *bdLDLfactor(BAND *A); extern VEC *bdLUsolve(const BAND *A,PERM *pivot,const VEC *b,VEC *x), *bdLDLsolve(const BAND *A,const VEC *b,VEC *x); extern VEC *hhvec(const VEC *,unsigned int,Real *,VEC *,Real *); extern VEC *hhtrvec(const VEC *,double,unsigned int,const VEC *,VEC *); extern MAT *hhtrrows(MAT *,unsigned int,unsigned int,const VEC *,double); extern MAT *hhtrcols(MAT *,unsigned int,unsigned int,const VEC *,double); extern MAT *_hhtrcols(MAT *,unsigned int,unsigned int,const VEC *,double,VEC *); extern void givens(double,double,Real *,Real *); extern VEC *rot_vec(const VEC *,unsigned int,unsigned int, double,double,VEC *); /* in situ */ extern MAT *rot_rows(const MAT *,unsigned int,unsigned int, double,double,MAT *); /* in situ */ extern MAT *rot_cols(const MAT *,unsigned int,unsigned int, double,double,MAT *); /* in situ */ /* eigenvalue routines */ /* compute eigenvalues of tridiagonal matrix with diagonal entries a[i], super & sub diagonal entries b[i]; eigenvectors stored in Q (if not NULL) */ extern VEC *trieig(VEC *a,VEC *b,MAT *Q), /* sets out to be vector of eigenvectors; eigenvectors stored in Q (if not NULL). A is unchanged */ *symmeig(const MAT *A,MAT *Q,VEC *out); /* computes real Schur form = Q^T.A.Q */ extern MAT *schur(MAT *A,MAT *Q); /* computes real and imaginary parts of the eigenvalues of A after schur() */ extern void schur_evals(MAT *A,VEC *re_part,VEC *im_part); /* computes real and imaginary parts of the eigenvectors of A after schur() */ extern MAT *schur_vecs(MAT *T,MAT *Q,MAT *X_re,MAT *X_im); /* singular value decomposition */ /* computes singular values of bi-diagonal matrix with diagonal entries a[i] and superdiagonal entries b[i]; singular vectors stored in U and V (if not NULL) */ VEC *bisvd(VEC *a,VEC *b,MAT *U,MAT *V), /* sets "out" to be vector of singular values; singular vectors stored in U and V */ *svd(MAT *A,MAT *U,MAT *V,VEC *out); /* matrix powers and exponent */ MAT *_m_pow(const MAT *A, int p, MAT *tmp,MAT *out); MAT *m_pow(const MAT *A, int p, MAT *out); MAT *m_exp(MAT *,double,MAT *); MAT *_m_exp(MAT *A, double eps, MAT *out, int *q_out, int *j_out); MAT *m_poly(const MAT *,const VEC *,MAT *); /* FFT */ void fft(VEC *,VEC *); void ifft(VEC *,VEC *); #endif #endif gtk-wave-cleaner-0.22-04/meschach/matrixio.c0000777000175000017500000004607713120075106021775 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* 1.6 matrixio.c 11/25/87 */ #include #include #include "matrix.h" static char rcsid[] = "$Id: matrixio.c,v 1.4 1994/01/13 05:31:10 des Exp $"; /* local variables */ static char line[MAXLINE]; /************************************************************************** Input routines **************************************************************************/ /* skipjunk -- skips white spaces and strings of the form #....\n Here .... is a comment string */ #ifndef ANSI_C int skipjunk(fp) FILE *fp; #else int skipjunk(FILE *fp) #endif { int c; for ( ; ; ) /* forever do... */ { /* skip blanks */ do c = getc(fp); while ( isspace(c) ); /* skip comments (if any) */ if ( c == '#' ) /* yes it is a comment (line) */ while ( (c=getc(fp)) != '\n' ) ; else { ungetc(c,fp); break; } } return 0; } /* m_finput -- input matrix -- input from a terminal is handled interactively -- batch/file input has the same format as produced by m_foutput except that whitespace and comments ("#..\n") are skipped -- returns a, which is created if a == NULL on entry */ #ifndef ANSI_C MAT *m_finput(fp,a) FILE *fp; MAT *a; #else MAT *m_finput(FILE *fp, MAT *a) #endif { MAT *im_finput(),*bm_finput(); if ( isatty(fileno(fp)) ) return im_finput(fp,a); else return bm_finput(fp,a); } /* im_finput -- interactive input of matrix */ #ifndef ANSI_C MAT *im_finput(fp,mat) FILE *fp; MAT *mat; #else MAT *im_finput(FILE *fp,MAT *mat) #endif { char c; unsigned int i, j, m, n, dynamic; /* dynamic set to TRUE if memory allocated here */ /* get matrix size */ if ( mat != (MAT *)NULL && mat->mnm; n = mat->n; dynamic = FALSE; } else { dynamic = TRUE; do { fprintf(stderr,"Matrix: rows cols:"); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"im_finput"); } while ( sscanf(line,"%u%u",&m,&n)<2 || m>MAXDIM || n>MAXDIM ); mat = m_get(m,n); } /* input elements */ for ( i=0; ime[i][j]); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"im_finput"); if ( (*line == 'b' || *line == 'B') && j > 0 ) { j--; dynamic = FALSE; goto redo2; } if ( (*line == 'f' || *line == 'F') && j < n-1 ) { j++; dynamic = FALSE; goto redo2; } #if REAL == DOUBLE } while ( *line=='\0' || sscanf(line,"%lf",&mat->me[i][j])<1 ); #elif REAL == FLOAT } while ( *line=='\0' || sscanf(line,"%f",&mat->me[i][j])<1 ); #endif fprintf(stderr,"Continue: "); fscanf(fp,"%c",&c); if ( c == 'n' || c == 'N' ) { dynamic = FALSE; goto redo; } if ( (c == 'b' || c == 'B') /* && i > 0 */ ) { if ( i > 0 ) i--; dynamic = FALSE; goto redo; } } return (mat); } /* bm_finput -- batch-file input of matrix */ #ifndef ANSI_C MAT *bm_finput(fp,mat) FILE *fp; MAT *mat; #else MAT *bm_finput(FILE *fp,MAT *mat) #endif { unsigned int i,j,m,n,dummy; int io_code; /* get dimension */ skipjunk(fp); if ((io_code=fscanf(fp," Matrix: %u by %u",&m,&n)) < 2 || m>MAXDIM || n>MAXDIM ) error(io_code==EOF ? E_EOF : E_FORMAT,"bm_finput"); /* allocate memory if necessary */ if ( mat==(MAT *)NULL ) mat = m_resize(mat,m,n); /* get entries */ for ( i=0; ime[i][j])) < 1 ) #elif REAL == FLOAT if ((io_code=fscanf(fp,"%f",&mat->me[i][j])) < 1 ) #endif error(io_code==EOF ? 7 : 6,"bm_finput"); } return (mat); } /* px_finput -- inputs permutation from file/stream fp -- input from a terminal is handled interactively -- batch/file input has the same format as produced by px_foutput except that whitespace and comments ("#..\n") are skipped -- returns px, which is created if px == NULL on entry */ #ifndef ANSI_C PERM *px_finput(fp,px) FILE *fp; PERM *px; #else PERM *px_finput(FILE *fp,PERM *px) #endif { PERM *ipx_finput(),*bpx_finput(); if ( isatty(fileno(fp)) ) return ipx_finput(fp,px); else return bpx_finput(fp,px); } /* ipx_finput -- interactive input of permutation */ #ifndef ANSI_C PERM *ipx_finput(fp,px) FILE *fp; PERM *px; #else PERM *ipx_finput(FILE *fp,PERM *px) #endif { unsigned int i,j,size,dynamic; /* dynamic set if memory allocated here */ unsigned int entry,ok; /* get permutation size */ if ( px!=(PERM *)NULL && px->sizesize; dynamic = FALSE; } else { dynamic = TRUE; do { fprintf(stderr,"Permutation: size: "); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"ipx_finput"); } while ( sscanf(line,"%u",&size)<1 || size>MAXDIM ); px = px_get(size); } /* get entries */ i = 0; while ( i%u new: ", i,px->pe[i]); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"ipx_finput"); if ( (*line == 'b' || *line == 'B') && i > 0 ) { i--; dynamic = FALSE; goto redo; } } while ( *line=='\0' || sscanf(line,"%u",&entry) < 1 ); /* check entry */ ok = (entry < size); for ( j=0; jpe[j]); if ( ok ) { px->pe[i] = entry; i++; } } return (px); } /* bpx_finput -- batch-file input of permutation */ #ifndef ANSI_C PERM *bpx_finput(fp,px) FILE *fp; PERM *px; #else PERM *bpx_finput(FILE *fp,PERM *px) #endif { unsigned int i,j,size,entry,ok; int io_code; /* get size of permutation */ skipjunk(fp); if ((io_code=fscanf(fp," Permutation: size:%u",&size)) < 1 || size>MAXDIM ) error(io_code==EOF ? 7 : 6,"bpx_finput"); /* allocate memory if necessary */ if ( px==(PERM *)NULL || px->size %u",&entry)) < 1 ) error(io_code==EOF ? 7 : 6,"bpx_finput"); /* check entry */ ok = (entry < size); for ( j=0; jpe[j]); if ( ok ) { px->pe[i] = entry; i++; } else error(E_BOUNDS,"bpx_finput"); } return (px); } /* v_finput -- inputs vector from file/stream fp -- input from a terminal is handled interactively -- batch/file input has the same format as produced by px_foutput except that whitespace and comments ("#..\n") are skipped -- returns x, which is created if x == NULL on entry */ #ifndef ANSI_C VEC *v_finput(fp,x) FILE *fp; VEC *x; #else VEC *v_finput(FILE *fp,VEC *x) #endif { VEC *ifin_vec(),*bfin_vec(); if ( isatty(fileno(fp)) ) return ifin_vec(fp,x); else return bfin_vec(fp,x); } /* ifin_vec -- interactive input of vector */ #ifndef ANSI_C VEC *ifin_vec(fp,vec) FILE *fp; VEC *vec; #else VEC *ifin_vec(FILE *fp,VEC *vec) #endif { unsigned int i,dim,dynamic; /* dynamic set if memory allocated here */ /* get vector dimension */ if ( vec != (VEC *)NULL && vec->dimdim; dynamic = FALSE; } else { dynamic = TRUE; do { fprintf(stderr,"Vector: dim: "); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"ifin_vec"); } while ( sscanf(line,"%u",&dim)<1 || dim>MAXDIM ); vec = v_get(dim); } /* input elements */ for ( i=0; ive[i]); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"ifin_vec"); if ( (*line == 'b' || *line == 'B') && i > 0 ) { i--; dynamic = FALSE; goto redo; } if ( (*line == 'f' || *line == 'F') && i < dim-1 ) { i++; dynamic = FALSE; goto redo; } #if REAL == DOUBLE } while ( *line=='\0' || sscanf(line,"%lf",&vec->ve[i]) < 1 ); #elif REAL == FLOAT } while ( *line=='\0' || sscanf(line,"%f",&vec->ve[i]) < 1 ); #endif return (vec); } /* bfin_vec -- batch-file input of vector */ #ifndef ANSI_C VEC *bfin_vec(fp,vec) FILE *fp; VEC *vec; #else VEC *bfin_vec(FILE *fp,VEC *vec) #endif { unsigned int i,dim; int io_code; /* get dimension */ skipjunk(fp); if ((io_code=fscanf(fp," Vector: dim:%u",&dim)) < 1 || dim>MAXDIM ) error(io_code==EOF ? 7 : 6,"bfin_vec"); /* allocate memory if necessary */ if ( vec==(VEC *)NULL ) vec = v_resize(vec,dim); /* get entries */ skipjunk(fp); for ( i=0; ive[i])) < 1 ) #elif REAL == FLOAT if ((io_code=fscanf(fp,"%f",&vec->ve[i])) < 1 ) #endif error(io_code==EOF ? 7 : 6,"bfin_vec"); return (vec); } /************************************************************************** Output routines **************************************************************************/ static const char *format = "%14.9g "; /* setformat -- sets the printf format string for the Meschach I/O operations -- returns the previous format string */ #ifndef ANSI_C char *setformat(f_string) char *f_string; #else const char *setformat(const char *f_string) #endif { const char *old_f_string; old_f_string = format; if ( f_string != (char *)NULL && *f_string != '\0' ) format = f_string; return old_f_string; } /* m_foutput -- prints a representation of the matrix a onto file/stream fp */ #ifndef ANSI_C void m_foutput(fp,a) FILE *fp; MAT *a; #else void m_foutput(FILE *fp, const MAT *a) #endif { unsigned int i, j, tmp; if ( a == (MAT *)NULL ) { fprintf(fp,"Matrix: NULL\n"); return; } fprintf(fp,"Matrix: %d by %d\n",a->m,a->n); if ( a->me == (Real **)NULL ) { fprintf(fp,"NULL\n"); return; } for ( i=0; im; i++ ) /* for each row... */ { fprintf(fp,"row %u: ",i); for ( j=0, tmp=2; jn; j++, tmp++ ) { /* for each col in row... */ fprintf(fp,format,a->me[i][j]); if ( ! (tmp % 5) ) putc('\n',fp); } if ( tmp % 5 != 1 ) putc('\n',fp); } } /* px_foutput -- prints a representation of px onto file/stream fp */ #ifndef ANSI_C void px_foutput(fp,px) FILE *fp; PERM *px; #else void px_foutput(FILE *fp, const PERM *px) #endif { unsigned int i; if ( px == (PERM *)NULL ) { fprintf(fp,"Permutation: NULL\n"); return; } fprintf(fp,"Permutation: size: %u\n",px->size); if ( px->pe == (unsigned int *)NULL ) { fprintf(fp,"NULL\n"); return; } for ( i=0; isize; i++ ) if ( ! (i % 8) && i != 0 ) fprintf(fp,"\n %u->%u ",i,px->pe[i]); else fprintf(fp,"%u->%u ",i,px->pe[i]); fprintf(fp,"\n"); } /* v_foutput -- prints a representation of x onto file/stream fp */ #ifndef ANSI_C void v_foutput(fp,x) FILE *fp; VEC *x; #else void v_foutput(FILE *fp, const VEC *x) #endif { unsigned int i, tmp; if ( x == (VEC *)NULL ) { fprintf(fp,"Vector: NULL\n"); return; } fprintf(fp,"Vector: dim: %d\n",x->dim); if ( x->ve == (Real *)NULL ) { fprintf(fp,"NULL\n"); return; } for ( i=0, tmp=0; idim; i++, tmp++ ) { fprintf(fp,format,x->ve[i]); if ( tmp % 5 == 4 ) putc('\n',fp); } if ( tmp % 5 != 0 ) putc('\n',fp); } /* m_dump -- prints a dump of all pointers and data in a onto fp -- suitable for low-level debugging */ #ifndef ANSI_C void m_dump(fp,a) FILE *fp; MAT *a; #else void m_dump(FILE *fp, const MAT *a) #endif { unsigned int i, j, tmp; if ( a == (MAT *)NULL ) { fprintf(fp,"Matrix: NULL\n"); return; } fprintf(fp,"Matrix: %d by %d @ 0x%lx\n",a->m,a->n,(long)a); fprintf(fp,"\tmax_m = %d, max_n = %d, max_size = %d\n", a->max_m, a->max_n, a->max_size); if ( a->me == (Real **)NULL ) { fprintf(fp,"NULL\n"); return; } fprintf(fp,"a->me @ 0x%lx\n",(long)(a->me)); fprintf(fp,"a->base @ 0x%lx\n",(long)(a->base)); for ( i=0; im; i++ ) /* for each row... */ { fprintf(fp,"row %u: @ 0x%lx ",i,(long)(a->me[i])); for ( j=0, tmp=2; jn; j++, tmp++ ) { /* for each col in row... */ fprintf(fp,format,a->me[i][j]); if ( ! (tmp % 5) ) putc('\n',fp); } if ( tmp % 5 != 1 ) putc('\n',fp); } } /* px_dump -- prints a dump of all pointers and data in a onto fp -- suitable for low-level debugging */ #ifndef ANSI_C void px_dump(fp,px) FILE *fp; PERM *px; #else void px_dump(FILE *fp, const PERM *px) #endif { unsigned int i; if ( ! px ) { fprintf(fp,"Permutation: NULL\n"); return; } fprintf(fp,"Permutation: size: %u @ 0x%lx\n",px->size,(long)(px)); if ( ! px->pe ) { fprintf(fp,"NULL\n"); return; } fprintf(fp,"px->pe @ 0x%lx\n",(long)(px->pe)); for ( i=0; isize; i++ ) fprintf(fp,"%u->%u ",i,px->pe[i]); fprintf(fp,"\n"); } /* v_dump -- prints a dump of all pointers and data in a onto fp -- suitable for low-level debugging */ #ifndef ANSI_C void v_dump(fp,x) FILE *fp; VEC *x; #else void v_dump(FILE *fp, const VEC *x) #endif { unsigned int i, tmp; if ( ! x ) { fprintf(fp,"Vector: NULL\n"); return; } fprintf(fp,"Vector: dim: %d @ 0x%lx\n",x->dim,(long)(x)); if ( ! x->ve ) { fprintf(fp,"NULL\n"); return; } fprintf(fp,"x->ve @ 0x%lx\n",(long)(x->ve)); for ( i=0, tmp=0; idim; i++, tmp++ ) { fprintf(fp,format,x->ve[i]); if ( tmp % 5 == 4 ) putc('\n',fp); } if ( tmp % 5 != 0 ) putc('\n',fp); } /* iv_foutput -- print a representation of iv on stream fp */ #ifndef ANSI_C void iv_foutput(fp,iv) FILE *fp; IVEC *iv; #else void iv_foutput(FILE *fp, const IVEC *iv) #endif { int i; fprintf(fp,"IntVector: "); if ( iv == IVNULL ) { fprintf(fp,"**** NULL ****\n"); return; } fprintf(fp,"dim: %d\n",iv->dim); for ( i = 0; i < iv->dim; i++ ) { if ( (i+1) % 8 ) fprintf(fp,"%8d ",iv->ive[i]); else fprintf(fp,"%8d\n",iv->ive[i]); } if ( i % 8 ) fprintf(fp,"\n"); } /* iv_finput -- input integer vector from stream fp -- input from a terminal is handled interactively -- batch/file input has the same format as produced by iv_foutput except that whitespace and comments ("#...\n") are skipped */ #ifndef ANSI_C IVEC *iv_finput(fp,x) FILE *fp; IVEC *x; #else IVEC *iv_finput(FILE *fp, IVEC *x) #endif { IVEC *iiv_finput(),*biv_finput(); if ( isatty(fileno(fp)) ) return iiv_finput(fp,x); else return biv_finput(fp,x); } /* iiv_finput -- interactive input of IVEC iv */ #ifndef ANSI_C IVEC *iiv_finput(fp,iv) FILE *fp; IVEC *iv; #else IVEC *iiv_finput(FILE *fp, IVEC *iv) #endif { unsigned int i,dim,dynamic; /* dynamic set if memory allocated here */ /* get dimension */ if ( iv != (IVEC *)NULL && iv->dimdim; dynamic = FALSE; } else { dynamic = TRUE; do { fprintf(stderr,"IntVector: dim: "); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"iiv_finput"); } while ( sscanf(line,"%u",&dim)<1 || dim>MAXDIM ); iv = iv_get(dim); } /* input elements */ for ( i=0; iive[i]); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"iiv_finput"); if ( (*line == 'b' || *line == 'B') && i > 0 ) { i--; dynamic = FALSE; goto redo; } if ( (*line == 'f' || *line == 'F') && i < dim-1 ) { i++; dynamic = FALSE; goto redo; } } while ( *line=='\0' || sscanf(line,"%d",&iv->ive[i]) < 1 ); return (iv); } /* biv_finput -- batch-file input of IVEC iv */ #ifndef ANSI_C IVEC *biv_finput(fp,iv) FILE *fp; IVEC *iv; #else IVEC *biv_finput(FILE *fp, IVEC *iv) #endif { unsigned int i,dim; int io_code; /* get dimension */ skipjunk(fp); if ((io_code=fscanf(fp," IntVector: dim:%u",&dim)) < 1 || dim>MAXDIM ) error(io_code==EOF ? 7 : 6,"biv_finput"); /* allocate memory if necessary */ if ( iv==(IVEC *)NULL || iv->dimive[i])) < 1 ) error(io_code==EOF ? 7 : 6,"biv_finput"); return (iv); } /* iv_dump -- dumps all the contents of IVEC iv onto stream fp */ #ifndef ANSI_C void iv_dump(fp,iv) FILE*fp; IVEC*iv; #else void iv_dump(FILE *fp, const IVEC *iv) #endif { int i; fprintf(fp,"IntVector: "); if ( ! iv ) { fprintf(fp,"**** NULL ****\n"); return; } fprintf(fp,"dim: %d, max_dim: %d\n",iv->dim,iv->max_dim); fprintf(fp,"ive @ 0x%lx\n",(long)(iv->ive)); for ( i = 0; i < iv->max_dim; i++ ) { if ( (i+1) % 8 ) fprintf(fp,"%8d ",iv->ive[i]); else fprintf(fp,"%8d\n",iv->ive[i]); } if ( i % 8 ) fprintf(fp,"\n"); } gtk-wave-cleaner-0.22-04/meschach/maxint.c0000777000175000017500000000235113120075106021424 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ main() { int i, old_i; i = 1; while ( i > 0 ) { old_i = i; i = (i << 1) | 1; } printf("%d\n", old_i); } gtk-wave-cleaner-0.22-04/meschach/meminfo.c0000777000175000017500000002405513120075106021563 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* meminfo.c revised 22/11/93 */ /* contains basic functions, types and arrays to keep track of memory allocation/deallocation */ #include #include "matrix.h" #include "meminfo.h" #ifdef COMPLEX #include "zmatrix.h" #endif #ifdef SPARSE #include "sparse.h" #include "iter.h" #endif static char rcsid[] = "$Id: meminfo.c,v 1.1 1994/01/13 05:31:39 des Exp $"; /* this array is defined further in this file */ extern MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS]; /* names of types */ static char *mem_type_names[] = { "MAT", "BAND", "PERM", "VEC", "IVEC" #ifdef SPARSE ,"ITER", "SPROW", "SPMAT" #endif #ifdef COMPLEX ,"ZVEC", "ZMAT" #endif }; #define MEM_NUM_STD_TYPES (sizeof(mem_type_names)/sizeof(mem_type_names[0])) /* local array for keeping track of memory */ static MEM_ARRAY mem_info_sum[MEM_NUM_STD_TYPES]; /* for freeing various types */ static int (*mem_free_funcs[MEM_NUM_STD_TYPES])() = { m_free, bd_free, px_free, v_free, iv_free #ifdef SPARSE ,iter_free, sprow_free, sp_free #endif #ifdef COMPLEX ,zv_free, zm_free #endif }; /* it is a global variable for passing pointers to local arrays defined here */ MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS] = { { mem_type_names, mem_free_funcs, MEM_NUM_STD_TYPES, mem_info_sum } }; /* attach a new list of types */ #ifndef ANSI_C int mem_attach_list(list, ntypes, type_names, free_funcs, info_sum) int list,ntypes; /* number of a list and number of types there */ char *type_names[]; /* list of names of types */ int (*free_funcs[])(); /* list of releasing functions */ MEM_ARRAY info_sum[]; /* local table */ #else int mem_attach_list(int list, int ntypes, char *type_names[], int (*free_funcs[])(void *), MEM_ARRAY info_sum[]) #endif { if (list < 0 || list >= MEM_CONNECT_MAX_LISTS) return -1; if (type_names == NULL || free_funcs == NULL || info_sum == NULL || ntypes < 0) return -1; /* if a list exists do not overwrite */ if ( mem_connect[list].ntypes != 0 ) error(E_OVERWRITE,"mem_attach_list"); mem_connect[list].ntypes = ntypes; mem_connect[list].type_names = type_names; mem_connect[list].free_funcs = free_funcs; mem_connect[list].info_sum = info_sum; return 0; } /* release a list of types */ #ifndef ANSI_C int mem_free_vars(list) int list; #else int mem_free_vars(int list) #endif { if (list < 0 || list >= MEM_CONNECT_MAX_LISTS) return -1; mem_connect[list].ntypes = 0; mem_connect[list].type_names = NULL; mem_connect[list].free_funcs = NULL; mem_connect[list].info_sum = NULL; return 0; } /* check if list is attached */ #ifndef ANSI_C int mem_is_list_attached(list) int list; #else int mem_is_list_attached(int list) #endif { if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS ) return FALSE; if ( mem_connect[list].type_names != NULL && mem_connect[list].free_funcs != NULL && mem_connect[list].info_sum != NULL) return TRUE; else return FALSE; } /* to print out the contents of mem_connect[list] */ #ifndef MEX #ifndef ANSI_C void mem_dump_list(fp,list) FILE *fp; int list; #else void mem_dump_list(FILE *fp, int list) #endif { int i; MEM_CONNECT *mlist; if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS ) return; mlist = &mem_connect[list]; fprintf(fp," %15s[%d]:\n","CONTENTS OF mem_connect",list); fprintf(fp," %-7s %-12s %-9s %s\n", "name of", "alloc.", "# alloc.", "address" ); fprintf(fp," %-7s %-12s %-9s %s\n", " type", "bytes", "variables", "of *_free()" ); for (i=0; i < mlist->ntypes; i++) fprintf(fp," %-7s %-12ld %-9d %p\n", mlist->type_names[i], mlist->info_sum[i].bytes, mlist->info_sum[i].numvar, mlist->free_funcs[i] ); fprintf(fp,"\n"); } #endif /* MEX */ /*=============================================================*/ /* local variables */ static int mem_switched_on = MEM_SWITCH_ON_DEF; /* on/off */ /* switch on/off memory info */ #ifndef ANSI_C int mem_info_on(sw) int sw; #else int mem_info_on(int sw) #endif { int old = mem_switched_on; mem_switched_on = sw; return old; } #ifdef ANSI_C int mem_info_is_on(void) #else int mem_info_is_on() #endif { return mem_switched_on; } /* information about allocated memory */ /* return the number of allocated bytes for type 'type' */ #ifndef ANSI_C long mem_info_bytes(type,list) int type,list; #else long mem_info_bytes(int type, int list) #endif { if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS ) return 0l; if ( !mem_switched_on || type < 0 || type >= mem_connect[list].ntypes || mem_connect[list].free_funcs[type] == NULL ) return 0l; return mem_connect[list].info_sum[type].bytes; } /* return the number of allocated variables for type 'type' */ #ifndef ANSI_C int mem_info_numvar(type,list) int type,list; #else int mem_info_numvar(int type, int list) #endif { if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS ) return 0l; if ( !mem_switched_on || type < 0 || type >= mem_connect[list].ntypes || mem_connect[list].free_funcs[type] == NULL ) return 0l; return mem_connect[list].info_sum[type].numvar; } #ifndef MEX /* print out memory info to the file fp */ #ifndef ANSI_C void mem_info_file(fp,list) FILE *fp; int list; #else void mem_info_file(FILE *fp, int list) #endif { unsigned int type; long t = 0l, d; int n = 0, nt = 0; MEM_CONNECT *mlist; if (!mem_switched_on) return; if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS ) return; if (list == 0) fprintf(fp," MEMORY INFORMATION (standard types):\n"); else fprintf(fp," MEMORY INFORMATION (list no. %d):\n",list); mlist = &mem_connect[list]; for (type=0; type < mlist->ntypes; type++) { if (mlist->type_names[type] == NULL ) continue; d = mlist->info_sum[type].bytes; t += d; n = mlist->info_sum[type].numvar; nt += n; fprintf(fp," type %-7s %10ld alloc. byte%c %6d alloc. variable%c\n", mlist->type_names[type], d, (d!=1 ? 's' : ' '), n, (n!=1 ? 's' : ' ')); } fprintf(fp," %-12s %10ld alloc. byte%c %6d alloc. variable%c\n\n", "total:",t, (t!=1 ? 's' : ' '), nt, (nt!=1 ? 's' : ' ')); } #endif /* function for memory information */ /* mem_bytes_list Arguments: type - the number of type; old_size - old size of allocated memory (in bytes); new_size - new size of allocated memory (in bytes); list - list of types */ #ifndef ANSI_C void mem_bytes_list(type,old_size,new_size,list) int type,list; int old_size,new_size; #else void mem_bytes_list(int type, int old_size, int new_size, int list) #endif { MEM_CONNECT *mlist; if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS ) return; mlist = &mem_connect[list]; if ( type < 0 || type >= mlist->ntypes || mlist->free_funcs[type] == NULL ) return; if ( old_size < 0 || new_size < 0 ) error(E_NEG,"mem_bytes_list"); mlist->info_sum[type].bytes += new_size - old_size; /* check if the number of bytes is non-negative */ if ( old_size > 0 ) { if (mlist->info_sum[type].bytes < 0) { #ifndef MEX fprintf(stderr, "\n WARNING !! memory info: allocated memory is less than 0\n"); fprintf(stderr,"\t TYPE %s \n\n", mlist->type_names[type]); if ( !isatty(fileno(stdout)) ) { fprintf(stdout, "\n WARNING !! memory info: allocated memory is less than 0\n"); fprintf(stdout,"\t TYPE %s \n\n", mlist->type_names[type]); } #else mexPrintf("\n WARNING !! memory info: allocated memory < 0\n"); mexPrintf("\t TYPE %s \n\n", mlist->type_names[type]); #endif } } } /* mem_numvar_list Arguments: type - the number of type; num - # of variables allocated (> 0) or deallocated ( < 0) list - list of types */ #ifndef ANSI_C void mem_numvar_list(type,num,list) int type,list,num; #else void mem_numvar_list(int type, int num, int list) #endif { MEM_CONNECT *mlist; if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS ) return; mlist = &mem_connect[list]; if ( type < 0 || type >= mlist->ntypes || mlist->free_funcs[type] == NULL ) return; mlist->info_sum[type].numvar += num; /* check if the number of variables is non-negative */ if ( num < 0 ) { if (mlist->info_sum[type].numvar < 0) { #ifndef MEX fprintf(stderr, "\n WARNING !! memory info: allocated # of variables is less than 0\n"); fprintf(stderr,"\t TYPE %s \n\n", mlist->type_names[type]); if ( !isatty(fileno(stdout)) ) { fprintf(stdout, "\n WARNING !! memory info: allocated # of variables is less than 0\n"); fprintf(stdout,"\t TYPE %s \n\n", mlist->type_names[type]); } #else mexPrintf("\n WARNING !! memory info: allocated # of variables < 0\n"); mexPrintf(stderr,"\t TYPE %s \n\n", mlist->type_names[type]); #endif } } } gtk-wave-cleaner-0.22-04/meschach/meminfo.h0000777000175000017500000001052113120075106021561 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* meminfo.h 26/08/93 */ /* changed 11/12/93 */ #ifndef MEM_INFOH #define MEM_INFOH /* for hash table in mem_stat.c */ /* Note: the hash size should be a prime, or at very least odd */ #define MEM_HASHSIZE 509 #define MEM_HASHSIZE_FILE "meminfo.h" /* default: memory information is off */ /* set it to 1 if you want it all the time */ #define MEM_SWITCH_ON_DEF 0 /* available standard types */ #define TYPE_NULL (-1) #define TYPE_MAT 0 #define TYPE_BAND 1 #define TYPE_PERM 2 #define TYPE_VEC 3 #define TYPE_IVEC 4 #ifdef SPARSE #define TYPE_ITER 5 #define TYPE_SPROW 6 #define TYPE_SPMAT 7 #endif #ifdef COMPLEX #ifdef SPARSE #define TYPE_ZVEC 8 #define TYPE_ZMAT 9 #else #define TYPE_ZVEC 5 #define TYPE_ZMAT 6 #endif #endif /* structure for memory information */ typedef struct { long bytes; /* # of allocated bytes for each type (summary) */ int numvar; /* # of allocated variables for each type */ } MEM_ARRAY; #ifdef ANSI_C int mem_info_is_on(void); int mem_info_on(int sw); long mem_info_bytes(int type,int list); int mem_info_numvar(int type,int list); void mem_info_file(FILE * fp,int list); void mem_bytes_list(int type,int old_size,int new_size, int list); void mem_numvar_list(int type, int num, int list); #ifndef THREADSAFE int mem_stat_reg_list(void **var,int type,int list,char *fname,int line); int mem_stat_mark(int mark); int mem_stat_free_list(int mark,int list); int mem_stat_show_mark(void); void mem_stat_dump(FILE *fp,int list); int mem_attach_list(int list,int ntypes,char *type_names[], int (*free_funcs[])(), MEM_ARRAY info_sum[]); int mem_free_vars(int list); int mem_is_list_attached(int list); void mem_dump_list(FILE *fp,int list); int mem_stat_reg_vars(int list,int type,char *fname,int line,...); #endif /* THREADSAFE */ #else int mem_info_is_on(); int mem_info_on(); long mem_info_bytes(); int mem_info_numvar(); void mem_info_file(); void mem_bytes_list(); void mem_numvar_list(); #ifndef THREADSAFE int mem_stat_reg_list(); int mem_stat_mark(); int mem_stat_free_list(); int mem_stat_show_mark(); void mem_stat_dump(); int mem_attach_list(); int mem_free_vars(); int mem_is_list_attached(); void mem_dump_list(); int mem_stat_reg_vars(); #endif /* THREADSAFE */ #endif /* macros */ #define mem_info() mem_info_file(stdout,0) #ifndef THREADSAFE #define mem_stat_reg(var,type) mem_stat_reg_list((void **)var,type,0,__FILE__,__LINE__) #define MEM_STAT_REG(var,type) mem_stat_reg_list((void **)&(var),type,0,__FILE__,__LINE__) #define mem_stat_free(mark) mem_stat_free_list(mark,0) #else #define mem_stat_reg(var,type) #define MEM_STAT_REG(var,type) #define mem_stat_free(mark) #endif #define mem_bytes(type,old_size,new_size) \ mem_bytes_list(type,old_size,new_size,0) #define mem_numvar(type,num) mem_numvar_list(type,num,0) /* internal type */ typedef struct { char **type_names; /* array of names of types (strings) */ int (**free_funcs)(); /* array of functions for releasing types */ unsigned ntypes; /* max number of types */ MEM_ARRAY *info_sum; /* local array for keeping track of memory */ } MEM_CONNECT; /* max number of lists of types */ #define MEM_CONNECT_MAX_LISTS 5 #endif gtk-wave-cleaner-0.22-04/meschach/memory.c0000777000175000017500000005032713120075106021442 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* memory.c 1.3 11/25/87 */ #include "matrix.h" static char rcsid[] = "$Id: memory.c,v 1.13 1994/04/05 02:10:37 des Exp $"; /* m_get -- gets an mxn matrix (in MAT form) by dynamic memory allocation -- normally ALL matrices should be obtained this way -- if either m or n is negative this will raise an error -- note that 0 x n and m x 0 matrices can be created */ #ifndef ANSI_C MAT *m_get(m,n) int m,n; #else MAT *m_get(int m, int n) #endif { MAT *matrix; int i; if (m < 0 || n < 0) error(E_NEG,"m_get"); if ((matrix=NEW(MAT)) == (MAT *)NULL ) error(E_MEM,"m_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_MAT,0,sizeof(MAT)); mem_numvar(TYPE_MAT,1); } matrix->m = m; matrix->n = matrix->max_n = n; matrix->max_m = m; matrix->max_size = m*n; #ifndef SEGMENTED if ((matrix->base = NEW_A(m*n,Real)) == (Real *)NULL ) { free(matrix); error(E_MEM,"m_get"); } else if (mem_info_is_on()) { mem_bytes(TYPE_MAT,0,m*n*sizeof(Real)); } #else matrix->base = (Real *)NULL; #endif if ((matrix->me = (Real **)calloc(m,sizeof(Real *))) == (Real **)NULL ) { free(matrix->base); free(matrix); error(E_MEM,"m_get"); } else if (mem_info_is_on()) { mem_bytes(TYPE_MAT,0,m*sizeof(Real *)); } #ifndef SEGMENTED /* set up pointers */ for ( i=0; ime[i] = &(matrix->base[i*n]); #else for ( i = 0; i < m; i++ ) if ( (matrix->me[i]=NEW_A(n,Real)) == (Real *)NULL ) error(E_MEM,"m_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_MAT,0,n*sizeof(Real)); } #endif return (matrix); } /* px_get -- gets a PERM of given 'size' by dynamic memory allocation -- Note: initialized to the identity permutation -- the permutation is on the set {0,1,2,...,size-1} */ #ifndef ANSI_C PERM *px_get(size) int size; #else PERM *px_get(int size) #endif { PERM *permute; int i; if (size < 0) error(E_NEG,"px_get"); if ((permute=NEW(PERM)) == (PERM *)NULL ) error(E_MEM,"px_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_PERM,0,sizeof(PERM)); mem_numvar(TYPE_PERM,1); } permute->size = permute->max_size = size; if ((permute->pe = NEW_A(size,unsigned int)) == (unsigned int *)NULL ) error(E_MEM,"px_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_PERM,0,size*sizeof(unsigned int)); } for ( i=0; ipe[i] = i; return (permute); } /* v_get -- gets a VEC of dimension 'size' -- Note: initialized to zero */ #ifndef ANSI_C VEC *v_get(size) int size; #else VEC *v_get(int size) #endif { VEC *vector; if (size < 0) error(E_NEG,"v_get"); if ((vector=NEW(VEC)) == (VEC *)NULL ) error(E_MEM,"v_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_VEC,0,sizeof(VEC)); mem_numvar(TYPE_VEC,1); } vector->dim = vector->max_dim = size; if ((vector->ve=NEW_A(size,Real)) == (Real *)NULL ) { free(vector); error(E_MEM,"v_get"); } else if (mem_info_is_on()) { mem_bytes(TYPE_VEC,0,size*sizeof(Real)); } return (vector); } /* m_free -- returns MAT & asoociated memory back to memory heap */ #ifndef ANSI_C int m_free(mat) MAT *mat; #else int m_free(MAT *mat) #endif { #ifdef SEGMENTED int i; #endif if ( mat==(MAT *)NULL || (int)(mat->m) < 0 || (int)(mat->n) < 0 ) /* don't trust it */ return (-1); #ifndef SEGMENTED if ( mat->base != (Real *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_MAT,mat->max_m*mat->max_n*sizeof(Real),0); } free((char *)(mat->base)); } #else for ( i = 0; i < mat->max_m; i++ ) if ( mat->me[i] != (Real *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_MAT,mat->max_n*sizeof(Real),0); } free((char *)(mat->me[i])); } #endif if ( mat->me != (Real **)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_MAT,mat->max_m*sizeof(Real *),0); } free((char *)(mat->me)); } if (mem_info_is_on()) { mem_bytes(TYPE_MAT,sizeof(MAT),0); mem_numvar(TYPE_MAT,-1); } free((char *)mat); return (0); } /* px_free -- returns PERM & asoociated memory back to memory heap */ #ifndef ANSI_C int px_free(px) PERM *px; #else int px_free(PERM *px) #endif { if ( px==(PERM *)NULL || (int)(px->size) < 0 ) /* don't trust it */ return (-1); if ( px->pe == (unsigned int *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_PERM,sizeof(PERM),0); mem_numvar(TYPE_PERM,-1); } free((char *)px); } else { if (mem_info_is_on()) { mem_bytes(TYPE_PERM,sizeof(PERM)+px->max_size*sizeof(unsigned int),0); mem_numvar(TYPE_PERM,-1); } free((char *)px->pe); free((char *)px); } return (0); } /* v_free -- returns VEC & asoociated memory back to memory heap */ #ifndef ANSI_C int v_free(vec) VEC *vec; #else int v_free(VEC *vec) #endif { if ( vec==(VEC *)NULL || (int)(vec->dim) < 0 ) /* don't trust it */ return (-1); if ( vec->ve == (Real *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_VEC,sizeof(VEC),0); mem_numvar(TYPE_VEC,-1); } free((char *)vec); } else { if (mem_info_is_on()) { mem_bytes(TYPE_VEC,sizeof(VEC)+vec->max_dim*sizeof(Real),0); mem_numvar(TYPE_VEC,-1); } free((char *)vec->ve); free((char *)vec); } return (0); } /* m_resize -- returns the matrix A of size new_m x new_n; A is zeroed -- if A == NULL on entry then the effect is equivalent to m_get() */ #ifndef ANSI_C MAT *m_resize(A,new_m,new_n) MAT *A; int new_m, new_n; #else MAT *m_resize(MAT *A,int new_m, int new_n) #endif { int i; int new_max_m, new_max_n, new_size, old_m, old_n; if (new_m < 0 || new_n < 0) error(E_NEG,"m_resize"); if ( ! A ) return m_get(new_m,new_n); /* nothing was changed */ if (new_m == A->m && new_n == A->n) return A; old_m = A->m; old_n = A->n; if ( new_m > A->max_m ) { /* re-allocate A->me */ if (mem_info_is_on()) { mem_bytes(TYPE_MAT,A->max_m*sizeof(Real *), new_m*sizeof(Real *)); } A->me = RENEW(A->me,new_m,Real *); if ( ! A->me ) error(E_MEM,"m_resize"); } new_max_m = max(new_m,A->max_m); new_max_n = max(new_n,A->max_n); #ifndef SEGMENTED new_size = new_max_m*new_max_n; if ( new_size > A->max_size ) { /* re-allocate A->base */ if (mem_info_is_on()) { mem_bytes(TYPE_MAT,A->max_m*A->max_n*sizeof(Real), new_size*sizeof(Real)); } A->base = RENEW(A->base,new_size,Real); if ( ! A->base ) error(E_MEM,"m_resize"); A->max_size = new_size; } /* now set up A->me[i] */ for ( i = 0; i < new_m; i++ ) A->me[i] = &(A->base[i*new_n]); /* now shift data in matrix */ if ( old_n > new_n ) { for ( i = 1; i < min(old_m,new_m); i++ ) MEM_COPY((char *)&(A->base[i*old_n]), (char *)&(A->base[i*new_n]), sizeof(Real)*new_n); } else if ( old_n < new_n ) { for ( i = (int)(min(old_m,new_m))-1; i > 0; i-- ) { /* copy & then zero extra space */ MEM_COPY((char *)&(A->base[i*old_n]), (char *)&(A->base[i*new_n]), sizeof(Real)*old_n); __zero__(&(A->base[i*new_n+old_n]),(new_n-old_n)); } __zero__(&(A->base[old_n]),(new_n-old_n)); A->max_n = new_n; } /* zero out the new rows.. */ for ( i = old_m; i < new_m; i++ ) __zero__(&(A->base[i*new_n]),new_n); #else if ( A->max_n < new_n ) { Real *tmp; for ( i = 0; i < A->max_m; i++ ) { if (mem_info_is_on()) { mem_bytes(TYPE_MAT,A->max_n*sizeof(Real), new_max_n*sizeof(Real)); } if ( (tmp = RENEW(A->me[i],new_max_n,Real)) == NULL ) error(E_MEM,"m_resize"); else { A->me[i] = tmp; } } for ( i = A->max_m; i < new_max_m; i++ ) { if ( (tmp = NEW_A(new_max_n,Real)) == NULL ) error(E_MEM,"m_resize"); else { A->me[i] = tmp; if (mem_info_is_on()) { mem_bytes(TYPE_MAT,0,new_max_n*sizeof(Real)); } } } } else if ( A->max_m < new_m ) { for ( i = A->max_m; i < new_m; i++ ) if ( (A->me[i] = NEW_A(new_max_n,Real)) == NULL ) error(E_MEM,"m_resize"); else if (mem_info_is_on()) { mem_bytes(TYPE_MAT,0,new_max_n*sizeof(Real)); } } if ( old_n < new_n ) { for ( i = 0; i < old_m; i++ ) __zero__(&(A->me[i][old_n]),new_n-old_n); } /* zero out the new rows.. */ for ( i = old_m; i < new_m; i++ ) __zero__(A->me[i],new_n); #endif A->max_m = new_max_m; A->max_n = new_max_n; A->max_size = A->max_m*A->max_n; A->m = new_m; A->n = new_n; return A; } /* px_resize -- returns the permutation px with size new_size -- px is set to the identity permutation */ #ifndef ANSI_C PERM *px_resize(px,new_size) PERM *px; int new_size; #else PERM *px_resize(PERM *px, int new_size) #endif { int i; if (new_size < 0) error(E_NEG,"px_resize"); if ( ! px ) return px_get(new_size); /* nothing is changed */ if (new_size == px->size) return px; if ( new_size > px->max_size ) { if (mem_info_is_on()) { mem_bytes(TYPE_PERM,px->max_size*sizeof(unsigned int), new_size*sizeof(unsigned int)); } px->pe = RENEW(px->pe,new_size,unsigned int); if ( ! px->pe ) error(E_MEM,"px_resize"); px->max_size = new_size; } if ( px->size <= new_size ) /* extend permutation */ for ( i = px->size; i < new_size; i++ ) px->pe[i] = i; else for ( i = 0; i < new_size; i++ ) px->pe[i] = i; px->size = new_size; return px; } /* v_resize -- returns the vector x with dim new_dim -- x is set to the zero vector */ #ifndef ANSI_C VEC *v_resize(x,new_dim) VEC *x; int new_dim; #else VEC *v_resize(VEC *x, int new_dim) #endif { if (new_dim < 0) error(E_NEG,"v_resize"); if ( ! x ) return v_get(new_dim); /* nothing is changed */ if (new_dim == x->dim) return x; if ( x->max_dim == 0 ) /* assume that it's from sub_vec */ return v_get(new_dim); if ( new_dim > x->max_dim ) { if (mem_info_is_on()) { mem_bytes(TYPE_VEC,x->max_dim*sizeof(Real), new_dim*sizeof(Real)); } x->ve = RENEW(x->ve,new_dim,Real); if ( ! x->ve ) error(E_MEM,"v_resize"); x->max_dim = new_dim; } if ( new_dim > x->dim ) __zero__(&(x->ve[x->dim]),new_dim - x->dim); x->dim = new_dim; return x; } /* Varying number of arguments */ /* other functions of this type are in sparse.c and zmemory.c */ #ifdef ANSI_C /* To allocate memory to many arguments. The function should be called: v_get_vars(dim,&x,&y,&z,...,NULL); where int dim; VEC *x, *y, *z,...; The last argument should be NULL ! dim is the length of vectors x,y,z,... returned value is equal to the number of allocated variables Other gec_... functions are similar. */ int v_get_vars(int dim,...) { va_list ap; int i=0; VEC **par; va_start(ap, dim); while (par = va_arg(ap,VEC **)) { /* NULL ends the list*/ *par = v_get(dim); i++; } va_end(ap); return i; } int iv_get_vars(int dim,...) { va_list ap; int i=0; IVEC **par; va_start(ap, dim); while (par = va_arg(ap,IVEC **)) { /* NULL ends the list*/ *par = iv_get(dim); i++; } va_end(ap); return i; } int m_get_vars(int m,int n,...) { va_list ap; int i=0; MAT **par; va_start(ap, n); while (par = va_arg(ap,MAT **)) { /* NULL ends the list*/ *par = m_get(m,n); i++; } va_end(ap); return i; } int px_get_vars(int dim,...) { va_list ap; int i=0; PERM **par; va_start(ap, dim); while (par = va_arg(ap,PERM **)) { /* NULL ends the list*/ *par = px_get(dim); i++; } va_end(ap); return i; } /* To resize memory for many arguments. The function should be called: v_resize_vars(new_dim,&x,&y,&z,...,NULL); where int new_dim; VEC *x, *y, *z,...; The last argument should be NULL ! rdim is the resized length of vectors x,y,z,... returned value is equal to the number of allocated variables. If one of x,y,z,.. arguments is NULL then memory is allocated to this argument. Other *_resize_list() functions are similar. */ int v_resize_vars(int new_dim,...) { va_list ap; int i=0; VEC **par; va_start(ap, new_dim); while (par = va_arg(ap,VEC **)) { /* NULL ends the list*/ *par = v_resize(*par,new_dim); i++; } va_end(ap); return i; } int iv_resize_vars(int new_dim,...) { va_list ap; int i=0; IVEC **par; va_start(ap, new_dim); while (par = va_arg(ap,IVEC **)) { /* NULL ends the list*/ *par = iv_resize(*par,new_dim); i++; } va_end(ap); return i; } int m_resize_vars(int m,int n,...) { va_list ap; int i=0; MAT **par; va_start(ap, n); while (par = va_arg(ap,MAT **)) { /* NULL ends the list*/ *par = m_resize(*par,m,n); i++; } va_end(ap); return i; } int px_resize_vars(int new_dim,...) { va_list ap; int i=0; PERM **par; va_start(ap, new_dim); while (par = va_arg(ap,PERM **)) { /* NULL ends the list*/ *par = px_resize(*par,new_dim); i++; } va_end(ap); return i; } /* To deallocate memory for many arguments. The function should be called: v_free_vars(&x,&y,&z,...,NULL); where VEC *x, *y, *z,...; The last argument should be NULL ! There must be at least one not NULL argument. returned value is equal to the number of allocated variables. Returned value of x,y,z,.. is VNULL. Other *_free_list() functions are similar. */ int v_free_vars(VEC **pv,...) { va_list ap; int i=1; VEC **par; v_free(*pv); *pv = VNULL; va_start(ap, pv); while (par = va_arg(ap,VEC **)) { /* NULL ends the list*/ v_free(*par); *par = VNULL; i++; } va_end(ap); return i; } int iv_free_vars(IVEC **ipv,...) { va_list ap; int i=1; IVEC **par; iv_free(*ipv); *ipv = IVNULL; va_start(ap, ipv); while (par = va_arg(ap,IVEC **)) { /* NULL ends the list*/ iv_free(*par); *par = IVNULL; i++; } va_end(ap); return i; } int px_free_vars(PERM **vpx,...) { va_list ap; int i=1; PERM **par; px_free(*vpx); *vpx = PNULL; va_start(ap, vpx); while (par = va_arg(ap,PERM **)) { /* NULL ends the list*/ px_free(*par); *par = PNULL; i++; } va_end(ap); return i; } int m_free_vars(MAT **va,...) { va_list ap; int i=1; MAT **par; m_free(*va); *va = MNULL; va_start(ap, va); while (par = va_arg(ap,MAT **)) { /* NULL ends the list*/ m_free(*par); *par = MNULL; i++; } va_end(ap); return i; } #elif VARARGS /* old varargs is used */ /* To allocate memory to many arguments. The function should be called: v_get_vars(dim,&x,&y,&z,...,VNULL); where int dim; VEC *x, *y, *z,...; The last argument should be VNULL ! dim is the length of vectors x,y,z,... */ int v_get_vars(va_alist) va_dcl { va_list ap; int dim,i=0; VEC **par; va_start(ap); dim = va_arg(ap,int); while (par = va_arg(ap,VEC **)) { /* NULL ends the list*/ *par = v_get(dim); i++; } va_end(ap); return i; } int iv_get_vars(va_alist) va_dcl { va_list ap; int i=0, dim; IVEC **par; va_start(ap); dim = va_arg(ap,int); while (par = va_arg(ap,IVEC **)) { /* NULL ends the list*/ *par = iv_get(dim); i++; } va_end(ap); return i; } int m_get_vars(va_alist) va_dcl { va_list ap; int i=0, n, m; MAT **par; va_start(ap); m = va_arg(ap,int); n = va_arg(ap,int); while (par = va_arg(ap,MAT **)) { /* NULL ends the list*/ *par = m_get(m,n); i++; } va_end(ap); return i; } int px_get_vars(va_alist) va_dcl { va_list ap; int i=0, dim; PERM **par; va_start(ap); dim = va_arg(ap,int); while (par = va_arg(ap,PERM **)) { /* NULL ends the list*/ *par = px_get(dim); i++; } va_end(ap); return i; } /* To resize memory for many arguments. The function should be called: v_resize_vars(new_dim,&x,&y,&z,...,NULL); where int new_dim; VEC *x, *y, *z,...; The last argument should be NULL ! rdim is the resized length of vectors x,y,z,... returned value is equal to the number of allocated variables. If one of x,y,z,.. arguments is NULL then memory is allocated to this argument. Other *_resize_list() functions are similar. */ int v_resize_vars(va_alist) va_dcl { va_list ap; int i=0, new_dim; VEC **par; va_start(ap); new_dim = va_arg(ap,int); while (par = va_arg(ap,VEC **)) { /* NULL ends the list*/ *par = v_resize(*par,new_dim); i++; } va_end(ap); return i; } int iv_resize_vars(va_alist) va_dcl { va_list ap; int i=0, new_dim; IVEC **par; va_start(ap); new_dim = va_arg(ap,int); while (par = va_arg(ap,IVEC **)) { /* NULL ends the list*/ *par = iv_resize(*par,new_dim); i++; } va_end(ap); return i; } int m_resize_vars(va_alist) va_dcl { va_list ap; int i=0, m, n; MAT **par; va_start(ap); m = va_arg(ap,int); n = va_arg(ap,int); while (par = va_arg(ap,MAT **)) { /* NULL ends the list*/ *par = m_resize(*par,m,n); i++; } va_end(ap); return i; } int px_resize_vars(va_alist) va_dcl { va_list ap; int i=0, new_dim; PERM **par; va_start(ap); new_dim = va_arg(ap,int); while (par = va_arg(ap,PERM **)) { /* NULL ends the list*/ *par = px_resize(*par,new_dim); i++; } va_end(ap); return i; } /* To deallocate memory for many arguments. The function should be called: v_free_vars(&x,&y,&z,...,NULL); where VEC *x, *y, *z,...; The last argument should be NULL ! returned value is equal to the number of allocated variables. Returned value of x,y,z,.. is VNULL. Other *_free_list() functions are similar. */ int v_free_vars(va_alist) va_dcl { va_list ap; int i=0; VEC **par; va_start(ap); while (par = va_arg(ap,VEC **)) { /* NULL ends the list*/ v_free(*par); *par = VNULL; i++; } va_end(ap); return i; } int iv_free_vars(va_alist) va_dcl { va_list ap; int i=0; IVEC **par; va_start(ap); while (par = va_arg(ap,IVEC **)) { /* NULL ends the list*/ iv_free(*par); *par = IVNULL; i++; } va_end(ap); return i; } int px_free_vars(va_alist) va_dcl { va_list ap; int i=0; PERM **par; va_start(ap); while (par = va_arg(ap,PERM **)) { /* NULL ends the list*/ px_free(*par); *par = PNULL; i++; } va_end(ap); return i; } int m_free_vars(va_alist) va_dcl { va_list ap; int i=0; MAT **par; va_start(ap); while (par = va_arg(ap,MAT **)) { /* NULL ends the list*/ m_free(*par); *par = MNULL; i++; } va_end(ap); return i; } #endif /* VARARGS */ gtk-wave-cleaner-0.22-04/meschach/memstat.c0000777000175000017500000002313613120075106021602 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* mem_stat.c 6/09/93 */ /* Deallocation of static arrays */ #include #include "matrix.h" #include "meminfo.h" #ifdef COMPLEX #include "zmatrix.h" #endif #ifdef SPARSE #include "sparse.h" #include "iter.h" #endif static char rcsid[] = "$Id: memstat.c,v 1.1 1994/01/13 05:32:44 des Exp $"; /* global variable */ extern MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS]; /* local type */ typedef struct { void **var; /* for &A, where A is a pointer */ int type; /* type of A */ int mark; /* what mark is chosen */ char *fname; /* source file name where last registered */ int line; /* line # of file where last registered */ } MEM_STAT_STRUCT; /* local variables */ /* how many marks are used */ static int mem_stat_mark_many = 0; /* current mark */ static int mem_stat_mark_curr = 0; static MEM_STAT_STRUCT mem_stat_var[MEM_HASHSIZE]; /* array of indices (+1) to mem_stat_var */ static unsigned int mem_hash_idx[MEM_HASHSIZE]; /* points to the first unused element in mem_hash_idx */ static unsigned int mem_hash_idx_end = 0; /* hashing function */ #ifndef ANSI_C static unsigned int mem_hash(ptr) void **ptr; #else static unsigned int mem_hash(void **ptr) #endif { unsigned long lp = (unsigned long)ptr; return (lp % MEM_HASHSIZE); } /* look for a place in mem_stat_var */ #ifndef ANSI_C static int mem_lookup(var) void **var; #else static int mem_lookup(void **var) #endif { int k, j; k = mem_hash(var); if (mem_stat_var[k].var == var) { return -1; } else if (mem_stat_var[k].var == NULL) { return k; } else { /* look for an empty place */ j = k; while (mem_stat_var[j].var != var && j < MEM_HASHSIZE && mem_stat_var[j].var != NULL) j++; if (mem_stat_var[j].var == NULL) return j; else if (mem_stat_var[j].var == var) return -1; else { /* if (j == MEM_HASHSIZE) */ j = 0; while (mem_stat_var[j].var != var && j < k && mem_stat_var[j].var != NULL) j++; if (mem_stat_var[j].var == NULL) return j; else if (mem_stat_var[j].var == var) return -1; else { /* if (j == k) */ fprintf(stderr, "\n WARNING !!! static memory: mem_stat_var is too small\n"); fprintf(stderr, " Increase MEM_HASHSIZE in file: %s (currently = %d)\n\n", MEM_HASHSIZE_FILE, MEM_HASHSIZE); if ( !isatty(fileno(stdout)) ) { fprintf(stdout, "\n WARNING !!! static memory: mem_stat_var is too small\n"); fprintf(stdout, " Increase MEM_HASHSIZE in file: %s (currently = %d)\n\n", MEM_HASHSIZE_FILE, MEM_HASHSIZE); } error(E_MEM,"mem_lookup"); } } } return -1; } /* register static variables; Input arguments: var - variable to be registered, type - type of this variable; list - list of types fname - source file name where last registered line - line number of source file returned value < 0 --> error, returned value == 0 --> not registered, returned value >= 0 --> registered with this mark; */ #ifndef ANSI_C int mem_stat_reg_list(var,type,list,fname,line) void **var; int type,list; char *fname; int line; #else int mem_stat_reg_list(void **var, int type, int list, char *fname, int line) #endif { int n; if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS ) return -1; if (mem_stat_mark_curr == 0) return 0; /* not registered */ if (var == NULL) return -1; /* error */ if ( type < 0 || type >= mem_connect[list].ntypes || mem_connect[list].free_funcs[type] == NULL ) { warning(WARN_WRONG_TYPE,"mem_stat_reg_list"); return -1; } if ((n = mem_lookup(var)) >= 0) { mem_stat_var[n].var = var; mem_stat_var[n].mark = mem_stat_mark_curr; mem_stat_var[n].type = type; mem_stat_var[n].fname = fname; mem_stat_var[n].line = line; /* save n+1, not n */ mem_hash_idx[mem_hash_idx_end++] = n+1; } return mem_stat_mark_curr; } /* set a mark; Input argument: mark - positive number denoting a mark; returned: mark if mark > 0, 0 if mark == 0, -1 if mark is negative. */ #ifndef ANSI_C int mem_stat_mark(mark) int mark; #else int mem_stat_mark(int mark) #endif { if (mark < 0) { mem_stat_mark_curr = 0; return -1; /* error */ } else if (mark == 0) { mem_stat_mark_curr = 0; return 0; } mem_stat_mark_curr = mark; mem_stat_mark_many++; return mark; } /* deallocate static variables; Input argument: mark - a positive number denoting the mark; Returned: -1 if mark < 0 (error); 0 if mark == 0; */ #ifndef ANSI_C int mem_stat_free_list(mark,list) int mark,list; #else int mem_stat_free_list(int mark, int list) #endif { unsigned int i,j; int (*free_fn)(); if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS || mem_connect[list].free_funcs == NULL ) return -1; if (mark < 0) { mem_stat_mark_curr = 0; return -1; } else if (mark == 0) { mem_stat_mark_curr = 0; return 0; } if (mem_stat_mark_many <= 0) { warning(WARN_NO_MARK,"mem_stat_free"); return -1; } #ifdef DEBUG printf("mem_stat_free: Freeing variables registered for mark %d\n", mark); #endif /* DEBUG */ /* deallocate the marked variables */ for (i=0; i < mem_hash_idx_end; i++) { j = mem_hash_idx[i]; if (j == 0) continue; else { j--; if (mem_stat_var[j].mark == mark) { free_fn = mem_connect[list].free_funcs[mem_stat_var[j].type]; #ifdef DEBUG printf("# Freeing variable(s) registered in file \"%s\", line %d\n", mem_stat_var[j].fname, mem_stat_var[j].line); #endif /* DEBUG */ if ( free_fn != NULL ) (*free_fn)(*mem_stat_var[j].var); else warning(WARN_WRONG_TYPE,"mem_stat_free"); *(mem_stat_var[j].var) = NULL; mem_stat_var[j].var = NULL; mem_stat_var[j].mark = 0; mem_stat_var[j].fname = NULL; mem_stat_var[j].line = 0; mem_hash_idx[i] = 0; } } } while (mem_hash_idx_end > 0 && mem_hash_idx[mem_hash_idx_end-1] == 0) mem_hash_idx_end--; mem_stat_mark_curr = 0; mem_stat_mark_many--; return 0; } /* only for diagnostic purposes */ #ifndef ANSI_C void mem_stat_dump(fp,list) FILE *fp; int list; #else void mem_stat_dump(FILE *fp, int list) #endif { unsigned int i,j,k=1; if ( list < 0 || list >= MEM_CONNECT_MAX_LISTS || mem_connect[list].free_funcs == NULL ) return; fprintf(fp," Array mem_stat_var (list no. %d):\n",list); for (i=0; i < mem_hash_idx_end; i++) { j = mem_hash_idx[i]; if (j == 0) continue; else { j--; fprintf(fp," %d. var = 0x%p, type = %s, mark = %d\n", k,mem_stat_var[j].var, mem_stat_var[j].type < mem_connect[list].ntypes && mem_connect[list].free_funcs[mem_stat_var[j].type] != NULL ? mem_connect[list].type_names[(int)mem_stat_var[j].type] : "???", mem_stat_var[j].mark); k++; } } fprintf(fp,"\n"); } /* query function about the current mark */ #ifdef ANSI_C int mem_stat_show_mark(void) #else int mem_stat_show_mark() #endif { return mem_stat_mark_curr; } /* Varying number of arguments */ #ifdef ANSI_C /* To allocate memory to many arguments. The function should be called: mem_stat_vars(list,type,&v1,&v2,&v3,...,VNULL); where int list,type; void **v1, **v2, **v3,...; The last argument should be VNULL ! type is the type of variables v1,v2,v3,... (of course they must be of the same type) */ int mem_stat_reg_vars(int list,int type,char *fname,int line, ...) { va_list ap; int i=0; void **par; /* va_start(ap, type); */ va_start(ap,line); /* Changed for Linux 7th Oct, 2003 */ while (par = va_arg(ap,void **)) { /* NULL ends the list*/ mem_stat_reg_list(par,type,list,fname,line); i++; } va_end(ap); return i; } #elif VARARGS /* old varargs is used */ /* To allocate memory to many arguments. The function should be called: mem_stat_vars(list,type,&v1,&v2,&v3,...,VNULL); where int list,type; void **v1, **v2, **v3,...; The last argument should be VNULL ! type is the type of variables v1,v2,v3,... (of course they must be of the same type) */ int mem_stat_reg_vars(va_alist) va_dcl { va_list ap; int type,list,i=0; void **par; va_start(ap); list = va_arg(ap,int); type = va_arg(ap,int); while (par = va_arg(ap,void **)) { /* NULL ends the list*/ mem_stat_reg_list(par,type,list); i++; } va_end(ap); return i; } #endif gtk-wave-cleaner-0.22-04/meschach/memtort.c0000777000175000017500000004204113120075106021613 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Tests for mem_info.c functions */ static char rcsid[] = "$Id: $"; #include #include #include "matrix2.h" #include "sparse2.h" #include "zmatrix2.h" #define errmesg(mesg) printf("Error: %s error: line %d\n",mesg,__LINE__) #define notice(mesg) printf("# Testing %s...\n",mesg) /* new types list */ extern MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS]; /* the number of a new list */ #define FOO_LIST 1 /* numbers of types */ #define TYPE_FOO_1 1 #define TYPE_FOO_2 2 typedef struct { int dim; int fix_dim; Real (*a)[10]; } FOO_1; typedef struct { int dim; int fix_dim; Real (*a)[2]; } FOO_2; FOO_1 *foo_1_get(dim) int dim; { FOO_1 *f; if ((f = (FOO_1 *)malloc(sizeof(FOO_1))) == NULL) error(E_MEM,"foo_1_get"); else if (mem_info_is_on()) { mem_bytes_list(TYPE_FOO_1,0,sizeof(FOO_1),FOO_LIST); mem_numvar_list(TYPE_FOO_1,1,FOO_LIST); } f->dim = dim; f->fix_dim = 10; if ((f->a = (Real (*)[10])malloc(dim*sizeof(Real [10]))) == NULL) error(E_MEM,"foo_1_get"); else if (mem_info_is_on()) mem_bytes_list(TYPE_FOO_1,0,dim*sizeof(Real [10]),FOO_LIST); return f; } FOO_2 *foo_2_get(dim) int dim; { FOO_2 *f; if ((f = (FOO_2 *)malloc(sizeof(FOO_2))) == NULL) error(E_MEM,"foo_2_get"); else if (mem_info_is_on()) { mem_bytes_list(TYPE_FOO_2,0,sizeof(FOO_2),FOO_LIST); mem_numvar_list(TYPE_FOO_2,1,FOO_LIST); } f->dim = dim; f->fix_dim = 2; if ((f->a = (Real (*)[2])malloc(dim*sizeof(Real [2]))) == NULL) error(E_MEM,"foo_2_get"); else if (mem_info_is_on()) mem_bytes_list(TYPE_FOO_2,0,dim*sizeof(Real [2]),FOO_LIST); return f; } int foo_1_free(f) FOO_1 *f; { if ( f != NULL) { if (mem_info_is_on()) { mem_bytes_list(TYPE_FOO_1,sizeof(FOO_1)+ f->dim*sizeof(Real [10]),0,FOO_LIST); mem_numvar_list(TYPE_FOO_1,-1,FOO_LIST); } free(f->a); free(f); } return 0; } int foo_2_free(f) FOO_2 *f; { if ( f != NULL) { if (mem_info_is_on()) { mem_bytes_list(TYPE_FOO_2,sizeof(FOO_2)+ f->dim*sizeof(Real [2]),0,FOO_LIST); mem_numvar_list(TYPE_FOO_2,-1,FOO_LIST); } free(f->a); free(f); } return 0; } char *foo_type_name[] = { "nothing", "FOO_1", "FOO_2" }; #define FOO_NUM_TYPES (sizeof(foo_type_name)/sizeof(*foo_type_name)) int (*foo_free_func[FOO_NUM_TYPES])() = { NULL, foo_1_free, foo_2_free }; static MEM_ARRAY foo_info_sum[FOO_NUM_TYPES]; /* px_rand -- generates sort-of random permutation */ PERM *px_rand(pi) PERM *pi; { int i, j, k; if ( ! pi ) error(E_NULL,"px_rand"); for ( i = 0; i < 3*pi->size; i++ ) { j = (rand() >> 8) % pi->size; k = (rand() >> 8) % pi->size; px_transp(pi,j,k); } return pi; } #ifdef SPARSE SPMAT *gen_non_symm(m,n) int m, n; { SPMAT *A; static PERM *px = PNULL; int i, j, k, k_max; Real s1; A = sp_get(m,n,8); px = px_resize(px,n); MEM_STAT_REG(px,TYPE_PERM); for ( i = 0; i < A->m; i++ ) { k_max = 1 + ((rand() >> 8) % 10); for ( k = 0; k < k_max; k++ ) { j = (rand() >> 8) % A->n; s1 = rand()/((double)MAX_RAND); sp_set_val(A,i,j,s1); } } /* to make it likely that A is nonsingular, use pivot... */ for ( i = 0; i < 2*A->n; i++ ) { j = (rand() >> 8) % A->n; k = (rand() >> 8) % A->n; px_transp(px,j,k); } for ( i = 0; i < A->n; i++ ) sp_set_val(A,i,px->pe[i],1.0); return A; } #endif void stat_test1(par) int par; { static MAT *AT = MNULL; static VEC *xt1 = VNULL, *yt1 = VNULL; static VEC *xt2 = VNULL, *yt2 = VNULL; static VEC *xt3 = VNULL, *yt3 = VNULL; static VEC *xt4 = VNULL, *yt4 = VNULL; AT = m_resize(AT,10,10); xt1 = v_resize(xt1,10); yt1 = v_resize(yt1,10); xt2 = v_resize(xt2,10); yt2 = v_resize(yt2,10); xt3 = v_resize(xt3,10); yt3 = v_resize(yt3,10); xt4 = v_resize(xt4,10); yt4 = v_resize(yt4,10); MEM_STAT_REG(AT,TYPE_MAT); #ifdef ANSI_C mem_stat_reg_vars(0,TYPE_VEC,__FILE__,__LINE__,&xt1,&xt2,&xt3,&xt4,&yt1, &yt2,&yt3,&yt4,NULL); #else #ifdef VARARGS mem_stat_reg_vars(0,TYPE_VEC,__FILE__,__LINE__,&xt1,&xt2,&xt3,&xt4,&yt1, &yt2,&yt3,&yt4,NULL); #else MEM_STAT_REG(xt1,TYPE_VEC); MEM_STAT_REG(yt1,TYPE_VEC); MEM_STAT_REG(xt2,TYPE_VEC); MEM_STAT_REG(yt2,TYPE_VEC); MEM_STAT_REG(xt3,TYPE_VEC); MEM_STAT_REG(yt3,TYPE_VEC); MEM_STAT_REG(xt4,TYPE_VEC); MEM_STAT_REG(yt4,TYPE_VEC); #endif #endif v_rand(xt1); m_rand(AT); mv_mlt(AT,xt1,yt1); } void stat_test2(par) int par; { static PERM *px = PNULL; static IVEC *ixt = IVNULL, *iyt = IVNULL; px = px_resize(px,10); ixt = iv_resize(ixt,10); iyt = iv_resize(iyt,10); MEM_STAT_REG(px,TYPE_PERM); MEM_STAT_REG(ixt,TYPE_IVEC); MEM_STAT_REG(iyt,TYPE_IVEC); px_rand(px); px_inv(px,px); } #ifdef SPARSE void stat_test3(par) int par; { static SPMAT *AT = (SPMAT *)NULL; static VEC *xt = VNULL, *yt = VNULL; static SPROW *r = (SPROW *) NULL; if (AT == (SPMAT *)NULL) AT = gen_non_symm(100,100); else AT = sp_resize(AT,100,100); xt = v_resize(xt,100); yt = v_resize(yt,100); if (r == NULL) r = sprow_get(100); MEM_STAT_REG(AT,TYPE_SPMAT); MEM_STAT_REG(xt,TYPE_VEC); MEM_STAT_REG(yt,TYPE_VEC); MEM_STAT_REG(r,TYPE_SPROW); v_rand(xt); sp_mv_mlt(AT,xt,yt); } #endif #ifdef COMPLEX void stat_test4(par) int par; { static ZMAT *AT = ZMNULL; static ZVEC *xt = ZVNULL, *yt = ZVNULL; AT = zm_resize(AT,10,10); xt = zv_resize(xt,10); yt = zv_resize(yt,10); MEM_STAT_REG(AT,TYPE_ZMAT); MEM_STAT_REG(xt,TYPE_ZVEC); MEM_STAT_REG(yt,TYPE_ZVEC); zv_rand(xt); zm_rand(AT); zmv_mlt(AT,xt,yt); } #endif void main(argc, argv) int argc; char *argv[]; { VEC *x = VNULL, *y = VNULL, *z = VNULL; PERM *pi1 = PNULL, *pi2 = PNULL, *pi3 = PNULL; MAT *A = MNULL, *B = MNULL, *C = MNULL; #ifdef SPARSE SPMAT *sA, *sB; SPROW *r; #endif IVEC *ix = IVNULL, *iy = IVNULL, *iz = IVNULL; int m,n,i,j,deg,k; Real s1,s2; #ifdef COMPLEX ZVEC *zx = ZVNULL, *zy = ZVNULL, *zz = ZVNULL; ZMAT *zA = ZMNULL, *zB = ZMNULL, *zC = ZMNULL; complex ONE; #endif /* variables for testing attaching new lists of types */ FOO_1 *foo_1; FOO_2 *foo_2; mem_info_on(TRUE); #if defined(ANSI_C) || defined(VARARGS) notice("vector initialize, copy & resize"); n = v_get_vars(15,&x,&y,&z,(VEC **)NULL); if (n != 3) { errmesg("v_get_vars"); printf(" n = %d (should be 3)\n",n); } v_rand(x); v_rand(y); z = v_copy(x,z); if ( v_norm2(v_sub(x,z,z)) >= MACHEPS ) errmesg("v_get_vars"); v_copy(x,y); n = v_resize_vars(10,&x,&y,&z,NULL); if ( n != 3 || v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("VEC copy/resize"); n = v_resize_vars(20,&x,&y,&z,NULL); if ( n != 3 || v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("VEC resize"); n = v_free_vars(&x,&y,&z,NULL); if (n != 3) errmesg("v_free_vars"); /* IVEC */ notice("int vector initialise, copy & resize"); n = iv_get_vars(15,&ix,&iy,&iz,NULL); if (n != 3) { errmesg("iv_get_vars"); printf(" n = %d (should be 3)\n",n); } for (i=0; i < ix->dim; i++) { ix->ive[i] = 2*i-1; iy->ive[i] = 3*i+2; } iz = iv_add(ix,iy,iz); for (i=0; i < ix->dim; i++) if ( iz->ive[i] != 5*i+1) errmesg("iv_get_vars"); n = iv_resize_vars(10,&ix,&iy,&iz,NULL); if ( n != 3) errmesg("IVEC copy/resize"); iv_add(ix,iy,iz); for (i=0; i < ix->dim; i++) if (iz->ive[i] != 5*i+1) errmesg("IVEC copy/resize"); n = iv_resize_vars(20,&ix,&iy,&iz,NULL); if ( n != 3 ) errmesg("IVEC resize"); iv_add(ix,iy,iz); for (i=0; i < 10; i++) if (iz->ive[i] != 5*i+1) errmesg("IVEC copy/resize"); n = iv_free_vars(&ix,&iy,&iz,NULL); if (n != 3) errmesg("iv_free_vars"); /* MAT */ notice("matrix initialise, copy & resize"); n = m_get_vars(10,10,&A,&B,&C,NULL); if (n != 3) { errmesg("m_get_vars"); printf(" n = %d (should be 3)\n",n); } m_rand(A); m_rand(B); C = m_copy(A,C); if ( m_norm_inf(m_sub(A,C,C)) >= MACHEPS ) errmesg("MAT copy"); m_copy(A,B); n = m_resize_vars(5,5,&A,&B,&C,NULL); if ( n != 3 || m_norm_inf(m_sub(A,B,C)) >= MACHEPS ) errmesg("MAT copy/resize"); n = m_resize_vars(20,20,&A,&B,NULL); if ( m_norm_inf(m_sub(A,B,C)) >= MACHEPS ) errmesg("MAT resize"); k = m_free_vars(&A,&B,&C,NULL); if ( k != 3 ) errmesg("MAT free"); /* PERM */ notice("permutation initialise, inverting & permuting vectors"); n = px_get_vars(15,&pi1,&pi2,&pi3,NULL); if (n != 3) { errmesg("px_get_vars"); printf(" n = %d (should be 3)\n",n); } v_get_vars(15,&x,&y,&z,NULL); px_rand(pi1); v_rand(x); px_vec(pi1,x,z); y = v_resize(y,x->dim); pxinv_vec(pi1,z,y); if ( v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("PERMute vector"); pi2 = px_inv(pi1,pi2); pi3 = px_mlt(pi1,pi2,pi3); for ( i = 0; i < pi3->size; i++ ) if ( pi3->pe[i] != i ) errmesg("PERM inverse/multiply"); px_resize_vars(20,&pi1,&pi2,&pi3,NULL); v_resize_vars(20,&x,&y,&z,NULL); px_rand(pi1); v_rand(x); px_vec(pi1,x,z); pxinv_vec(pi1,z,y); if ( v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("PERMute vector"); pi2 = px_inv(pi1,pi2); pi3 = px_mlt(pi1,pi2,pi3); for ( i = 0; i < pi3->size; i++ ) if ( pi3->pe[i] != i ) errmesg("PERM inverse/multiply"); n = px_free_vars(&pi1,&pi2,&pi3,NULL); if ( n != 3 ) errmesg("PERM px_free_vars"); #ifdef SPARSE /* set up two random sparse matrices */ m = 120; n = 100; deg = 5; notice("allocating sparse matrices"); k = sp_get_vars(m,n,deg,&sA,&sB,NULL); if (k != 2) { errmesg("sp_get_vars"); printf(" n = %d (should be 2)\n",k); } notice("setting and getting matrix entries"); for ( k = 0; k < m*deg; k++ ) { i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(sA,i,j,rand()/((Real)MAX_RAND)); i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(sB,i,j,rand()/((Real)MAX_RAND)); } for ( k = 0; k < 10; k++ ) { s1 = rand()/((Real)MAX_RAND); i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(sA,i,j,s1); s2 = sp_get_val(sA,i,j); if ( fabs(s1 - s2) >= MACHEPS ) { printf(" s1 = %g, s2 = %g, |s1 - s2| = %g\n", s1,s2,fabs(s1-s2)); break; } } if ( k < 10 ) errmesg("sp_set_val()/sp_get_val()"); /* check column access paths */ notice("resizing and access paths"); k = sp_resize_vars(sA->m+10,sA->n+10,&sA,&sB,NULL); if (k != 2) { errmesg("sp_get_vars"); printf(" n = %d (should be 2)\n",k); } for ( k = 0 ; k < 20; k++ ) { i = sA->m - 1 - ((rand() >> 8) % 10); j = sA->n - 1 - ((rand() >> 8) % 10); s1 = rand()/((Real)MAX_RAND); sp_set_val(sA,i,j,s1); if ( fabs(s1 - sp_get_val(sA,i,j)) >= MACHEPS ) break; } if ( k < 20 ) errmesg("sp_resize()"); sp_col_access(sA); if ( ! chk_col_access(sA) ) { errmesg("sp_col_access()"); } sp_diag_access(sA); for ( i = 0; i < sA->m; i++ ) { r = &(sA->row[i]); if ( r->diag != sprow_idx(r,i) ) break; } if ( i < sA->m ) { errmesg("sp_diag_access()"); } k = sp_free_vars(&sA,&sB,NULL); if (k != 2) errmesg("sp_free_vars"); #endif /* SPARSE */ #ifdef COMPLEX /* complex stuff */ ONE = zmake(1.0,0.0); printf("# ONE = "); z_output(ONE); printf("# Check: MACHEPS = %g\n",MACHEPS); /* allocate, initialise, copy and resize operations */ /* ZVEC */ notice("vector initialise, copy & resize"); zv_get_vars(12,&zx,&zy,&zz,NULL); zv_rand(zx); zv_rand(zy); zz = zv_copy(zx,zz); if ( zv_norm2(zv_sub(zx,zz,zz)) >= MACHEPS ) errmesg("ZVEC copy"); zv_copy(zx,zy); zv_resize_vars(10,&zx,&zy,NULL); if ( zv_norm2(zv_sub(zx,zy,zz)) >= MACHEPS ) errmesg("ZVEC copy/resize"); zv_resize_vars(20,&zx,&zy,NULL); if ( zv_norm2(zv_sub(zx,zy,zz)) >= MACHEPS ) errmesg("VZEC resize"); zv_free_vars(&zx,&zy,&zz,NULL); /* ZMAT */ notice("matrix initialise, copy & resize"); zm_get_vars(8,5,&zA,&zB,&zC,NULL); zm_rand(zA); zm_rand(zB); zC = zm_copy(zA,zC); if ( zm_norm_inf(zm_sub(zA,zC,zC)) >= MACHEPS ) errmesg("ZMAT copy"); zm_copy(zA,zB); zm_resize_vars(3,5,&zA,&zB,&zC,NULL); if ( zm_norm_inf(zm_sub(zA,zB,zC)) >= MACHEPS ) errmesg("ZMAT copy/resize"); zm_resize_vars(20,20,&zA,&zB,&zC,NULL); if ( zm_norm_inf(zm_sub(zA,zB,zC)) >= MACHEPS ) errmesg("ZMAT resize"); zm_free_vars(&zA,&zB,&zC,NULL); #endif /* COMPLEX */ #endif /* if defined(ANSI_C) || defined(VARARGS) */ printf("# test of mem_info_bytes and mem_info_numvar\n"); printf(" TYPE VEC: %ld bytes allocated, %d variables allocated\n", mem_info_bytes(TYPE_VEC,0),mem_info_numvar(TYPE_VEC,0)); notice("static memory test"); mem_info_on(TRUE); mem_stat_mark(1); for (i=0; i < 100; i++) stat_test1(i); mem_stat_free(1); mem_stat_mark(1); for (i=0; i < 100; i++) { stat_test1(i); #ifdef COMPLEX stat_test4(i); #endif } mem_stat_mark(2); for (i=0; i < 100; i++) stat_test2(i); mem_stat_mark(3); #ifdef SPARSE for (i=0; i < 100; i++) stat_test3(i); #endif mem_info(); mem_dump_list(stdout,0); mem_stat_free(1); mem_stat_free(3); mem_stat_mark(4); for (i=0; i < 100; i++) { stat_test1(i); #ifdef COMPLEX stat_test4(i); #endif } mem_stat_dump(stdout,0); if (mem_stat_show_mark() != 4) { errmesg("not 4 in mem_stat_show_mark()"); } mem_stat_free(2); mem_stat_free(4); if (mem_stat_show_mark() != 0) { errmesg("not 0 in mem_stat_show_mark()"); } /* add new list of types */ mem_attach_list(FOO_LIST,FOO_NUM_TYPES,foo_type_name, foo_free_func,foo_info_sum); if (!mem_is_list_attached(FOO_LIST)) errmesg("list FOO_LIST is not attached"); mem_dump_list(stdout,FOO_LIST); foo_1 = foo_1_get(6); foo_2 = foo_2_get(3); for (i=0; i < foo_1->dim; i++) for (j=0; j < foo_1->fix_dim; j++) foo_1->a[i][j] = i+j; for (i=0; i < foo_2->dim; i++) for (j=0; j < foo_2->fix_dim; j++) foo_2->a[i][j] = i+j; printf(" foo_1->a[%d][%d] = %g\n",5,9,foo_1->a[5][9]); printf(" foo_2->a[%d][%d] = %g\n",2,1,foo_2->a[2][1]); mem_stat_mark(5); mem_stat_reg_list((void **)&foo_1,TYPE_FOO_1,FOO_LIST,__FILE__,__LINE__); mem_stat_reg_list((void **)&foo_2,TYPE_FOO_2,FOO_LIST,__FILE__,__LINE__); mem_stat_dump(stdout,FOO_LIST); mem_info_file(stdout,FOO_LIST); mem_stat_free_list(5,FOO_LIST); mem_stat_dump(stdout,FOO_LIST); if ( foo_1 != NULL ) errmesg(" foo_1 is not released"); if ( foo_2 != NULL ) errmesg(" foo_2 is not released"); mem_dump_list(stdout,FOO_LIST); mem_info_file(stdout,FOO_LIST); mem_free_vars(FOO_LIST); if ( mem_is_list_attached(FOO_LIST) ) errmesg("list FOO_LIST is not detached"); mem_info(); #if REAL == FLOAT printf("# SINGLE PRECISION was used\n"); #elif REAL == DOUBLE printf("# DOUBLE PRECISION was used\n"); #endif #define ANSI_OR_VAR #ifndef ANSI_C #ifndef VARARGS #undef ANSI_OR_VAR #endif #endif #ifdef ANSI_OR_VAR printf("# you should get: \n"); #if (REAL == FLOAT) printf("# type VEC: 276 bytes allocated, 3 variables allocated\n"); #elif (REAL == DOUBLE) printf("# type VEC: 516 bytes allocated, 3 variables allocated\n"); #endif printf("# and other types are zeros\n"); #endif /*#if defined(ANSI_C) || defined(VARAGS) */ printf("# Finished memory torture test\n"); dmalloc_shutdown(); return; } gtk-wave-cleaner-0.22-04/meschach/mfunc.c0000777000175000017500000002323713120075106021242 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains routines for computing functions of matrices especially polynomials and exponential functions Copyright (C) Teresa Leyk and David Stewart, 1993 */ #include #include #include "matrix.h" #include "matrix2.h" static char rcsid[] = "$Id: mfunc.c,v 1.2 1994/11/01 05:57:56 des Exp $"; /* _m_pow -- computes integer powers of a square matrix A, A^p -- uses tmp as temporary workspace */ #ifndef ANSI_C MAT *_m_pow(A, p, tmp, out) MAT *A, *tmp, *out; int p; #else MAT *_m_pow(const MAT *A, int p, MAT *tmp, MAT *out) #endif { int it_cnt, k, max_bit; /* File containing routines for evaluating matrix functions esp. the exponential function */ #define Z(k) (((k) & 1) ? tmp : out) if ( ! A ) error(E_NULL,"_m_pow"); if ( A->m != A->n ) error(E_SQUARE,"_m_pow"); if ( p < 0 ) error(E_NEG,"_m_pow"); out = m_resize(out,A->m,A->n); tmp = m_resize(tmp,A->m,A->n); if ( p == 0 ) m_ident(out); else if ( p > 0 ) { it_cnt = 1; for ( max_bit = 0; ; max_bit++ ) if ( (p >> (max_bit+1)) == 0 ) break; tmp = m_copy(A,tmp); for ( k = 0; k < max_bit; k++ ) { m_mlt(Z(it_cnt),Z(it_cnt),Z(it_cnt+1)); it_cnt++; if ( p & (1 << (max_bit-1)) ) { m_mlt(A,Z(it_cnt),Z(it_cnt+1)); /* m_copy(Z(it_cnt),out); */ it_cnt++; } p <<= 1; } if (it_cnt & 1) out = m_copy(Z(it_cnt),out); } return out; #undef Z } /* m_pow -- computes integer powers of a square matrix A, A^p */ #ifndef ANSI_C MAT *m_pow(A, p, out) MAT *A, *out; int p; #else MAT *m_pow(const MAT *A, int p, MAT *out) #endif { STATIC MAT *wkspace=MNULL, *tmp=MNULL; if ( ! A ) error(E_NULL,"m_pow"); if ( A->m != A->n ) error(E_SQUARE,"m_pow"); wkspace = m_resize(wkspace,A->m,A->n); MEM_STAT_REG(wkspace,TYPE_MAT); if ( p < 0 ) { tmp = m_resize(tmp,A->m,A->n); MEM_STAT_REG(tmp,TYPE_MAT); tracecatch(m_inverse(A,tmp),"m_pow"); out = _m_pow(tmp, -p, wkspace, out); } else out = _m_pow(A, p, wkspace, out); #ifdef THREADSAFE M_FREE(wkspace); M_FREE(tmp); #endif return out; } /**************************************************/ /* _m_exp -- compute matrix exponential of A and save it in out -- uses Pade approximation followed by repeated squaring -- eps is the tolerance used for the Pade approximation -- A is not changed -- q_out - degree of the Pade approximation (q_out,q_out) -- j_out - the power of 2 for scaling the matrix A such that ||A/2^j_out|| <= 0.5 */ #ifndef ANSI_C MAT *_m_exp(A,eps,out,q_out,j_out) MAT *A,*out; double eps; int *q_out, *j_out; #else MAT *_m_exp(MAT *A, double eps, MAT *out, int *q_out, int *j_out) #endif { STATIC MAT *D = MNULL, *Apow = MNULL, *N = MNULL, *Y = MNULL; STATIC VEC *c1 = VNULL, *tmp = VNULL; VEC y0, y1; /* additional structures */ STATIC PERM *pivot = PNULL; int j, k, l, q, r, s, j2max, t; double inf_norm, eqq, power2, c, sign; if ( ! A ) error(E_SIZES,"_m_exp"); if ( A->m != A->n ) error(E_SIZES,"_m_exp"); if ( A == out ) error(E_INSITU,"_m_exp"); if ( eps < 0.0 ) error(E_RANGE,"_m_exp"); else if (eps == 0.0) eps = MACHEPS; N = m_resize(N,A->m,A->n); D = m_resize(D,A->m,A->n); Apow = m_resize(Apow,A->m,A->n); out = m_resize(out,A->m,A->n); MEM_STAT_REG(N,TYPE_MAT); MEM_STAT_REG(D,TYPE_MAT); MEM_STAT_REG(Apow,TYPE_MAT); /* normalise A to have ||A||_inf <= 1 */ inf_norm = m_norm_inf(A); if (inf_norm <= 0.0) { m_ident(out); *q_out = -1; *j_out = 0; return out; } else { j2max = floor(1+log(inf_norm)/log(2.0)); j2max = max(0, j2max); } power2 = 1.0; for ( k = 1; k <= j2max; k++ ) power2 *= 2; power2 = 1.0/power2; if ( j2max > 0 ) sm_mlt(power2,A,A); /* compute order for polynomial approximation */ eqq = 1.0/6.0; for ( q = 1; eqq > eps; q++ ) eqq /= 16.0*(2.0*q+1.0)*(2.0*q+3.0); /* construct vector of coefficients */ c1 = v_resize(c1,q+1); MEM_STAT_REG(c1,TYPE_VEC); c1->ve[0] = 1.0; for ( k = 1; k <= q; k++ ) c1->ve[k] = c1->ve[k-1]*(q-k+1)/((2*q-k+1)*(double)k); tmp = v_resize(tmp,A->n); MEM_STAT_REG(tmp,TYPE_VEC); s = (int)floor(sqrt((double)q/2.0)); if ( s <= 0 ) s = 1; _m_pow(A,s,out,Apow); r = q/s; Y = m_resize(Y,s,A->n); MEM_STAT_REG(Y,TYPE_MAT); /* y0 and y1 are pointers to rows of Y, N and D */ y0.dim = y0.max_dim = A->n; y1.dim = y1.max_dim = A->n; m_zero(Y); m_zero(N); m_zero(D); for( j = 0; j < A->n; j++ ) { if (j > 0) Y->me[0][j-1] = 0.0; y0.ve = Y->me[0]; y0.ve[j] = 1.0; for ( k = 0; k < s-1; k++ ) { y1.ve = Y->me[k+1]; mv_mlt(A,&y0,&y1); y0.ve = y1.ve; } y0.ve = N->me[j]; y1.ve = D->me[j]; t = s*r; for ( l = 0; l <= q-t; l++ ) { c = c1->ve[t+l]; sign = ((t+l) & 1) ? -1.0 : 1.0; __mltadd__(y0.ve,Y->me[l],c, Y->n); __mltadd__(y1.ve,Y->me[l],c*sign,Y->n); } for (k=1; k <= r; k++) { v_copy(mv_mlt(Apow,&y0,tmp),&y0); v_copy(mv_mlt(Apow,&y1,tmp),&y1); t = s*(r-k); for (l=0; l < s; l++) { c = c1->ve[t+l]; sign = ((t+l) & 1) ? -1.0 : 1.0; __mltadd__(y0.ve,Y->me[l],c, Y->n); __mltadd__(y1.ve,Y->me[l],c*sign,Y->n); } } } pivot = px_resize(pivot,A->m); MEM_STAT_REG(pivot,TYPE_PERM); /* note that N and D are transposed, therefore we use LUTsolve; out is saved row-wise, and must be transposed after this */ LUfactor(D,pivot); for (k=0; k < A->n; k++) { y0.ve = N->me[k]; y1.ve = out->me[k]; LUTsolve(D,pivot,&y0,&y1); } m_transp(out,out); /* Use recursive squaring to turn the normalised exponential to the true exponential */ #define Z(k) ((k) & 1 ? Apow : out) for( k = 1; k <= j2max; k++) m_mlt(Z(k-1),Z(k-1),Z(k)); if (Z(k) == out) m_copy(Apow,out); /* output parameters */ *j_out = j2max; *q_out = q; /* restore the matrix A */ sm_mlt(1.0/power2,A,A); #ifdef THREADSAFE M_FREE(D); M_FREE(Apow); M_FREE(N); M_FREE(Y); V_FREE(c1); V_FREE(tmp); PX_FREE(pivot); #endif return out; #undef Z } /* simple interface for _m_exp */ #ifndef ANSI_C MAT *m_exp(A,eps,out) MAT *A,*out; double eps; #else MAT *m_exp(MAT *A, double eps, MAT *out) #endif { int q_out, j_out; return _m_exp(A,eps,out,&q_out,&j_out); } /*--------------------------------*/ /* m_poly -- computes sum_i a[i].A^i, where i=0,1,...dim(a); -- uses C. Van Loan's fast and memory efficient method */ #ifndef ANSI_C MAT *m_poly(A,a,out) MAT *A,*out; VEC *a; #else MAT *m_poly(const MAT *A, const VEC *a, MAT *out) #endif { STATIC MAT *Apow = MNULL, *Y = MNULL; STATIC VEC *tmp = VNULL; VEC y0, y1; /* additional vectors */ int j, k, l, q, r, s, t; if ( ! A || ! a ) error(E_NULL,"m_poly"); if ( A->m != A->n ) error(E_SIZES,"m_poly"); if ( A == out ) error(E_INSITU,"m_poly"); out = m_resize(out,A->m,A->n); Apow = m_resize(Apow,A->m,A->n); MEM_STAT_REG(Apow,TYPE_MAT); tmp = v_resize(tmp,A->n); MEM_STAT_REG(tmp,TYPE_VEC); q = a->dim - 1; if ( q == 0 ) { m_zero(out); for (j=0; j < out->n; j++) out->me[j][j] = a->ve[0]; return out; } else if ( q == 1) { sm_mlt(a->ve[1],A,out); for (j=0; j < out->n; j++) out->me[j][j] += a->ve[0]; return out; } s = (int)floor(sqrt((double)q/2.0)); if ( s <= 0 ) s = 1; _m_pow(A,s,out,Apow); r = q/s; Y = m_resize(Y,s,A->n); MEM_STAT_REG(Y,TYPE_MAT); /* pointers to rows of Y */ y0.dim = y0.max_dim = A->n; y1.dim = y1.max_dim = A->n; m_zero(Y); m_zero(out); #define Z(k) ((k) & 1 ? tmp : &y0) #define ZZ(k) ((k) & 1 ? tmp->ve : y0.ve) for( j = 0; j < A->n; j++) { if( j > 0 ) Y->me[0][j-1] = 0.0; Y->me[0][j] = 1.0; y0.ve = Y->me[0]; for (k = 0; k < s-1; k++) { y1.ve = Y->me[k+1]; mv_mlt(A,&y0,&y1); y0.ve = y1.ve; } y0.ve = out->me[j]; t = s*r; for ( l = 0; l <= q-t; l++ ) __mltadd__(y0.ve,Y->me[l],a->ve[t+l],Y->n); for (k=1; k <= r; k++) { mv_mlt(Apow,Z(k-1),Z(k)); t = s*(r-k); for (l=0; l < s; l++) __mltadd__(ZZ(k),Y->me[l],a->ve[t+l],Y->n); } if (Z(k) == &y0) v_copy(tmp,&y0); } m_transp(out,out); #ifdef THREADSAFE M_FREE(Apow); M_FREE(Y); V_FREE(tmp); #endif return out; } gtk-wave-cleaner-0.22-04/meschach/mfuntort.c0000777000175000017500000001066513120075106022011 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* mfuntort.c, 10/11/93 */ static char rcsid[] = "$Id: mfuntort.c,v 1.2 1994/01/14 01:08:06 des Exp $"; #include #include #include "matrix.h" #include "matrix2.h" #define errmesg(mesg) printf("Error: %s error: line %d\n",mesg,__LINE__) #define notice(mesg) printf("# Testing %s...\n",mesg); #define DIM 10 void main() { MAT *A, *B, *C, *OUTA, *OUTB, *TMP; MAT *exp_A_expected, *exp_A; VEC *x, *b; double c, eps = 1e-10; int i, j, q_out, j_out; mem_info_on(TRUE); A = m_get(DIM,DIM); B = m_get(DIM,DIM); C = m_get(DIM,DIM); OUTA = m_get(DIM,DIM); OUTB = m_get(DIM,DIM); TMP = m_get(DIM,DIM); x = v_get(DIM); b = v_get(6); notice("exponent of a matrix"); m_ident(A); mem_stat_mark(1); _m_exp(A,eps,OUTA,&q_out,&j_out); printf("# q_out = %d, j_out = %d\n",q_out,j_out); m_exp(A,eps,OUTA); sm_mlt(exp(1.0),A,A); m_sub(OUTA,A,TMP); printf("# ||exp(I) - e*I|| = %g\n",m_norm_inf(TMP)); m_rand(A); m_transp(A,TMP); m_add(A,TMP,A); B = m_copy(A,B); m_exp(A,eps,OUTA); symmeig(B,OUTB,x); m_zero(TMP); for (i=0; i < x->dim; i++) TMP->me[i][i] = exp(x->ve[i]); m_mlt(OUTB,TMP,C); mmtr_mlt(C,OUTB,TMP); m_sub(TMP,OUTA,TMP); printf("# ||exp(A) - Q*exp(lambda)*Q^T|| = %g\n",m_norm_inf(TMP)); notice("polynomial of a matrix"); m_rand(A); m_transp(A,TMP); m_add(A,TMP,A); B = m_copy(A,B); v_rand(b); m_poly(A,b,OUTA); symmeig(B,OUTB,x); m_zero(TMP); for (i=0; i < x->dim; i++) { c = b->ve[b->dim-1]; for (j=b->dim-2; j >= 0; j--) c = c*x->ve[i] + b->ve[j]; TMP->me[i][i] = c; } m_mlt(OUTB,TMP,C); mmtr_mlt(C,OUTB,TMP); m_sub(TMP,OUTA,TMP); printf("# ||poly(A) - Q*poly(lambda)*Q^T|| = %g\n",m_norm_inf(TMP)); mem_stat_free(1); /* Brook Milligan's test */ M_FREE(A); M_FREE(B); M_FREE(C); notice("exponent of a nonsymmetric matrix"); A = m_get (2, 2); A -> me [0][0] = 1.0; A -> me [0][1] = 1.0; A -> me [1][0] = 4.0; A -> me [1][1] = 1.0; exp_A_expected = m_get(2, 2); exp_A_expected -> me [0][0] = exp (3.0) / 2.0 + exp (-1.0) / 2.0; exp_A_expected -> me [0][1] = exp (3.0) / 4.0 - exp (-1.0) / 4.0; exp_A_expected -> me [1][0] = exp (3.0) - exp (-1.0); exp_A_expected -> me [1][1] = exp (3.0) / 2.0 + exp (-1.0) / 2.0; printf ("A:\n"); for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) printf (" %15.8e", A -> me [i][j]); printf ("\n"); } printf ("\nexp(A) (expected):\n"); for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) printf (" %15.8e", exp_A_expected -> me [i][j]); printf ("\n"); } mem_stat_mark(3); exp_A = m_exp (A, 1e-16,NULL); mem_stat_free(3); printf ("\nexp(A):\n"); for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) printf (" %15.8e", exp_A -> me [i][j]); printf ("\n"); } printf ("\nexp(A) - exp(A) (expected):\n"); for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) printf (" %15.8e", exp_A -> me [i][j] - exp_A_expected -> me [i][j]); printf ("\n"); } M_FREE(A); M_FREE(B); M_FREE(C); M_FREE(exp_A); M_FREE(exp_A_expected); M_FREE(OUTA); M_FREE(OUTB); M_FREE(TMP); V_FREE(b); V_FREE(x); mem_info(); } gtk-wave-cleaner-0.22-04/meschach/norm.c0000777000175000017500000001113213120075106021074 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* A collection of functions for computing norms: scaled and unscaled */ static char rcsid[] = "$Id: norm.c,v 1.6 1994/01/13 05:34:35 des Exp $"; #include #include #include "matrix.h" /* _v_norm1 -- computes (scaled) 1-norms of vectors */ #ifndef ANSI_C double _v_norm1(x,scale) VEC *x, *scale; #else double _v_norm1(const VEC *x, const VEC *scale) #endif { int i, dim; Real s, sum; if ( x == (VEC *)NULL ) error(E_NULL,"_v_norm1"); dim = x->dim; sum = 0.0; if ( scale == (VEC *)NULL ) for ( i = 0; i < dim; i++ ) sum += fabs(x->ve[i]); else if ( scale->dim < dim ) error(E_SIZES,"_v_norm1"); else for ( i = 0; i < dim; i++ ) { s = scale->ve[i]; sum += ( s== 0.0 ) ? fabs(x->ve[i]) : fabs(x->ve[i]/s); } return sum; } /* square -- returns x^2 */ #ifndef ANSI_C double square(x) double x; #else double square(double x) #endif { return x*x; } /* cube -- returns x^3 */ #ifndef ANSI_C double cube(x) double x; #else double cube(double x) #endif { return x*x*x; } /* _v_norm2 -- computes (scaled) 2-norm (Euclidean norm) of vectors */ #ifndef ANSI_C double _v_norm2(x,scale) VEC *x, *scale; #else double _v_norm2(const VEC *x, const VEC *scale) #endif { int i, dim; Real s, sum; if ( x == (VEC *)NULL ) error(E_NULL,"_v_norm2"); dim = x->dim; sum = 0.0; if ( scale == (VEC *)NULL ) for ( i = 0; i < dim; i++ ) sum += square(x->ve[i]); else if ( scale->dim < dim ) error(E_SIZES,"_v_norm2"); else for ( i = 0; i < dim; i++ ) { s = scale->ve[i]; sum += ( s== 0.0 ) ? square(x->ve[i]) : square(x->ve[i]/s); } return sqrt(sum); } #define max(a,b) ((a) > (b) ? (a) : (b)) /* _v_norm_inf -- computes (scaled) infinity-norm (supremum norm) of vectors */ #ifndef ANSI_C double _v_norm_inf(x,scale) VEC *x, *scale; #else double _v_norm_inf(const VEC *x, const VEC *scale) #endif { int i, dim; Real s, maxval, tmp; if ( x == (VEC *)NULL ) error(E_NULL,"_v_norm_inf"); dim = x->dim; maxval = 0.0; if ( scale == (VEC *)NULL ) for ( i = 0; i < dim; i++ ) { tmp = fabs(x->ve[i]); maxval = max(maxval,tmp); } else if ( scale->dim < dim ) error(E_SIZES,"_v_norm_inf"); else for ( i = 0; i < dim; i++ ) { s = scale->ve[i]; tmp = ( s== 0.0 ) ? fabs(x->ve[i]) : fabs(x->ve[i]/s); maxval = max(maxval,tmp); } return maxval; } /* m_norm1 -- compute matrix 1-norm -- unscaled */ #ifndef ANSI_C double m_norm1(A) MAT *A; #else double m_norm1(const MAT *A) #endif { int i, j, m, n; Real maxval, sum; if ( A == (MAT *)NULL ) error(E_NULL,"m_norm1"); m = A->m; n = A->n; maxval = 0.0; for ( j = 0; j < n; j++ ) { sum = 0.0; for ( i = 0; i < m; i ++ ) sum += fabs(A->me[i][j]); maxval = max(maxval,sum); } return maxval; } /* m_norm_inf -- compute matrix infinity-norm -- unscaled */ #ifndef ANSI_C double m_norm_inf(A) MAT *A; #else double m_norm_inf(const MAT *A) #endif { int i, j, m, n; Real maxval, sum; if ( A == (MAT *)NULL ) error(E_NULL,"m_norm_inf"); m = A->m; n = A->n; maxval = 0.0; for ( i = 0; i < m; i++ ) { sum = 0.0; for ( j = 0; j < n; j ++ ) sum += fabs(A->me[i][j]); maxval = max(maxval,sum); } return maxval; } /* m_norm_frob -- compute matrix frobenius-norm -- unscaled */ #ifndef ANSI_C double m_norm_frob(A) MAT *A; #else double m_norm_frob(const MAT *A) #endif { int i, j, m, n; Real sum; if ( A == (MAT *)NULL ) error(E_NULL,"m_norm_frob"); m = A->m; n = A->n; sum = 0.0; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j ++ ) sum += square(A->me[i][j]); return sqrt(sum); } gtk-wave-cleaner-0.22-04/meschach/oldnames.h0000777000175000017500000000741513120075107021742 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* macros for names used in versions 1.0 and 1.1 */ /* 8/11/93 */ #ifndef OLDNAMESH #define OLDNAMESH /* type IVEC */ #define get_ivec iv_get #define freeivec IV_FREE #define cp_ivec iv_copy #define fout_ivec iv_foutput #define out_ivec iv_output #define fin_ivec iv_finput #define in_ivec iv_input #define dump_ivec iv_dump /* type ZVEC */ #define get_zvec zv_get #define freezvec ZV_FREE #define cp_zvec zv_copy #define fout_zvec zv_foutput #define out_zvec zv_output #define fin_zvec zv_finput #define in_zvec zv_input #define zero_zvec zv_zero #define rand_zvec zv_rand #define dump_zvec zv_dump /* type ZMAT */ #define get_zmat zm_get #define freezmat ZM_FREE #define cp_zmat zm_copy #define fout_zmat zm_foutput #define out_zmat zm_output #define fin_zmat zm_finput #define in_zmat zm_input #define zero_zmat zm_zero #define rand_zmat zm_rand #define dump_zmat zm_dump /* types SPMAT */ #define sp_mat SPMAT #define sp_get_mat sp_get #define sp_free_mat sp_free #define sp_cp_mat sp_copy #define sp_cp_mat2 sp_copy2 #define sp_fout_mat sp_foutput #define sp_fout_mat2 sp_foutput2 #define sp_out_mat sp_output #define sp_out_mat2 sp_output2 #define sp_fin_mat sp_finput #define sp_in_mat sp_input #define sp_zero_mat sp_zero #define sp_dump_mat sp_dump /* type SPROW */ #define sp_row SPROW #define sp_get_idx sprow_idx #define row_xpd sprow_xpd #define sp_get_row sprow_get #define row_set_val sprow_set_val #define fout_row sprow_foutput #define _row_mltadd sprow_mltadd #define sp_row_copy sprow_copy #define sp_row_merge sprow_merge #define sp_row_ip sprow_ip #define sp_row_sqr sprow_sqr /* type MAT */ #define get_mat m_get #define freemat M_FREE #define cp_mat m_copy #define fout_mat m_foutput #define out_mat m_output #define fin_mat m_finput #define in_mat m_input #define zero_mat m_zero #define id_mat m_ident #define rand_mat m_rand #define ones_mat m_ones #define dump_mat m_dump /* type VEC */ #define get_vec v_get #define freevec V_FREE #define cp_vec v_copy #define fout_vec v_foutput #define out_vec v_output #define fin_vec v_finput #define in_vec v_input #define zero_vec v_zero #define rand_vec v_rand #define ones_vec v_ones #define dump_vec v_dump /* type PERM */ #define get_perm px_get #define freeperm PX_FREE #define cp_perm px_copy #define fout_perm px_foutput #define out_perm px_output #define fin_perm px_finput #define in_perm px_input #define id_perm px_ident #define px_id px_ident #define trans_px px_transp #define sign_px px_sign #define dump_perm px_dump #endif gtk-wave-cleaner-0.22-04/meschach/otherio.c0000777000175000017500000001065013120075107021577 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* File for doing assorted I/O operations not invlolving MAT/VEC/PERM objects */ static char rcsid[] = "$Id: otherio.c,v 1.2 1994/01/13 05:34:52 des Exp $"; #include #include #include "matrix.h" /* scratch area -- enough for a single line */ static char scratch[MAXLINE+1]; /* default value for fy_or_n */ static int y_n_dflt = TRUE; /* fy_or_n -- yes-or-no to question is string s -- question written to stderr, input from fp -- if fp is NOT a tty then return y_n_dflt */ #ifndef ANSI_C int fy_or_n(fp,s) FILE *fp; char *s; #else int fy_or_n(FILE *fp, const char *s) #endif { char *cp; if ( ! isatty(fileno(fp)) ) return y_n_dflt; for ( ; ; ) { fprintf(stderr,"%s (y/n) ? ",s); if ( fgets(scratch,MAXLINE,fp)==NULL ) error(E_INPUT,"fy_or_n"); cp = scratch; while ( isspace(*cp) ) cp++; if ( *cp == 'y' || *cp == 'Y' ) return TRUE; if ( *cp == 'n' || *cp == 'N' ) return FALSE; fprintf(stderr,"Please reply with 'y' or 'Y' for yes "); fprintf(stderr,"and 'n' or 'N' for no.\n"); } } /* yn_dflt -- sets the value of y_n_dflt to val */ #ifndef ANSI_C int yn_dflt(val) int val; #else int yn_dflt(int val) #endif { return y_n_dflt = val; } /* fin_int -- return integer read from file/stream fp -- prompt s on stderr if fp is a tty -- check that x lies between low and high: re-prompt if fp is a tty, error exit otherwise -- ignore check if low > high */ #ifndef ANSI_C int fin_int(fp,s,low,high) FILE *fp; char *s; int low, high; #else int fin_int(FILE *fp, const char *s, int low, int high) #endif { int retcode, x; if ( ! isatty(fileno(fp)) ) { skipjunk(fp); if ( (retcode=fscanf(fp,"%d",&x)) == EOF ) error(E_INPUT,"fin_int"); if ( retcode <= 0 ) error(E_FORMAT,"fin_int"); if ( low <= high && ( x < low || x > high ) ) error(E_BOUNDS,"fin_int"); return x; } for ( ; ; ) { fprintf(stderr,"%s: ",s); if ( fgets(scratch,MAXLINE,stdin)==NULL ) error(E_INPUT,"fin_int"); retcode = sscanf(scratch,"%d",&x); if ( ( retcode==1 && low > high ) || ( x >= low && x <= high ) ) return x; fprintf(stderr,"Please type an integer in range [%d,%d].\n", low,high); } } /* fin_double -- return double read from file/stream fp -- prompt s on stderr if fp is a tty -- check that x lies between low and high: re-prompt if fp is a tty, error exit otherwise -- ignore check if low > high */ #ifndef ANSI_C double fin_double(fp,s,low,high) FILE *fp; char *s; double low, high; #else double fin_double(FILE *fp, const char *s, double low, double high) #endif { Real retcode, x; if ( ! isatty(fileno(fp)) ) { skipjunk(fp); #if REAL == DOUBLE if ( (retcode=fscanf(fp,"%lf",&x)) == EOF ) #elif REAL == FLOAT if ( (retcode=fscanf(fp,"%f",&x)) == EOF ) #endif error(E_INPUT,"fin_double"); if ( retcode <= 0 ) error(E_FORMAT,"fin_double"); if ( low <= high && ( x < low || x > high ) ) error(E_BOUNDS,"fin_double"); return (double)x; } for ( ; ; ) { fprintf(stderr,"%s: ",s); if ( fgets(scratch,MAXLINE,stdin)==NULL ) error(E_INPUT,"fin_double"); #if REAL == DOUBLE retcode = sscanf(scratch,"%lf",&x); #elif REAL == FLOAT retcode = sscanf(scratch,"%f",&x); #endif if ( ( retcode==1 && low > high ) || ( x >= low && x <= high ) ) return (double)x; fprintf(stderr,"Please type an double in range [%g,%g].\n", low,high); } } gtk-wave-cleaner-0.22-04/meschach/pxop.c0000777000175000017500000002001013120075107021103 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* pxop.c 1.5 12/03/87 */ #include #include "matrix.h" static char rcsid[] = "$Id: pxop.c,v 1.6 1995/06/08 14:57:11 des Exp $"; /********************************************************************** Note: A permutation is often interpreted as a matrix (i.e. a permutation matrix). A permutation px represents a permutation matrix P where P[i][j] == 1 if and only if px->pe[i] == j **********************************************************************/ /* px_inv -- invert permutation -- in situ -- taken from ACM Collected Algorithms #250 */ #ifndef ANSI_C PERM *px_inv(px,out) PERM *px, *out; #else PERM *px_inv(const PERM *px, PERM *out) #endif { int i, j, k, n, *p; out = px_copy(px, out); n = out->size; p = (int *)(out->pe); for ( n--; n>=0; n-- ) { i = p[n]; if ( i < 0 ) p[n] = -1 - i; else if ( i != n ) { k = n; while (TRUE) { if ( i < 0 || i >= out->size ) error(E_BOUNDS,"px_inv"); j = p[i]; p[i] = -1 - k; if ( j == n ) { p[n] = i; break; } k = i; i = j; } } } return out; } /* px_mlt -- permutation multiplication (composition) */ #ifndef ANSI_C PERM *px_mlt(px1,px2,out) PERM *px1,*px2,*out; #else PERM *px_mlt(const PERM *px1, const PERM *px2, PERM *out) #endif { unsigned int i,size; if ( px1==(PERM *)NULL || px2==(PERM *)NULL ) error(E_NULL,"px_mlt"); if ( px1->size != px2->size ) error(E_SIZES,"px_mlt"); if ( px1 == out || px2 == out ) error(E_INSITU,"px_mlt"); if ( out==(PERM *)NULL || out->size < px1->size ) out = px_resize(out,px1->size); size = px1->size; for ( i=0; ipe[i] >= size ) error(E_BOUNDS,"px_mlt"); else out->pe[i] = px1->pe[px2->pe[i]]; return out; } /* px_vec -- permute vector */ #ifndef ANSI_C VEC *px_vec(px,vector,out) PERM *px; VEC *vector,*out; #else VEC *px_vec(PERM *px, const VEC *vector, VEC *out) #endif { unsigned int old_i, i, size, start; Real tmp; if ( px==PNULL || vector==VNULL ) error(E_NULL,"px_vec"); if ( px->size > vector->dim ) error(E_SIZES,"px_vec"); if ( out==VNULL || out->dim < vector->dim ) out = v_resize(out,vector->dim); size = px->size; if ( size == 0 ) return v_copy(vector,out); if ( out != vector ) { for ( i=0; ipe[i] >= size ) error(E_BOUNDS,"px_vec"); else out->ve[i] = vector->ve[px->pe[i]]; } else { /* in situ algorithm */ start = 0; while ( start < size ) { old_i = start; i = px->pe[old_i]; if ( i >= size ) { start++; continue; } tmp = vector->ve[start]; while ( TRUE ) { vector->ve[old_i] = vector->ve[i]; px->pe[old_i] = i+size; old_i = i; i = px->pe[old_i]; if ( i >= size ) break; if ( i == start ) { vector->ve[old_i] = tmp; px->pe[old_i] = i+size; break; } } start++; } for ( i = 0; i < size; i++ ) if ( px->pe[i] < size ) error(E_BOUNDS,"px_vec"); else px->pe[i] = px->pe[i]-size; } return out; } /* pxinv_vec -- apply the inverse of px to x, returning the result in out */ #ifndef ANSI_C VEC *pxinv_vec(px,x,out) PERM *px; VEC *x, *out; #else VEC *pxinv_vec(PERM *px, const VEC *x, VEC *out) #endif { unsigned int i, size; if ( ! px || ! x ) error(E_NULL,"pxinv_vec"); if ( px->size > x->dim ) error(E_SIZES,"pxinv_vec"); /* if ( x == out ) error(E_INSITU,"pxinv_vec"); */ if ( ! out || out->dim < x->dim ) out = v_resize(out,x->dim); size = px->size; if ( size == 0 ) return v_copy(x,out); if ( out != x ) { for ( i=0; ipe[i] >= size ) error(E_BOUNDS,"pxinv_vec"); else out->ve[px->pe[i]] = x->ve[i]; } else { /* in situ algorithm --- cheat's way out */ px_inv(px,px); px_vec(px,x,out); px_inv(px,px); } return out; } /* px_transp -- transpose elements of permutation -- Really multiplying a permutation by a transposition */ #ifndef ANSI_C PERM *px_transp(px,i1,i2) PERM *px; /* permutation to transpose */ unsigned int i1,i2; /* elements to transpose */ #else PERM *px_transp(PERM *px, unsigned int i1, unsigned int i2) #endif { unsigned int temp; if ( px==(PERM *)NULL ) error(E_NULL,"px_transp"); if ( i1 < px->size && i2 < px->size ) { temp = px->pe[i1]; px->pe[i1] = px->pe[i2]; px->pe[i2] = temp; } return px; } /* myqsort -- a cheap implementation of Quicksort on integers -- returns number of swaps */ #ifndef ANSI_C static int myqsort(a,num) int *a, num; #else static int myqsort(int *a, int num) #endif { int i, j, tmp, v; int numswaps; numswaps = 0; if ( num <= 1 ) return 0; i = 0; j = num; v = a[0]; for ( ; ; ) { while ( a[++i] < v ) ; while ( a[--j] > v ) ; if ( i >= j ) break; tmp = a[i]; a[i] = a[j]; a[j] = tmp; numswaps++; } tmp = a[0]; a[0] = a[j]; a[j] = tmp; if ( j != 0 ) numswaps++; numswaps += myqsort(&a[0],j); numswaps += myqsort(&a[j+1],num-(j+1)); return numswaps; } /* px_sign -- compute the ``sign'' of a permutation = +/-1 where px is the product of an even/odd # transpositions */ #ifndef ANSI_C int px_sign(px) PERM *px; #else int px_sign(const PERM *px) #endif { int numtransp; PERM *px2; if ( px==(PERM *)NULL ) error(E_NULL,"px_sign"); px2 = px_copy(px,PNULL); numtransp = myqsort((int *)px2->pe,px2->size); px_free(px2); return ( numtransp % 2 ) ? -1 : 1; } /* px_cols -- permute columns of matrix A; out = A.px' -- May NOT be in situ */ #ifndef ANSI_C MAT *px_cols(px,A,out) PERM *px; MAT *A, *out; #else MAT *px_cols(const PERM *px, const MAT *A, MAT *out) #endif { int i, j, m, n, px_j; Real **A_me, **out_me; #ifdef ANSI_C MAT *m_get(int, int); #else extern MAT *m_get(); #endif if ( ! A || ! px ) error(E_NULL,"px_cols"); if ( px->size != A->n ) error(E_SIZES,"px_cols"); if ( A == out ) error(E_INSITU,"px_cols"); m = A->m; n = A->n; if ( ! out || out->m != m || out->n != n ) out = m_get(m,n); A_me = A->me; out_me = out->me; for ( j = 0; j < n; j++ ) { px_j = px->pe[j]; if ( px_j >= n ) error(E_BOUNDS,"px_cols"); for ( i = 0; i < m; i++ ) out_me[i][px_j] = A_me[i][j]; } return out; } /* px_rows -- permute columns of matrix A; out = px.A -- May NOT be in situ */ #ifndef ANSI_C MAT *px_rows(px,A,out) PERM *px; MAT *A, *out; #else MAT *px_rows(const PERM *px, const MAT *A, MAT *out) #endif { int i, j, m, n, px_i; Real **A_me, **out_me; #ifdef ANSI_C MAT *m_get(int, int); #else extern MAT *m_get(); #endif if ( ! A || ! px ) error(E_NULL,"px_rows"); if ( px->size != A->m ) error(E_SIZES,"px_rows"); if ( A == out ) error(E_INSITU,"px_rows"); m = A->m; n = A->n; if ( ! out || out->m != m || out->n != n ) out = m_get(m,n); A_me = A->me; out_me = out->me; for ( i = 0; i < m; i++ ) { px_i = px->pe[i]; if ( px_i >= m ) error(E_BOUNDS,"px_rows"); for ( j = 0; j < n; j++ ) out_me[i][j] = A_me[px_i][j]; } return out; } gtk-wave-cleaner-0.22-04/meschach/qrfactor.c0000777000175000017500000003421313120075107021750 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains the routines needed to perform QR factorisation of matrices, as well as Householder transformations. The internal "factored form" of a matrix A is not quite standard. The diagonal of A is replaced by the diagonal of R -- not by the 1st non-zero entries of the Householder vectors. The 1st non-zero entries are held in the diag parameter of QRfactor(). The reason for this non-standard representation is that it enables direct use of the Usolve() function rather than requiring that a seperate function be written just for this case. See, e.g., QRsolve() below for more details. */ static char rcsid[] = "$Id: qrfactor.c,v 1.5 1994/01/13 05:35:07 des Exp $"; #include #include #include "matrix2.h" #define sign(x) ((x) > 0.0 ? 1 : ((x) < 0.0 ? -1 : 0 )) extern VEC *Usolve(); /* See matrix2.h */ /* Note: The usual representation of a Householder transformation is taken to be: P = I - beta.u.uT where beta = 2/(uT.u) and u is called the Householder vector */ /* QRfactor -- forms the QR factorisation of A -- factorisation stored in compact form as described above ( not quite standard format ) */ #ifndef ANSI_C MAT *QRfactor(A,diag) MAT *A; VEC *diag; #else MAT *QRfactor(MAT *A, VEC *diag) #endif { unsigned int k,limit; Real beta; STATIC VEC *hh=VNULL, *w=VNULL; if ( ! A || ! diag ) error(E_NULL,"QRfactor"); limit = min(A->m,A->n); if ( diag->dim < limit ) error(E_SIZES,"QRfactor"); hh = v_resize(hh,A->m); w = v_resize(w, A->n); MEM_STAT_REG(hh,TYPE_VEC); MEM_STAT_REG(w, TYPE_VEC); for ( k=0; kve[k],hh,&A->me[k][k]); */ hhvec(hh,k,&beta,hh,&A->me[k][k]); diag->ve[k] = hh->ve[k]; /* apply H/holder vector to remaining columns */ /* hhtrcols(A,k,k+1,hh,beta->ve[k]); */ _hhtrcols(A,k,k+1,hh,beta,w); } #ifdef THREADSAFE V_FREE(hh); V_FREE(w); #endif return (A); } /* QRCPfactor -- forms the QR factorisation of A with column pivoting -- factorisation stored in compact form as described above ( not quite standard format ) */ #ifndef ANSI_C MAT *QRCPfactor(A,diag,px) MAT *A; VEC *diag; PERM *px; #else MAT *QRCPfactor(MAT *A, VEC *diag, PERM *px) #endif { unsigned int i, i_max, j, k, limit; STATIC VEC *gamma=VNULL, *tmp1=VNULL, *tmp2=VNULL, *w=VNULL; Real beta, maxgamma, sum, tmp; if ( ! A || ! diag || ! px ) error(E_NULL,"QRCPfactor"); limit = min(A->m,A->n); if ( diag->dim < limit || px->size != A->n ) error(E_SIZES,"QRCPfactor"); tmp1 = v_resize(tmp1,A->m); tmp2 = v_resize(tmp2,A->m); gamma = v_resize(gamma,A->n); w = v_resize(w, A->n); MEM_STAT_REG(tmp1,TYPE_VEC); MEM_STAT_REG(tmp2,TYPE_VEC); MEM_STAT_REG(gamma,TYPE_VEC); MEM_STAT_REG(w, TYPE_VEC); /* initialise gamma and px */ for ( j=0; jn; j++ ) { px->pe[j] = j; sum = 0.0; for ( i=0; im; i++ ) sum += square(A->me[i][j]); gamma->ve[j] = sum; } for ( k=0; kve[k]; for ( i=k+1; in; i++ ) /* Loop invariant:maxgamma=gamma[i_max] >=gamma[l];l=k,...,i-1 */ if ( gamma->ve[i] > maxgamma ) { maxgamma = gamma->ve[i]; i_max = i; } /* swap columns if necessary */ if ( i_max != k ) { /* swap gamma values */ tmp = gamma->ve[k]; gamma->ve[k] = gamma->ve[i_max]; gamma->ve[i_max] = tmp; /* update column permutation */ px_transp(px,k,i_max); /* swap columns of A */ for ( i=0; im; i++ ) { tmp = A->me[i][k]; A->me[i][k] = A->me[i][i_max]; A->me[i][i_max] = tmp; } } /* get H/holder vector for the k-th column */ get_col(A,k,tmp1); /* hhvec(tmp1,k,&beta->ve[k],tmp1,&A->me[k][k]); */ hhvec(tmp1,k,&beta,tmp1,&A->me[k][k]); diag->ve[k] = tmp1->ve[k]; /* apply H/holder vector to remaining columns */ /* hhtrcols(A,k,k+1,tmp1,beta->ve[k]); */ _hhtrcols(A,k,k+1,tmp1,beta,w); /* update gamma values */ for ( j=k+1; jn; j++ ) gamma->ve[j] -= square(A->me[k][j]); } #ifdef THREADSAFE V_FREE(gamma); V_FREE(tmp1); V_FREE(tmp2); V_FREE(w); #endif return (A); } /* Qsolve -- solves Qx = b, Q is an orthogonal matrix stored in compact form a la QRfactor() -- may be in-situ */ #ifndef ANSI_C VEC *_Qsolve(QR,diag,b,x,tmp) MAT *QR; VEC *diag, *b, *x, *tmp; #else VEC *_Qsolve(const MAT *QR, const VEC *diag, const VEC *b, VEC *x, VEC *tmp) #endif { unsigned int dynamic; int k, limit; Real beta, r_ii, tmp_val; limit = min(QR->m,QR->n); dynamic = FALSE; if ( ! QR || ! diag || ! b ) error(E_NULL,"_Qsolve"); if ( diag->dim < limit || b->dim != QR->m ) error(E_SIZES,"_Qsolve"); x = v_resize(x,QR->m); if ( tmp == VNULL ) dynamic = TRUE; tmp = v_resize(tmp,QR->m); /* apply H/holder transforms in normal order */ x = v_copy(b,x); for ( k = 0 ; k < limit ; k++ ) { get_col(QR,k,tmp); r_ii = fabs(tmp->ve[k]); tmp->ve[k] = diag->ve[k]; tmp_val = (r_ii*fabs(diag->ve[k])); beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val; /* hhtrvec(tmp,beta->ve[k],k,x,x); */ hhtrvec(tmp,beta,k,x,x); } if ( dynamic ) V_FREE(tmp); return (x); } /* makeQ -- constructs orthogonal matrix from Householder vectors stored in compact QR form */ #ifndef ANSI_C MAT *makeQ(QR,diag,Qout) MAT *QR,*Qout; VEC *diag; #else MAT *makeQ(const MAT *QR,const VEC *diag, MAT *Qout) #endif { STATIC VEC *tmp1=VNULL,*tmp2=VNULL; unsigned int i, limit; Real beta, r_ii, tmp_val; int j; limit = min(QR->m,QR->n); if ( ! QR || ! diag ) error(E_NULL,"makeQ"); if ( diag->dim < limit ) error(E_SIZES,"makeQ"); if ( Qout==(MAT *)NULL || Qout->m < QR->m || Qout->n < QR->m ) Qout = m_get(QR->m,QR->m); tmp1 = v_resize(tmp1,QR->m); /* contains basis vec & columns of Q */ tmp2 = v_resize(tmp2,QR->m); /* contains H/holder vectors */ MEM_STAT_REG(tmp1,TYPE_VEC); MEM_STAT_REG(tmp2,TYPE_VEC); for ( i=0; im ; i++ ) { /* get i-th column of Q */ /* set up tmp1 as i-th basis vector */ for ( j=0; jm ; j++ ) tmp1->ve[j] = 0.0; tmp1->ve[i] = 1.0; /* apply H/h transforms in reverse order */ for ( j=limit-1; j>=0; j-- ) { get_col(QR,j,tmp2); r_ii = fabs(tmp2->ve[j]); tmp2->ve[j] = diag->ve[j]; tmp_val = (r_ii*fabs(diag->ve[j])); beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val; /* hhtrvec(tmp2,beta->ve[j],j,tmp1,tmp1); */ hhtrvec(tmp2,beta,j,tmp1,tmp1); } /* insert into Q */ set_col(Qout,i,tmp1); } #ifdef THREADSAFE V_FREE(tmp1); V_FREE(tmp2); #endif return (Qout); } /* makeR -- constructs upper triangular matrix from QR (compact form) -- may be in-situ (all it does is zero the lower 1/2) */ #ifndef ANSI_C MAT *makeR(QR,Rout) MAT *QR,*Rout; #else MAT *makeR(const MAT *QR, MAT *Rout) #endif { unsigned int i,j; if ( QR==MNULL ) error(E_NULL,"makeR"); Rout = m_copy(QR,Rout); for ( i=1; im; i++ ) for ( j=0; jn && jme[i][j] = 0.0; return (Rout); } /* QRsolve -- solves the system Q.R.x=b where Q & R are stored in compact form -- returns x, which is created if necessary */ #ifndef ANSI_C VEC *QRsolve(QR,diag,b,x) MAT *QR; VEC *diag /* , *beta */ , *b, *x; #else VEC *QRsolve(const MAT *QR, const VEC *diag, const VEC *b, VEC *x) #endif { int limit; STATIC VEC *tmp = VNULL; if ( ! QR || ! diag || ! b ) error(E_NULL,"QRsolve"); limit = min(QR->m,QR->n); if ( diag->dim < limit || b->dim != QR->m ) error(E_SIZES,"QRsolve"); tmp = v_resize(tmp,limit); MEM_STAT_REG(tmp,TYPE_VEC); x = v_resize(x,QR->n); _Qsolve(QR,diag,b,x,tmp); x = Usolve(QR,x,x,0.0); v_resize(x,QR->n); #ifdef THREADSAFE V_FREE(tmp); #endif return x; } /* QRCPsolve -- solves A.x = b where A is factored by QRCPfactor() -- assumes that A is in the compact factored form */ #ifndef ANSI_C VEC *QRCPsolve(QR,diag,pivot,b,x) MAT *QR; VEC *diag; PERM *pivot; VEC *b, *x; #else VEC *QRCPsolve(const MAT *QR, const VEC *diag, PERM *pivot, const VEC *b, VEC *x) #endif { STATIC VEC *tmp=VNULL; if ( ! QR || ! diag || ! pivot || ! b ) error(E_NULL,"QRCPsolve"); if ( (QR->m > diag->dim &&QR->n > diag->dim) || QR->n != pivot->size ) error(E_SIZES,"QRCPsolve"); tmp = QRsolve(QR,diag,b,tmp); MEM_STAT_REG(tmp,TYPE_VEC); x = pxinv_vec(pivot,tmp,x); #ifdef THREADSAFE V_FREE(tmp); #endif return x; } /* Umlt -- compute out = upper_triang(U).x -- may be in situ */ #ifndef ANSI_C static VEC *Umlt(U,x,out) MAT *U; VEC *x, *out; #else static VEC *Umlt(const MAT *U, const VEC *x, VEC *out) #endif { int i, limit; if ( U == MNULL || x == VNULL ) error(E_NULL,"Umlt"); limit = min(U->m,U->n); if ( limit != x->dim ) error(E_SIZES,"Umlt"); if ( out == VNULL || out->dim < limit ) out = v_resize(out,limit); for ( i = 0; i < limit; i++ ) out->ve[i] = __ip__(&(x->ve[i]),&(U->me[i][i]),limit - i); return out; } /* UTmlt -- returns out = upper_triang(U)^T.x */ #ifndef ANSI_C static VEC *UTmlt(U,x,out) MAT *U; VEC *x, *out; #else static VEC *UTmlt(const MAT *U, const VEC *x, VEC *out) #endif { Real sum; int i, j, limit; if ( U == MNULL || x == VNULL ) error(E_NULL,"UTmlt"); limit = min(U->m,U->n); if ( out == VNULL || out->dim < limit ) out = v_resize(out,limit); for ( i = limit-1; i >= 0; i-- ) { sum = 0.0; for ( j = 0; j <= i; j++ ) sum += U->me[j][i]*x->ve[j]; out->ve[i] = sum; } return out; } /* QRTsolve -- solve A^T.sc = c where the QR factors of A are stored in compact form -- returns sc -- original due to Mike Osborne modified Wed 09th Dec 1992 */ #ifndef ANSI_C VEC *QRTsolve(A,diag,c,sc) MAT *A; VEC *diag, *c, *sc; #else VEC *QRTsolve(const MAT *A, const VEC *diag, const VEC *c, VEC *sc) #endif { int i, j, k, n, p; Real beta, r_ii, s, tmp_val; if ( ! A || ! diag || ! c ) error(E_NULL,"QRTsolve"); if ( diag->dim < min(A->m,A->n) ) error(E_SIZES,"QRTsolve"); sc = v_resize(sc,A->m); n = sc->dim; p = c->dim; if ( n == p ) k = p-2; else k = p-1; v_zero(sc); sc->ve[0] = c->ve[0]/A->me[0][0]; if ( n == 1) return sc; if ( p > 1) { for ( i = 1; i < p; i++ ) { s = 0.0; for ( j = 0; j < i; j++ ) s += A->me[j][i]*sc->ve[j]; if ( A->me[i][i] == 0.0 ) error(E_SING,"QRTsolve"); sc->ve[i]=(c->ve[i]-s)/A->me[i][i]; } } for (i = k; i >= 0; i--) { s = diag->ve[i]*sc->ve[i]; for ( j = i+1; j < n; j++ ) s += A->me[j][i]*sc->ve[j]; r_ii = fabs(A->me[i][i]); tmp_val = (r_ii*fabs(diag->ve[i])); beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val; tmp_val = beta*s; sc->ve[i] -= tmp_val*diag->ve[i]; for ( j = i+1; j < n; j++ ) sc->ve[j] -= tmp_val*A->me[j][i]; } return sc; } /* QRcondest -- returns an estimate of the 2-norm condition number of the matrix factorised by QRfactor() or QRCPfactor() -- note that as Q does not affect the 2-norm condition number, it is not necessary to pass the diag, beta (or pivot) vectors -- generates a lower bound on the true condition number -- if the matrix is exactly singular, HUGE_VAL is returned -- note that QRcondest() is likely to be more reliable for matrices factored using QRCPfactor() */ #ifndef ANSI_C double QRcondest(QR) MAT *QR; #else double QRcondest(const MAT *QR) #endif { STATIC VEC *y=VNULL; Real norm1, norm2, sum, tmp1, tmp2; int i, j, limit; if ( QR == MNULL ) error(E_NULL,"QRcondest"); limit = min(QR->m,QR->n); for ( i = 0; i < limit; i++ ) if ( QR->me[i][i] == 0.0 ) return HUGE_VAL; y = v_resize(y,limit); MEM_STAT_REG(y,TYPE_VEC); /* use the trick for getting a unit vector y with ||R.y||_inf small from the LU condition estimator */ for ( i = 0; i < limit; i++ ) { sum = 0.0; for ( j = 0; j < i; j++ ) sum -= QR->me[j][i]*y->ve[j]; sum -= (sum < 0.0) ? 1.0 : -1.0; y->ve[i] = sum / QR->me[i][i]; } UTmlt(QR,y,y); /* now apply inverse power method to R^T.R */ for ( i = 0; i < 3; i++ ) { tmp1 = v_norm2(y); sv_mlt(1/tmp1,y,y); UTsolve(QR,y,y,0.0); tmp2 = v_norm2(y); sv_mlt(1/v_norm2(y),y,y); Usolve(QR,y,y,0.0); } /* now compute approximation for ||R^{-1}||_2 */ norm1 = sqrt(tmp1)*sqrt(tmp2); /* now use complementary approach to compute approximation to ||R||_2 */ for ( i = limit-1; i >= 0; i-- ) { sum = 0.0; for ( j = i+1; j < limit; j++ ) sum += QR->me[i][j]*y->ve[j]; y->ve[i] = (sum >= 0.0) ? 1.0 : -1.0; y->ve[i] = (QR->me[i][i] >= 0.0) ? y->ve[i] : - y->ve[i]; } /* now apply power method to R^T.R */ for ( i = 0; i < 3; i++ ) { tmp1 = v_norm2(y); sv_mlt(1/tmp1,y,y); Umlt(QR,y,y); tmp2 = v_norm2(y); sv_mlt(1/tmp2,y,y); UTmlt(QR,y,y); } norm2 = sqrt(tmp1)*sqrt(tmp2); /* printf("QRcondest: norm1 = %g, norm2 = %g\n",norm1,norm2); */ #ifdef THREADSAFE V_FREE(y); #endif return norm1*norm2; } gtk-wave-cleaner-0.22-04/meschach/rk4.dat0000777000175000017500000000021513120075107021150 0ustar00alisteralister00000000000000# No. of a problem 1 # Initial time 0 # Final time 1 # Solution is x(t) = (cos(t),-sin(t)) # x(0) = Vector: dim: 2 1 0 # Step size 0.1 gtk-wave-cleaner-0.22-04/meschach/schur.c0000777000175000017500000004476313120075107021266 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Stewart & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* File containing routines for computing the Schur decomposition of a real non-symmetric matrix See also: hessen.c */ #include #include #include "matrix.h" #include "matrix2.h" static char rcsid[] = "$Id: schur.c,v 1.7 1994/03/17 05:36:53 des Exp $"; #ifndef ANSI_C static void hhldr3(x,y,z,nu1,beta,newval) double x, y, z; Real *nu1, *beta, *newval; #else static void hhldr3(double x, double y, double z, Real *nu1, Real *beta, Real *newval) #endif { Real alpha; if ( x >= 0.0 ) alpha = sqrt(x*x+y*y+z*z); else alpha = -sqrt(x*x+y*y+z*z); *nu1 = x + alpha; *beta = 1.0/(alpha*(*nu1)); *newval = alpha; } #ifndef ANSI_C static void hhldr3cols(A,k,j0,beta,nu1,nu2,nu3) MAT *A; int k, j0; double beta, nu1, nu2, nu3; #else static void hhldr3cols(MAT *A, int k, int j0, double beta, double nu1, double nu2, double nu3) #endif { Real **A_me, ip, prod; int j, n; if ( k < 0 || k+3 > A->m || j0 < 0 ) error(E_BOUNDS,"hhldr3cols"); A_me = A->me; n = A->n; /* printf("hhldr3cols:(l.%d) j0 = %d, k = %d, A at 0x%lx, m = %d, n = %d\n", __LINE__, j0, k, (long)A, A->m, A->n); */ /* printf("hhldr3cols: A (dumped) =\n"); m_dump(stdout,A); */ for ( j = j0; j < n; j++ ) { /***** ip = nu1*A_me[k][j] + nu2*A_me[k+1][j] + nu3*A_me[k+2][j]; prod = ip*beta; A_me[k][j] -= prod*nu1; A_me[k+1][j] -= prod*nu2; A_me[k+2][j] -= prod*nu3; *****/ /* printf("hhldr3cols: j = %d\n", j); */ ip = nu1*m_entry(A,k,j)+nu2*m_entry(A,k+1,j)+nu3*m_entry(A,k+2,j); prod = ip*beta; /***** m_set_val(A,k ,j,m_entry(A,k ,j) - prod*nu1); m_set_val(A,k+1,j,m_entry(A,k+1,j) - prod*nu2); m_set_val(A,k+2,j,m_entry(A,k+2,j) - prod*nu3); *****/ m_add_val(A,k ,j,-prod*nu1); m_add_val(A,k+1,j,-prod*nu2); m_add_val(A,k+2,j,-prod*nu3); } /* printf("hhldr3cols:(l.%d) j0 = %d, k = %d, m = %d, n = %d\n", __LINE__, j0, k, A->m, A->n); */ /* putc('\n',stdout); */ } #ifndef ANSI_C static void hhldr3rows(A,k,i0,beta,nu1,nu2,nu3) MAT *A; int k, i0; double beta, nu1, nu2, nu3; #else static void hhldr3rows(MAT *A, int k, int i0, double beta, double nu1, double nu2, double nu3) #endif { Real **A_me, ip, prod; int i, m; /* printf("hhldr3rows:(l.%d) A at 0x%lx\n", __LINE__, (long)A); */ /* printf("hhldr3rows: k = %d\n", k); */ if ( k < 0 || k+3 > A->n ) error(E_BOUNDS,"hhldr3rows"); A_me = A->me; m = A->m; i0 = min(i0,m-1); for ( i = 0; i <= i0; i++ ) { /**** ip = nu1*A_me[i][k] + nu2*A_me[i][k+1] + nu3*A_me[i][k+2]; prod = ip*beta; A_me[i][k] -= prod*nu1; A_me[i][k+1] -= prod*nu2; A_me[i][k+2] -= prod*nu3; ****/ ip = nu1*m_entry(A,i,k)+nu2*m_entry(A,i,k+1)+nu3*m_entry(A,i,k+2); prod = ip*beta; m_add_val(A,i,k , - prod*nu1); m_add_val(A,i,k+1, - prod*nu2); m_add_val(A,i,k+2, - prod*nu3); } } /* schur -- computes the Schur decomposition of the matrix A in situ -- optionally, gives Q matrix such that Q^T.A.Q is upper triangular -- returns upper triangular Schur matrix */ #ifndef ANSI_C MAT *schur(A,Q) MAT *A, *Q; #else MAT *schur(MAT *A, MAT *Q) #endif { int i, j, iter, k, k_min, k_max, k_tmp, n, split; Real beta2, c, discrim, dummy, nu1, s, t, tmp, x, y, z; Real **A_me; Real sqrt_macheps; STATIC VEC *diag=VNULL, *beta=VNULL; if ( ! A ) error(E_NULL,"schur"); if ( A->m != A->n || ( Q && Q->m != Q->n ) ) error(E_SQUARE,"schur"); if ( Q != MNULL && Q->m != A->m ) error(E_SIZES,"schur"); n = A->n; diag = v_resize(diag,A->n); beta = v_resize(beta,A->n); MEM_STAT_REG(diag,TYPE_VEC); MEM_STAT_REG(beta,TYPE_VEC); /* compute Hessenberg form */ Hfactor(A,diag,beta); /* save Q if necessary */ if ( Q ) Q = makeHQ(A,diag,beta,Q); makeH(A,A); sqrt_macheps = sqrt(MACHEPS); k_min = 0; A_me = A->me; while ( k_min < n ) { Real a00, a01, a10, a11; double scale, t, numer, denom; /* find k_max to suit: submatrix k_min..k_max should be irreducible */ k_max = n-1; for ( k = k_min; k < k_max; k++ ) /* if ( A_me[k+1][k] == 0.0 ) */ if ( m_entry(A,k+1,k) == 0.0 ) { k_max = k; break; } if ( k_max <= k_min ) { k_min = k_max + 1; continue; /* outer loop */ } /* check to see if we have a 2 x 2 block with complex eigenvalues */ if ( k_max == k_min + 1 ) { /* tmp = A_me[k_min][k_min] - A_me[k_max][k_max]; */ a00 = m_entry(A,k_min,k_min); a01 = m_entry(A,k_min,k_max); a10 = m_entry(A,k_max,k_min); a11 = m_entry(A,k_max,k_max); tmp = a00 - a11; /* discrim = tmp*tmp + 4*A_me[k_min][k_max]*A_me[k_max][k_min]; */ discrim = tmp*tmp + 4*a01*a10; if ( discrim < 0.0 ) { /* yes -- e-vals are complex -- put 2 x 2 block in form [a b; c a]; then eigenvalues have real part a & imag part sqrt(|bc|) */ numer = - tmp; denom = ( a01+a10 >= 0.0 ) ? (a01+a10) + sqrt((a01+a10)*(a01+a10)+tmp*tmp) : (a01+a10) - sqrt((a01+a10)*(a01+a10)+tmp*tmp); if ( denom != 0.0 ) { /* t = s/c = numer/denom */ t = numer/denom; scale = c = 1.0/sqrt(1+t*t); s = c*t; } else { c = 1.0; s = 0.0; } rot_cols(A,k_min,k_max,c,s,A); rot_rows(A,k_min,k_max,c,s,A); if ( Q != MNULL ) rot_cols(Q,k_min,k_max,c,s,Q); k_min = k_max + 1; continue; } else /* discrim >= 0; i.e. block has two real eigenvalues */ { /* no -- e-vals are not complex; split 2 x 2 block and continue */ /* s/c = numer/denom */ numer = ( tmp >= 0.0 ) ? - tmp - sqrt(discrim) : - tmp + sqrt(discrim); denom = 2*a01; if ( fabs(numer) < fabs(denom) ) { /* t = s/c = numer/denom */ t = numer/denom; scale = c = 1.0/sqrt(1+t*t); s = c*t; } else if ( numer != 0.0 ) { /* t = c/s = denom/numer */ t = denom/numer; scale = 1.0/sqrt(1+t*t); c = fabs(t)*scale; s = ( t >= 0.0 ) ? scale : -scale; } else /* numer == denom == 0 */ { c = 0.0; s = 1.0; } rot_cols(A,k_min,k_max,c,s,A); rot_rows(A,k_min,k_max,c,s,A); /* A->me[k_max][k_min] = 0.0; */ if ( Q != MNULL ) rot_cols(Q,k_min,k_max,c,s,Q); k_min = k_max + 1; /* go to next block */ continue; } } /* now have r x r block with r >= 2: apply Francis QR step until block splits */ split = FALSE; iter = 0; while ( ! split ) { iter++; /* set up Wilkinson/Francis complex shift */ k_tmp = k_max - 1; a00 = m_entry(A,k_tmp,k_tmp); a01 = m_entry(A,k_tmp,k_max); a10 = m_entry(A,k_max,k_tmp); a11 = m_entry(A,k_max,k_max); /* treat degenerate cases differently -- if there are still no splits after five iterations and the bottom 2 x 2 looks degenerate, force it to split */ #ifdef DEBUG printf("# schur: bottom 2 x 2 = [%lg, %lg; %lg, %lg]\n", a00, a01, a10, a11); #endif if ( iter >= 5 && fabs(a00-a11) < sqrt_macheps*(fabs(a00)+fabs(a11)) && (fabs(a01) < sqrt_macheps*(fabs(a00)+fabs(a11)) || fabs(a10) < sqrt_macheps*(fabs(a00)+fabs(a11))) ) { if ( fabs(a01) < sqrt_macheps*(fabs(a00)+fabs(a11)) ) m_set_val(A,k_tmp,k_max,0.0); if ( fabs(a10) < sqrt_macheps*(fabs(a00)+fabs(a11)) ) { m_set_val(A,k_max,k_tmp,0.0); split = TRUE; continue; } } s = a00 + a11; t = a00*a11 - a01*a10; /* break loop if a 2 x 2 complex block */ if ( k_max == k_min + 1 && s*s < 4.0*t ) { split = TRUE; continue; } /* perturb shift if convergence is slow */ if ( (iter % 10) == 0 ) { s += iter*0.02; t += iter*0.02; } /* set up Householder transformations */ k_tmp = k_min + 1; /******************** x = A_me[k_min][k_min]*A_me[k_min][k_min] + A_me[k_min][k_tmp]*A_me[k_tmp][k_min] - s*A_me[k_min][k_min] + t; y = A_me[k_tmp][k_min]* (A_me[k_min][k_min]+A_me[k_tmp][k_tmp]-s); if ( k_min + 2 <= k_max ) z = A_me[k_tmp][k_min]*A_me[k_min+2][k_tmp]; else z = 0.0; ********************/ a00 = m_entry(A,k_min,k_min); a01 = m_entry(A,k_min,k_tmp); a10 = m_entry(A,k_tmp,k_min); a11 = m_entry(A,k_tmp,k_tmp); /******************** a00 = A->me[k_min][k_min]; a01 = A->me[k_min][k_tmp]; a10 = A->me[k_tmp][k_min]; a11 = A->me[k_tmp][k_tmp]; ********************/ x = a00*a00 + a01*a10 - s*a00 + t; y = a10*(a00+a11-s); if ( k_min + 2 <= k_max ) z = a10* /* m_entry(A,k_min+2,k_tmp) */ A->me[k_min+2][k_tmp]; else z = 0.0; for ( k = k_min; k <= k_max-1; k++ ) { if ( k < k_max - 1 ) { hhldr3(x,y,z,&nu1,&beta2,&dummy); tracecatch(hhldr3cols(A,k,max(k-1,0), beta2,nu1,y,z),"schur"); tracecatch(hhldr3rows(A,k,min(n-1,k+3),beta2,nu1,y,z),"schur"); if ( Q != MNULL ) hhldr3rows(Q,k,n-1,beta2,nu1,y,z); } else { givens(x,y,&c,&s); rot_cols(A,k,k+1,c,s,A); rot_rows(A,k,k+1,c,s,A); if ( Q ) rot_cols(Q,k,k+1,c,s,Q); } /* if ( k >= 2 ) m_set_val(A,k,k-2,0.0); */ /* x = A_me[k+1][k]; */ x = m_entry(A,k+1,k); if ( k <= k_max - 2 ) /* y = A_me[k+2][k];*/ y = m_entry(A,k+2,k); else y = 0.0; if ( k <= k_max - 3 ) /* z = A_me[k+3][k]; */ z = m_entry(A,k+3,k); else z = 0.0; } /* if ( k_min > 0 ) m_set_val(A,k_min,k_min-1,0.0); if ( k_max < n - 1 ) m_set_val(A,k_max+1,k_max,0.0); */ for ( k = k_min; k <= k_max-2; k++ ) { /* zero appropriate sub-diagonals */ m_set_val(A,k+2,k,0.0); if ( k < k_max-2 ) m_set_val(A,k+3,k,0.0); } /* test to see if matrix should split */ for ( k = k_min; k < k_max; k++ ) if ( fabs(A_me[k+1][k]) < MACHEPS* (fabs(A_me[k][k])+fabs(A_me[k+1][k+1])) ) { A_me[k+1][k] = 0.0; split = TRUE; } } } /* polish up A by zeroing strictly lower triangular elements and small sub-diagonal elements */ for ( i = 0; i < A->m; i++ ) for ( j = 0; j < i-1; j++ ) A_me[i][j] = 0.0; for ( i = 0; i < A->m - 1; i++ ) if ( fabs(A_me[i+1][i]) < MACHEPS* (fabs(A_me[i][i])+fabs(A_me[i+1][i+1])) ) A_me[i+1][i] = 0.0; #ifdef THREADSAFE V_FREE(diag); V_FREE(beta); #endif return A; } /* schur_vals -- compute real & imaginary parts of eigenvalues -- assumes T contains a block upper triangular matrix as produced by schur() -- real parts stored in real_pt, imaginary parts in imag_pt */ #ifndef ANSI_C void schur_evals(T,real_pt,imag_pt) MAT *T; VEC *real_pt, *imag_pt; #else void schur_evals(MAT *T, VEC *real_pt, VEC *imag_pt) #endif { int i, n; Real discrim, **T_me; Real diff, sum, tmp; if ( ! T || ! real_pt || ! imag_pt ) error(E_NULL,"schur_evals"); if ( T->m != T->n ) error(E_SQUARE,"schur_evals"); n = T->n; T_me = T->me; real_pt = v_resize(real_pt,(unsigned int)n); imag_pt = v_resize(imag_pt,(unsigned int)n); i = 0; while ( i < n ) { if ( i < n-1 && T_me[i+1][i] != 0.0 ) { /* should be a complex eigenvalue */ sum = 0.5*(T_me[i][i]+T_me[i+1][i+1]); diff = 0.5*(T_me[i][i]-T_me[i+1][i+1]); discrim = diff*diff + T_me[i][i+1]*T_me[i+1][i]; if ( discrim < 0.0 ) { /* yes -- complex e-vals */ real_pt->ve[i] = real_pt->ve[i+1] = sum; imag_pt->ve[i] = sqrt(-discrim); imag_pt->ve[i+1] = - imag_pt->ve[i]; } else { /* no -- actually both real */ tmp = sqrt(discrim); real_pt->ve[i] = sum + tmp; real_pt->ve[i+1] = sum - tmp; imag_pt->ve[i] = imag_pt->ve[i+1] = 0.0; } i += 2; } else { /* real eigenvalue */ real_pt->ve[i] = T_me[i][i]; imag_pt->ve[i] = 0.0; i++; } } } /* schur_vecs -- returns eigenvectors computed from the real Schur decomposition of a matrix -- T is the block upper triangular Schur matrix -- Q is the orthognal matrix where A = Q.T.Q^T -- if Q is null, the eigenvectors of T are returned -- X_re is the real part of the matrix of eigenvectors, and X_im is the imaginary part of the matrix. -- X_re is returned */ #ifndef ANSI_C MAT *schur_vecs(T,Q,X_re,X_im) MAT *T, *Q, *X_re, *X_im; #else MAT *schur_vecs(MAT *T, MAT *Q, MAT *X_re, MAT *X_im) #endif { int i, j, limit; Real t11_re, t11_im, t12, t21, t22_re, t22_im; Real l_re, l_im, det_re, det_im, invdet_re, invdet_im, val1_re, val1_im, val2_re, val2_im, tmp_val1_re, tmp_val1_im, tmp_val2_re, tmp_val2_im, **T_me; Real sum, diff, discrim, magdet, norm, scale; STATIC VEC *tmp1_re=VNULL, *tmp1_im=VNULL, *tmp2_re=VNULL, *tmp2_im=VNULL; if ( ! T || ! X_re ) error(E_NULL,"schur_vecs"); if ( T->m != T->n || X_re->m != X_re->n || ( Q != MNULL && Q->m != Q->n ) || ( X_im != MNULL && X_im->m != X_im->n ) ) error(E_SQUARE,"schur_vecs"); if ( T->m != X_re->m || ( Q != MNULL && T->m != Q->m ) || ( X_im != MNULL && T->m != X_im->m ) ) error(E_SIZES,"schur_vecs"); tmp1_re = v_resize(tmp1_re,T->m); tmp1_im = v_resize(tmp1_im,T->m); tmp2_re = v_resize(tmp2_re,T->m); tmp2_im = v_resize(tmp2_im,T->m); MEM_STAT_REG(tmp1_re,TYPE_VEC); MEM_STAT_REG(tmp1_im,TYPE_VEC); MEM_STAT_REG(tmp2_re,TYPE_VEC); MEM_STAT_REG(tmp2_im,TYPE_VEC); T_me = T->me; i = 0; while ( i < T->m ) { if ( i+1 < T->m && T->me[i+1][i] != 0.0 ) { /* complex eigenvalue */ sum = 0.5*(T_me[i][i]+T_me[i+1][i+1]); diff = 0.5*(T_me[i][i]-T_me[i+1][i+1]); discrim = diff*diff + T_me[i][i+1]*T_me[i+1][i]; l_re = l_im = 0.0; if ( discrim < 0.0 ) { /* yes -- complex e-vals */ l_re = sum; l_im = sqrt(-discrim); } else /* not correct Real Schur form */ error(E_RANGE,"schur_vecs"); } else { l_re = T_me[i][i]; l_im = 0.0; } v_zero(tmp1_im); v_rand(tmp1_re); sv_mlt(MACHEPS,tmp1_re,tmp1_re); /* solve (T-l.I)x = tmp1 */ limit = ( l_im != 0.0 ) ? i+1 : i; /* printf("limit = %d\n",limit); */ for ( j = limit+1; j < T->m; j++ ) tmp1_re->ve[j] = 0.0; j = limit; while ( j >= 0 ) { if ( j > 0 && T->me[j][j-1] != 0.0 ) { /* 2 x 2 diagonal block */ /* printf("checkpoint A\n"); */ val1_re = tmp1_re->ve[j-1] - __ip__(&(tmp1_re->ve[j+1]),&(T->me[j-1][j+1]),limit-j); /* printf("checkpoint B\n"); */ val1_im = tmp1_im->ve[j-1] - __ip__(&(tmp1_im->ve[j+1]),&(T->me[j-1][j+1]),limit-j); /* printf("checkpoint C\n"); */ val2_re = tmp1_re->ve[j] - __ip__(&(tmp1_re->ve[j+1]),&(T->me[j][j+1]),limit-j); /* printf("checkpoint D\n"); */ val2_im = tmp1_im->ve[j] - __ip__(&(tmp1_im->ve[j+1]),&(T->me[j][j+1]),limit-j); /* printf("checkpoint E\n"); */ t11_re = T_me[j-1][j-1] - l_re; t11_im = - l_im; t22_re = T_me[j][j] - l_re; t22_im = - l_im; t12 = T_me[j-1][j]; t21 = T_me[j][j-1]; scale = fabs(T_me[j-1][j-1]) + fabs(T_me[j][j]) + fabs(t12) + fabs(t21) + fabs(l_re) + fabs(l_im); det_re = t11_re*t22_re - t11_im*t22_im - t12*t21; det_im = t11_re*t22_im + t11_im*t22_re; magdet = det_re*det_re+det_im*det_im; if ( sqrt(magdet) < MACHEPS*scale ) { det_re = MACHEPS*scale; magdet = det_re*det_re+det_im*det_im; } invdet_re = det_re/magdet; invdet_im = - det_im/magdet; tmp_val1_re = t22_re*val1_re-t22_im*val1_im-t12*val2_re; tmp_val1_im = t22_im*val1_re+t22_re*val1_im-t12*val2_im; tmp_val2_re = t11_re*val2_re-t11_im*val2_im-t21*val1_re; tmp_val2_im = t11_im*val2_re+t11_re*val2_im-t21*val1_im; tmp1_re->ve[j-1] = invdet_re*tmp_val1_re - invdet_im*tmp_val1_im; tmp1_im->ve[j-1] = invdet_im*tmp_val1_re + invdet_re*tmp_val1_im; tmp1_re->ve[j] = invdet_re*tmp_val2_re - invdet_im*tmp_val2_im; tmp1_im->ve[j] = invdet_im*tmp_val2_re + invdet_re*tmp_val2_im; j -= 2; } else { t11_re = T_me[j][j] - l_re; t11_im = - l_im; magdet = t11_re*t11_re + t11_im*t11_im; scale = fabs(T_me[j][j]) + fabs(l_re); if ( sqrt(magdet) < MACHEPS*scale ) { t11_re = MACHEPS*scale; magdet = t11_re*t11_re + t11_im*t11_im; } invdet_re = t11_re/magdet; invdet_im = - t11_im/magdet; /* printf("checkpoint F\n"); */ val1_re = tmp1_re->ve[j] - __ip__(&(tmp1_re->ve[j+1]),&(T->me[j][j+1]),limit-j); /* printf("checkpoint G\n"); */ val1_im = tmp1_im->ve[j] - __ip__(&(tmp1_im->ve[j+1]),&(T->me[j][j+1]),limit-j); /* printf("checkpoint H\n"); */ tmp1_re->ve[j] = invdet_re*val1_re - invdet_im*val1_im; tmp1_im->ve[j] = invdet_im*val1_re + invdet_re*val1_im; j -= 1; } } norm = v_norm_inf(tmp1_re) + v_norm_inf(tmp1_im); sv_mlt(1/norm,tmp1_re,tmp1_re); if ( l_im != 0.0 ) sv_mlt(1/norm,tmp1_im,tmp1_im); mv_mlt(Q,tmp1_re,tmp2_re); if ( l_im != 0.0 ) mv_mlt(Q,tmp1_im,tmp2_im); if ( l_im != 0.0 ) norm = sqrt(in_prod(tmp2_re,tmp2_re)+in_prod(tmp2_im,tmp2_im)); else norm = v_norm2(tmp2_re); sv_mlt(1/norm,tmp2_re,tmp2_re); if ( l_im != 0.0 ) sv_mlt(1/norm,tmp2_im,tmp2_im); if ( l_im != 0.0 ) { if ( ! X_im ) error(E_NULL,"schur_vecs"); set_col(X_re,i,tmp2_re); set_col(X_im,i,tmp2_im); sv_mlt(-1.0,tmp2_im,tmp2_im); set_col(X_re,i+1,tmp2_re); set_col(X_im,i+1,tmp2_im); i += 2; } else { set_col(X_re,i,tmp2_re); if ( X_im != MNULL ) set_col(X_im,i,tmp1_im); /* zero vector */ i += 1; } } #ifdef THREADSAFE V_FREE(tmp1_re); V_FREE(tmp1_im); V_FREE(tmp2_re); V_FREE(tmp2_im); #endif return X_re; } gtk-wave-cleaner-0.22-04/meschach/solve.c0000777000175000017500000001617013120075107021261 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Matrix factorisation routines to work with the other matrix files. */ /* solve.c 1.2 11/25/87 */ static char rcsid[] = "$Id: solve.c,v 1.3 1994/01/13 05:29:57 des Exp $"; #include #include #include "matrix2.h" /* Most matrix factorisation routines are in-situ unless otherwise specified */ /* Usolve -- back substitution with optional over-riding diagonal -- can be in-situ but doesn't need to be */ #ifndef ANSI_C VEC *Usolve(matrix,b,out,diag) MAT *matrix; VEC *b, *out; double diag; #else VEC *Usolve(const MAT *matrix, const VEC *b, VEC *out, double diag) #endif { unsigned int dim /* , j */; int i, i_lim; Real **mat_ent, *mat_row, *b_ent, *out_ent, *out_col, sum, tiny; if ( matrix==MNULL || b==VNULL ) error(E_NULL,"Usolve"); dim = min(matrix->m,matrix->n); if ( b->dim < dim ) error(E_SIZES,"Usolve"); if ( out==VNULL || out->dim < dim ) out = v_resize(out,matrix->n); mat_ent = matrix->me; b_ent = b->ve; out_ent = out->ve; tiny = 10.0/HUGE_VAL; for ( i=dim-1; i>=0; i-- ) if ( b_ent[i] != 0.0 ) break; else out_ent[i] = 0.0; i_lim = i; for ( ; i>=0; i-- ) { sum = b_ent[i]; mat_row = &(mat_ent[i][i+1]); out_col = &(out_ent[i+1]); sum -= __ip__(mat_row,out_col,i_lim-i); /****************************************************** for ( j=i+1; j<=i_lim; j++ ) sum -= mat_ent[i][j]*out_ent[j]; sum -= (*mat_row++)*(*out_col++); ******************************************************/ if ( diag==0.0 ) { if ( fabs(mat_ent[i][i]) <= tiny*fabs(sum) ) error(E_SING,"Usolve"); else out_ent[i] = sum/mat_ent[i][i]; } else out_ent[i] = sum/diag; } return (out); } /* Lsolve -- forward elimination with (optional) default diagonal value */ #ifndef ANSI_C VEC *Lsolve(matrix,b,out,diag) MAT *matrix; VEC *b,*out; double diag; #else VEC *Lsolve(const MAT *matrix, const VEC *b, VEC *out, double diag) #endif { unsigned int dim, i, i_lim /* , j */; Real **mat_ent, *mat_row, *b_ent, *out_ent, *out_col, sum, tiny; if ( matrix==(MAT *)NULL || b==(VEC *)NULL ) error(E_NULL,"Lsolve"); dim = min(matrix->m,matrix->n); if ( b->dim < dim ) error(E_SIZES,"Lsolve"); if ( out==(VEC *)NULL || out->dim < dim ) out = v_resize(out,matrix->n); mat_ent = matrix->me; b_ent = b->ve; out_ent = out->ve; for ( i=0; im,U->n); if ( b->dim < dim ) error(E_SIZES,"UTsolve"); out = v_resize(out,U->n); U_me = U->me; b_ve = b->ve; out_ve = out->ve; tiny = 10.0/HUGE_VAL; for ( i=0; idim); MEM_COPY(&(b_ve[i_lim]),&(out_ve[i_lim]),(dim-i_lim)*sizeof(Real)); } if ( diag == 0.0 ) { for ( ; im,A->n); if ( b->dim < dim ) error(E_SIZES,"Dsolve"); x = v_resize(x,A->n); tiny = 10.0/HUGE_VAL; dim = b->dim; for ( i=0; ime[i][i]) <= tiny*fabs(b->ve[i]) ) error(E_SING,"Dsolve"); else x->ve[i] = b->ve[i]/A->me[i][i]; return (x); } /* LTsolve -- back substitution with optional over-riding diagonal using the LOWER triangular part of matrix -- can be in-situ but doesn't need to be */ #ifndef ANSI_C VEC *LTsolve(L,b,out,diag) MAT *L; VEC *b, *out; double diag; #else VEC *LTsolve(const MAT *L, const VEC *b, VEC *out, double diag) #endif { unsigned int dim; int i, i_lim; Real **L_me, *b_ve, *out_ve, tmp, invdiag, tiny; if ( ! L || ! b ) error(E_NULL,"LTsolve"); dim = min(L->m,L->n); if ( b->dim < dim ) error(E_SIZES,"LTsolve"); out = v_resize(out,L->n); L_me = L->me; b_ve = b->ve; out_ve = out->ve; tiny = 10.0/HUGE_VAL; for ( i=dim-1; i>=0; i-- ) if ( b_ve[i] != 0.0 ) break; i_lim = i; if ( b != out ) { __zero__(out_ve,out->dim); MEM_COPY(b_ve,out_ve,(i_lim+1)*sizeof(Real)); } if ( diag == 0.0 ) { for ( ; i>=0; i-- ) { tmp = L_me[i][i]; if ( fabs(tmp) <= tiny*fabs(out_ve[i]) ) error(E_SING,"LTsolve"); out_ve[i] /= tmp; __mltadd__(out_ve,L_me[i],-out_ve[i],i); } } else { invdiag = 1.0/diag; for ( ; i>=0; i-- ) { out_ve[i] *= invdiag; __mltadd__(out_ve,L_me[i],-out_ve[i],i); } } return (out); } gtk-wave-cleaner-0.22-04/meschach/sparse.c0000777000175000017500000006333113120075107021427 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Sparse matrix package See also: sparse.h, matrix.h */ #include #include #include #include "sparse.h" static char rcsid[] = "$Id: sparse.c,v 1.10 1994/03/08 05:46:07 des Exp $"; #define MINROWLEN 10 /* sp_get_val -- returns the (i,j) entry of the sparse matrix A */ #ifndef ANSI_C double sp_get_val(A,i,j) SPMAT *A; int i, j; #else double sp_get_val(const SPMAT *A, int i, int j) #endif { SPROW *r; int idx; if ( A == SMNULL ) error(E_NULL,"sp_get_val"); if ( i < 0 || i >= A->m || j < 0 || j >= A->n ) error(E_SIZES,"sp_get_val"); r = A->row+i; idx = sprow_idx(r,j); if ( idx < 0 ) return 0.0; /* else */ return r->elt[idx].val; } /* sp_set_val -- sets the (i,j) entry of the sparse matrix A */ #ifndef ANSI_C double sp_set_val(A,i,j,val) SPMAT *A; int i, j; double val; #else double sp_set_val(SPMAT *A, int i, int j, double val) #endif { SPROW *r; int idx, idx2, new_len; if ( A == SMNULL ) error(E_NULL,"sp_set_val"); if ( i < 0 || i >= A->m || j < 0 || j >= A->n ) error(E_SIZES,"sp_set_val"); r = A->row+i; idx = sprow_idx(r,j); /* printf("sp_set_val: idx = %d\n",idx); */ if ( idx >= 0 ) { r->elt[idx].val = val; return val; } /* else */ if ( idx < -1 ) { /* Note: this destroys the column & diag access paths */ A->flag_col = A->flag_diag = FALSE; /* shift & insert new value */ idx = -(idx+2); /* this is the intended insertion index */ if ( r->len >= r->maxlen ) { r->len = r->maxlen; new_len = max(2*r->maxlen+1,5); if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,A->row[i].maxlen*sizeof(row_elt), new_len*sizeof(row_elt)); } r->elt = RENEW(r->elt,new_len,row_elt); if ( ! r->elt ) /* can't allocate */ error(E_MEM,"sp_set_val"); r->maxlen = 2*r->maxlen+1; } for ( idx2 = r->len-1; idx2 >= idx; idx2-- ) MEM_COPY((char *)(&(r->elt[idx2])), (char *)(&(r->elt[idx2+1])),sizeof(row_elt)); /************************************************************ if ( idx < r->len ) MEM_COPY((char *)(&(r->elt[idx])),(char *)(&(r->elt[idx+1])), (r->len-idx)*sizeof(row_elt)); ************************************************************/ r->len++; r->elt[idx].col = j; return r->elt[idx].val = val; } /* else -- idx == -1, error in index/matrix! */ return 0.0; } /* sp_mv_mlt -- sparse matrix/dense vector multiply -- result is in out, which is returned unless out==NULL on entry -- if out==NULL on entry then the result vector is created */ #ifndef ANSI_C VEC *sp_mv_mlt(A,x,out) SPMAT *A; VEC *x, *out; #else VEC *sp_mv_mlt(const SPMAT *A, const VEC *x, VEC *out) #endif { int i, j_idx, m, n, max_idx; Real sum, *x_ve; SPROW *r; row_elt *elts; if ( ! A || ! x ) error(E_NULL,"sp_mv_mlt"); if ( x->dim != A->n ) error(E_SIZES,"sp_mv_mlt"); if ( ! out || out->dim < A->m ) out = v_resize(out,A->m); if ( out == x ) error(E_INSITU,"sp_mv_mlt"); m = A->m; n = A->n; x_ve = x->ve; for ( i = 0; i < m; i++ ) { sum = 0.0; r = &(A->row[i]); max_idx = r->len; elts = r->elt; for ( j_idx = 0; j_idx < max_idx; j_idx++, elts++ ) sum += elts->val*x_ve[elts->col]; out->ve[i] = sum; } return out; } /* sp_vm_mlt -- sparse matrix/dense vector multiply from left -- result is in out, which is returned unless out==NULL on entry -- if out==NULL on entry then result vector is created & returned */ #ifndef ANSI_C VEC *sp_vm_mlt(A,x,out) SPMAT *A; VEC *x, *out; #else VEC *sp_vm_mlt(const SPMAT *A, const VEC *x, VEC *out) #endif { int i, j_idx, m, n, max_idx; Real tmp, *x_ve, *out_ve; SPROW *r; row_elt *elts; if ( ! A || ! x ) error(E_NULL,"sp_vm_mlt"); if ( x->dim != A->m ) error(E_SIZES,"sp_vm_mlt"); if ( ! out || out->dim < A->n ) out = v_resize(out,A->n); if ( out == x ) error(E_INSITU,"sp_vm_mlt"); m = A->m; n = A->n; v_zero(out); x_ve = x->ve; out_ve = out->ve; for ( i = 0; i < m; i++ ) { r = A->row+i; max_idx = r->len; elts = r->elt; tmp = x_ve[i]; for ( j_idx = 0; j_idx < max_idx; j_idx++, elts++ ) out_ve[elts->col] += elts->val*tmp; } return out; } /* sp_get -- get sparse matrix -- len is number of elements available for each row without allocating further memory */ #ifndef ANSI_C SPMAT *sp_get(m,n,maxlen) int m, n, maxlen; #else SPMAT *sp_get(int m, int n, int maxlen) #endif { SPMAT *A; SPROW *rows; int i; if ( m < 0 || n < 0 ) error(E_NEG,"sp_get"); maxlen = max(maxlen,1); A = NEW(SPMAT); if ( ! A ) /* can't allocate */ error(E_MEM,"sp_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,0,sizeof(SPMAT)); mem_numvar(TYPE_SPMAT,1); } /* fprintf(stderr,"Have SPMAT structure\n"); */ A->row = rows = NEW_A(m,SPROW); if ( ! A->row ) /* can't allocate */ error(E_MEM,"sp_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,0,m*sizeof(SPROW)); } /* fprintf(stderr,"Have row structure array\n"); */ A->start_row = NEW_A(n,int); A->start_idx = NEW_A(n,int); if ( ! A->start_row || ! A->start_idx ) /* can't allocate */ error(E_MEM,"sp_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,0,2*n*sizeof(int)); } for ( i = 0; i < n; i++ ) A->start_row[i] = A->start_idx[i] = -1; /* fprintf(stderr,"Have start_row array\n"); */ A->m = A->max_m = m; A->n = A->max_n = n; for ( i = 0; i < m; i++, rows++ ) { rows->elt = NEW_A(maxlen,row_elt); if ( ! rows->elt ) error(E_MEM,"sp_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,0,maxlen*sizeof(row_elt)); } /* fprintf(stderr,"Have row %d element array\n",i); */ rows->len = 0; rows->maxlen = maxlen; rows->diag = -1; } return A; } /* sp_free -- frees up the memory for a sparse matrix */ #ifndef ANSI_C int sp_free(A) SPMAT *A; #else int sp_free(SPMAT *A) #endif { SPROW *r; int i; if ( ! A ) return -1; if ( A->start_row != (int *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,A->max_n*sizeof(int),0); } free((char *)(A->start_row)); } if ( A->start_idx != (int *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,A->max_n*sizeof(int),0); } free((char *)(A->start_idx)); } if ( ! A->row ) { if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,sizeof(SPMAT),0); mem_numvar(TYPE_SPMAT,-1); } free((char *)A); return 0; } for ( i = 0; i < A->m; i++ ) { r = &(A->row[i]); if ( r->elt != (row_elt *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,A->row[i].maxlen*sizeof(row_elt),0); } free((char *)(r->elt)); } } if (mem_info_is_on()) { if (A->row) mem_bytes(TYPE_SPMAT,A->max_m*sizeof(SPROW),0); mem_bytes(TYPE_SPMAT,sizeof(SPMAT),0); mem_numvar(TYPE_SPMAT,-1); } free((char *)(A->row)); free((char *)A); return 0; } /* sp_copy -- constructs a copy of a given matrix -- note that the max_len fields (etc) are no larger in the copy than necessary -- result is returned */ #ifndef ANSI_C SPMAT *sp_copy(A) SPMAT *A; #else SPMAT *sp_copy(const SPMAT *A) #endif { SPMAT *out; SPROW *row1, *row2; int i; if ( A == SMNULL ) error(E_NULL,"sp_copy"); if ( ! (out=NEW(SPMAT)) ) error(E_MEM,"sp_copy"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,0,sizeof(SPMAT)); mem_numvar(TYPE_SPMAT,1); } out->m = out->max_m = A->m; out->n = out->max_n = A->n; /* set up rows */ if ( ! (out->row=NEW_A(A->m,SPROW)) ) error(E_MEM,"sp_copy"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,0,A->m*sizeof(SPROW)); } for ( i = 0; i < A->m; i++ ) { row1 = &(A->row[i]); row2 = &(out->row[i]); if ( ! (row2->elt=NEW_A(max(row1->len,3),row_elt)) ) error(E_MEM,"sp_copy"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,0,max(row1->len,3)*sizeof(row_elt)); } row2->len = row1->len; row2->maxlen = max(row1->len,3); row2->diag = row1->diag; MEM_COPY((char *)(row1->elt),(char *)(row2->elt), row1->len*sizeof(row_elt)); } /* set up start arrays -- for column access */ if ( ! (out->start_idx=NEW_A(A->n,int)) || ! (out->start_row=NEW_A(A->n,int)) ) error(E_MEM,"sp_copy"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,0,2*A->n*sizeof(int)); } MEM_COPY((char *)(A->start_idx),(char *)(out->start_idx), A->n*sizeof(int)); MEM_COPY((char *)(A->start_row),(char *)(out->start_row), A->n*sizeof(int)); return out; } /* sp_col_access -- set column access path; i.e. nxt_row, nxt_idx fields -- returns A */ #ifndef ANSI_C SPMAT *sp_col_access(A) SPMAT *A; #else SPMAT *sp_col_access(SPMAT *A) #endif { int i, j, j_idx, len, m, n; SPROW *row; row_elt *r_elt; int *start_row, *start_idx; if ( A == SMNULL ) error(E_NULL,"sp_col_access"); m = A->m; n = A->n; /* initialise start_row and start_idx */ start_row = A->start_row; start_idx = A->start_idx; for ( j = 0; j < n; j++ ) { *start_row++ = -1; *start_idx++ = -1; } start_row = A->start_row; start_idx = A->start_idx; /* now work UP the rows, setting nxt_row, nxt_idx fields */ for ( i = m-1; i >= 0; i-- ) { row = &(A->row[i]); r_elt = row->elt; len = row->len; for ( j_idx = 0; j_idx < len; j_idx++, r_elt++ ) { j = r_elt->col; r_elt->nxt_row = start_row[j]; r_elt->nxt_idx = start_idx[j]; start_row[j] = i; start_idx[j] = j_idx; } } A->flag_col = TRUE; return A; } /* sp_diag_access -- set diagonal access path(s) */ #ifndef ANSI_C SPMAT *sp_diag_access(A) SPMAT *A; #else SPMAT *sp_diag_access(SPMAT *A) #endif { int i, m; SPROW *row; if ( A == SMNULL ) error(E_NULL,"sp_diag_access"); m = A->m; row = A->row; for ( i = 0; i < m; i++, row++ ) row->diag = sprow_idx(row,i); A->flag_diag = TRUE; return A; } /* sp_m2dense -- convert a sparse matrix to a dense one */ #ifndef ANSI_C MAT *sp_m2dense(A,out) SPMAT *A; MAT *out; #else MAT *sp_m2dense(const SPMAT *A, MAT *out) #endif { int i, j_idx; SPROW *row; row_elt *elt; if ( ! A ) error(E_NULL,"sp_m2dense"); if ( ! out || out->m < A->m || out->n < A->n ) out = m_get(A->m,A->n); m_zero(out); for ( i = 0; i < A->m; i++ ) { row = &(A->row[i]); elt = row->elt; for ( j_idx = 0; j_idx < row->len; j_idx++, elt++ ) out->me[i][elt->col] = elt->val; } return out; } /* C = A+B, can be in situ */ #ifndef ANSI_C SPMAT *sp_add(A,B,C) SPMAT *A, *B, *C; #else SPMAT *sp_add(const SPMAT *A, const SPMAT *B, SPMAT *C) #endif { int i, in_situ; SPROW *rc; STATIC SPROW *tmp = NULL; if ( ! A || ! B ) error(E_NULL,"sp_add"); if ( A->m != B->m || A->n != B->n ) error(E_SIZES,"sp_add"); if (C == A || C == B) in_situ = TRUE; else in_situ = FALSE; if ( ! C ) C = sp_get(A->m,A->n,5); else { if ( C->m != A->m || C->n != A->n ) error(E_SIZES,"sp_add"); if (!in_situ) sp_zero(C); } if (tmp == (SPROW *)NULL && in_situ) { tmp = sprow_get(MINROWLEN); MEM_STAT_REG(tmp,TYPE_SPROW); } if (in_situ) for (i=0; i < A->m; i++) { rc = &(C->row[i]); sprow_add(&(A->row[i]),&(B->row[i]),0,tmp,TYPE_SPROW); sprow_resize(rc,tmp->len,TYPE_SPMAT); MEM_COPY(tmp->elt,rc->elt,tmp->len*sizeof(row_elt)); rc->len = tmp->len; } else for (i=0; i < A->m; i++) { sprow_add(&(A->row[i]),&(B->row[i]),0,&(C->row[i]),TYPE_SPMAT); } C->flag_col = C->flag_diag = FALSE; #ifdef THREADSAFE sprow_free(tmp); #endif return C; } /* C = A-B, cannot be in situ */ #ifndef ANSI_C SPMAT *sp_sub(A,B,C) SPMAT *A, *B, *C; #else SPMAT *sp_sub(const SPMAT *A, const SPMAT *B, SPMAT *C) #endif { int i, in_situ; SPROW *rc; STATIC SPROW *tmp = NULL; if ( ! A || ! B ) error(E_NULL,"sp_sub"); if ( A->m != B->m || A->n != B->n ) error(E_SIZES,"sp_sub"); if (C == A || C == B) in_situ = TRUE; else in_situ = FALSE; if ( ! C ) C = sp_get(A->m,A->n,5); else { if ( C->m != A->m || C->n != A->n ) error(E_SIZES,"sp_sub"); if (!in_situ) sp_zero(C); } if (tmp == (SPROW *)NULL && in_situ) { tmp = sprow_get(MINROWLEN); MEM_STAT_REG(tmp,TYPE_SPROW); } if (in_situ) for (i=0; i < A->m; i++) { rc = &(C->row[i]); sprow_sub(&(A->row[i]),&(B->row[i]),0,tmp,TYPE_SPROW); sprow_resize(rc,tmp->len,TYPE_SPMAT); MEM_COPY(tmp->elt,rc->elt,tmp->len*sizeof(row_elt)); rc->len = tmp->len; } else for (i=0; i < A->m; i++) { sprow_sub(&(A->row[i]),&(B->row[i]),0,&(C->row[i]),TYPE_SPMAT); } C->flag_col = C->flag_diag = FALSE; #ifdef THREADSAFE sprow_free(tmp); #endif return C; } /* C = A+alpha*B, cannot be in situ */ #ifndef ANSI_C SPMAT *sp_mltadd(A,B,alpha,C) SPMAT *A, *B, *C; double alpha; #else SPMAT *sp_mltadd(const SPMAT *A, const SPMAT *B, double alpha, SPMAT *C) #endif { int i, in_situ; SPROW *rc; STATIC SPROW *tmp = NULL; if ( ! A || ! B ) error(E_NULL,"sp_mltadd"); if ( A->m != B->m || A->n != B->n ) error(E_SIZES,"sp_mltadd"); if (C == A || C == B) in_situ = TRUE; else in_situ = FALSE; if ( ! C ) C = sp_get(A->m,A->n,5); else { if ( C->m != A->m || C->n != A->n ) error(E_SIZES,"sp_mltadd"); if (!in_situ) sp_zero(C); } if (tmp == (SPROW *)NULL && in_situ) { tmp = sprow_get(MINROWLEN); MEM_STAT_REG(tmp,TYPE_SPROW); } if (in_situ) for (i=0; i < A->m; i++) { rc = &(C->row[i]); sprow_mltadd(&(A->row[i]),&(B->row[i]),alpha,0,tmp,TYPE_SPROW); sprow_resize(rc,tmp->len,TYPE_SPMAT); MEM_COPY(tmp->elt,rc->elt,tmp->len*sizeof(row_elt)); rc->len = tmp->len; } else for (i=0; i < A->m; i++) { sprow_mltadd(&(A->row[i]),&(B->row[i]),alpha,0, &(C->row[i]),TYPE_SPMAT); } C->flag_col = C->flag_diag = FALSE; #ifdef THREADSAFE sprow_free(tmp); #endif return C; } /* B = alpha*A, can be in situ */ #ifndef ANSI_C SPMAT *sp_smlt(A,alpha,B) SPMAT *A, *B; double alpha; #else SPMAT *sp_smlt(const SPMAT *A, double alpha, SPMAT *B) #endif { int i; if ( ! A ) error(E_NULL,"sp_smlt"); if ( ! B ) B = sp_get(A->m,A->n,5); else if ( A->m != B->m || A->n != B->n ) error(E_SIZES,"sp_smlt"); for (i=0; i < A->m; i++) { sprow_smlt(&(A->row[i]),alpha,0,&(B->row[i]),TYPE_SPMAT); } return B; } /* sp_zero -- zero all the (represented) elements of a sparse matrix */ #ifndef ANSI_C SPMAT *sp_zero(A) SPMAT *A; #else SPMAT *sp_zero(SPMAT *A) #endif { int i, idx, len; row_elt *elt; if ( ! A ) error(E_NULL,"sp_zero"); for ( i = 0; i < A->m; i++ ) { elt = A->row[i].elt; len = A->row[i].len; for ( idx = 0; idx < len; idx++ ) (*elt++).val = 0.0; } return A; } /* sp_copy2 -- copy sparse matrix (type 2) -- keeps structure of the OUT matrix */ #ifndef ANSI_C SPMAT *sp_copy2(A,OUT) SPMAT *A, *OUT; #else SPMAT *sp_copy2(const SPMAT *A, SPMAT *OUT) #endif { int i /* , idx, len1, len2 */; SPROW *r1, *r2; STATIC SPROW *scratch = (SPROW *)NULL; /* row_elt *e1, *e2; */ if ( ! A ) error(E_NULL,"sp_copy2"); if ( ! OUT ) OUT = sp_get(A->m,A->n,10); if ( ! scratch ) { scratch = sprow_xpd(scratch,MINROWLEN,TYPE_SPROW); MEM_STAT_REG(scratch,TYPE_SPROW); } if ( OUT->m < A->m ) { if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,A->max_m*sizeof(SPROW), A->m*sizeof(SPROW)); } OUT->row = RENEW(OUT->row,A->m,SPROW); if ( ! OUT->row ) error(E_MEM,"sp_copy2"); for ( i = OUT->m; i < A->m; i++ ) { OUT->row[i].elt = NEW_A(MINROWLEN,row_elt); if ( ! OUT->row[i].elt ) error(E_MEM,"sp_copy2"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,0,MINROWLEN*sizeof(row_elt)); } OUT->row[i].maxlen = MINROWLEN; OUT->row[i].len = 0; } OUT->m = A->m; } OUT->flag_col = OUT->flag_diag = FALSE; /* sp_zero(OUT); */ for ( i = 0; i < A->m; i++ ) { r1 = &(A->row[i]); r2 = &(OUT->row[i]); sprow_copy(r1,r2,scratch,TYPE_SPROW); if ( r2->maxlen < scratch->len ) sprow_xpd(r2,scratch->len,TYPE_SPMAT); MEM_COPY((char *)(scratch->elt),(char *)(r2->elt), scratch->len*sizeof(row_elt)); r2->len = scratch->len; /******************************************************* e1 = r1->elt; e2 = r2->elt; len1 = r1->len; len2 = r2->len; for ( idx = 0; idx < len2; idx++, e2++ ) e2->val = 0.0; for ( idx = 0; idx < len1; idx++, e1++ ) sprow_set_val(r2,e1->col,e1->val); *******************************************************/ } sp_col_access(OUT); #ifdef THREADSAFE sprow_free(scratch); #endif return OUT; } /* sp_resize -- resize a sparse matrix -- don't destroying any contents if possible -- returns resized matrix */ #ifndef ANSI_C SPMAT *sp_resize(A,m,n) SPMAT *A; int m, n; #else SPMAT *sp_resize(SPMAT *A, int m, int n) #endif { int i, len; SPROW *r; if (m < 0 || n < 0) error(E_NEG,"sp_resize"); if ( ! A ) return sp_get(m,n,10); if (m == A->m && n == A->n) return A; if ( m <= A->max_m ) { for ( i = A->m; i < m; i++ ) A->row[i].len = 0; A->m = m; } else { if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,A->max_m*sizeof(SPROW), m*sizeof(SPROW)); } A->row = RENEW(A->row,(unsigned)m,SPROW); if ( ! A->row ) error(E_MEM,"sp_resize"); for ( i = A->m; i < m; i++ ) { if ( ! (A->row[i].elt = NEW_A(MINROWLEN,row_elt)) ) error(E_MEM,"sp_resize"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,0,MINROWLEN*sizeof(row_elt)); } A->row[i].len = 0; A->row[i].maxlen = MINROWLEN; } A->m = A->max_m = m; } /* update number of rows */ A->n = n; /* do we need to increase the size of start_idx[] and start_row[] ? */ if ( n > A->max_n ) { /* only have to update the start_idx & start_row arrays */ if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT,2*A->max_n*sizeof(int), 2*n*sizeof(int)); } A->start_row = RENEW(A->start_row,(unsigned)n,int); A->start_idx = RENEW(A->start_idx,(unsigned)n,int); if ( ! A->start_row || ! A->start_idx ) error(E_MEM,"sp_resize"); A->max_n = n; /* ...and update max_n */ return A; } if ( n <= A->n ) /* make sure that all rows are truncated just before column n */ for ( i = 0; i < A->m; i++ ) { r = &(A->row[i]); len = sprow_idx(r,n); if ( len < 0 ) len = -(len+2); if ( len < 0 ) error(E_MEM,"sp_resize"); r->len = len; } return A; } /* sp_compact -- removes zeros and near-zeros from a sparse matrix */ #ifndef ANSI_C SPMAT *sp_compact(A,tol) SPMAT *A; double tol; #else SPMAT *sp_compact(SPMAT *A, double tol) #endif { int i, idx1, idx2; SPROW *r; row_elt *elt1, *elt2; if ( ! A ) error(E_NULL,"sp_compact"); if ( tol < 0.0 ) error(E_RANGE,"sp_compact"); A->flag_col = A->flag_diag = FALSE; for ( i = 0; i < A->m; i++ ) { r = &(A->row[i]); elt1 = elt2 = r->elt; idx1 = idx2 = 0; while ( idx1 < r->len ) { /* printf("# sp_compact: idx1 = %d, idx2 = %d\n",idx1,idx2); */ if ( fabs(elt1->val) <= tol ) { idx1++; elt1++; continue; } if ( elt1 != elt2 ) MEM_COPY(elt1,elt2,sizeof(row_elt)); idx1++; elt1++; idx2++; elt2++; } r->len = idx2; } return A; } /* sp_mlt (C) Copyright David Stewart and Fabrizio Novalis */ /* sp_mlt -- computes out = A*B and returns out */ SPMAT *sp_mlt(const SPMAT *A, const SPMAT *B, SPMAT *out) { int i, j, k, idx, cp; SPROW *rA, *rB, *rout, *rtemp; double valA; if ( ! A || ! B ) error(E_NULL,"sp_mlt"); if ( A->n != B->m ) error(E_SIZES,"sp_mlt"); out = sp_resize(out,A->m,B->n); sp_zero(out); rtemp = sprow_get(B->n); for ( i = 0; i < A->m; i++ ) /* per ogni riga */ { rtemp = sprow_resize(rtemp,0,TYPE_SPROW); rA = &(A->row[i]); rout = &(out->row[i]); for ( idx = 0; idx < rA->len; idx++ ) /* per ogni elemento != 0 della riga corrente */ { j = rA->elt[idx].col; valA = rA->elt[idx].val; rB = &(B->row[j]); sprow_mltadd(rtemp,rB,valA,0,rout,TYPE_SPMAT); for ( cp = 0; cp < rout->len; cp++ ) { rtemp->elt[cp].col = rout->elt[cp].col; rtemp->elt[cp].val = rout->elt[cp].val; } rtemp->len=rout->len; } } return out; } /* varying number of arguments */ #ifdef ANSI_C /* To allocate memory to many arguments. The function should be called: sp_get_vars(m,n,deg,&x,&y,&z,...,NULL); where int m,n,deg; SPMAT *x, *y, *z,...; The last argument should be NULL ! m x n is the dimension of matrices x,y,z,... returned value is equal to the number of allocated variables */ int sp_get_vars(int m,int n,int deg,...) { va_list ap; int i=0; SPMAT **par; va_start(ap, deg); while (par = va_arg(ap,SPMAT **)) { /* NULL ends the list*/ *par = sp_get(m,n,deg); i++; } va_end(ap); return i; } /* To resize memory for many arguments. The function should be called: sp_resize_vars(m,n,&x,&y,&z,...,NULL); where int m,n; SPMAT *x, *y, *z,...; The last argument should be NULL ! m X n is the resized dimension of matrices x,y,z,... returned value is equal to the number of allocated variables. If one of x,y,z,.. arguments is NULL then memory is allocated to this argument. */ int sp_resize_vars(int m,int n,...) { va_list ap; int i=0; SPMAT **par; va_start(ap, n); while (par = va_arg(ap,SPMAT **)) { /* NULL ends the list*/ *par = sp_resize(*par,m,n); i++; } va_end(ap); return i; } /* To deallocate memory for many arguments. The function should be called: sp_free_vars(&x,&y,&z,...,NULL); where SPMAT *x, *y, *z,...; The last argument should be NULL ! There must be at least one not NULL argument. returned value is equal to the number of allocated variables. Returned value of x,y,z,.. is VNULL. */ int sp_free_vars(SPMAT **va,...) { va_list ap; int i=1; SPMAT **par; sp_free(*va); *va = (SPMAT *) NULL; va_start(ap, va); while (par = va_arg(ap,SPMAT **)) { /* NULL ends the list*/ sp_free(*par); *par = (SPMAT *)NULL; i++; } va_end(ap); return i; } #elif VARARGS /* To allocate memory to many arguments. The function should be called: sp_get_vars(m,n,deg,&x,&y,&z,...,NULL); where int m,n,deg; SPMAT *x, *y, *z,...; The last argument should be NULL ! m x n is the dimension of matrices x,y,z,... returned value is equal to the number of allocated variables */ int sp_get_vars(va_alist) va_dcl { va_list ap; int i=0, m, n, deg; SPMAT **par; va_start(ap); m = va_arg(ap,int); n = va_arg(ap,int); deg = va_arg(ap,int); while (par = va_arg(ap,SPMAT **)) { /* NULL ends the list*/ *par = sp_get(m,n,deg); i++; } va_end(ap); return i; } /* To resize memory for many arguments. The function should be called: sp_resize_vars(m,n,&x,&y,&z,...,NULL); where int m,n; SPMAT *x, *y, *z,...; The last argument should be NULL ! m X n is the resized dimension of matrices x,y,z,... returned value is equal to the number of allocated variables. If one of x,y,z,.. arguments is NULL then memory is allocated to this argument. */ int sp_resize_vars(va_alist) va_dcl { va_list ap; int i=0, m, n; SPMAT **par; va_start(ap); m = va_arg(ap,int); n = va_arg(ap,int); while (par = va_arg(ap,SPMAT **)) { /* NULL ends the list*/ *par = sp_resize(*par,m,n); i++; } va_end(ap); return i; } /* To deallocate memory for many arguments. The function should be called: sp_free_vars(&x,&y,&z,...,NULL); where SPMAT *x, *y, *z,...; The last argument should be NULL ! There must be at least one not NULL argument. returned value is equal to the number of allocated variables. Returned value of x,y,z,.. is VNULL. */ int sp_free_vars(va_alist) va_dcl { va_list ap; int i=0; SPMAT **par; va_start(ap); while (par = va_arg(ap,SPMAT **)) { /* NULL ends the list*/ sp_free(*par); *par = (SPMAT *)NULL; i++; } va_end(ap); return i; } #endif gtk-wave-cleaner-0.22-04/meschach/sparse.h0000777000175000017500000001511213120075107021426 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Header for sparse matrix stuff. Basic sparse routines to be held in sparse.c */ /* RCS id: $Id: sparse.h,v 1.2 1994/01/13 05:33:36 des Exp $ */ #ifndef SPARSEH #define SPARSEH #include "matrix.h" /* basic sparse types */ typedef struct row_elt { int col, nxt_row, nxt_idx; Real val; } row_elt; typedef struct SPROW { int len, maxlen, diag; row_elt *elt; /* elt[maxlen] */ } SPROW; typedef struct SPMAT { int m, n, max_m, max_n; char flag_col, flag_diag; SPROW *row; /* row[max_m] */ int *start_row; /* start_row[max_n] */ int *start_idx; /* start_idx[max_n] */ } SPMAT; /* Note that the first allocated entry in column j is start_row[j]; This starts the chain down the columns using the nxt_row and nxt_idx fields of each entry in each row. */ typedef struct pair { int pos; Real val; } pair; typedef struct SPVEC { int dim, max_dim; pair *elt; /* elt[max_dim] */ } SPVEC; #define SMNULL ((SPMAT*)NULL) #define SVNULL ((SPVEC*)NULL) /* Macro for speedup */ #define sprow_idx2(r,c,hint) \ ( ( (hint) >= 0 && (hint) < (r)->len && \ (r)->elt[hint].col == (c)) ? (hint) : sprow_idx((r),(c)) ) /* memory functions */ #ifdef ANSI_C int sp_get_vars(int m,int n,int deg,...); int sp_resize_vars(int m,int n,...); int sp_free_vars(SPMAT **,...); #elif VARARGS int sp_get_vars(); int sp_resize_vars(); int sp_free_vars(); #endif /* ANSI_C */ /* Sparse Matrix Operations and Utilities */ #ifndef ANSI_C extern SPMAT *sp_get(), *sp_copy(), *sp_copy2(), *sp_zero(), *sp_resize(), *sp_compact(); extern double sp_get_val(), sp_set_val(); extern VEC *sp_mv_mlt(), *sp_vm_mlt(); extern int sp_free(); /* Access path operations */ extern SPMAT *sp_col_access(); extern SPMAT *sp_diag_access(); extern int chk_col_access(); /* Input/output operations */ extern SPMAT *sp_finput(); extern void sp_foutput(), sp_foutput2(); /* algebraic operations */ extern SPMAT *sp_smlt(), *sp_add(), *sp_sub(), *sp_mltadd(); /* sparse row operations */ extern SPROW *sprow_get(), *sprow_xpd(), *sprow_merge(), *sprow_mltadd(), *sprow_resize(), *sprow_copy(); extern SPROW *sprow_add(), *sprow_sub(), *sprow_smlt(); extern double sprow_set_val(); extern void sprow_foutput(); extern int sprow_idx(), sprow_free(); /* dump */ extern void sp_dump(), sprow_dump(); extern MAT *sp_m2dense(); #else SPMAT *sp_get(int,int,int), *sp_copy(const SPMAT *), *sp_copy2(const SPMAT *,SPMAT *), *sp_zero(SPMAT *), *sp_resize(SPMAT *,int,int), *sp_compact(SPMAT *,double); double sp_get_val(const SPMAT *,int,int), sp_set_val(SPMAT *,int,int,double); VEC *sp_mv_mlt(const SPMAT *, const VEC *, VEC *), *sp_vm_mlt(const SPMAT *, const VEC *, VEC *); int sp_free(SPMAT *); /* Access path operations */ SPMAT *sp_col_access(SPMAT *); SPMAT *sp_diag_access(SPMAT *); int chk_col_access(const SPMAT *); /* Input/output operations */ SPMAT *sp_finput(FILE *); void sp_foutput(FILE *, const SPMAT *); /* algebraic operations */ SPMAT *sp_smlt(const SPMAT *A,double alpha,SPMAT *B), *sp_add(const SPMAT *A,const SPMAT *B,SPMAT *C), *sp_sub(const SPMAT *A,const SPMAT *B,SPMAT *C), *sp_mltadd(const SPMAT *A,const SPMAT *B,double alpha,SPMAT *C); /* sparse row operations */ SPROW *sprow_get(int), *sprow_xpd(SPROW *r,int n,int type), *sprow_resize(SPROW *r,int n,int type), *sprow_merge(const SPROW *,const SPROW *,SPROW *,int type), *sprow_copy(const SPROW *,const SPROW *,SPROW *,int type), *sprow_mltadd(const SPROW *r1,const SPROW *r2, double alpha, int j0, SPROW *r_out, int type); SPROW *sprow_add(const SPROW *r1,const SPROW *r2, int j0,SPROW *r_out, int type), *sprow_sub(const SPROW *r1,const SPROW *r2, int j0,SPROW *r_out, int type), *sprow_smlt(const SPROW *r1,double alpha, int j0,SPROW *r_out, int type); double sprow_set_val(SPROW *,int,double); int sprow_free(SPROW *); int sprow_idx(const SPROW *,int); void sprow_foutput(FILE *,const SPROW *); /* dump */ void sp_dump(FILE *fp, const SPMAT *A); void sprow_dump(FILE *fp, const SPROW *r); MAT *sp_m2dense(const SPMAT *A,MAT *out); #endif /* ANSI_C */ /* MACROS */ #define sp_input() sp_finput(stdin) #define sp_output(A) sp_foutput(stdout,(A)) #define sp_output2(A) sp_foutput2(stdout,(A)) #define row_mltadd(r1,r2,alpha,out) sprow_mltadd(r1,r2,alpha,0,out) #define out_row(r) sprow_foutput(stdout,(r)) #define SP_FREE(A) ( sp_free((A)), (A)=(SPMAT *)NULL) /* utility for index computations -- ensures index returned >= 0 */ #define fixindex(idx) ((idx) == -1 ? (error(E_BOUNDS,"fixindex"),0) : \ (idx) < 0 ? -((idx)+2) : (idx)) /* NOT USED */ /* loop over the columns in a row */ /* #define loop_cols(r,e,code) \ do { int _r_idx; row_elt *e; SPROW *_t_row; \ _t_row = (r); e = &(_t_row->elt); \ for ( _r_idx = 0; _r_idx < _t_row->len; _r_idx++, e++ ) \ { code; } } while ( 0 ) */ /* loop over the rows in a column */ /* #define loop_cols(A,col,e,code) \ do { int _r_num, _r_idx, _c; SPROW *_r; row_elt *e; \ if ( ! (A)->flag_col ) sp_col_access((A)); \ col_num = (col); \ if ( col_num < 0 || col_num >= A->n ) \ error(E_BOUNDS,"loop_cols"); \ _r_num = (A)->start_row[_c]; _r_idx = (A)->start_idx[_c]; \ while ( _r_num >= 0 ) { \ _r = &((A)->row[_r_num]); \ _r_idx = sprow_idx2(_r,_c,_r_idx); \ if ( _r_idx < 0 ) continue; \ e = &(_r->elt[_r_idx]); code; \ _r_num = e->nxt_row; _r_idx = e->nxt_idx; \ } } while ( 0 ) */ #endif /* SPARSEH */ gtk-wave-cleaner-0.22-04/meschach/sparse2.h0000777000175000017500000000627713120075107021524 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Sparse matrix factorise/solve header */ /* RCS id: $Id: sparse2.h,v 1.4 1994/01/13 05:33:46 des Exp $ */ #ifndef SPARSE2H #define SPARSE2H #include "sparse.h" #ifdef ANSI_C SPMAT *spCHfactor(SPMAT *A), *spICHfactor(SPMAT *A), *spCHsymb(SPMAT *A); VEC *spCHsolve(SPMAT *CH, const VEC *b, VEC *x); SPMAT *spLUfactor(SPMAT *A,PERM *pivot,double threshold); SPMAT *spILUfactor(SPMAT *A,double theshold); VEC *spLUsolve(const SPMAT *LU,PERM *pivot, const VEC *b,VEC *x), *spLUTsolve(SPMAT *LU,PERM *pivot, const VEC *b,VEC *x); SPMAT *spBKPfactor(SPMAT *, PERM *, PERM *, double); VEC *spBKPsolve(SPMAT *, PERM *, PERM *, const VEC *, VEC *); VEC *pccg(VEC *(*A)(),void *A_par,VEC *(*M_inv)(),void *M_par,VEC *b, double tol,VEC *x); VEC *sp_pccg(SPMAT *,SPMAT *,VEC *,double,VEC *); VEC *cgs(VEC *(*A)(),void *A_par,VEC *b,VEC *r0,double tol,VEC *x); VEC *sp_cgs(SPMAT *,VEC *,VEC *,double,VEC *); VEC *lsqr(VEC *(*A)(),VEC *(*AT)(),void *A_par,VEC *b,double tol,VEC *x); VEC *sp_lsqr(SPMAT *,VEC *,double,VEC *); int cg_set_maxiter(int); void lanczos(VEC *(*A)(),void *A_par,int m,VEC *x0,VEC *a,VEC *b, Real *beta_m1,MAT *Q); void sp_lanczos(SPMAT *,int,VEC *,VEC *,VEC *,Real *,MAT *); VEC *lanczos2(VEC *(*A)(),void *A_par,int m,VEC *x0,VEC *evals, VEC *err_est); VEC *sp_lanczos2(SPMAT *,int,VEC *,VEC *,VEC *); extern void scan_to(SPMAT *,IVEC *,IVEC *,IVEC *,int); extern row_elt *chase_col(const SPMAT *,int,int *,int *,int); extern row_elt *chase_past(const SPMAT *,int,int *,int *,int); extern row_elt *bump_col(const SPMAT *,int,int *,int *); #else extern SPMAT *spCHfactor(), *spICHfactor(), *spCHsymb(); extern VEC *spCHsolve(); extern SPMAT *spLUfactor(); extern SPMAT *spILUfactor(); extern VEC *spLUsolve(), *spLUTsolve(); extern SPMAT *spBKPfactor(); extern VEC *spBKPsolve(); extern VEC *pccg(), *sp_pccg(), *cgs(), *sp_cgs(), *lsqr(), *sp_lsqr(); extern int cg_set_maxiter(); void lanczos(), sp_lanczos(); VEC *lanczos2(), *sp_lanczos2(); extern void scan_to(); extern row_elt *chase_col(); extern row_elt *chase_past(); extern row_elt *bump_col(); #endif #endif gtk-wave-cleaner-0.22-04/meschach/sparseio.c0000777000175000017500000002177613120075107021766 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file has the routines for sparse matrix input/output It works in conjunction with sparse.c, sparse.h etc */ #include #include "sparse.h" static char rcsid[] = "$Id: sparseio.c,v 1.4 1994/01/13 05:34:25 des Exp $"; /* local variables */ static char line[MAXLINE]; /* sp_foutput -- output sparse matrix A to file/stream fp */ #ifndef ANSI_C void sp_foutput(fp,A) FILE *fp; SPMAT *A; #else void sp_foutput(FILE *fp, const SPMAT *A) #endif { int i, j_idx, m /* , n */; SPROW *rows; row_elt *elts; fprintf(fp,"SparseMatrix: "); if ( A == SMNULL ) { fprintf(fp,"*** NULL ***\n"); error(E_NULL,"sp_foutput"); return; } fprintf(fp,"%d by %d\n",A->m,A->n); m = A->m; /* n = A->n; */ if ( ! (rows=A->row) ) { fprintf(fp,"*** NULL rows ***\n"); error(E_NULL,"sp_foutput"); return; } for ( i = 0; i < m; i++ ) { fprintf(fp,"row %d: ",i); if ( ! (elts=rows[i].elt) ) { fprintf(fp,"*** NULL element list ***\n"); continue; } for ( j_idx = 0; j_idx < rows[i].len; j_idx++ ) { fprintf(fp,"%d:%-20.15g ",elts[j_idx].col, elts[j_idx].val); if ( j_idx % 3 == 2 && j_idx != rows[i].len-1 ) fprintf(fp,"\n "); } fprintf(fp,"\n"); } fprintf(fp,"#\n"); /* to stop looking beyond for next entry */ } /* sp_foutput2 -- print out sparse matrix **as a dense matrix** -- see output format used in matrix.h etc */ /****************************************************************** void sp_foutput2(fp,A) FILE *fp; SPMAT *A; { int cnt, i, j, j_idx; SPROW *r; row_elt *elt; if ( A == SMNULL ) { fprintf(fp,"Matrix: *** NULL ***\n"); return; } fprintf(fp,"Matrix: %d by %d\n",A->m,A->n); for ( i = 0; i < A->m; i++ ) { fprintf(fp,"row %d:",i); r = &(A->row[i]); elt = r->elt; cnt = j = j_idx = 0; while ( j_idx < r->len || j < A->n ) { if ( j_idx >= r->len ) fprintf(fp,"%14.9g ",0.0); else if ( j < elt[j_idx].col ) fprintf(fp,"%14.9g ",0.0); else fprintf(fp,"%14.9g ",elt[j_idx++].val); if ( cnt++ % 4 == 3 ) fprintf(fp,"\n"); j++; } fprintf(fp,"\n"); } } ******************************************************************/ /* sp_dump -- prints ALL relevant information about the sparse matrix A */ #ifndef ANSI_C void sp_dump(fp,A) FILE *fp; SPMAT *A; #else void sp_dump(FILE *fp, const SPMAT *A) #endif { int i, j, j_idx; SPROW *rows; row_elt *elts; fprintf(fp,"SparseMatrix dump:\n"); if ( ! A ) { fprintf(fp,"*** NULL ***\n"); return; } fprintf(fp,"Matrix at 0x%lx\n",(long)A); fprintf(fp,"Dimensions: %d by %d\n",A->m,A->n); fprintf(fp,"MaxDimensions: %d by %d\n",A->max_m,A->max_n); fprintf(fp,"flag_col = %d, flag_diag = %d\n",A->flag_col,A->flag_diag); fprintf(fp,"start_row @ 0x%lx:\n",(long)(A->start_row)); for ( j = 0; j < A->n; j++ ) { fprintf(fp,"%d ",A->start_row[j]); if ( j % 10 == 9 ) fprintf(fp,"\n"); } fprintf(fp,"\n"); fprintf(fp,"start_idx @ 0x%lx:\n",(long)(A->start_idx)); for ( j = 0; j < A->n; j++ ) { fprintf(fp,"%d ",A->start_idx[j]); if ( j % 10 == 9 ) fprintf(fp,"\n"); } fprintf(fp,"\n"); fprintf(fp,"Rows @ 0x%lx:\n",(long)(A->row)); if ( ! A->row ) { fprintf(fp,"*** NULL row ***\n"); return; } rows = A->row; for ( i = 0; i < A->m; i++ ) { fprintf(fp,"row %d: len = %d, maxlen = %d, diag idx = %d\n", i,rows[i].len,rows[i].maxlen,rows[i].diag); fprintf(fp,"element list @ 0x%lx\n",(long)(rows[i].elt)); if ( ! rows[i].elt ) { fprintf(fp,"*** NULL element list ***\n"); continue; } elts = rows[i].elt; for ( j_idx = 0; j_idx < rows[i].len; j_idx++, elts++ ) fprintf(fp,"Col: %d, Val: %g, nxt_row = %d, nxt_idx = %d\n", elts->col,elts->val,elts->nxt_row,elts->nxt_idx); fprintf(fp,"\n"); } } #define MINSCRATCH 100 /* sp_finput -- input sparse matrix from stream/file fp -- uses friendly input routine if fp is a tty -- uses format identical to output format otherwise */ #ifndef ANSI_C SPMAT *sp_finput(fp) FILE *fp; #else SPMAT *sp_finput(FILE *fp) #endif { int i, len, ret_val; int col, curr_col, m, n, tmp, tty; Real val; SPMAT *A; SPROW *rows; static row_elt *scratch; static int scratch_len = 0; if ( ! scratch ) { scratch = NEW_A(MINSCRATCH,row_elt); if ( scratch == NULL ) error(E_MEM,"sp_finput"); scratch_len = MINSCRATCH; } for ( i = 0; i < scratch_len; i++ ) scratch[i].nxt_row = scratch[i].nxt_idx = -1; tty = isatty(fileno(fp)); if ( tty ) { fprintf(stderr,"SparseMatrix: "); do { fprintf(stderr,"input rows cols: "); if ( ! fgets(line,MAXLINE,fp) ) error(E_INPUT,"sp_finput"); } while ( sscanf(line,"%u %u",&m,&n) != 2 ); A = sp_get(m,n,5); rows = A->row; for ( i = 0; i < m; i++ ) { /* get a row... */ fprintf(stderr,"Row %d:\n",i); fprintf(stderr,"Enter or 'e' to end row\n"); curr_col = -1; len = 0; for ( ; ; ) /* forever do... */ { /* if we need more scratch space, let's get it! -- using amortized doubling */ if ( len >= scratch_len ) { scratch = RENEW(scratch,2*scratch_len,row_elt); if ( ! scratch ) error(E_MEM,"sp_finput"); scratch_len = 2*scratch_len; } do { /* get an entry... */ fprintf(stderr,"Entry %d: ",len); if ( ! fgets(line,MAXLINE,fp) ) error(E_INPUT,"sp_finput"); if ( *line == 'e' || *line == 'E' ) break; #if REAL == DOUBLE } while ( sscanf(line,"%u %lf",&col,&val) != 2 || #elif REAL == FLOAT } while ( sscanf(line,"%u %f",&col,&val) != 2 || #endif col >= n || col <= curr_col ); if ( *line == 'e' || *line == 'E' ) break; scratch[len].col = col; scratch[len].val = val; curr_col = col; len++; } /* Note: len = # elements in row */ if ( len > 5 ) { if (mem_info_is_on()) { mem_bytes(TYPE_SPMAT, A->row[i].maxlen*sizeof(row_elt), len*sizeof(row_elt)); } rows[i].elt = (row_elt *)realloc((char *)rows[i].elt, len*sizeof(row_elt)); rows[i].maxlen = len; } MEM_COPY(scratch,rows[i].elt,len*sizeof(row_elt)); rows[i].len = len; rows[i].diag = sprow_idx(&(rows[i]),i); } } else /* not tty */ { ret_val = 0; skipjunk(fp); fscanf(fp,"SparseMatrix:"); skipjunk(fp); if ( (ret_val=fscanf(fp,"%u by %u",&m,&n)) != 2 ) error((ret_val == EOF) ? E_EOF : E_FORMAT,"sp_finput"); A = sp_get(m,n,5); /* initialise start_row */ for ( i = 0; i < A->n; i++ ) A->start_row[i] = -1; rows = A->row; for ( i = 0; i < m; i++ ) { /* printf("Reading row # %d\n",i); */ rows[i].diag = -1; skipjunk(fp); if ( (ret_val=fscanf(fp,"row %d :",&tmp)) != 1 || tmp != i ) error((ret_val == EOF) ? E_EOF : E_FORMAT, "sp_finput"); curr_col = -1; len = 0; for ( ; ; ) /* forever do... */ { /* if we need more scratch space, let's get it! -- using amortized doubling */ if ( len >= scratch_len ) { scratch = RENEW(scratch,2*scratch_len,row_elt); if ( ! scratch ) error(E_MEM,"sp_finput"); scratch_len = 2*scratch_len; } #if REAL == DOUBLE if ( (ret_val=fscanf(fp,"%u : %lf",&col,&val)) != 2 ) #elif REAL == FLOAT if ( (ret_val=fscanf(fp,"%u : %f",&col,&val)) != 2 ) #endif break; if ( col <= curr_col || col >= n ) error(E_FORMAT,"sp_finput"); scratch[len].col = col; scratch[len].val = val; len++; } if ( ret_val == EOF ) error(E_EOF,"sp_finput"); if ( len > rows[i].maxlen ) { rows[i].elt = (row_elt *)realloc((char *)rows[i].elt, len*sizeof(row_elt)); rows[i].maxlen = len; } MEM_COPY(scratch,rows[i].elt,len*sizeof(row_elt)); rows[i].len = len; /* printf("Have read row # %d\n",i); */ rows[i].diag = sprow_idx(&(rows[i]),i); /* printf("Have set diag index for row # %d\n",i); */ } } return A; } gtk-wave-cleaner-0.22-04/meschach/spbkp.c0000777000175000017500000010774013120075107021254 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Sparse matrix Bunch--Kaufman--Parlett factorisation and solve Radical revision started Thu 05th Nov 1992, 09:36:12 AM to use Karen George's suggestion of leaving the the row elements unordered Radical revision completed Mon 07th Dec 1992, 10:59:57 AM */ static char rcsid[] = "$Id: spbkp.c,v 1.6 1996/08/20 19:53:10 stewart Exp $"; #include #include #include "sparse2.h" #ifdef MALLOCDECL #include #endif #define alpha 0.6403882032022076 /* = (1+sqrt(17))/8 */ #define btos(x) ((x) ? "TRUE" : "FALSE") /* assume no use of sqr() uses side-effects */ #define sqr(x) ((x)*(x)) /* unord_get_idx -- returns index (encoded if entry not allocated) of the element of row r with column j -- uses linear search */ #ifndef ANSI_C int unord_get_idx(r,j) SPROW *r; int j; #else int unord_get_idx(SPROW *r, int j) #endif { int idx; row_elt *e; if ( ! r || ! r->elt ) error(E_NULL,"unord_get_idx"); for ( idx = 0, e = r->elt; idx < r->len; idx++, e++ ) if ( e->col == j ) break; if ( idx >= r->len ) return -(r->len+2); else return idx; } /* unord_get_val -- returns value of the (i,j) entry of A -- same assumptions as unord_get_idx() */ #ifndef ANSI_C double unord_get_val(A,i,j) SPMAT *A; int i, j; #else double unord_get_val(SPMAT *A, int i, int j) #endif { SPROW *r; int idx; if ( ! A ) error(E_NULL,"unord_get_val"); if ( i < 0 || i >= A->m || j < 0 || j >= A->n ) error(E_BOUNDS,"unord_get_val"); r = &(A->row[i]); idx = unord_get_idx(r,j); if ( idx < 0 ) return 0.0; else return r->elt[idx].val; } /* bkp_swap_elt -- swaps the (i,j) with the (k,l) entry of sparse matrix -- either or both of the entries may be unallocated */ #ifndef ANSI_C static SPMAT *bkp_swap_elt(A,i1,j1,idx1,i2,j2,idx2) SPMAT *A; int i1, j1, idx1, i2, j2, idx2; #else static SPMAT *bkp_swap_elt(SPMAT *A, int i1, int j1, int idx1, int i2, int j2, int idx2) #endif { int tmp_row, tmp_idx; SPROW *r1, *r2; row_elt *e1, *e2; Real tmp; if ( ! A ) error(E_NULL,"bkp_swap_elt"); if ( i1 < 0 || j1 < 0 || i2 < 0 || j2 < 0 || i1 >= A->m || j1 >= A->n || i2 >= A->m || j2 >= A->n ) { error(E_BOUNDS,"bkp_swap_elt"); } if ( i1 == i2 && j1 == j2 ) return A; if ( idx1 < 0 && idx2 < 0 ) /* neither allocated */ return A; r1 = &(A->row[i1]); r2 = &(A->row[i2]); /* if ( idx1 >= r1->len || idx2 >= r2->len ) error(E_BOUNDS,"bkp_swap_elt"); */ if ( idx1 < 0 ) /* assume not allocated */ { idx1 = r1->len; if ( idx1 >= r1->maxlen ) { tracecatch(sprow_xpd(r1,2*r1->maxlen+1,TYPE_SPMAT), "bkp_swap_elt"); } r1->len = idx1+1; r1->elt[idx1].col = j1; r1->elt[idx1].val = 0.0; /* now patch up column access path */ tmp_row = -1; tmp_idx = j1; chase_col(A,j1,&tmp_row,&tmp_idx,i1-1); if ( tmp_row < 0 ) { r1->elt[idx1].nxt_row = A->start_row[j1]; r1->elt[idx1].nxt_idx = A->start_idx[j1]; A->start_row[j1] = i1; A->start_idx[j1] = idx1; } else { row_elt *tmp_e; tmp_e = &(A->row[tmp_row].elt[tmp_idx]); r1->elt[idx1].nxt_row = tmp_e->nxt_row; r1->elt[idx1].nxt_idx = tmp_e->nxt_idx; tmp_e->nxt_row = i1; tmp_e->nxt_idx = idx1; } } else if ( r1->elt[idx1].col != j1 ) error(E_INTERN,"bkp_swap_elt"); if ( idx2 < 0 ) { idx2 = r2->len; if ( idx2 >= r2->maxlen ) { tracecatch(sprow_xpd(r2,2*r2->maxlen+1,TYPE_SPMAT), "bkp_swap_elt"); } r2->len = idx2+1; r2->elt[idx2].col = j2; r2->elt[idx2].val = 0.0; /* now patch up column access path */ tmp_row = -1; tmp_idx = j2; chase_col(A,j2,&tmp_row,&tmp_idx,i2-1); if ( tmp_row < 0 ) { r2->elt[idx2].nxt_row = A->start_row[j2]; r2->elt[idx2].nxt_idx = A->start_idx[j2]; A->start_row[j2] = i2; A->start_idx[j2] = idx2; } else { row_elt *tmp_e; tmp_e = &(A->row[tmp_row].elt[tmp_idx]); r2->elt[idx2].nxt_row = tmp_e->nxt_row; r2->elt[idx2].nxt_idx = tmp_e->nxt_idx; tmp_e->nxt_row = i2; tmp_e->nxt_idx = idx2; } } else if ( r2->elt[idx2].col != j2 ) error(E_INTERN,"bkp_swap_elt"); e1 = &(r1->elt[idx1]); e2 = &(r2->elt[idx2]); tmp = e1->val; e1->val = e2->val; e2->val = tmp; return A; } /* bkp_bump_col -- bumps row and idx to next entry in column j */ #ifndef ANSI_C row_elt *bkp_bump_col(A, j, row, idx) SPMAT *A; int j, *row, *idx; #else row_elt *bkp_bump_col(SPMAT *A, int j, int *row, int *idx) #endif { SPROW *r; row_elt *e; if ( *row < 0 ) { *row = A->start_row[j]; *idx = A->start_idx[j]; } else { r = &(A->row[*row]); e = &(r->elt[*idx]); if ( e->col != j ) error(E_INTERN,"bkp_bump_col"); *row = e->nxt_row; *idx = e->nxt_idx; } if ( *row < 0 ) return (row_elt *)NULL; else return &(A->row[*row].elt[*idx]); } /* bkp_interchange -- swap rows/cols i and j (symmetric pivot) -- uses just the upper triangular part */ #ifndef ANSI_C SPMAT *bkp_interchange(A, i1, i2) SPMAT *A; int i1, i2; #else SPMAT *bkp_interchange(SPMAT *A, int i1, int i2) #endif { int tmp_row, tmp_idx; int row1, row2, idx1, idx2, tmp_row1, tmp_idx1, tmp_row2, tmp_idx2; SPROW *r1, *r2; row_elt *e1, *e2; IVEC *done_list = IVNULL; if ( ! A ) error(E_NULL,"bkp_interchange"); if ( i1 < 0 || i1 >= A->n || i2 < 0 || i2 >= A->n ) error(E_BOUNDS,"bkp_interchange"); if ( A->m != A->n ) error(E_SQUARE,"bkp_interchange"); if ( i1 == i2 ) return A; if ( i1 > i2 ) { tmp_idx = i1; i1 = i2; i2 = tmp_idx; } done_list = iv_resize(done_list,A->n); for ( tmp_idx = 0; tmp_idx < A->n; tmp_idx++ ) done_list->ive[tmp_idx] = FALSE; row1 = -1; idx1 = i1; row2 = -1; idx2 = i2; e1 = bkp_bump_col(A,i1,&row1,&idx1); e2 = bkp_bump_col(A,i2,&row2,&idx2); while ( (row1 >= 0 && row1 < i1) || (row2 >= 0 && row2 < i1) ) /* Note: "row2 < i1" not "row2 < i2" as we must stop before the "knee bend" */ { if ( row1 >= 0 && row1 < i1 && ( row1 < row2 || row2 < 0 ) ) { tmp_row1 = row1; tmp_idx1 = idx1; e1 = bkp_bump_col(A,i1,&tmp_row1,&tmp_idx1); if ( ! done_list->ive[row1] ) { if ( row1 == row2 ) bkp_swap_elt(A,row1,i1,idx1,row1,i2,idx2); else bkp_swap_elt(A,row1,i1,idx1,row1,i2,-1); done_list->ive[row1] = TRUE; } row1 = tmp_row1; idx1 = tmp_idx1; } else if ( row2 >= 0 && row2 < i1 && ( row2 < row1 || row1 < 0 ) ) { tmp_row2 = row2; tmp_idx2 = idx2; e2 = bkp_bump_col(A,i2,&tmp_row2,&tmp_idx2); if ( ! done_list->ive[row2] ) { if ( row1 == row2 ) bkp_swap_elt(A,row2,i1,idx1,row2,i2,idx2); else bkp_swap_elt(A,row2,i1,-1,row2,i2,idx2); done_list->ive[row2] = TRUE; } row2 = tmp_row2; idx2 = tmp_idx2; } else if ( row1 == row2 ) { tmp_row1 = row1; tmp_idx1 = idx1; e1 = bkp_bump_col(A,i1,&tmp_row1,&tmp_idx1); tmp_row2 = row2; tmp_idx2 = idx2; e2 = bkp_bump_col(A,i2,&tmp_row2,&tmp_idx2); if ( ! done_list->ive[row1] ) { bkp_swap_elt(A,row1,i1,idx1,row2,i2,idx2); done_list->ive[row1] = TRUE; } row1 = tmp_row1; idx1 = tmp_idx1; row2 = tmp_row2; idx2 = tmp_idx2; } } /* ensure we are **past** the first knee */ while ( row2 >= 0 && row2 <= i1 ) e2 = bkp_bump_col(A,i2,&row2,&idx2); /* at/after 1st "knee bend" */ r1 = &(A->row[i1]); idx1 = 0; e1 = &(r1->elt[idx1]); while ( row2 >= 0 && row2 < i2 ) { /* used for update of e2 at end of loop */ tmp_row = row2; tmp_idx = idx2; if ( ! done_list->ive[row2] ) { r2 = &(A->row[row2]); bkp_bump_col(A,i2,&tmp_row,&tmp_idx); done_list->ive[row2] = TRUE; tmp_idx1 = unord_get_idx(r1,row2); tracecatch(bkp_swap_elt(A,row2,i2,idx2,i1,row2,tmp_idx1), "bkp_interchange"); } /* update e1 and e2 */ row2 = tmp_row; idx2 = tmp_idx; e2 = ( row2 >= 0 ) ? &(A->row[row2].elt[idx2]) : (row_elt *)NULL; } idx1 = 0; e1 = r1->elt; while ( idx1 < r1->len ) { if ( e1->col >= i2 || e1->col <= i1 ) { idx1++; e1++; continue; } if ( ! done_list->ive[e1->col] ) { tmp_idx2 = unord_get_idx(&(A->row[e1->col]),i2); tracecatch(bkp_swap_elt(A,i1,e1->col,idx1,e1->col,i2,tmp_idx2), "bkp_interchange"); done_list->ive[e1->col] = TRUE; } idx1++; e1++; } /* at/after 2nd "knee bend" */ idx1 = 0; e1 = &(r1->elt[idx1]); r2 = &(A->row[i2]); idx2 = 0; e2 = &(r2->elt[idx2]); while ( idx1 < r1->len ) { if ( e1->col <= i2 ) { idx1++; e1++; continue; } if ( ! done_list->ive[e1->col] ) { tmp_idx2 = unord_get_idx(r2,e1->col); tracecatch(bkp_swap_elt(A,i1,e1->col,idx1,i2,e1->col,tmp_idx2), "bkp_interchange"); done_list->ive[e1->col] = TRUE; } idx1++; e1++; } idx2 = 0; e2 = r2->elt; while ( idx2 < r2->len ) { if ( e2->col <= i2 ) { idx2++; e2++; continue; } if ( ! done_list->ive[e2->col] ) { tmp_idx1 = unord_get_idx(r1,e2->col); tracecatch(bkp_swap_elt(A,i2,e2->col,idx2,i1,e2->col,tmp_idx1), "bkp_interchange"); done_list->ive[e2->col] = TRUE; } idx2++; e2++; } /* now interchange the digonal entries! */ idx1 = unord_get_idx(&(A->row[i1]),i1); idx2 = unord_get_idx(&(A->row[i2]),i2); if ( idx1 >= 0 || idx2 >= 0 ) { tracecatch(bkp_swap_elt(A,i1,i1,idx1,i2,i2,idx2), "bkp_interchange"); } return A; } /* iv_min -- returns minimum of an integer vector -- sets index to the position in iv if index != NULL */ #ifndef ANSI_C int iv_min(iv,index) IVEC *iv; int *index; #else int iv_min(IVEC *iv, int *index) #endif { int i, i_min, min_val, tmp; if ( ! iv ) error(E_NULL,"iv_min"); if ( iv->dim <= 0 ) error(E_SIZES,"iv_min"); i_min = 0; min_val = iv->ive[0]; for ( i = 1; i < iv->dim; i++ ) { tmp = iv->ive[i]; if ( tmp < min_val ) { min_val = tmp; i_min = i; } } if ( index != (int *)NULL ) *index = i_min; return min_val; } /* max_row_col -- returns max { |A[j][k]| : k >= i, k != j, k != l } given j using symmetry and only the upper triangular part of A */ #ifndef ANSI_C static double max_row_col(A,i,j,l) SPMAT *A; int i, j, l; #else static double max_row_col(SPMAT *A, int i,int j, int l) #endif { int row_num, idx; SPROW *r; row_elt *e; Real max_val, tmp; if ( ! A ) error(E_NULL,"max_row_col"); if ( i < 0 || i > A->n || j < 0 || j >= A->n ) error(E_BOUNDS,"max_row_col"); max_val = 0.0; idx = unord_get_idx(&(A->row[i]),j); if ( idx < 0 ) { row_num = -1; idx = j; e = chase_past(A,j,&row_num,&idx,i); } else { row_num = i; e = &(A->row[i].elt[idx]); } while ( row_num >= 0 && row_num < j ) { if ( row_num != l ) { tmp = fabs(e->val); if ( tmp > max_val ) max_val = tmp; } e = bump_col(A,j,&row_num,&idx); } r = &(A->row[j]); for ( idx = 0, e = r->elt; idx < r->len; idx++, e++ ) { if ( e->col > j && e->col != l ) { tmp = fabs(e->val); if ( tmp > max_val ) max_val = tmp; } } return max_val; } /* nonzeros -- counts non-zeros in A */ #ifndef ANSI_C static int nonzeros(A) SPMAT *A; #else static int nonzeros(const SPMAT *A) #endif { int cnt, i; if ( ! A ) return 0; cnt = 0; for ( i = 0; i < A->m; i++ ) cnt += A->row[i].len; return cnt; } /* chk_col_access -- for spBKPfactor() -- checks that column access path is OK */ #ifndef ANSI_C int chk_col_access(A) SPMAT *A; #else int chk_col_access(const SPMAT *A) #endif { int cnt_nz, j, row, idx; SPROW *r; row_elt *e; if ( ! A ) error(E_NULL,"chk_col_access"); /* count nonzeros as we go down columns */ cnt_nz = 0; for ( j = 0; j < A->n; j++ ) { row = A->start_row[j]; idx = A->start_idx[j]; while ( row >= 0 ) { if ( row >= A->m || idx < 0 ) return FALSE; r = &(A->row[row]); if ( idx >= r->len ) return FALSE; e = &(r->elt[idx]); if ( e->nxt_row >= 0 && e->nxt_row <= row ) return FALSE; row = e->nxt_row; idx = e->nxt_idx; cnt_nz++; } } if ( cnt_nz != nonzeros(A) ) return FALSE; else return TRUE; } /* col_cmp -- compare two columns -- for sorting rows using qsort() */ #ifndef ANSI_C static int col_cmp(e1,e2) row_elt *e1, *e2; #else static int col_cmp(const row_elt *e1, const row_elt *e2) #endif { return e1->col - e2->col; } /* spBKPfactor -- sparse Bunch-Kaufman-Parlett factorisation of A in-situ -- A is factored into the form P'AP = MDM' where P is a permutation matrix, M lower triangular and D is block diagonal with blocks of size 1 or 2 -- P is stored in pivot; blocks[i]==i iff D[i][i] is a block */ #ifndef ANSI_C SPMAT *spBKPfactor(A,pivot,blocks,tol) SPMAT *A; PERM *pivot, *blocks; double tol; #else SPMAT *spBKPfactor(SPMAT *A, PERM *pivot, PERM *blocks, double tol) #endif { int i, j, k, l, n, onebyone, r; int idx, idx1, idx_piv; int row_num; int best_deg, best_j, best_l, best_cost, mark_cost, deg, deg_j, deg_l, ignore_deg; int list_idx, list_idx2, old_list_idx; SPROW *row, *r_piv, *r1_piv; row_elt *e, *e1; Real aii, aip1, aip1i; Real det, max_j, max_l, s, t; STATIC IVEC *scan_row = IVNULL, *scan_idx = IVNULL, *col_list = IVNULL, *tmp_iv = IVNULL; STATIC IVEC *deg_list = IVNULL; STATIC IVEC *orig_idx = IVNULL, *orig1_idx = IVNULL; STATIC PERM *order = PNULL; if ( ! A || ! pivot || ! blocks ) error(E_NULL,"spBKPfactor"); if ( A->m != A->n ) error(E_SQUARE,"spBKPfactor"); if ( A->m != pivot->size || pivot->size != blocks->size ) error(E_SIZES,"spBKPfactor"); if ( tol <= 0.0 || tol > 1.0 ) error(E_RANGE,"spBKPfactor"); n = A->n; px_ident(pivot); px_ident(blocks); sp_col_access(A); sp_diag_access(A); ignore_deg = FALSE; deg_list = iv_resize(deg_list,n); if ( order != NULL ) px_ident(order); order = px_resize(order,n); MEM_STAT_REG(deg_list,TYPE_IVEC); MEM_STAT_REG(order,TYPE_PERM); scan_row = iv_resize(scan_row,5); scan_idx = iv_resize(scan_idx,5); col_list = iv_resize(col_list,5); orig_idx = iv_resize(orig_idx,5); orig_idx = iv_resize(orig1_idx,5); orig_idx = iv_resize(tmp_iv,5); MEM_STAT_REG(scan_row,TYPE_IVEC); MEM_STAT_REG(scan_idx,TYPE_IVEC); MEM_STAT_REG(col_list,TYPE_IVEC); MEM_STAT_REG(orig_idx,TYPE_IVEC); MEM_STAT_REG(orig1_idx,TYPE_IVEC); MEM_STAT_REG(tmp_iv,TYPE_IVEC); for ( i = 0; i < n-1; i = onebyone ? i+1 : i+2 ) { /* now we want to use a Markowitz-style selection rule for determining which rows to swap and whether to use 1x1 or 2x2 pivoting */ /* get list of degrees of nodes */ deg_list = iv_resize(deg_list,n-i); if ( ! ignore_deg ) for ( j = i; j < n; j++ ) deg_list->ive[j-i] = 0; else { for ( j = i; j < n; j++ ) deg_list->ive[j-i] = 1; if ( i < n ) deg_list->ive[0] = 0; } order = px_resize(order,n-i); px_ident(order); if ( ! ignore_deg ) { for ( j = i; j < n; j++ ) { /* idx = sprow_idx(&(A->row[j]),j+1); */ /* idx = fixindex(idx); */ idx = 0; row = &(A->row[j]); e = &(row->elt[idx]); /* deg_list->ive[j-i] += row->len - idx; */ for ( ; idx < row->len; idx++, e++ ) if ( e->col >= i ) deg_list->ive[e->col - i]++; } /* now deg_list[k] == degree of node k+i */ /* now sort them into increasing order */ iv_sort(deg_list,order); /* now deg_list[idx] == degree of node i+order[idx] */ } /* now we can chase through the nodes in order of increasing degree, picking out the ones that satisfy our stability criterion */ list_idx = 0; r = -1; best_j = best_l = -1; for ( deg = 0; deg <= n; deg++ ) { Real ajj, all, ajl; if ( list_idx >= deg_list->dim ) break; /* That's all folks! */ old_list_idx = list_idx; while ( list_idx < deg_list->dim && deg_list->ive[list_idx] <= deg ) { j = i+order->pe[list_idx]; if ( j < i ) continue; /* can we use row/col j for a 1 x 1 pivot? */ /* find max_j = max_{k>=i} {|A[k][j]|,|A[j][k]|} */ ajj = fabs(unord_get_val(A,j,j)); if ( ajj == 0.0 ) { list_idx++; continue; /* can't use this for 1 x 1 pivot */ } max_j = max_row_col(A,i,j,-1); if ( ajj >= tol/* *alpha */ *max_j ) { onebyone = TRUE; best_j = j; best_deg = deg_list->ive[list_idx]; break; } list_idx++; } if ( best_j >= 0 ) break; best_cost = 2*n; /* > any possible Markowitz cost (bound) */ best_j = best_l = -1; list_idx = old_list_idx; while ( list_idx < deg_list->dim && deg_list->ive[list_idx] <= deg ) { j = i+order->pe[list_idx]; ajj = fabs(unord_get_val(A,j,j)); for ( list_idx2 = 0; list_idx2 < list_idx; list_idx2++ ) { deg_j = deg; deg_l = deg_list->ive[list_idx2]; l = i+order->pe[list_idx2]; if ( l < i ) continue; /* try using rows/cols (j,l) for a 2 x 2 pivot block */ all = fabs(unord_get_val(A,l,l)); ajl = ( j > l ) ? fabs(unord_get_val(A,l,j)) : fabs(unord_get_val(A,j,l)); det = fabs(ajj*all - ajl*ajl); if ( det == 0.0 ) continue; max_j = max_row_col(A,i,j,l); max_l = max_row_col(A,i,l,j); if ( tol*(all*max_j+ajl*max_l) < det && tol*(ajl*max_j+ajj*max_l) < det ) { /* acceptably stable 2 x 2 pivot */ /* this is actually an overestimate of the Markowitz cost for choosing (j,l) */ mark_cost = (ajj == 0.0) ? ((all == 0.0) ? deg_j+deg_l : deg_j+2*deg_l) : ((all == 0.0) ? 2*deg_j+deg_l : 2*(deg_j+deg_l)); if ( mark_cost < best_cost ) { onebyone = FALSE; best_cost = mark_cost; best_j = j; best_l = l; best_deg = deg_j; } } } list_idx++; } if ( best_j >= 0 ) break; } if ( best_deg > (int)floor(0.8*(n-i)) ) ignore_deg = TRUE; /* now do actual interchanges */ if ( best_j >= 0 && onebyone ) { bkp_interchange(A,i,best_j); px_transp(pivot,i,best_j); } else if ( best_j >= 0 && best_l >= 0 && ! onebyone ) { if ( best_j == i || best_j == i+1 ) { if ( best_l == i || best_l == i+1 ) { /* no pivoting, but must update blocks permutation */ px_transp(blocks,i,i+1); goto dopivot; } bkp_interchange(A,(best_j == i) ? i+1 : i,best_l); px_transp(pivot,(best_j == i) ? i+1 : i,best_l); } else if ( best_l == i || best_l == i+1 ) { bkp_interchange(A,(best_l == i) ? i+1 : i,best_j); px_transp(pivot,(best_l == i) ? i+1 : i,best_j); } else /* best_j & best_l outside i, i+1 */ { if ( i != best_j ) { bkp_interchange(A,i,best_j); px_transp(pivot,i,best_j); } if ( i+1 != best_l ) { bkp_interchange(A,i+1,best_l); px_transp(pivot,i+1,best_l); } } } else /* can't pivot &/or nothing to pivot */ continue; /* update blocks permutation */ if ( ! onebyone ) px_transp(blocks,i,i+1); dopivot: if ( onebyone ) { int idx_j, idx_k, s_idx, s_idx2; row_elt *e_ij, *e_ik; r_piv = &(A->row[i]); idx_piv = unord_get_idx(r_piv,i); /* if idx_piv < 0 then aii == 0 and no pivoting can be done; -- this means that we should continue to the next iteration */ if ( idx_piv < 0 ) continue; aii = r_piv->elt[idx_piv].val; if ( aii == 0.0 ) continue; /* for ( j = i+1; j < n; j++ ) { ... pivot step ... } */ /* initialise scan_... etc for the 1 x 1 pivot */ scan_row = iv_resize(scan_row,r_piv->len); scan_idx = iv_resize(scan_idx,r_piv->len); col_list = iv_resize(col_list,r_piv->len); orig_idx = iv_resize(orig_idx,r_piv->len); row_num = i; s_idx = idx = 0; e = &(r_piv->elt[idx]); for ( idx = 0; idx < r_piv->len; idx++, e++ ) { if ( e->col < i ) continue; scan_row->ive[s_idx] = i; scan_idx->ive[s_idx] = idx; orig_idx->ive[s_idx] = idx; col_list->ive[s_idx] = e->col; s_idx++; } scan_row = iv_resize(scan_row,s_idx); scan_idx = iv_resize(scan_idx,s_idx); col_list = iv_resize(col_list,s_idx); orig_idx = iv_resize(orig_idx,s_idx); order = px_resize(order,scan_row->dim); px_ident(order); iv_sort(col_list,order); tmp_iv = iv_resize(tmp_iv,scan_row->dim); for ( idx = 0; idx < order->size; idx++ ) tmp_iv->ive[idx] = scan_idx->ive[order->pe[idx]]; iv_copy(tmp_iv,scan_idx); for ( idx = 0; idx < order->size; idx++ ) tmp_iv->ive[idx] = scan_row->ive[order->pe[idx]]; iv_copy(tmp_iv,scan_row); for ( idx = 0; idx < scan_row->dim; idx++ ) tmp_iv->ive[idx] = orig_idx->ive[order->pe[idx]]; iv_copy(tmp_iv,orig_idx); /* now do actual pivot */ /* for ( j = i+1; j < n-1; j++ ) .... */ for ( s_idx = 0; s_idx < scan_row->dim; s_idx++ ) { idx_j = orig_idx->ive[s_idx]; if ( idx_j < 0 ) error(E_INTERN,"spBKPfactor"); e_ij = &(r_piv->elt[idx_j]); j = e_ij->col; if ( j < i+1 ) continue; scan_to(A,scan_row,scan_idx,col_list,j); /* compute multiplier */ t = e_ij->val / aii; /* for ( k = j; k < n; k++ ) { .... update A[j][k] .... } */ /* this is the row in which pivoting is done */ row = &(A->row[j]); for ( s_idx2 = s_idx; s_idx2 < scan_row->dim; s_idx2++ ) { idx_k = orig_idx->ive[s_idx2]; e_ik = &(r_piv->elt[idx_k]); k = e_ik->col; /* k >= j since col_list has been sorted */ if ( scan_row->ive[s_idx2] == j ) { /* no fill-in -- can be done directly */ idx = scan_idx->ive[s_idx2]; /* idx = sprow_idx2(row,k,idx); */ row->elt[idx].val -= t*e_ik->val; } else { /* fill-in -- insert entry & patch column */ int old_row, old_idx; row_elt *old_e, *new_e; old_row = scan_row->ive[s_idx2]; old_idx = scan_idx->ive[s_idx2]; /* old_idx = sprow_idx2(&(A->row[old_row]),k,old_idx); */ if ( old_idx < 0 ) error(E_INTERN,"spBKPfactor"); /* idx = sprow_idx(row,k); */ /* idx = fixindex(idx); */ idx = row->len; /* sprow_set_val(row,k,-t*e_ik->val); */ if ( row->len >= row->maxlen ) { tracecatch(sprow_xpd(row,2*row->maxlen+1,TYPE_SPMAT), "spBKPfactor"); } row->len = idx+1; new_e = &(row->elt[idx]); new_e->val = -t*e_ik->val; new_e->col = k; old_e = &(A->row[old_row].elt[old_idx]); new_e->nxt_row = old_e->nxt_row; new_e->nxt_idx = old_e->nxt_idx; old_e->nxt_row = j; old_e->nxt_idx = idx; } } e_ij->val = t; } } else /* onebyone == FALSE */ { /* do 2 x 2 pivot */ int idx_k, idx1_k, s_idx, s_idx2; int old_col; row_elt *e_tmp; r_piv = &(A->row[i]); idx_piv = unord_get_idx(r_piv,i); aii = aip1i = 0.0; e_tmp = r_piv->elt; for ( idx_piv = 0; idx_piv < r_piv->len; idx_piv++, e_tmp++ ) if ( e_tmp->col == i ) aii = e_tmp->val; else if ( e_tmp->col == i+1 ) aip1i = e_tmp->val; r1_piv = &(A->row[i+1]); e_tmp = r1_piv->elt; aip1 = unord_get_val(A,i+1,i+1); det = aii*aip1 - aip1i*aip1i; /* Must have det < 0 */ if ( aii == 0.0 && aip1i == 0.0 ) { /* error(E_RANGE,"spBKPfactor"); */ onebyone = TRUE; continue; /* cannot pivot */ } if ( det == 0.0 ) { if ( aii != 0.0 ) error(E_RANGE,"spBKPfactor"); onebyone = TRUE; continue; /* cannot pivot */ } aip1i = aip1i/det; aii = aii/det; aip1 = aip1/det; /* initialise scan_... etc for the 2 x 2 pivot */ s_idx = r_piv->len + r1_piv->len; scan_row = iv_resize(scan_row,s_idx); scan_idx = iv_resize(scan_idx,s_idx); col_list = iv_resize(col_list,s_idx); orig_idx = iv_resize(orig_idx,s_idx); orig1_idx = iv_resize(orig1_idx,s_idx); e = r_piv->elt; for ( idx = 0; idx < r_piv->len; idx++, e++ ) { scan_row->ive[idx] = i; scan_idx->ive[idx] = idx; col_list->ive[idx] = e->col; orig_idx->ive[idx] = idx; orig1_idx->ive[idx] = -1; } e = r_piv->elt; e1 = r1_piv->elt; for ( idx = 0; idx < r1_piv->len; idx++, e1++ ) { scan_row->ive[idx+r_piv->len] = i+1; scan_idx->ive[idx+r_piv->len] = idx; col_list->ive[idx+r_piv->len] = e1->col; orig_idx->ive[idx+r_piv->len] = -1; orig1_idx->ive[idx+r_piv->len] = idx; } e1 = r1_piv->elt; order = px_resize(order,scan_row->dim); px_ident(order); iv_sort(col_list,order); tmp_iv = iv_resize(tmp_iv,scan_row->dim); for ( idx = 0; idx < order->size; idx++ ) tmp_iv->ive[idx] = scan_idx->ive[order->pe[idx]]; iv_copy(tmp_iv,scan_idx); for ( idx = 0; idx < order->size; idx++ ) tmp_iv->ive[idx] = scan_row->ive[order->pe[idx]]; iv_copy(tmp_iv,scan_row); for ( idx = 0; idx < scan_row->dim; idx++ ) tmp_iv->ive[idx] = orig_idx->ive[order->pe[idx]]; iv_copy(tmp_iv,orig_idx); for ( idx = 0; idx < scan_row->dim; idx++ ) tmp_iv->ive[idx] = orig1_idx->ive[order->pe[idx]]; iv_copy(tmp_iv,orig1_idx); s_idx = 0; old_col = -1; for ( idx = 0; idx < scan_row->dim; idx++ ) { if ( col_list->ive[idx] == old_col ) { if ( scan_row->ive[idx] == i ) { scan_row->ive[s_idx-1] = scan_row->ive[idx]; scan_idx->ive[s_idx-1] = scan_idx->ive[idx]; col_list->ive[s_idx-1] = col_list->ive[idx]; orig_idx->ive[s_idx-1] = orig_idx->ive[idx]; orig1_idx->ive[s_idx-1] = orig1_idx->ive[idx-1]; } else if ( idx > 0 ) { scan_row->ive[s_idx-1] = scan_row->ive[idx-1]; scan_idx->ive[s_idx-1] = scan_idx->ive[idx-1]; col_list->ive[s_idx-1] = col_list->ive[idx-1]; orig_idx->ive[s_idx-1] = orig_idx->ive[idx-1]; orig1_idx->ive[s_idx-1] = orig1_idx->ive[idx]; } } else { scan_row->ive[s_idx] = scan_row->ive[idx]; scan_idx->ive[s_idx] = scan_idx->ive[idx]; col_list->ive[s_idx] = col_list->ive[idx]; orig_idx->ive[s_idx] = orig_idx->ive[idx]; orig1_idx->ive[s_idx] = orig1_idx->ive[idx]; s_idx++; } old_col = col_list->ive[idx]; } scan_row = iv_resize(scan_row,s_idx); scan_idx = iv_resize(scan_idx,s_idx); col_list = iv_resize(col_list,s_idx); orig_idx = iv_resize(orig_idx,s_idx); orig1_idx = iv_resize(orig1_idx,s_idx); /* for ( j = i+2; j < n; j++ ) { .... row operation .... } */ for ( s_idx = 0; s_idx < scan_row->dim; s_idx++ ) { int idx_piv, idx1_piv; Real aip1j, aij, aik, aip1k; row_elt *e_ik, *e_ip1k; j = col_list->ive[s_idx]; if ( j < i+2 ) continue; tracecatch(scan_to(A,scan_row,scan_idx,col_list,j), "spBKPfactor"); idx_piv = orig_idx->ive[s_idx]; aij = ( idx_piv < 0 ) ? 0.0 : r_piv->elt[idx_piv].val; /* aij = ( s_idx < r_piv->len ) ? r_piv->elt[s_idx].val : 0.0; */ /* aij = sp_get_val(A,i,j); */ idx1_piv = orig1_idx->ive[s_idx]; aip1j = ( idx1_piv < 0 ) ? 0.0 : r1_piv->elt[idx1_piv].val; /* aip1j = ( s_idx < r_piv->len ) ? 0.0 : r1_piv->elt[s_idx-r_piv->len].val; */ /* aip1j = sp_get_val(A,i+1,j); */ s = - aip1i*aip1j + aip1*aij; t = - aip1i*aij + aii*aip1j; /* for ( k = j; k < n; k++ ) { .... update entry .... } */ row = &(A->row[j]); /* set idx_k and idx1_k indices */ s_idx2 = s_idx; k = col_list->ive[s_idx2]; idx_k = orig_idx->ive[s_idx2]; idx1_k = orig1_idx->ive[s_idx2]; while ( s_idx2 < scan_row->dim ) { k = col_list->ive[s_idx2]; idx_k = orig_idx->ive[s_idx2]; idx1_k = orig1_idx->ive[s_idx2]; e_ik = ( idx_k < 0 ) ? (row_elt *)NULL : &(r_piv->elt[idx_k]); e_ip1k = ( idx1_k < 0 ) ? (row_elt *)NULL : &(r1_piv->elt[idx1_k]); aik = ( idx_k >= 0 ) ? e_ik->val : 0.0; aip1k = ( idx1_k >= 0 ) ? e_ip1k->val : 0.0; if ( scan_row->ive[s_idx2] == j ) { /* no fill-in */ row = &(A->row[j]); /* idx = sprow_idx(row,k); */ idx = scan_idx->ive[s_idx2]; if ( idx < 0 ) error(E_INTERN,"spBKPfactor"); row->elt[idx].val -= s*aik + t*aip1k; } else { /* fill-in -- insert entry & patch column */ Real tmp; int old_row, old_idx; row_elt *old_e, *new_e; tmp = - s*aik - t*aip1k; if ( tmp != 0.0 ) { row = &(A->row[j]); old_row = scan_row->ive[s_idx2]; old_idx = scan_idx->ive[s_idx2]; idx = row->len; if ( row->len >= row->maxlen ) { tracecatch(sprow_xpd(row,2*row->maxlen+1, TYPE_SPMAT), "spBKPfactor"); } row->len = idx + 1; /* idx = sprow_idx(row,k); */ new_e = &(row->elt[idx]); new_e->val = tmp; new_e->col = k; if ( old_row < 0 ) error(E_INTERN,"spBKPfactor"); /* old_idx = sprow_idx2(&(A->row[old_row]), k,old_idx); */ old_e = &(A->row[old_row].elt[old_idx]); new_e->nxt_row = old_e->nxt_row; new_e->nxt_idx = old_e->nxt_idx; old_e->nxt_row = j; old_e->nxt_idx = idx; } } /* update idx_k, idx1_k, s_idx2 etc */ s_idx2++; } /* store multipliers -- may involve fill-in (!) */ /* idx = sprow_idx(r_piv,j); */ idx = orig_idx->ive[s_idx]; if ( idx >= 0 ) { r_piv->elt[idx].val = s; } else if ( s != 0.0 ) { int old_row, old_idx; row_elt *new_e, *old_e; old_row = -1; old_idx = j; if ( i > 0 ) { tracecatch(chase_col(A,j,&old_row,&old_idx,i-1), "spBKPfactor"); } /* sprow_set_val(r_piv,j,s); */ idx = r_piv->len; if ( r_piv->len >= r_piv->maxlen ) { tracecatch(sprow_xpd(r_piv,2*r_piv->maxlen+1, TYPE_SPMAT), "spBKPfactor"); } r_piv->len = idx + 1; /* idx = sprow_idx(r_piv,j); */ /* if ( idx < 0 ) error(E_INTERN,"spBKPfactor"); */ new_e = &(r_piv->elt[idx]); new_e->val = s; new_e->col = j; if ( old_row < 0 ) { new_e->nxt_row = A->start_row[j]; new_e->nxt_idx = A->start_idx[j]; A->start_row[j] = i; A->start_idx[j] = idx; } else { /* old_idx = sprow_idx2(&(A->row[old_row]),j,old_idx);*/ if ( old_idx < 0 ) error(E_INTERN,"spBKPfactor"); old_e = &(A->row[old_row].elt[old_idx]); new_e->nxt_row = old_e->nxt_row; new_e->nxt_idx = old_e->nxt_idx; old_e->nxt_row = i; old_e->nxt_idx = idx; } } /* idx1 = sprow_idx(r1_piv,j); */ idx1 = orig1_idx->ive[s_idx]; if ( idx1 >= 0 ) { r1_piv->elt[idx1].val = t; } else if ( t != 0.0 ) { int old_row, old_idx; row_elt *new_e, *old_e; old_row = -1; old_idx = j; tracecatch(chase_col(A,j,&old_row,&old_idx,i), "spBKPfactor"); /* sprow_set_val(r1_piv,j,t); */ idx1 = r1_piv->len; if ( r1_piv->len >= r1_piv->maxlen ) { tracecatch(sprow_xpd(r1_piv,2*r1_piv->maxlen+1, TYPE_SPMAT), "spBKPfactor"); } r1_piv->len = idx1 + 1; /* idx1 = sprow_idx(r1_piv,j); */ /* if ( idx < 0 ) error(E_INTERN,"spBKPfactor"); */ new_e = &(r1_piv->elt[idx1]); new_e->val = t; new_e->col = j; if ( idx1 < 0 ) error(E_INTERN,"spBKPfactor"); new_e = &(r1_piv->elt[idx1]); if ( old_row < 0 ) { new_e->nxt_row = A->start_row[j]; new_e->nxt_idx = A->start_idx[j]; A->start_row[j] = i+1; A->start_idx[j] = idx1; } else { old_idx = sprow_idx2(&(A->row[old_row]),j,old_idx); if ( old_idx < 0 ) error(E_INTERN,"spBKPfactor"); old_e = &(A->row[old_row].elt[old_idx]); new_e->nxt_row = old_e->nxt_row; new_e->nxt_idx = old_e->nxt_idx; old_e->nxt_row = i+1; old_e->nxt_idx = idx1; } } } } } /* now sort the rows arrays */ for ( i = 0; i < A->m; i++ ) qsort(A->row[i].elt,A->row[i].len,sizeof(row_elt),(int(*)())col_cmp); A->flag_col = A->flag_diag = FALSE; #ifdef THREADSAFE IV_FREE(scan_row); IV_FREE(scan_idx); IV_FREE(col_list); IV_FREE(tmp_iv); IV_FREE(deg_list); IV_FREE(orig_idx); IV_FREE(orig1_idx); PX_FREE(order); #endif return A; } /* spBKPsolve -- solves A.x = b where A has been factored a la BKPfactor() -- returns x, which is created if NULL */ #ifndef ANSI_C VEC *spBKPsolve(A,pivot,block,b,x) SPMAT *A; PERM *pivot, *block; VEC *b, *x; #else VEC *spBKPsolve(SPMAT *A, PERM *pivot, PERM *block, const VEC *b, VEC *x) #endif { STATIC VEC *tmp=VNULL; /* dummy storage needed */ int i /* , j */, n, onebyone; int row_num, idx; Real a11, a12, a22, b1, b2, det, sum, *tmp_ve, tmp_diag; SPROW *r; row_elt *e; if ( ! A || ! pivot || ! block || ! b ) error(E_NULL,"spBKPsolve"); if ( A->m != A->n ) error(E_SQUARE,"spBKPsolve"); n = A->n; if ( b->dim != n || pivot->size != n || block->size != n ) error(E_SIZES,"spBKPsolve"); x = v_resize(x,n); tmp = v_resize(tmp,n); MEM_STAT_REG(tmp,TYPE_VEC); tmp_ve = tmp->ve; if ( ! A->flag_col ) sp_col_access(A); px_vec(pivot,b,tmp); /* printf("# BKPsolve: effect of pivot: tmp =\n"); v_output(tmp); */ /* solve for lower triangular part */ for ( i = 0; i < n; i++ ) { sum = tmp_ve[i]; if ( block->pe[i] < i ) { /* for ( j = 0; j < i-1; j++ ) sum -= A_me[j][i]*tmp_ve[j]; */ row_num = -1; idx = i; e = bump_col(A,i,&row_num,&idx); while ( row_num >= 0 && row_num < i-1 ) { sum -= e->val*tmp_ve[row_num]; e = bump_col(A,i,&row_num,&idx); } } else { /* for ( j = 0; j < i; j++ ) sum -= A_me[j][i]*tmp_ve[j]; */ row_num = -1; idx = i; e = bump_col(A,i,&row_num,&idx); while ( row_num >= 0 && row_num < i ) { sum -= e->val*tmp_ve[row_num]; e = bump_col(A,i,&row_num,&idx); } } tmp_ve[i] = sum; } /* printf("# BKPsolve: solving L part: tmp =\n"); v_output(tmp); */ /* solve for diagonal part */ for ( i = 0; i < n; i = onebyone ? i+1 : i+2 ) { onebyone = ( block->pe[i] == i ); if ( onebyone ) { /* tmp_ve[i] /= A_me[i][i]; */ tmp_diag = sp_get_val(A,i,i); if ( tmp_diag == 0.0 ) error(E_SING,"spBKPsolve"); tmp_ve[i] /= tmp_diag; } else { a11 = sp_get_val(A,i,i); a22 = sp_get_val(A,i+1,i+1); a12 = sp_get_val(A,i,i+1); b1 = tmp_ve[i]; b2 = tmp_ve[i+1]; det = a11*a22-a12*a12; /* < 0 : see BKPfactor() */ if ( det == 0.0 ) error(E_SING,"BKPsolve"); det = 1/det; tmp_ve[i] = det*(a22*b1-a12*b2); tmp_ve[i+1] = det*(a11*b2-a12*b1); } } /* printf("# BKPsolve: solving D part: tmp =\n"); v_output(tmp); */ /* solve for transpose of lower triangular part */ for ( i = n-2; i >= 0; i-- ) { sum = tmp_ve[i]; if ( block->pe[i] > i ) { /* onebyone is false */ /* for ( j = i+2; j < n; j++ ) sum -= A_me[i][j]*tmp_ve[j]; */ if ( i+2 >= n ) continue; r = &(A->row[i]); idx = sprow_idx(r,i+2); idx = fixindex(idx); e = &(r->elt[idx]); for ( ; idx < r->len; idx++, e++ ) sum -= e->val*tmp_ve[e->col]; } else /* onebyone */ { /* for ( j = i+1; j < n; j++ ) sum -= A_me[i][j]*tmp_ve[j]; */ r = &(A->row[i]); idx = sprow_idx(r,i+1); idx = fixindex(idx); e = &(r->elt[idx]); for ( ; idx < r->len; idx++, e++ ) sum -= e->val*tmp_ve[e->col]; } tmp_ve[i] = sum; } /* printf("# BKPsolve: solving L^T part: tmp =\n");v_output(tmp); */ /* and do final permutation */ x = pxinv_vec(pivot,tmp,x); #ifdef THREADSAFE V_FREE(tmp); #endif return x; } gtk-wave-cleaner-0.22-04/meschach/spchfctr.c0000777000175000017500000003771113120075107021751 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Sparse Cholesky factorisation code To be used with sparse.h, sparse.c etc */ static char rcsid[] = "$Id: spchfctr.c,v 1.5 1996/08/20 19:45:33 stewart Exp $"; #include #include #include "sparse2.h" #ifndef MALLOCDECL #ifndef ANSI_C extern char *calloc(), *realloc(); #endif #endif /* sprow_ip -- finds the (partial) inner product of a pair of sparse rows -- uses a "merging" approach & assumes column ordered rows -- row indices for inner product are all < lim */ #ifndef ANSI_C static double sprow_ip(row1, row2, lim) SPROW *row1, *row2; int lim; #else static double sprow_ip(const SPROW *row1, const SPROW *row2, int lim) #endif { int idx1, idx2, len1, len2, tmp; register row_elt *elts1, *elts2; register Real sum; elts1 = row1->elt; elts2 = row2->elt; len1 = row1->len; len2 = row2->len; sum = 0.0; if ( len1 <= 0 || len2 <= 0 ) return 0.0; if ( elts1->col >= lim || elts2->col >= lim ) return 0.0; /* use sprow_idx() to speed up inner product where one row is much longer than the other */ idx1 = idx2 = 0; if ( len1 > 2*len2 ) { idx1 = sprow_idx(row1,elts2->col); idx1 = (idx1 < 0) ? -(idx1+2) : idx1; if ( idx1 < 0 ) error(E_UNKNOWN,"sprow_ip"); len1 -= idx1; } else if ( len2 > 2*len1 ) { idx2 = sprow_idx(row2,elts1->col); idx2 = (idx2 < 0) ? -(idx2+2) : idx2; if ( idx2 < 0 ) error(E_UNKNOWN,"sprow_ip"); len2 -= idx2; } if ( len1 <= 0 || len2 <= 0 ) return 0.0; elts1 = &(elts1[idx1]); elts2 = &(elts2[idx2]); for ( ; ; ) /* forever do... */ { if ( (tmp=elts1->col-elts2->col) < 0 ) { len1--; elts1++; if ( ! len1 || elts1->col >= lim ) break; } else if ( tmp > 0 ) { len2--; elts2++; if ( ! len2 || elts2->col >= lim ) break; } else { sum += elts1->val * elts2->val; len1--; elts1++; len2--; elts2++; if ( ! len1 || ! len2 || elts1->col >= lim || elts2->col >= lim ) break; } } return sum; } /* sprow_sqr -- returns same as sprow_ip(row, row, lim) */ #ifndef ANSI_C static double sprow_sqr(row, lim) SPROW *row; int lim; #else static double sprow_sqr(const SPROW *row, int lim) #endif { register row_elt *elts; int idx, len; register Real sum, tmp; sum = 0.0; elts = row->elt; len = row->len; for ( idx = 0; idx < len; idx++, elts++ ) { if ( elts->col >= lim ) break; tmp = elts->val; sum += tmp*tmp; } return sum; } static int *scan_row = (int *)NULL, *scan_idx = (int *)NULL, *col_list = (int *)NULL; static int scan_len = 0; /* set_scan -- expand scan_row and scan_idx arrays -- return new length */ #ifndef ANSI_C int set_scan(new_len) int new_len; #else int set_scan(int new_len) #endif { if ( new_len <= scan_len ) return scan_len; if ( new_len <= scan_len+5 ) new_len += 5; /* update scan_len */ scan_len = new_len; if ( ! scan_row || ! scan_idx || ! col_list ) { scan_row = (int *)calloc(new_len,sizeof(int)); scan_idx = (int *)calloc(new_len,sizeof(int)); col_list = (int *)calloc(new_len,sizeof(int)); } else { scan_row = (int *)realloc((char *)scan_row,new_len*sizeof(int)); scan_idx = (int *)realloc((char *)scan_idx,new_len*sizeof(int)); col_list = (int *)realloc((char *)col_list,new_len*sizeof(int)); } if ( ! scan_row || ! scan_idx || ! col_list ) error(E_MEM,"set_scan"); return new_len; } /* spCHfactor -- sparse Cholesky factorisation -- only the lower triangular part of A (incl. diagonal) is used */ #ifndef ANSI_C SPMAT *spCHfactor(A) SPMAT *A; #else SPMAT *spCHfactor(SPMAT *A) #endif { register int i; int idx, k, m, minim, n, num_scan, diag_idx, tmp1; Real pivot, tmp2; SPROW *r_piv, *r_op; row_elt *elt_piv, *elt_op, *old_elt; if ( A == SMNULL ) error(E_NULL,"spCHfactor"); if ( A->m != A->n ) error(E_SQUARE,"spCHfactor"); /* set up access paths if not already done so */ sp_col_access(A); sp_diag_access(A); /* printf("spCHfactor() -- checkpoint 1\n"); */ m = A->m; n = A->n; for ( k = 0; k < m; k++ ) { r_piv = &(A->row[k]); if ( r_piv->len > scan_len ) set_scan(r_piv->len); elt_piv = r_piv->elt; diag_idx = sprow_idx2(r_piv,k,r_piv->diag); if ( diag_idx < 0 ) error(E_POSDEF,"spCHfactor"); old_elt = &(elt_piv[diag_idx]); for ( i = 0; i < r_piv->len; i++ ) { if ( elt_piv[i].col > k ) break; col_list[i] = elt_piv[i].col; scan_row[i] = elt_piv[i].nxt_row; scan_idx[i] = elt_piv[i].nxt_idx; } /* printf("spCHfactor() -- checkpoint 2\n"); */ num_scan = i; /* number of actual entries in scan_row etc. */ /* printf("num_scan = %d\n",num_scan); */ /* set diagonal entry of Cholesky factor */ tmp2 = elt_piv[diag_idx].val - sprow_sqr(r_piv,k); if ( tmp2 <= 0.0 ) error(E_POSDEF,"spCHfactor"); elt_piv[diag_idx].val = pivot = sqrt(tmp2); /* now set the k-th column of the Cholesky factors */ /* printf("k = %d\n",k); */ for ( ; ; ) /* forever do... */ { /* printf("spCHfactor() -- checkpoint 3\n"); */ /* find next row where something (non-trivial) happens i.e. find min(scan_row) */ /* printf("scan_row: "); */ minim = n; for ( i = 0; i < num_scan; i++ ) { tmp1 = scan_row[i]; /* printf("%d ",tmp1); */ minim = ( tmp1 >= 0 && tmp1 < minim ) ? tmp1 : minim; } /* printf("minim = %d\n",minim); */ /* printf("col_list: "); */ /* for ( i = 0; i < num_scan; i++ ) */ /* printf("%d ",col_list[i]); */ /* printf("\n"); */ if ( minim >= n ) break; /* nothing more to do for this column */ r_op = &(A->row[minim]); elt_op = r_op->elt; /* set next entry in column k of Cholesky factors */ idx = sprow_idx2(r_op,k,scan_idx[num_scan-1]); if ( idx < 0 ) { /* fill-in */ sp_set_val(A,minim,k, -sprow_ip(r_piv,r_op,k)/pivot); /* in case a realloc() has occurred... */ elt_op = r_op->elt; /* now set up column access path again */ idx = sprow_idx2(r_op,k,-(idx+2)); tmp1 = old_elt->nxt_row; old_elt->nxt_row = minim; r_op->elt[idx].nxt_row = tmp1; tmp1 = old_elt->nxt_idx; old_elt->nxt_idx = idx; r_op->elt[idx].nxt_idx = tmp1; } else elt_op[idx].val = (elt_op[idx].val - sprow_ip(r_piv,r_op,k))/pivot; /* printf("spCHfactor() -- checkpoint 4\n"); */ /* remember current element in column k for column chain */ idx = sprow_idx2(r_op,k,idx); old_elt = &(r_op->elt[idx]); /* update scan_row */ /* printf("spCHfactor() -- checkpoint 5\n"); */ /* printf("minim = %d\n",minim); */ for ( i = 0; i < num_scan; i++ ) { if ( scan_row[i] != minim ) continue; idx = sprow_idx2(r_op,col_list[i],scan_idx[i]); if ( idx < 0 ) { scan_row[i] = -1; continue; } scan_row[i] = elt_op[idx].nxt_row; scan_idx[i] = elt_op[idx].nxt_idx; /* printf("scan_row[%d] = %d\n",i,scan_row[i]); */ /* printf("scan_idx[%d] = %d\n",i,scan_idx[i]); */ } } /* printf("spCHfactor() -- checkpoint 6\n"); */ /* sp_dump(stdout,A); */ /* printf("\n\n\n"); */ } return A; } /* spCHsolve -- solve L.L^T.out=b where L is a sparse matrix, -- out, b dense vectors -- returns out; operation may be in-situ */ #ifndef ANSI_C VEC *spCHsolve(L,b,out) SPMAT *L; VEC *b, *out; #else VEC *spCHsolve(SPMAT *L, const VEC *b, VEC *out) #endif { int i, j_idx, n, scan_idx, scan_row; SPROW *row; row_elt *elt; Real diag_val, sum, *out_ve; if ( L == SMNULL || b == VNULL ) error(E_NULL,"spCHsolve"); if ( L->m != L->n ) error(E_SQUARE,"spCHsolve"); if ( b->dim != L->m ) error(E_SIZES,"spCHsolve"); if ( ! L->flag_col ) sp_col_access(L); if ( ! L->flag_diag ) sp_diag_access(L); out = v_copy(b,out); out_ve = out->ve; /* forward substitution: solve L.x=b for x */ n = L->n; for ( i = 0; i < n; i++ ) { sum = out_ve[i]; row = &(L->row[i]); elt = row->elt; for ( j_idx = 0; j_idx < row->len; j_idx++, elt++ ) { if ( elt->col >= i ) break; sum -= elt->val*out_ve[elt->col]; } if ( row->diag >= 0 ) out_ve[i] = sum/(row->elt[row->diag].val); else error(E_SING,"spCHsolve"); } /* backward substitution: solve L^T.out = x for out */ for ( i = n-1; i >= 0; i-- ) { sum = out_ve[i]; row = &(L->row[i]); /* Note that row->diag >= 0 by above loop */ elt = &(row->elt[row->diag]); diag_val = elt->val; /* scan down column */ scan_idx = elt->nxt_idx; scan_row = elt->nxt_row; while ( scan_row >= 0 /* && scan_idx >= 0 */ ) { row = &(L->row[scan_row]); elt = &(row->elt[scan_idx]); sum -= elt->val*out_ve[scan_row]; scan_idx = elt->nxt_idx; scan_row = elt->nxt_row; } out_ve[i] = sum/diag_val; } return out; } /* spICHfactor -- sparse Incomplete Cholesky factorisation -- does a Cholesky factorisation assuming NO FILL-IN -- as for spCHfactor(), only the lower triangular part of A is used */ #ifndef ANSI_C SPMAT *spICHfactor(A) SPMAT *A; #else SPMAT *spICHfactor(SPMAT *A) #endif { int k, m, n, nxt_row, nxt_idx, diag_idx; Real pivot, tmp2; SPROW *r_piv, *r_op; row_elt *elt_piv, *elt_op; if ( A == SMNULL ) error(E_NULL,"spICHfactor"); if ( A->m != A->n ) error(E_SQUARE,"spICHfactor"); /* set up access paths if not already done so */ if ( ! A->flag_col ) sp_col_access(A); if ( ! A->flag_diag ) sp_diag_access(A); m = A->m; n = A->n; for ( k = 0; k < m; k++ ) { r_piv = &(A->row[k]); diag_idx = r_piv->diag; if ( diag_idx < 0 ) error(E_POSDEF,"spICHfactor"); elt_piv = r_piv->elt; /* set diagonal entry of Cholesky factor */ tmp2 = elt_piv[diag_idx].val - sprow_sqr(r_piv,k); if ( tmp2 <= 0.0 ) error(E_POSDEF,"spICHfactor"); elt_piv[diag_idx].val = pivot = sqrt(tmp2); /* find next row where something (non-trivial) happens */ nxt_row = elt_piv[diag_idx].nxt_row; nxt_idx = elt_piv[diag_idx].nxt_idx; /* now set the k-th column of the Cholesky factors */ while ( nxt_row >= 0 && nxt_idx >= 0 ) { /* nxt_row and nxt_idx give next next row (& index) of the entry to be modified */ r_op = &(A->row[nxt_row]); elt_op = r_op->elt; elt_op[nxt_idx].val = (elt_op[nxt_idx].val - sprow_ip(r_piv,r_op,k))/pivot; nxt_row = elt_op[nxt_idx].nxt_row; nxt_idx = elt_op[nxt_idx].nxt_idx; } } return A; } /* spCHsymb -- symbolic sparse Cholesky factorisation -- does NOT do any floating point arithmetic; just sets up the structure -- only the lower triangular part of A (incl. diagonal) is used */ #ifndef ANSI_C SPMAT *spCHsymb(A) SPMAT *A; #else SPMAT *spCHsymb(SPMAT *A) #endif { register int i; int idx, k, m, minim, n, num_scan, diag_idx, tmp1; SPROW *r_piv, *r_op; row_elt *elt_piv, *elt_op, *old_elt; if ( A == SMNULL ) error(E_NULL,"spCHsymb"); if ( A->m != A->n ) error(E_SQUARE,"spCHsymb"); /* set up access paths if not already done so */ if ( ! A->flag_col ) sp_col_access(A); if ( ! A->flag_diag ) sp_diag_access(A); /* printf("spCHsymb() -- checkpoint 1\n"); */ m = A->m; n = A->n; for ( k = 0; k < m; k++ ) { r_piv = &(A->row[k]); if ( r_piv->len > scan_len ) set_scan(r_piv->len); elt_piv = r_piv->elt; diag_idx = sprow_idx2(r_piv,k,r_piv->diag); if ( diag_idx < 0 ) error(E_POSDEF,"spCHsymb"); old_elt = &(elt_piv[diag_idx]); for ( i = 0; i < r_piv->len; i++ ) { if ( elt_piv[i].col > k ) break; col_list[i] = elt_piv[i].col; scan_row[i] = elt_piv[i].nxt_row; scan_idx[i] = elt_piv[i].nxt_idx; } /* printf("spCHsymb() -- checkpoint 2\n"); */ num_scan = i; /* number of actual entries in scan_row etc. */ /* printf("num_scan = %d\n",num_scan); */ /* now set the k-th column of the Cholesky factors */ /* printf("k = %d\n",k); */ for ( ; ; ) /* forever do... */ { /* printf("spCHsymb() -- checkpoint 3\n"); */ /* find next row where something (non-trivial) happens i.e. find min(scan_row) */ minim = n; for ( i = 0; i < num_scan; i++ ) { tmp1 = scan_row[i]; /* printf("%d ",tmp1); */ minim = ( tmp1 >= 0 && tmp1 < minim ) ? tmp1 : minim; } if ( minim >= n ) break; /* nothing more to do for this column */ r_op = &(A->row[minim]); elt_op = r_op->elt; /* set next entry in column k of Cholesky factors */ idx = sprow_idx2(r_op,k,scan_idx[num_scan-1]); if ( idx < 0 ) { /* fill-in */ sp_set_val(A,minim,k,0.0); /* in case a realloc() has occurred... */ elt_op = r_op->elt; /* now set up column access path again */ idx = sprow_idx2(r_op,k,-(idx+2)); tmp1 = old_elt->nxt_row; old_elt->nxt_row = minim; r_op->elt[idx].nxt_row = tmp1; tmp1 = old_elt->nxt_idx; old_elt->nxt_idx = idx; r_op->elt[idx].nxt_idx = tmp1; } /* printf("spCHsymb() -- checkpoint 4\n"); */ /* remember current element in column k for column chain */ idx = sprow_idx2(r_op,k,idx); old_elt = &(r_op->elt[idx]); /* update scan_row */ /* printf("spCHsymb() -- checkpoint 5\n"); */ /* printf("minim = %d\n",minim); */ for ( i = 0; i < num_scan; i++ ) { if ( scan_row[i] != minim ) continue; idx = sprow_idx2(r_op,col_list[i],scan_idx[i]); if ( idx < 0 ) { scan_row[i] = -1; continue; } scan_row[i] = elt_op[idx].nxt_row; scan_idx[i] = elt_op[idx].nxt_idx; /* printf("scan_row[%d] = %d\n",i,scan_row[i]); */ /* printf("scan_idx[%d] = %d\n",i,scan_idx[i]); */ } } /* printf("spCHsymb() -- checkpoint 6\n"); */ } return A; } /* comp_AAT -- compute A.A^T where A is a given sparse matrix */ #ifndef ANSI_C SPMAT *comp_AAT(A) SPMAT *A; #else SPMAT *comp_AAT(SPMAT *A) #endif { SPMAT *AAT; SPROW *r, *r2; row_elt *elts, *elts2; int i, idx, idx2, j, m, minim, n, num_scan, tmp1; Real ip; if ( ! A ) error(E_NULL,"comp_AAT"); m = A->m; n = A->n; /* set up column access paths */ if ( ! A->flag_col ) sp_col_access(A); AAT = sp_get(m,m,10); for ( i = 0; i < m; i++ ) { /* initialisation */ r = &(A->row[i]); elts = r->elt; /* set up scan lists for this row */ if ( r->len > scan_len ) set_scan(r->len); for ( j = 0; j < r->len; j++ ) { col_list[j] = elts[j].col; scan_row[j] = elts[j].nxt_row; scan_idx[j] = elts[j].nxt_idx; } num_scan = r->len; /* scan down the rows for next non-zero not associated with a diagonal entry */ for ( ; ; ) { minim = m; for ( idx = 0; idx < num_scan; idx++ ) { tmp1 = scan_row[idx]; minim = ( tmp1 >= 0 && tmp1 < minim ) ? tmp1 : minim; } if ( minim >= m ) break; r2 = &(A->row[minim]); if ( minim > i ) { ip = sprow_ip(r,r2,n); sp_set_val(AAT,minim,i,ip); sp_set_val(AAT,i,minim,ip); } /* update scan entries */ elts2 = r2->elt; for ( idx = 0; idx < num_scan; idx++ ) { if ( scan_row[idx] != minim || scan_idx[idx] < 0 ) continue; idx2 = scan_idx[idx]; scan_row[idx] = elts2[idx2].nxt_row; scan_idx[idx] = elts2[idx2].nxt_idx; } } /* set the diagonal entry */ sp_set_val(AAT,i,i,sprow_sqr(r,n)); } return AAT; } gtk-wave-cleaner-0.22-04/meschach/splufctr.c0000777000175000017500000002575513120075107022004 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Stewart & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Sparse LU factorisation See also: sparse.[ch] etc for details about sparse matrices */ #include #include #include "sparse2.h" /* Macro for speedup */ /* #define sprow_idx2(r,c,hint) \ ( ( (hint) >= 0 && (r)->elt[hint].col == (c)) ? hint : sprow_idx((r),(c)) ) */ /* spLUfactor -- sparse LU factorisation with pivoting -- uses partial pivoting and Markowitz criterion |a[p][k]| >= alpha * max_i |a[i][k]| -- creates fill-in as needed -- in situ factorisation */ #ifndef ANSI_C SPMAT *spLUfactor(A,px,alpha) SPMAT *A; PERM *px; double alpha; #else SPMAT *spLUfactor(SPMAT *A, PERM *px, double alpha) #endif { int i, best_i, k, idx, len, best_len, m, n; SPROW *r, *r_piv, tmp_row; STATIC SPROW *merge = (SPROW *)NULL; Real max_val, tmp; STATIC VEC *col_vals=VNULL; if ( ! A || ! px ) error(E_NULL,"spLUfctr"); if ( alpha <= 0.0 || alpha > 1.0 ) error(E_RANGE,"alpha in spLUfctr"); if ( px->size <= A->m ) px = px_resize(px,A->m); px_ident(px); col_vals = v_resize(col_vals,A->m); MEM_STAT_REG(col_vals,TYPE_VEC); m = A->m; n = A->n; if ( ! A->flag_col ) sp_col_access(A); if ( ! A->flag_diag ) sp_diag_access(A); A->flag_col = A->flag_diag = FALSE; if ( ! merge ) { merge = sprow_get(20); MEM_STAT_REG(merge,TYPE_SPROW); } for ( k = 0; k < n; k++ ) { /* find pivot row/element for partial pivoting */ /* get first row with a non-zero entry in the k-th column */ max_val = 0.0; for ( i = k; i < m; i++ ) { r = &(A->row[i]); idx = sprow_idx(r,k); if ( idx < 0 ) tmp = 0.0; else tmp = r->elt[idx].val; if ( fabs(tmp) > max_val ) max_val = fabs(tmp); col_vals->ve[i] = tmp; } if ( max_val == 0.0 ) continue; best_len = n+1; /* only if no possibilities */ best_i = -1; for ( i = k; i < m; i++ ) { tmp = fabs(col_vals->ve[i]); if ( tmp == 0.0 ) continue; if ( tmp >= alpha*max_val ) { r = &(A->row[i]); idx = sprow_idx(r,k); len = (r->len) - idx; if ( len < best_len ) { best_len = len; best_i = i; } } } /* swap row #best_i with row #k */ MEM_COPY(&(A->row[best_i]),&tmp_row,sizeof(SPROW)); MEM_COPY(&(A->row[k]),&(A->row[best_i]),sizeof(SPROW)); MEM_COPY(&tmp_row,&(A->row[k]),sizeof(SPROW)); /* swap col_vals entries */ tmp = col_vals->ve[best_i]; col_vals->ve[best_i] = col_vals->ve[k]; col_vals->ve[k] = tmp; px_transp(px,k,best_i); r_piv = &(A->row[k]); for ( i = k+1; i < n; i++ ) { /* compute and set multiplier */ tmp = col_vals->ve[i]/col_vals->ve[k]; if ( tmp != 0.0 ) sp_set_val(A,i,k,tmp); else continue; /* perform row operations */ merge->len = 0; r = &(A->row[i]); sprow_mltadd(r,r_piv,-tmp,k+1,merge,TYPE_SPROW); idx = sprow_idx(r,k+1); if ( idx < 0 ) idx = -(idx+2); /* see if r needs expanding */ if ( r->maxlen < idx + merge->len ) sprow_xpd(r,idx+merge->len,TYPE_SPMAT); r->len = idx+merge->len; MEM_COPY((char *)(merge->elt),(char *)&(r->elt[idx]), merge->len*sizeof(row_elt)); } } #ifdef THREADSAFE sprow_free(merge); V_FREE(col_vals); #endif return A; } /* spLUsolve -- solve A.x = b using factored matrix A from spLUfactor() -- returns x -- may not be in-situ */ #ifndef ANSI_C VEC *spLUsolve(A,pivot,b,x) SPMAT *A; PERM *pivot; VEC *b, *x; #else VEC *spLUsolve(const SPMAT *A, PERM *pivot, const VEC *b, VEC *x) #endif { int i, idx, len, lim; Real sum, *x_ve; SPROW *r; row_elt *elt; if ( ! A || ! b ) error(E_NULL,"spLUsolve"); if ( (pivot != PNULL && A->m != pivot->size) || A->m != b->dim ) error(E_SIZES,"spLUsolve"); if ( ! x || x->dim != A->n ) x = v_resize(x,A->n); if ( pivot != PNULL ) x = px_vec(pivot,b,x); else x = v_copy(b,x); x_ve = x->ve; lim = min(A->m,A->n); for ( i = 0; i < lim; i++ ) { sum = x_ve[i]; r = &(A->row[i]); len = r->len; elt = r->elt; for ( idx = 0; idx < len && elt->col < i; idx++, elt++ ) sum -= elt->val*x_ve[elt->col]; x_ve[i] = sum; } for ( i = lim-1; i >= 0; i-- ) { sum = x_ve[i]; r = &(A->row[i]); len = r->len; elt = &(r->elt[len-1]); for ( idx = len-1; idx >= 0 && elt->col > i; idx--, elt-- ) sum -= elt->val*x_ve[elt->col]; if ( idx < 0 || elt->col != i || elt->val == 0.0 ) error(E_SING,"spLUsolve"); x_ve[i] = sum/elt->val; } return x; } /* spLUTsolve -- solve A.x = b using factored matrix A from spLUfactor() -- returns x -- may not be in-situ */ #ifndef ANSI_C VEC *spLUTsolve(A,pivot,b,x) SPMAT *A; PERM *pivot; VEC *b, *x; #else VEC *spLUTsolve(SPMAT *A, PERM *pivot, const VEC *b, VEC *x) #endif { int i, idx, lim, rownum; Real sum, *tmp_ve; /* SPROW *r; */ row_elt *elt; STATIC VEC *tmp=VNULL; if ( ! A || ! b ) error(E_NULL,"spLUTsolve"); if ( (pivot != PNULL && A->m != pivot->size) || A->m != b->dim ) error(E_SIZES,"spLUTsolve"); tmp = v_copy(b,tmp); MEM_STAT_REG(tmp,TYPE_VEC); if ( ! A->flag_col ) sp_col_access(A); if ( ! A->flag_diag ) sp_diag_access(A); lim = min(A->m,A->n); tmp_ve = tmp->ve; /* solve U^T.tmp = b */ for ( i = 0; i < lim; i++ ) { sum = tmp_ve[i]; rownum = A->start_row[i]; idx = A->start_idx[i]; if ( rownum < 0 || idx < 0 ) error(E_SING,"spLUTsolve"); while ( rownum < i && rownum >= 0 && idx >= 0 ) { elt = &(A->row[rownum].elt[idx]); sum -= elt->val*tmp_ve[rownum]; rownum = elt->nxt_row; idx = elt->nxt_idx; } if ( rownum != i ) error(E_SING,"spLUTsolve"); elt = &(A->row[rownum].elt[idx]); if ( elt->val == 0.0 ) error(E_SING,"spLUTsolve"); tmp_ve[i] = sum/elt->val; } /* now solve L^T.tmp = (old) tmp */ for ( i = lim-1; i >= 0; i-- ) { sum = tmp_ve[i]; rownum = i; idx = A->row[rownum].diag; if ( idx < 0 ) error(E_NULL,"spLUTsolve"); elt = &(A->row[rownum].elt[idx]); rownum = elt->nxt_row; idx = elt->nxt_idx; while ( rownum < lim && rownum >= 0 && idx >= 0 ) { elt = &(A->row[rownum].elt[idx]); sum -= elt->val*tmp_ve[rownum]; rownum = elt->nxt_row; idx = elt->nxt_idx; } tmp_ve[i] = sum; } if ( pivot != PNULL ) x = pxinv_vec(pivot,tmp,x); else x = v_copy(tmp,x); #ifdef THREADSAFE V_FREE(tmp); #endif return x; } /* spILUfactor -- sparse modified incomplete LU factorisation with no pivoting -- all pivot entries are ensured to be >= alpha in magnitude -- setting alpha = 0 gives incomplete LU factorisation -- no fill-in is generated -- in situ factorisation */ #ifndef ANSI_C SPMAT *spILUfactor(A,alpha) SPMAT *A; double alpha; #else SPMAT *spILUfactor(SPMAT *A, double alpha) #endif { int i, k, idx, idx_piv, m, n, old_idx, old_idx_piv; SPROW *r, *r_piv; Real piv_val, tmp; /* printf("spILUfactor: entered\n"); */ if ( ! A ) error(E_NULL,"spILUfactor"); if ( alpha < 0.0 ) error(E_RANGE,"[alpha] in spILUfactor"); m = A->m; n = A->n; sp_diag_access(A); sp_col_access(A); for ( k = 0; k < n; k++ ) { /* printf("spILUfactor(l.%d): checkpoint A: k = %d\n",__LINE__,k); */ /* printf("spILUfactor(l.%d): A =\n", __LINE__); */ /* sp_output(A); */ r_piv = &(A->row[k]); idx_piv = r_piv->diag; if ( idx_piv < 0 ) { sprow_set_val(r_piv,k,alpha); idx_piv = sprow_idx(r_piv,k); } /* printf("spILUfactor: checkpoint B\n"); */ if ( idx_piv < 0 ) error(E_BOUNDS,"spILUfactor"); old_idx_piv = idx_piv; piv_val = r_piv->elt[idx_piv].val; /* printf("spILUfactor: checkpoint C\n"); */ if ( fabs(piv_val) < alpha ) piv_val = ( piv_val < 0.0 ) ? -alpha : alpha; if ( piv_val == 0.0 ) /* alpha == 0.0 too! */ error(E_SING,"spILUfactor"); /* go to next row with a non-zero in this column */ i = r_piv->elt[idx_piv].nxt_row; old_idx = idx = r_piv->elt[idx_piv].nxt_idx; while ( i >= k ) { /* printf("spILUfactor: checkpoint D: i = %d\n",i); */ /* perform row operations */ r = &(A->row[i]); /* idx = sprow_idx(r,k); */ /* printf("spLUfactor(l.%d) i = %d, idx = %d\n", __LINE__, i, idx); */ if ( idx < 0 ) { idx = r->elt[old_idx].nxt_idx; i = r->elt[old_idx].nxt_row; continue; } /* printf("spILUfactor: checkpoint E\n"); */ /* compute and set multiplier */ r->elt[idx].val = tmp = r->elt[idx].val/piv_val; /* printf("spILUfactor: piv_val = %g, multiplier = %g\n", piv_val, tmp); */ /* printf("spLUfactor(l.%d) multiplier = %g\n", __LINE__, tmp); */ if ( tmp == 0.0 ) { idx = r->elt[old_idx].nxt_idx; i = r->elt[old_idx].nxt_row; continue; } /* idx = sprow_idx(r,k+1); */ /* if ( idx < 0 ) idx = -(idx+2); */ idx_piv++; idx++; /* now look beyond the multiplier entry */ /* printf("spILUfactor: checkpoint F: idx = %d, idx_piv = %d\n", idx, idx_piv); */ while ( idx_piv < r_piv->len && idx < r->len ) { /* printf("spILUfactor: checkpoint G: idx = %d, idx_piv = %d\n", idx, idx_piv); */ if ( r_piv->elt[idx_piv].col < r->elt[idx].col ) idx_piv++; else if ( r_piv->elt[idx_piv].col > r->elt[idx].col ) idx++; else /* column numbers match */ { /* printf("spILUfactor(l.%d) subtract %g times the ", __LINE__, tmp); */ /* printf("(%d,%d) entry to the (%d,%d) entry\n", k, r_piv->elt[idx_piv].col, i, r->elt[idx].col); */ r->elt[idx].val -= tmp*r_piv->elt[idx_piv].val; idx++; idx_piv++; } } /* bump to next row with a non-zero in column k */ /* printf("spILUfactor(l.%d) column = %d, row[%d] =\n", __LINE__, r->elt[old_idx].col, i); */ /* sprow_foutput(stdout,r); */ i = r->elt[old_idx].nxt_row; old_idx = idx = r->elt[old_idx].nxt_idx; /* printf("spILUfactor(l.%d) i = %d, idx = %d\n", __LINE__, i, idx); */ /* and restore idx_piv to index of pivot entry */ idx_piv = old_idx_piv; } } /* printf("spILUfactor: exiting\n"); */ return A; } gtk-wave-cleaner-0.22-04/meschach/sprow.c0000777000175000017500000004505713120075107021311 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Sparse rows package See also: sparse.h, matrix.h */ #include #include #include #include "sparse.h" static char rcsid[] = "$Id: sprow.c,v 1.1 1994/01/13 05:35:36 des Exp $"; #define MINROWLEN 10 #ifndef MEX /* sprow_dump - prints relevant information about the sparse row r */ #ifndef ANSI_C void sprow_dump(fp,r) FILE *fp; SPROW *r; #else void sprow_dump(FILE *fp, const SPROW *r) #endif { int j_idx; row_elt *elts; fprintf(fp,"SparseRow dump:\n"); if ( ! r ) { fprintf(fp,"*** NULL row ***\n"); return; } fprintf(fp,"row: len = %d, maxlen = %d, diag idx = %d\n", r->len,r->maxlen,r->diag); fprintf(fp,"element list @ 0x%lx\n",(long)(r->elt)); if ( ! r->elt ) { fprintf(fp,"*** NULL element list ***\n"); return; } elts = r->elt; for ( j_idx = 0; j_idx < r->len; j_idx++, elts++ ) fprintf(fp,"Col: %d, Val: %g, nxt_row = %d, nxt_idx = %d\n", elts->col,elts->val,elts->nxt_row,elts->nxt_idx); fprintf(fp,"\n"); } #endif /* MEX */ /* sprow_idx -- get index into row for a given column in a given row -- return -1 on error -- return -(idx+2) where idx is index to insertion point */ #ifndef ANSI_C int sprow_idx(r,col) SPROW *r; int col; #else int sprow_idx(const SPROW *r, int col) #endif { register int lo, hi, mid; int tmp; register row_elt *r_elt; /******************************************* if ( r == (SPROW *)NULL ) return -1; if ( col < 0 ) return -1; *******************************************/ r_elt = r->elt; if ( r->len <= 0 ) return -2; /* try the hint */ /* if ( hint >= 0 && hint < r->len && r_elt[hint].col == col ) return hint; */ /* otherwise use binary search... */ /* code from K&R Ch. 6, p. 125 */ lo = 0; hi = r->len - 1; mid = lo; while ( lo <= hi ) { mid = (hi + lo)/2; if ( (tmp=r_elt[mid].col-col) > 0 ) hi = mid-1; else if ( tmp < 0 ) lo = mid+1; else /* tmp == 0 */ return mid; } tmp = r_elt[mid].col - col; if ( tmp > 0 ) return -(mid+2); /* insert at mid */ else /* tmp < 0 */ return -(mid+3); /* insert at mid+1 */ } /* sprow_get -- gets, initialises and returns a SPROW structure -- max. length is maxlen */ #ifndef ANSI_C SPROW *sprow_get(maxlen) int maxlen; #else SPROW *sprow_get(int maxlen) #endif { SPROW *r; if ( maxlen < 0 ) error(E_NEG,"sprow_get"); r = NEW(SPROW); if ( ! r ) error(E_MEM,"sprow_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPROW,0,sizeof(SPROW)); mem_numvar(TYPE_SPROW,1); } r->elt = NEW_A(maxlen,row_elt); if ( ! r->elt ) error(E_MEM,"sprow_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_SPROW,0,maxlen*sizeof(row_elt)); } r->len = 0; r->maxlen = maxlen; r->diag = -1; return r; } /* sprow_xpd -- expand row by means of realloc() -- type must be TYPE_SPMAT if r is a row of a SPMAT structure, otherwise it must be TYPE_SPROW -- returns r */ #ifndef ANSI_C SPROW *sprow_xpd(r,n,type) SPROW *r; int n,type; #else SPROW *sprow_xpd(SPROW *r, int n, int type) #endif { int newlen; if ( ! r ) { r = NEW(SPROW); if (! r ) error(E_MEM,"sprow_xpd"); else if ( mem_info_is_on()) { if (type != TYPE_SPMAT && type != TYPE_SPROW) warning(WARN_WRONG_TYPE,"sprow_xpd"); mem_bytes(type,0,sizeof(SPROW)); if (type == TYPE_SPROW) mem_numvar(type,1); } } if ( ! r->elt ) { r->elt = NEW_A((unsigned)n,row_elt); if ( ! r->elt ) error(E_MEM,"sprow_xpd"); else if (mem_info_is_on()) { mem_bytes(type,0,n*sizeof(row_elt)); } r->len = 0; r->maxlen = n; return r; } if ( n <= r->len ) newlen = max(2*r->len + 1,MINROWLEN); else newlen = n; if ( newlen <= r->maxlen ) { MEM_ZERO((char *)(&(r->elt[r->len])), (newlen-r->len)*sizeof(row_elt)); r->len = newlen; } else { if (mem_info_is_on()) { mem_bytes(type,r->maxlen*sizeof(row_elt), newlen*sizeof(row_elt)); } r->elt = RENEW(r->elt,newlen,row_elt); if ( ! r->elt ) error(E_MEM,"sprow_xpd"); r->maxlen = newlen; r->len = newlen; } return r; } /* sprow_resize -- resize a SPROW variable by means of realloc() -- n is a new size -- returns r */ #ifndef ANSI_C SPROW *sprow_resize(r,n,type) SPROW *r; int n,type; #else SPROW *sprow_resize(SPROW *r, int n, int type) #endif { if (n < 0) error(E_NEG,"sprow_resize"); if ( ! r ) return sprow_get(n); if (n == r->len) return r; if ( ! r->elt ) { r->elt = NEW_A((unsigned)n,row_elt); if ( ! r->elt ) error(E_MEM,"sprow_resize"); else if (mem_info_is_on()) { mem_bytes(type,0,n*sizeof(row_elt)); } r->maxlen = r->len = n; return r; } if ( n <= r->maxlen ) r->len = n; else { if (mem_info_is_on()) { mem_bytes(type,r->maxlen*sizeof(row_elt), n*sizeof(row_elt)); } r->elt = RENEW(r->elt,n,row_elt); if ( ! r->elt ) error(E_MEM,"sprow_resize"); r->maxlen = r->len = n; } return r; } /* release a row of a matrix */ #ifndef ANSI_C int sprow_free(r) SPROW *r; #else int sprow_free(SPROW *r) #endif { if ( ! r ) return -1; if (mem_info_is_on()) { mem_bytes(TYPE_SPROW,sizeof(SPROW),0); mem_numvar(TYPE_SPROW,-1); } if ( r->elt ) { if (mem_info_is_on()) { mem_bytes(TYPE_SPROW,r->maxlen*sizeof(row_elt),0); } free((char *)r->elt); } free((char *)r); return 0; } /* sprow_merge -- merges r1 and r2 into r_out -- cannot be done in-situ -- type must be TYPE_SPMAT or TYPE_SPROW depending on whether r_out is a row of a SPMAT structure or a SPROW variable -- returns r_out */ #ifndef ANSI_C SPROW *sprow_merge(r1,r2,r_out,type) SPROW *r1, *r2, *r_out; int type; #else SPROW *sprow_merge(const SPROW *r1, const SPROW *r2, SPROW *r_out, int type) #endif { int idx1, idx2, idx_out, len1, len2, len_out; row_elt *elt1, *elt2, *elt_out; if ( ! r1 || ! r2 ) error(E_NULL,"sprow_merge"); if ( ! r_out ) r_out = sprow_get(MINROWLEN); if ( r1 == r_out || r2 == r_out ) error(E_INSITU,"sprow_merge"); /* Initialise */ len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen; idx1 = idx2 = idx_out = 0; elt1 = r1->elt; elt2 = r2->elt; elt_out = r_out->elt; while ( idx1 < len1 || idx2 < len2 ) { if ( idx_out >= len_out ) { /* r_out is too small */ r_out->len = idx_out; r_out = sprow_xpd(r_out,0,type); len_out = r_out->len; elt_out = &(r_out->elt[idx_out]); } if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) ) { elt_out->col = elt1->col; elt_out->val = elt1->val; if ( elt1->col == elt2->col && idx2 < len2 ) { elt2++; idx2++; } elt1++; idx1++; } else { elt_out->col = elt2->col; elt_out->val = elt2->val; elt2++; idx2++; } elt_out++; idx_out++; } r_out->len = idx_out; return r_out; } /* sprow_copy -- copies r1 and r2 into r_out -- cannot be done in-situ -- type must be TYPE_SPMAT or TYPE_SPROW depending on whether r_out is a row of a SPMAT structure or a SPROW variable -- returns r_out */ #ifndef ANSI_C SPROW *sprow_copy(r1,r2,r_out,type) SPROW *r1, *r2, *r_out; int type; #else SPROW *sprow_copy(const SPROW *r1, const SPROW *r2, SPROW *r_out, int type) #endif { int idx1, idx2, idx_out, len1, len2, len_out; row_elt *elt1, *elt2, *elt_out; if ( ! r1 || ! r2 ) error(E_NULL,"sprow_copy"); if ( ! r_out ) r_out = sprow_get(MINROWLEN); if ( r1 == r_out || r2 == r_out ) error(E_INSITU,"sprow_copy"); /* Initialise */ len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen; idx1 = idx2 = idx_out = 0; elt1 = r1->elt; elt2 = r2->elt; elt_out = r_out->elt; while ( idx1 < len1 || idx2 < len2 ) { while ( idx_out >= len_out ) { /* r_out is too small */ r_out->len = idx_out; r_out = sprow_xpd(r_out,0,type); len_out = r_out->maxlen; elt_out = &(r_out->elt[idx_out]); } if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) ) { elt_out->col = elt1->col; elt_out->val = elt1->val; if ( elt1->col == elt2->col && idx2 < len2 ) { elt2++; idx2++; } elt1++; idx1++; } else { elt_out->col = elt2->col; elt_out->val = 0.0; elt2++; idx2++; } elt_out++; idx_out++; } r_out->len = idx_out; return r_out; } /* sprow_mltadd -- sets r_out <- r1 + alpha.r2 -- cannot be in situ -- only for columns j0, j0+1, ... -- type must be TYPE_SPMAT or TYPE_SPROW depending on whether r_out is a row of a SPMAT structure or a SPROW variable -- returns r_out */ #ifndef ANSI_C SPROW *sprow_mltadd(r1,r2,alpha,j0,r_out,type) SPROW *r1, *r2, *r_out; double alpha; int j0, type; #else SPROW *sprow_mltadd(const SPROW *r1,const SPROW *r2, double alpha, int j0, SPROW *r_out, int type) #endif { int idx1, idx2, idx_out, len1, len2, len_out; row_elt *elt1, *elt2, *elt_out; if ( ! r1 || ! r2 ) error(E_NULL,"sprow_mltadd"); if ( r1 == r_out || r2 == r_out ) error(E_INSITU,"sprow_mltadd"); if ( j0 < 0 ) error(E_BOUNDS,"sprow_mltadd"); if ( ! r_out ) r_out = sprow_get(MINROWLEN); /* Initialise */ len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen; /* idx1 = idx2 = idx_out = 0; */ idx1 = sprow_idx(r1,j0); idx2 = sprow_idx(r2,j0); idx_out = sprow_idx(r_out,j0); idx1 = (idx1 < 0) ? -(idx1+2) : idx1; idx2 = (idx2 < 0) ? -(idx2+2) : idx2; idx_out = (idx_out < 0) ? -(idx_out+2) : idx_out; elt1 = &(r1->elt[idx1]); elt2 = &(r2->elt[idx2]); elt_out = &(r_out->elt[idx_out]); while ( idx1 < len1 || idx2 < len2 ) { if ( idx_out >= len_out ) { /* r_out is too small */ r_out->len = idx_out; r_out = sprow_xpd(r_out,0,type); len_out = r_out->maxlen; elt_out = &(r_out->elt[idx_out]); } if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) ) { elt_out->col = elt1->col; elt_out->val = elt1->val; if ( idx2 < len2 && elt1->col == elt2->col ) { elt_out->val += alpha*elt2->val; elt2++; idx2++; } elt1++; idx1++; } else { elt_out->col = elt2->col; elt_out->val = alpha*elt2->val; elt2++; idx2++; } elt_out++; idx_out++; } r_out->len = idx_out; return r_out; } /* sprow_add -- sets r_out <- r1 + r2 -- cannot be in situ -- only for columns j0, j0+1, ... -- type must be TYPE_SPMAT or TYPE_SPROW depending on whether r_out is a row of a SPMAT structure or a SPROW variable -- returns r_out */ #ifndef ANSI_C SPROW *sprow_add(r1,r2,j0,r_out,type) SPROW *r1, *r2, *r_out; int j0, type; #else SPROW *sprow_add(const SPROW *r1,const SPROW *r2, int j0, SPROW *r_out, int type) #endif { int idx1, idx2, idx_out, len1, len2, len_out; row_elt *elt1, *elt2, *elt_out; if ( ! r1 || ! r2 ) error(E_NULL,"sprow_add"); if ( r1 == r_out || r2 == r_out ) error(E_INSITU,"sprow_add"); if ( j0 < 0 ) error(E_BOUNDS,"sprow_add"); if ( ! r_out ) r_out = sprow_get(MINROWLEN); /* Initialise */ len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen; /* idx1 = idx2 = idx_out = 0; */ idx1 = sprow_idx(r1,j0); idx2 = sprow_idx(r2,j0); idx_out = sprow_idx(r_out,j0); idx1 = (idx1 < 0) ? -(idx1+2) : idx1; idx2 = (idx2 < 0) ? -(idx2+2) : idx2; idx_out = (idx_out < 0) ? -(idx_out+2) : idx_out; elt1 = &(r1->elt[idx1]); elt2 = &(r2->elt[idx2]); elt_out = &(r_out->elt[idx_out]); while ( idx1 < len1 || idx2 < len2 ) { if ( idx_out >= len_out ) { /* r_out is too small */ r_out->len = idx_out; r_out = sprow_xpd(r_out,0,type); len_out = r_out->maxlen; elt_out = &(r_out->elt[idx_out]); } if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) ) { elt_out->col = elt1->col; elt_out->val = elt1->val; if ( idx2 < len2 && elt1->col == elt2->col ) { elt_out->val += elt2->val; elt2++; idx2++; } elt1++; idx1++; } else { elt_out->col = elt2->col; elt_out->val = elt2->val; elt2++; idx2++; } elt_out++; idx_out++; } r_out->len = idx_out; return r_out; } /* sprow_sub -- sets r_out <- r1 - r2 -- cannot be in situ -- only for columns j0, j0+1, ... -- type must be TYPE_SPMAT or TYPE_SPROW depending on whether r_out is a row of a SPMAT structure or a SPROW variable -- returns r_out */ #ifndef ANSI_C SPROW *sprow_sub(r1,r2,j0,r_out,type) SPROW *r1, *r2, *r_out; int j0, type; #else SPROW *sprow_sub(const SPROW *r1, const SPROW *r2, int j0, SPROW *r_out, int type) #endif { int idx1, idx2, idx_out, len1, len2, len_out; row_elt *elt1, *elt2, *elt_out; if ( ! r1 || ! r2 ) error(E_NULL,"sprow_sub"); if ( r1 == r_out || r2 == r_out ) error(E_INSITU,"sprow_sub"); if ( j0 < 0 ) error(E_BOUNDS,"sprow_sub"); if ( ! r_out ) r_out = sprow_get(MINROWLEN); /* Initialise */ len1 = r1->len; len2 = r2->len; len_out = r_out->maxlen; /* idx1 = idx2 = idx_out = 0; */ idx1 = sprow_idx(r1,j0); idx2 = sprow_idx(r2,j0); idx_out = sprow_idx(r_out,j0); idx1 = (idx1 < 0) ? -(idx1+2) : idx1; idx2 = (idx2 < 0) ? -(idx2+2) : idx2; idx_out = (idx_out < 0) ? -(idx_out+2) : idx_out; elt1 = &(r1->elt[idx1]); elt2 = &(r2->elt[idx2]); elt_out = &(r_out->elt[idx_out]); while ( idx1 < len1 || idx2 < len2 ) { if ( idx_out >= len_out ) { /* r_out is too small */ r_out->len = idx_out; r_out = sprow_xpd(r_out,0,type); len_out = r_out->maxlen; elt_out = &(r_out->elt[idx_out]); } if ( idx2 >= len2 || (idx1 < len1 && elt1->col <= elt2->col) ) { elt_out->col = elt1->col; elt_out->val = elt1->val; if ( idx2 < len2 && elt1->col == elt2->col ) { elt_out->val -= elt2->val; elt2++; idx2++; } elt1++; idx1++; } else { elt_out->col = elt2->col; elt_out->val = -elt2->val; elt2++; idx2++; } elt_out++; idx_out++; } r_out->len = idx_out; return r_out; } /* sprow_smlt -- sets r_out <- alpha*r1 -- can be in situ -- only for columns j0, j0+1, ... -- returns r_out */ #ifndef ANSI_C SPROW *sprow_smlt(r1,alpha,j0,r_out,type) SPROW *r1, *r_out; double alpha; int j0, type; #else SPROW *sprow_smlt(const SPROW *r1, double alpha, int j0, SPROW *r_out, int type) #endif { int idx1, idx_out, len1; row_elt *elt1, *elt_out; if ( ! r1 ) error(E_NULL,"sprow_smlt"); if ( j0 < 0 ) error(E_BOUNDS,"sprow_smlt"); if ( ! r_out ) r_out = sprow_get(MINROWLEN); /* Initialise */ len1 = r1->len; idx1 = sprow_idx(r1,j0); idx_out = sprow_idx(r_out,j0); idx1 = (idx1 < 0) ? -(idx1+2) : idx1; idx_out = (idx_out < 0) ? -(idx_out+2) : idx_out; elt1 = &(r1->elt[idx1]); r_out = sprow_resize(r_out,idx_out+len1-idx1,type); elt_out = &(r_out->elt[idx_out]); for ( ; idx1 < len1; elt1++,elt_out++,idx1++,idx_out++ ) { elt_out->col = elt1->col; elt_out->val = alpha*elt1->val; } r_out->len = idx_out; return r_out; } #ifndef MEX /* sprow_foutput -- print a representation of r on stream fp */ #ifndef ANSI_C void sprow_foutput(fp,r) FILE *fp; SPROW *r; #else void sprow_foutput(FILE *fp, const SPROW *r) #endif { int i, len; row_elt *e; if ( ! r ) { fprintf(fp,"SparseRow: **** NULL ****\n"); return; } len = r->len; fprintf(fp,"SparseRow: length: %d\n",len); for ( i = 0, e = r->elt; i < len; i++, e++ ) fprintf(fp,"Column %d: %g, next row: %d, next index %d\n", e->col, e->val, e->nxt_row, e->nxt_idx); } #endif /* sprow_set_val -- sets the j-th column entry of the sparse row r -- Note: destroys the usual column & row access paths */ #ifndef ANSI_C double sprow_set_val(r,j,val) SPROW *r; int j; double val; #else double sprow_set_val(SPROW *r, int j, double val) #endif { int idx, idx2, new_len; if ( ! r ) error(E_NULL,"sprow_set_val"); idx = sprow_idx(r,j); if ( idx >= 0 ) { r->elt[idx].val = val; return val; } /* else */ if ( idx < -1 ) { /* shift & insert new value */ idx = -(idx+2); /* this is the intended insertion index */ if ( r->len >= r->maxlen ) { r->len = r->maxlen; new_len = max(2*r->maxlen+1,5); if (mem_info_is_on()) { mem_bytes(TYPE_SPROW,r->maxlen*sizeof(row_elt), new_len*sizeof(row_elt)); } r->elt = RENEW(r->elt,new_len,row_elt); if ( ! r->elt ) /* can't allocate */ error(E_MEM,"sprow_set_val"); r->maxlen = 2*r->maxlen+1; } for ( idx2 = r->len-1; idx2 >= idx; idx2-- ) MEM_COPY((char *)(&(r->elt[idx2])), (char *)(&(r->elt[idx2+1])),sizeof(row_elt)); /************************************************************ if ( idx < r->len ) MEM_COPY((char *)(&(r->elt[idx])),(char *)(&(r->elt[idx+1])), (r->len-idx)*sizeof(row_elt)); ************************************************************/ r->len++; r->elt[idx].col = j; r->elt[idx].nxt_row = -1; r->elt[idx].nxt_idx = -1; return r->elt[idx].val = val; } /* else -- idx == -1, error in index/matrix! */ return 0.0; } gtk-wave-cleaner-0.22-04/meschach/spswap.c0000777000175000017500000001737113120075107021452 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Sparse matrix swap and permutation routines Modified Mon 09th Nov 1992, 08:50:54 PM to use Karen George's suggestion to use unordered rows */ static char rcsid[] = "$Id: spswap.c,v 1.3 1994/01/13 05:44:43 des Exp $"; #include #include #include "sparse2.h" #define btos(x) ((x) ? "TRUE" : "FALSE") /* scan_to -- updates scan (int) vectors to point to the last row in each column with row # <= max_row, if any */ #ifndef ANSI_C void scan_to(A, scan_row, scan_idx, col_list, max_row) SPMAT *A; IVEC *scan_row, *scan_idx, *col_list; int max_row; #else void scan_to(SPMAT *A, IVEC *scan_row, IVEC *scan_idx, IVEC *col_list, int max_row) #endif { int col, idx, j_idx, row_num; SPROW *r; row_elt *e; if ( ! A || ! scan_row || ! scan_idx || ! col_list ) error(E_NULL,"scan_to"); if ( scan_row->dim != scan_idx->dim || scan_idx->dim != col_list->dim ) error(E_SIZES,"scan_to"); if ( max_row < 0 ) return; if ( ! A->flag_col ) sp_col_access(A); for ( j_idx = 0; j_idx < scan_row->dim; j_idx++ ) { row_num = scan_row->ive[j_idx]; idx = scan_idx->ive[j_idx]; col = col_list->ive[j_idx]; if ( col < 0 || col >= A->n ) error(E_BOUNDS,"scan_to"); if ( row_num < 0 ) { idx = col; continue; } r = &(A->row[row_num]); if ( idx < 0 ) error(E_INTERN,"scan_to"); e = &(r->elt[idx]); if ( e->col != col ) error(E_INTERN,"scan_to"); if ( idx < 0 ) { printf("scan_to: row_num = %d, idx = %d, col = %d\n", row_num, idx, col); error(E_INTERN,"scan_to"); } /* if ( e->nxt_row <= max_row ) chase_col(A, col, &row_num, &idx, max_row); */ while ( e->nxt_row >= 0 && e->nxt_row <= max_row ) { row_num = e->nxt_row; idx = e->nxt_idx; e = &(A->row[row_num].elt[idx]); } /* printf("scan_to: computed j_idx = %d, row_num = %d, idx = %d\n", j_idx, row_num, idx); */ scan_row->ive[j_idx] = row_num; scan_idx->ive[j_idx] = idx; } } /* patch_col -- patches column access paths for fill-in */ #ifndef ANSI_C void patch_col(A, col, old_row, old_idx, row_num, idx) SPMAT *A; int col, old_row, old_idx, row_num, idx; #else void patch_col(SPMAT *A, int col, int old_row, int old_idx, int row_num, int idx) #endif { SPROW *r; row_elt *e; if ( old_row >= 0 ) { r = &(A->row[old_row]); old_idx = sprow_idx2(r,col,old_idx); e = &(r->elt[old_idx]); e->nxt_row = row_num; e->nxt_idx = idx; } else { A->start_row[col] = row_num; A->start_idx[col] = idx; } } /* chase_col -- chases column access path in column col, starting with row_num and idx, to find last row # in this column <= max_row -- row_num is returned; idx is also set by this routine -- assumes that the column access paths (possibly without the nxt_idx fields) are set up */ #ifndef ANSI_C row_elt *chase_col(A, col, row_num, idx, max_row) SPMAT *A; int col, *row_num, *idx, max_row; #else row_elt *chase_col(const SPMAT *A, int col, int *row_num, int *idx, int max_row) #endif { int old_idx, old_row, tmp_idx, tmp_row; SPROW *r; row_elt *e; if ( col < 0 || col >= A->n ) error(E_BOUNDS,"chase_col"); tmp_row = *row_num; if ( tmp_row < 0 ) { if ( A->start_row[col] > max_row ) { tmp_row = -1; tmp_idx = col; return (row_elt *)NULL; } else { tmp_row = A->start_row[col]; tmp_idx = A->start_idx[col]; } } else tmp_idx = *idx; old_row = tmp_row; old_idx = tmp_idx; while ( tmp_row >= 0 && tmp_row < max_row ) { r = &(A->row[tmp_row]); /* tmp_idx = sprow_idx2(r,col,tmp_idx); */ if ( tmp_idx < 0 || tmp_idx >= r->len || r->elt[tmp_idx].col != col ) { #ifdef DEBUG printf("chase_col:error: col = %d, row # = %d, idx = %d\n", col, tmp_row, tmp_idx); printf("chase_col:error: old_row = %d, old_idx = %d\n", old_row, old_idx); printf("chase_col:error: A =\n"); sp_dump(stdout,A); #endif error(E_INTERN,"chase_col"); } e = &(r->elt[tmp_idx]); old_row = tmp_row; old_idx = tmp_idx; tmp_row = e->nxt_row; tmp_idx = e->nxt_idx; } if ( old_row > max_row ) { old_row = -1; old_idx = col; e = (row_elt *)NULL; } else if ( tmp_row <= max_row && tmp_row >= 0 ) { old_row = tmp_row; old_idx = tmp_idx; } *row_num = old_row; if ( old_row >= 0 ) *idx = old_idx; else *idx = col; return e; } /* chase_past -- as for chase_col except that we want the first row whose row # >= min_row; -1 indicates no such row */ #ifndef ANSI_C row_elt *chase_past(A, col, row_num, idx, min_row) SPMAT *A; int col, *row_num, *idx, min_row; #else row_elt *chase_past(const SPMAT *A, int col, int *row_num, int *idx, int min_row) #endif { SPROW *r; row_elt *e; int tmp_idx, tmp_row; tmp_row = *row_num; tmp_idx = *idx; chase_col(A,col,&tmp_row,&tmp_idx,min_row); if ( tmp_row < 0 ) /* use A->start_row[..] etc. */ { if ( A->start_row[col] < 0 ) tmp_row = -1; else { tmp_row = A->start_row[col]; tmp_idx = A->start_idx[col]; } } else if ( tmp_row < min_row ) { r = &(A->row[tmp_row]); if ( tmp_idx < 0 || tmp_idx >= r->len || r->elt[tmp_idx].col != col ) error(E_INTERN,"chase_past"); tmp_row = r->elt[tmp_idx].nxt_row; tmp_idx = r->elt[tmp_idx].nxt_idx; } *row_num = tmp_row; *idx = tmp_idx; if ( tmp_row < 0 ) e = (row_elt *)NULL; else { if ( tmp_idx < 0 || tmp_idx >= A->row[tmp_row].len || A->row[tmp_row].elt[tmp_idx].col != col ) error(E_INTERN,"bump_col"); e = &(A->row[tmp_row].elt[tmp_idx]); } return e; } /* bump_col -- move along to next nonzero entry in column col after row_num -- update row_num and idx */ #ifndef ANSI_C row_elt *bump_col(A, col, row_num, idx) SPMAT *A; int col, *row_num, *idx; #else row_elt *bump_col(const SPMAT *A, int col, int *row_num, int *idx) #endif { SPROW *r; row_elt *e; int tmp_row, tmp_idx; tmp_row = *row_num; tmp_idx = *idx; /* printf("bump_col: col = %d, row# = %d, idx = %d\n", col, *row_num, *idx); */ if ( tmp_row < 0 ) { tmp_row = A->start_row[col]; tmp_idx = A->start_idx[col]; } else { r = &(A->row[tmp_row]); if ( tmp_idx < 0 || tmp_idx >= r->len || r->elt[tmp_idx].col != col ) error(E_INTERN,"bump_col"); e = &(r->elt[tmp_idx]); tmp_row = e->nxt_row; tmp_idx = e->nxt_idx; } if ( tmp_row < 0 ) { e = (row_elt *)NULL; tmp_idx = col; } else { if ( tmp_idx < 0 || tmp_idx >= A->row[tmp_row].len || A->row[tmp_row].elt[tmp_idx].col != col ) error(E_INTERN,"bump_col"); e = &(A->row[tmp_row].elt[tmp_idx]); } *row_num = tmp_row; *idx = tmp_idx; return e; } gtk-wave-cleaner-0.22-04/meschach/sptort.c0000777000175000017500000002603713120075107021467 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains tests for the sparse matrix part of Meschach */ #include #include #include "matrix2.h" #include "sparse2.h" #include "iter.h" #define errmesg(mesg) printf("Error: %s error: line %d\n",mesg,__LINE__) #define notice(mesg) printf("# Testing %s...\n",mesg); /* for iterative methods */ #if REAL == DOUBLE #define EPS 1e-7 #elif REAL == FLOAT #define EPS 1e-3 #endif int chk_col_accessSPT(A) SPMAT *A; { int i, j, nxt_idx, nxt_row, scan_cnt, total_cnt; SPROW *r; row_elt *e; if ( ! A ) error(E_NULL,"chk_col_accessSPT"); if ( ! A->flag_col ) return FALSE; /* scan down each column, counting the number of entries met */ scan_cnt = 0; for ( j = 0; j < A->n; j++ ) { i = -1; nxt_idx = A->start_idx[j]; nxt_row = A->start_row[j]; while ( nxt_row >= 0 && nxt_idx >= 0 && nxt_row > i ) { i = nxt_row; r = &(A->row[i]); e = &(r->elt[nxt_idx]); nxt_idx = e->nxt_idx; nxt_row = e->nxt_row; scan_cnt++; } } total_cnt = 0; for ( i = 0; i < A->m; i++ ) total_cnt += A->row[i].len; if ( total_cnt != scan_cnt ) return FALSE; else return TRUE; } void main(argc, argv) int argc; char *argv[]; { VEC *x, *y, *z, *u, *v; Real s1, s2; PERM *pivot; SPMAT *A, *B, *C; SPMAT *B1, *C1; SPROW *r; int i, j, k, deg, seed, m, m_old, n, n_old; mem_info_on(TRUE); setbuf(stdout, (char *)NULL); /* get seed if in argument list */ if ( argc == 1 ) seed = 1111; else if ( argc == 2 && sscanf(argv[1],"%d",&seed) == 1 ) ; else { printf("usage: %s [seed]\n", argv[0]); exit(0); } srand(seed); /* set up two random sparse matrices */ m = 120; n = 100; deg = 8; notice("allocating sparse matrices"); A = sp_get(m,n,deg); B = sp_get(m,n,deg); notice("setting and getting matrix entries"); for ( k = 0; k < m*deg; k++ ) { i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(A,i,j,rand()/((Real)MAX_RAND)); i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(B,i,j,rand()/((Real)MAX_RAND)); } for ( k = 0; k < 10; k++ ) { s1 = rand()/((Real)MAX_RAND); i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(A,i,j,s1); s2 = sp_get_val(A,i,j); if ( fabs(s1 - s2) >= MACHEPS ) break; } if ( k < 10 ) errmesg("sp_set_val()/sp_get_val()"); /* test copy routines */ notice("copy routines"); x = v_get(n); y = v_get(m); z = v_get(m); /* first copy routine */ C = sp_copy(A); for ( k = 0; k < 100; k++ ) { v_rand(x); sp_mv_mlt(A,x,y); sp_mv_mlt(C,x,z); if ( v_norm_inf(v_sub(y,z,z)) >= MACHEPS*deg*m ) break; } if ( k < 100 ) { errmesg("sp_copy()/sp_mv_mlt()"); printf("# Error in A.x (inf norm) = %g [cf MACHEPS = %g]\n", v_norm_inf(z), MACHEPS); } /* second copy routine -- note that A & B have different sparsity patterns */ mem_stat_mark(1); sp_copy2(A,B); mem_stat_free(1); for ( k = 0; k < 10; k++ ) { v_rand(x); sp_mv_mlt(A,x,y); sp_mv_mlt(B,x,z); if ( v_norm_inf(v_sub(y,z,z)) >= MACHEPS*deg*m ) break; } if ( k < 10 ) { errmesg("sp_copy2()/sp_mv_mlt()"); printf("# Error in A.x (inf norm) = %g [cf MACHEPS = %g]\n", v_norm_inf(z), MACHEPS); } /* now check compacting routine */ notice("compacting routine"); sp_compact(B,0.0); for ( k = 0; k < 10; k++ ) { v_rand(x); sp_mv_mlt(A,x,y); sp_mv_mlt(B,x,z); if ( v_norm_inf(v_sub(y,z,z)) >= MACHEPS*deg*m ) break; } if ( k < 10 ) { errmesg("sp_compact()"); printf("# Error in A.x (inf norm) = %g [cf MACHEPS = %g]\n", v_norm_inf(z), MACHEPS); } for ( i = 0; i < B->m; i++ ) { r = &(B->row[i]); for ( j = 0; j < r->len; j++ ) if ( r->elt[j].val == 0.0 ) break; } if ( i < B->m ) { errmesg("sp_compact()"); printf("# Zero entry in compacted matrix\n"); } /* check column access paths */ notice("resizing and access paths"); m_old = A->m-1; n_old = A->n-1; A = sp_resize(A,A->m+10,A->n+10); for ( k = 0 ; k < 20; k++ ) { i = m_old + ((rand() >> 8) % 10); j = n_old + ((rand() >> 8) % 10); s1 = rand()/((Real)MAX_RAND); sp_set_val(A,i,j,s1); if ( fabs(s1 - sp_get_val(A,i,j)) >= MACHEPS ) break; } if ( k < 20 ) errmesg("sp_resize()"); sp_col_access(A); if ( ! chk_col_accessSPT(A) ) { errmesg("sp_col_access()"); } sp_diag_access(A); for ( i = 0; i < A->m; i++ ) { r = &(A->row[i]); if ( r->diag != sprow_idx(r,i) ) break; } if ( i < A->m ) { errmesg("sp_diag_access()"); } /* test both sp_mv_mlt() and sp_vm_mlt() */ x = v_resize(x,B->n); y = v_resize(y,B->m); u = v_get(B->m); v = v_get(B->n); for ( k = 0; k < 10; k++ ) { v_rand(x); v_rand(y); sp_mv_mlt(B,x,u); sp_vm_mlt(B,y,v); if ( fabs(in_prod(x,v) - in_prod(y,u)) >= MACHEPS*v_norm2(x)*v_norm2(u)*5 ) break; } if ( k < 10 ) { errmesg("sp_mv_mlt()/sp_vm_mlt()"); printf("# Error in inner products = %g [cf MACHEPS = %g]\n", fabs(in_prod(x,v) - in_prod(y,u)), MACHEPS); } SP_FREE(A); SP_FREE(B); SP_FREE(C); /* now test Cholesky and LU factorise and solve */ notice("sparse Cholesky factorise/solve"); A = iter_gen_sym(120,8); B = sp_copy(A); spCHfactor(A); x = v_resize(x,A->m); y = v_resize(y,A->m); v_rand(x); sp_mv_mlt(B,x,y); z = v_resize(z,A->m); spCHsolve(A,y,z); v = v_resize(v,A->m); sp_mv_mlt(B,z,v); /* compute residual */ v_sub(y,v,v); if ( v_norm2(v) >= MACHEPS*v_norm2(y)*10 ) { errmesg("spCHfactor()/spCHsolve()"); printf("# Sparse Cholesky residual = %g [cf MACHEPS = %g]\n", v_norm2(v), MACHEPS); } /* compute error in solution */ v_sub(x,z,z); if ( v_norm2(z) > MACHEPS*v_norm2(x)*10 ) { errmesg("spCHfactor()/spCHsolve()"); printf("# Solution error = %g [cf MACHEPS = %g]\n", v_norm2(z), MACHEPS); } /* now test symbolic and incomplete factorisation */ SP_FREE(A); A = sp_copy(B); mem_stat_mark(2); spCHsymb(A); mem_stat_mark(2); spICHfactor(A); spCHsolve(A,y,z); v = v_resize(v,A->m); sp_mv_mlt(B,z,v); /* compute residual */ v_sub(y,v,v); if ( v_norm2(v) >= MACHEPS*v_norm2(y)*5 ) { errmesg("spCHsymb()/spICHfactor()"); printf("# Sparse Cholesky residual = %g [cf MACHEPS = %g]\n", v_norm2(v), MACHEPS); } /* compute error in solution */ v_sub(x,z,z); if ( v_norm2(z) > MACHEPS*v_norm2(x)*10 ) { errmesg("spCHsymb()/spICHfactor()"); printf("# Solution error = %g [cf MACHEPS = %g]\n", v_norm2(z), MACHEPS); } /* now test sparse LU factorisation */ notice("sparse LU factorise/solve"); SP_FREE(A); SP_FREE(B); A = iter_gen_nonsym(100,100,8,1.0); B = sp_copy(A); x = v_resize(x,A->n); z = v_resize(z,A->n); y = v_resize(y,A->m); v = v_resize(v,A->m); v_rand(x); sp_mv_mlt(B,x,y); pivot = px_get(A->m); mem_stat_mark(3); spLUfactor(A,pivot,0.1); spLUsolve(A,pivot,y,z); mem_stat_free(3); sp_mv_mlt(B,z,v); /* compute residual */ v_sub(y,v,v); if ( v_norm2(v) >= MACHEPS*v_norm2(y)*A->m ) { errmesg("spLUfactor()/spLUsolve()"); printf("# Sparse LU residual = %g [cf MACHEPS = %g]\n", v_norm2(v), MACHEPS); } /* compute error in solution */ v_sub(x,z,z); if ( v_norm2(z) > MACHEPS*v_norm2(x)*100*A->m ) { errmesg("spLUfactor()/spLUsolve()"); printf("# Sparse LU solution error = %g [cf MACHEPS = %g]\n", v_norm2(z), MACHEPS); } /* now check spLUTsolve */ mem_stat_mark(4); sp_vm_mlt(B,x,y); spLUTsolve(A,pivot,y,z); sp_vm_mlt(B,z,v); mem_stat_free(4); /* compute residual */ v_sub(y,v,v); if ( v_norm2(v) >= MACHEPS*v_norm2(y)*A->m ) { errmesg("spLUTsolve()"); printf("# Sparse LU residual = %g [cf MACHEPS = %g]\n", v_norm2(v), MACHEPS); } /* compute error in solution */ v_sub(x,z,z); if ( v_norm2(z) > MACHEPS*v_norm2(x)*100*A->m ) { errmesg("spLUTsolve()"); printf("# Sparse LU solution error = %g [cf MACHEPS = %g]\n", v_norm2(z), MACHEPS); } /* algebraic operations */ notice("addition,subtraction and multiplying by a number"); SP_FREE(A); SP_FREE(B); m = 120; n = 120; deg = 5; A = sp_get(m,n,deg); B = sp_get(m,n,deg); C = sp_get(m,n,deg); C1 = sp_get(m,n,deg); for ( k = 0; k < m*deg; k++ ) { i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(A,i,j,rand()/((Real)MAX_RAND)); i = (rand() >> 8) % m; j = (rand() >> 8) % n; sp_set_val(B,i,j,rand()/((Real)MAX_RAND)); } s1 = mrand(); B1 = sp_copy(B); mem_stat_mark(1); sp_smlt(B,s1,C); sp_add(A,C,C1); sp_sub(C1,A,C); sp_smlt(C,-1.0/s1,C); sp_add(C,B1,C); s2 = 0.0; for (k=0; k < C->m; k++) { r = &(C->row[k]); for (j=0; j < r->len; j++) { if (s2 < fabs(r->elt[j].val)) s2 = fabs(r->elt[j].val); } } if (s2 > MACHEPS*A->m) { errmesg("add, sub, mlt sparse matrices (args not in situ)\n"); printf(" difference = %g [MACEPS = %g]\n",s2,MACHEPS); } sp_mltadd(A,B1,s1,C1); sp_sub(C1,A,A); sp_smlt(A,1.0/s1,C1); sp_sub(C1,B1,C1); mem_stat_free(1); s2 = 0.0; for (k=0; k < C1->m; k++) { r = &(C1->row[k]); for (j=0; j < r->len; j++) { if (s2 < fabs(r->elt[j].val)) s2 = fabs(r->elt[j].val); } } if (s2 > MACHEPS*A->m) { errmesg("add, sub, mlt sparse matrices (args not in situ)\n"); printf(" difference = %g [MACEPS = %g]\n",s2,MACHEPS); } V_FREE(x); V_FREE(y); V_FREE(z); V_FREE(u); V_FREE(v); PX_FREE(pivot); SP_FREE(A); SP_FREE(B); SP_FREE(C); SP_FREE(B1); SP_FREE(C1); printf("# Done testing (%s)\n",argv[0]); mem_info(); } gtk-wave-cleaner-0.22-04/meschach/submat.c0000777000175000017500000001221313120075107021416 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* 1.2 submat.c 11/25/87 */ #include #include "matrix.h" static char rcsid[] = "$Id: submat.c,v 1.2 1994/01/13 05:28:12 des Exp $"; /* get_col -- gets a specified column of a matrix and retruns it as a vector */ #ifndef ANSI_C VEC *get_col(mat,col,vec) unsigned int col; MAT *mat; VEC *vec; #else VEC *get_col(const MAT *mat, unsigned int col, VEC *vec) #endif { unsigned int i; if ( mat==(MAT *)NULL ) error(E_NULL,"get_col"); if ( col >= mat->n ) error(E_RANGE,"get_col"); if ( vec==(VEC *)NULL || vec->dimm ) vec = v_resize(vec,mat->m); for ( i=0; im; i++ ) vec->ve[i] = mat->me[i][col]; return (vec); } /* get_row -- gets a specified row of a matrix and retruns it as a vector */ #ifndef ANSI_C VEC *get_row(mat,row,vec) unsigned int row; MAT *mat; VEC *vec; #else VEC *get_row(const MAT *mat, unsigned int row, VEC *vec) #endif { unsigned int i; if ( mat==(MAT *)NULL ) error(E_NULL,"get_row"); if ( row >= mat->m ) error(E_RANGE,"get_row"); if ( vec==(VEC *)NULL || vec->dimn ) vec = v_resize(vec,mat->n); for ( i=0; in; i++ ) vec->ve[i] = mat->me[row][i]; return (vec); } /* _set_col -- sets column of matrix to values given in vec (in situ) -- that is, mat(i0:lim,col) <- vec(i0:lim) */ #ifndef ANSI_C MAT *_set_col(mat,col,vec,i0) MAT *mat; VEC *vec; unsigned int col,i0; #else MAT *_set_col(MAT *mat, unsigned int col, const VEC *vec, unsigned int i0) #endif { unsigned int i,lim; if ( mat==(MAT *)NULL || vec==(VEC *)NULL ) error(E_NULL,"_set_col"); if ( col >= mat->n ) error(E_RANGE,"_set_col"); lim = min(mat->m,vec->dim); for ( i=i0; ime[i][col] = vec->ve[i]; return (mat); } /* _set_row -- sets row of matrix to values given in vec (in situ) */ #ifndef ANSI_C MAT *_set_row(mat,row,vec,j0) MAT *mat; VEC *vec; unsigned int row,j0; #else MAT *_set_row(MAT *mat, unsigned int row, const VEC *vec, unsigned int j0) #endif { unsigned int j,lim; if ( mat==(MAT *)NULL || vec==(VEC *)NULL ) error(E_NULL,"_set_row"); if ( row >= mat->m ) error(E_RANGE,"_set_row"); lim = min(mat->n,vec->dim); for ( j=j0; jme[row][j] = vec->ve[j]; return (mat); } /* sub_mat -- returns sub-matrix of old which is formed by the rectangle from (row1,col1) to (row2,col2) -- Note: storage is shared so that altering the "new" matrix will alter the "old" matrix */ #ifndef ANSI_C MAT *sub_mat(old,row1,col1,row2,col2,new) MAT *old,*new; unsigned int row1,col1,row2,col2; #else MAT *sub_mat(const MAT *old, unsigned int row1, unsigned int col1, unsigned int row2, unsigned int col2, MAT *new) #endif { unsigned int i; if ( old==(MAT *)NULL ) error(E_NULL,"sub_mat"); if ( row1 > row2 || col1 > col2 || row2 >= old->m || col2 >= old->n ) error(E_RANGE,"sub_mat"); if ( new==(MAT *)NULL || new->m < row2-row1+1 ) { new = NEW(MAT); new->me = NEW_A(row2-row1+1,Real *); if ( new==(MAT *)NULL || new->me==(Real **)NULL ) error(E_MEM,"sub_mat"); else if (mem_info_is_on()) { mem_bytes(TYPE_MAT,0,sizeof(MAT)+ (row2-row1+1)*sizeof(Real *)); } } new->m = row2-row1+1; new->n = col2-col1+1; new->base = (Real *)NULL; for ( i=0; i < new->m; i++ ) new->me[i] = (old->me[i+row1]) + col1; return (new); } /* sub_vec -- returns sub-vector which is formed by the elements i1 to i2 -- as for sub_mat, storage is shared */ #ifndef ANSI_C VEC *sub_vec(old,i1,i2,new) VEC *old, *new; int i1, i2; #else VEC *sub_vec(const VEC *old, int i1, int i2, VEC *new) #endif { if ( old == (VEC *)NULL ) error(E_NULL,"sub_vec"); if ( i1 > i2 || old->dim < i2 ) error(E_RANGE,"sub_vec"); if ( new == (VEC *)NULL ) new = NEW(VEC); if ( new == (VEC *)NULL ) error(E_MEM,"sub_vec"); else if (mem_info_is_on()) { mem_bytes(TYPE_VEC,0,sizeof(VEC)); } new->dim = i2 - i1 + 1; new->ve = &(old->ve[i1]); return new; } gtk-wave-cleaner-0.22-04/meschach/svd.c0000777000175000017500000002441413120075107020725 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* File containing routines for computing the SVD of matrices */ #include #include #include "matrix.h" #include "matrix2.h" static char rcsid[] = "$Id: svd.c,v 1.7 1995/09/08 14:45:43 des Exp $"; #define sgn(x) ((x) >= 0 ? 1 : -1) #define MAX_STACK 100 /* fixsvd -- fix minor details about SVD -- make singular values non-negative -- sort singular values in decreasing order -- variables as for bisvd() -- no argument checking */ #ifndef ANSI_C static void fixsvd(d,U,V) VEC *d; MAT *U, *V; #else static void fixsvd(VEC *d, MAT *U, MAT *V) #endif { int i, j, k, l, r, stack[MAX_STACK], sp; Real tmp, v; /* make singular values non-negative */ for ( i = 0; i < d->dim; i++ ) if ( d->ve[i] < 0.0 ) { d->ve[i] = - d->ve[i]; if ( U != MNULL ) for ( j = 0; j < U->m; j++ ) U->me[i][j] = - U->me[i][j]; } /* sort singular values */ /* nonrecursive implementation of quicksort due to R.Sedgewick, "Algorithms in C", p. 122 (1990) */ sp = -1; l = 0; r = d->dim - 1; for ( ; ; ) { while ( r > l ) { /* i = partition(d->ve,l,r) */ v = d->ve[r]; i = l - 1; j = r; for ( ; ; ) { /* inequalities are "backwards" for **decreasing** order */ while ( d->ve[++i] > v ) ; while ( d->ve[--j] < v ) ; if ( i >= j ) break; /* swap entries in d->ve */ tmp = d->ve[i]; d->ve[i] = d->ve[j]; d->ve[j] = tmp; /* swap rows of U & V as well */ if ( U != MNULL ) for ( k = 0; k < U->n; k++ ) { tmp = U->me[i][k]; U->me[i][k] = U->me[j][k]; U->me[j][k] = tmp; } if ( V != MNULL ) for ( k = 0; k < V->n; k++ ) { tmp = V->me[i][k]; V->me[i][k] = V->me[j][k]; V->me[j][k] = tmp; } } tmp = d->ve[i]; d->ve[i] = d->ve[r]; d->ve[r] = tmp; if ( U != MNULL ) for ( k = 0; k < U->n; k++ ) { tmp = U->me[i][k]; U->me[i][k] = U->me[r][k]; U->me[r][k] = tmp; } if ( V != MNULL ) for ( k = 0; k < V->n; k++ ) { tmp = V->me[i][k]; V->me[i][k] = V->me[r][k]; V->me[r][k] = tmp; } /* end i = partition(...) */ if ( i - l > r - i ) { stack[++sp] = l; stack[++sp] = i-1; l = i+1; } else { stack[++sp] = i+1; stack[++sp] = r; r = i-1; } } if ( sp < 0 ) break; r = stack[sp--]; l = stack[sp--]; } } /* bisvd -- svd of a bidiagonal m x n matrix represented by d (diagonal) and f (super-diagonals) -- returns with d set to the singular values, f zeroed -- if U, V non-NULL, the orthogonal operations are accumulated in U, V; if U, V == I on entry, then SVD == U^T.A.V where A is initial matrix -- returns d on exit */ #ifndef ANSI_C VEC *bisvd(d,f,U,V) VEC *d, *f; MAT *U, *V; #else VEC *bisvd(VEC *d, VEC *f, MAT *U, MAT *V) #endif { int i, j, n; int i_min, i_max, split; Real c, s, shift, size, z; Real d_tmp, diff, t11, t12, t22, *d_ve, *f_ve; if ( ! d || ! f ) error(E_NULL,"bisvd"); if ( d->dim != f->dim + 1 ) error(E_SIZES,"bisvd"); n = d->dim; if ( ( U && U->n < n ) || ( V && V->m < n ) ) error(E_SIZES,"bisvd"); if ( ( U && U->m != U->n ) || ( V && V->m != V->n ) ) error(E_SQUARE,"bisvd"); if ( n == 1 ) { if ( d->ve[0] < 0.0 ) { d->ve[0] = - d->ve[0]; if ( U != MNULL ) sm_mlt(-1.0,U,U); } return d; } d_ve = d->ve; f_ve = f->ve; size = v_norm_inf(d) + v_norm_inf(f); i_min = 0; while ( i_min < n ) /* outer while loop */ { /* find i_max to suit; submatrix i_min..i_max should be irreducible */ i_max = n - 1; for ( i = i_min; i < n - 1; i++ ) if ( d_ve[i] == 0.0 || f_ve[i] == 0.0 ) { i_max = i; if ( f_ve[i] != 0.0 ) { /* have to ``chase'' f[i] element out of matrix */ z = f_ve[i]; f_ve[i] = 0.0; for ( j = i; j < n-1 && z != 0.0; j++ ) { givens(d_ve[j+1],z, &c, &s); s = -s; d_ve[j+1] = c*d_ve[j+1] - s*z; if ( j+1 < n-1 ) { z = s*f_ve[j+1]; f_ve[j+1] = c*f_ve[j+1]; } if ( U ) rot_rows(U,i,j+1,c,s,U); } } break; } if ( i_max <= i_min ) { i_min = i_max + 1; continue; } /* printf("bisvd: i_min = %d, i_max = %d\n",i_min,i_max); */ split = FALSE; while ( ! split ) { /* compute shift */ t11 = d_ve[i_max-1]*d_ve[i_max-1] + (i_max > i_min+1 ? f_ve[i_max-2]*f_ve[i_max-2] : 0.0); t12 = d_ve[i_max-1]*f_ve[i_max-1]; t22 = d_ve[i_max]*d_ve[i_max] + f_ve[i_max-1]*f_ve[i_max-1]; /* use e-val of [[t11,t12],[t12,t22]] matrix closest to t22 */ diff = (t11-t22)/2; shift = t22 - t12*t12/(diff + sgn(diff)*sqrt(diff*diff+t12*t12)); /* initial Givens' rotation */ givens(d_ve[i_min]*d_ve[i_min]-shift, d_ve[i_min]*f_ve[i_min], &c, &s); /* do initial Givens' rotations */ d_tmp = c*d_ve[i_min] + s*f_ve[i_min]; f_ve[i_min] = c*f_ve[i_min] - s*d_ve[i_min]; d_ve[i_min] = d_tmp; z = s*d_ve[i_min+1]; d_ve[i_min+1] = c*d_ve[i_min+1]; if ( V ) rot_rows(V,i_min,i_min+1,c,s,V); /* 2nd Givens' rotation */ givens(d_ve[i_min],z, &c, &s); d_ve[i_min] = c*d_ve[i_min] + s*z; d_tmp = c*d_ve[i_min+1] - s*f_ve[i_min]; f_ve[i_min] = s*d_ve[i_min+1] + c*f_ve[i_min]; d_ve[i_min+1] = d_tmp; if ( i_min+1 < i_max ) { z = s*f_ve[i_min+1]; f_ve[i_min+1] = c*f_ve[i_min+1]; } if ( U ) rot_rows(U,i_min,i_min+1,c,s,U); for ( i = i_min+1; i < i_max; i++ ) { /* get Givens' rotation for zeroing z */ givens(f_ve[i-1],z, &c, &s); f_ve[i-1] = c*f_ve[i-1] + s*z; d_tmp = c*d_ve[i] + s*f_ve[i]; f_ve[i] = c*f_ve[i] - s*d_ve[i]; d_ve[i] = d_tmp; z = s*d_ve[i+1]; d_ve[i+1] = c*d_ve[i+1]; if ( V ) rot_rows(V,i,i+1,c,s,V); /* get 2nd Givens' rotation */ givens(d_ve[i],z, &c, &s); d_ve[i] = c*d_ve[i] + s*z; d_tmp = c*d_ve[i+1] - s*f_ve[i]; f_ve[i] = c*f_ve[i] + s*d_ve[i+1]; d_ve[i+1] = d_tmp; if ( i+1 < i_max ) { z = s*f_ve[i+1]; f_ve[i+1] = c*f_ve[i+1]; } if ( U ) rot_rows(U,i,i+1,c,s,U); } /* should matrix be split? */ for ( i = i_min; i < i_max; i++ ) if ( fabs(f_ve[i]) < MACHEPS*(fabs(d_ve[i])+fabs(d_ve[i+1])) ) { split = TRUE; f_ve[i] = 0.0; } else if ( fabs(d_ve[i]) < MACHEPS*size ) { split = TRUE; d_ve[i] = 0.0; } /* printf("bisvd: d =\n"); v_output(d); */ /* printf("bisvd: f = \n"); v_output(f); */ } } fixsvd(d,U,V); return d; } /* bifactor -- perform preliminary factorisation for bisvd -- updates U and/or V, which ever is not NULL */ #ifndef ANSI_C MAT *bifactor(A,U,V) MAT *A, *U, *V; #else MAT *bifactor(MAT *A, MAT *U, MAT *V) #endif { int k; STATIC VEC *tmp1=VNULL, *tmp2=VNULL, *w=VNULL; Real beta; if ( ! A ) error(E_NULL,"bifactor"); if ( ( U && ( U->m != U->n ) ) || ( V && ( V->m != V->n ) ) ) error(E_SQUARE,"bifactor"); if ( ( U && U->m != A->m ) || ( V && V->m != A->n ) ) error(E_SIZES,"bifactor"); tmp1 = v_resize(tmp1,A->m); tmp2 = v_resize(tmp2,A->n); w = v_resize(w, max(A->m,A->n)); MEM_STAT_REG(tmp1,TYPE_VEC); MEM_STAT_REG(tmp2,TYPE_VEC); MEM_STAT_REG(w, TYPE_VEC); if ( A->m >= A->n ) for ( k = 0; k < A->n; k++ ) { get_col(A,k,tmp1); hhvec(tmp1,k,&beta,tmp1,&(A->me[k][k])); _hhtrcols(A,k,k+1,tmp1,beta,w); if ( U ) _hhtrcols(U,k,0,tmp1,beta,w); if ( k+1 >= A->n ) continue; get_row(A,k,tmp2); hhvec(tmp2,k+1,&beta,tmp2,&(A->me[k][k+1])); hhtrrows(A,k+1,k+1,tmp2,beta); if ( V ) _hhtrcols(V,k+1,0,tmp2,beta,w); } else for ( k = 0; k < A->m; k++ ) { get_row(A,k,tmp2); hhvec(tmp2,k,&beta,tmp2,&(A->me[k][k])); hhtrrows(A,k+1,k,tmp2,beta); if ( V ) _hhtrcols(V,k,0,tmp2,beta,w); if ( k+1 >= A->m ) continue; get_col(A,k,tmp1); hhvec(tmp1,k+1,&beta,tmp1,&(A->me[k+1][k])); _hhtrcols(A,k+1,k+1,tmp1,beta,w); if ( U ) _hhtrcols(U,k+1,0,tmp1,beta,w); } #ifdef THREADSAFE V_FREE(tmp1); V_FREE(tmp2); #endif return A; } /* svd -- returns vector of singular values in d -- also updates U and/or V, if one or the other is non-NULL -- destroys A */ #ifndef ANSI_C VEC *svd(A,U,V,d) MAT *A, *U, *V; VEC *d; #else VEC *svd(MAT *A, MAT *U, MAT *V, VEC *d) #endif { STATIC VEC *f=VNULL; int i, limit; MAT *A_tmp; if ( ! A ) error(E_NULL,"svd"); if ( ( U && ( U->m != U->n ) ) || ( V && ( V->m != V->n ) ) ) error(E_SQUARE,"svd"); if ( ( U && U->m != A->m ) || ( V && V->m != A->n ) ) error(E_SIZES,"svd"); A_tmp = m_copy(A,MNULL); if ( U != MNULL ) m_ident(U); if ( V != MNULL ) m_ident(V); limit = min(A_tmp->m,A_tmp->n); d = v_resize(d,limit); f = v_resize(f,limit-1); MEM_STAT_REG(f,TYPE_VEC); bifactor(A_tmp,U,V); if ( A_tmp->m >= A_tmp->n ) for ( i = 0; i < limit; i++ ) { d->ve[i] = A_tmp->me[i][i]; if ( i+1 < limit ) f->ve[i] = A_tmp->me[i][i+1]; } else for ( i = 0; i < limit; i++ ) { d->ve[i] = A_tmp->me[i][i]; if ( i+1 < limit ) f->ve[i] = A_tmp->me[i+1][i]; } if ( A_tmp->m >= A_tmp->n ) bisvd(d,f,U,V); else bisvd(d,f,V,U); M_FREE(A_tmp); #ifdef THREADSAFE V_FREE(f); #endif return d; } gtk-wave-cleaner-0.22-04/meschach/symmeig.c0000777000175000017500000001412513120075107021601 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* File containing routines for symmetric eigenvalue problems */ #include #include #include "matrix.h" #include "matrix2.h" static char rcsid[] = "$Id: symmeig.c,v 1.6 1995/03/27 15:45:55 des Exp $"; #define SQRT2 1.4142135623730949 #define sgn(x) ( (x) >= 0 ? 1 : -1 ) /* trieig -- finds eigenvalues of symmetric tridiagonal matrices -- matrix represented by a pair of vectors a (diag entries) and b (sub- & super-diag entries) -- eigenvalues in a on return */ #ifndef ANSI_C VEC *trieig(a,b,Q) VEC *a, *b; MAT *Q; #else VEC *trieig(VEC *a, VEC *b, MAT *Q) #endif { int i, i_min, i_max, n, split; Real *a_ve, *b_ve; Real b_sqr, bk, ak1, bk1, ak2, bk2, z; Real c, c2, cs, s, s2, d, mu; if ( ! a || ! b ) error(E_NULL,"trieig"); if ( a->dim != b->dim + 1 || ( Q && Q->m != a->dim ) ) error(E_SIZES,"trieig"); if ( Q && Q->m != Q->n ) error(E_SQUARE,"trieig"); n = a->dim; a_ve = a->ve; b_ve = b->ve; i_min = 0; while ( i_min < n ) /* outer while loop */ { /* find i_max to suit; submatrix i_min..i_max should be irreducible */ i_max = n-1; for ( i = i_min; i < n-1; i++ ) if ( b_ve[i] == 0.0 ) { i_max = i; break; } if ( i_max <= i_min ) { /* printf("# i_min = %d, i_max = %d\n",i_min,i_max); */ i_min = i_max + 1; continue; /* outer while loop */ } /* printf("# i_min = %d, i_max = %d\n",i_min,i_max); */ /* repeatedly perform QR method until matrix splits */ split = FALSE; while ( ! split ) /* inner while loop */ { /* find Wilkinson shift */ d = (a_ve[i_max-1] - a_ve[i_max])/2; b_sqr = b_ve[i_max-1]*b_ve[i_max-1]; mu = a_ve[i_max] - b_sqr/(d + sgn(d)*sqrt(d*d+b_sqr)); /* printf("# Wilkinson shift = %g\n",mu); */ /* initial Givens' rotation */ givens(a_ve[i_min]-mu,b_ve[i_min],&c,&s); s = -s; /* printf("# c = %g, s = %g\n",c,s); */ if ( fabs(c) < SQRT2 ) { c2 = c*c; s2 = 1-c2; } else { s2 = s*s; c2 = 1-s2; } cs = c*s; ak1 = c2*a_ve[i_min]+s2*a_ve[i_min+1]-2*cs*b_ve[i_min]; bk1 = cs*(a_ve[i_min]-a_ve[i_min+1]) + (c2-s2)*b_ve[i_min]; ak2 = s2*a_ve[i_min]+c2*a_ve[i_min+1]+2*cs*b_ve[i_min]; bk2 = ( i_min < i_max-1 ) ? c*b_ve[i_min+1] : 0.0; z = ( i_min < i_max-1 ) ? -s*b_ve[i_min+1] : 0.0; a_ve[i_min] = ak1; a_ve[i_min+1] = ak2; b_ve[i_min] = bk1; if ( i_min < i_max-1 ) b_ve[i_min+1] = bk2; if ( Q ) rot_cols(Q,i_min,i_min+1,c,-s,Q); /* printf("# z = %g\n",z); */ /* printf("# a [temp1] =\n"); v_output(a); */ /* printf("# b [temp1] =\n"); v_output(b); */ for ( i = i_min+1; i < i_max; i++ ) { /* get Givens' rotation for sub-block -- k == i-1 */ givens(b_ve[i-1],z,&c,&s); s = -s; /* printf("# c = %g, s = %g\n",c,s); */ /* perform Givens' rotation on sub-block */ if ( fabs(c) < SQRT2 ) { c2 = c*c; s2 = 1-c2; } else { s2 = s*s; c2 = 1-s2; } cs = c*s; bk = c*b_ve[i-1] - s*z; ak1 = c2*a_ve[i]+s2*a_ve[i+1]-2*cs*b_ve[i]; bk1 = cs*(a_ve[i]-a_ve[i+1]) + (c2-s2)*b_ve[i]; ak2 = s2*a_ve[i]+c2*a_ve[i+1]+2*cs*b_ve[i]; bk2 = ( i+1 < i_max ) ? c*b_ve[i+1] : 0.0; z = ( i+1 < i_max ) ? -s*b_ve[i+1] : 0.0; a_ve[i] = ak1; a_ve[i+1] = ak2; b_ve[i] = bk1; if ( i < i_max-1 ) b_ve[i+1] = bk2; if ( i > i_min ) b_ve[i-1] = bk; if ( Q ) rot_cols(Q,i,i+1,c,-s,Q); /* printf("# a [temp2] =\n"); v_output(a); */ /* printf("# b [temp2] =\n"); v_output(b); */ } /* test to see if matrix should be split */ for ( i = i_min; i < i_max; i++ ) if ( fabs(b_ve[i]) < MACHEPS* (fabs(a_ve[i])+fabs(a_ve[i+1])) ) { b_ve[i] = 0.0; split = TRUE; } /* printf("# a =\n"); v_output(a); */ /* printf("# b =\n"); v_output(b); */ } } return a; } /* symmeig -- computes eigenvalues of a dense symmetric matrix -- A **must** be symmetric on entry -- eigenvalues stored in out -- Q contains orthogonal matrix of eigenvectors -- returns vector of eigenvalues */ #ifndef ANSI_C VEC *symmeig(A,Q,out) MAT *A, *Q; VEC *out; #else VEC *symmeig(const MAT *A, MAT *Q, VEC *out) #endif { int i; STATIC MAT *tmp = MNULL; STATIC VEC *b = VNULL, *diag = VNULL, *beta = VNULL; if ( ! A ) error(E_NULL,"symmeig"); if ( A->m != A->n ) error(E_SQUARE,"symmeig"); if ( ! out || out->dim != A->m ) out = v_resize(out,A->m); tmp = m_resize(tmp,A->m,A->n); tmp = m_copy(A,tmp); b = v_resize(b,A->m - 1); diag = v_resize(diag,(unsigned int)A->m); beta = v_resize(beta,(unsigned int)A->m); MEM_STAT_REG(tmp,TYPE_MAT); MEM_STAT_REG(b,TYPE_VEC); MEM_STAT_REG(diag,TYPE_VEC); MEM_STAT_REG(beta,TYPE_VEC); Hfactor(tmp,diag,beta); if ( Q ) makeHQ(tmp,diag,beta,Q); for ( i = 0; i < A->m - 1; i++ ) { out->ve[i] = tmp->me[i][i]; b->ve[i] = tmp->me[i][i+1]; } out->ve[i] = tmp->me[i][i]; trieig(out,b,Q); #ifdef THREADSAFE M_FREE(tmp); V_FREE(b); V_FREE(diag); V_FREE(beta); #endif return out; } gtk-wave-cleaner-0.22-04/meschach/tags0000777000175000017500000013362113120075107020647 0ustar00alisteralister00000000000000!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ !_TAG_PROGRAM_NAME Exuberant Ctags // !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ !_TAG_PROGRAM_VERSION 5.5.2 // ABS extras.c 200;" d file: ANON itertort.c 52;" d file: ANSI_OR_VAR memtort.c 736;" d file: ANSI_OR_VAR memtort.c 740;" d file: ASYM itertort.c 53;" d file: BKPfactor bkpfacto.c /^MAT *BKPfactor(A,pivot,blocks)$/;" f BKPsolve bkpfacto.c /^VEC *BKPsolve(A,pivot,block,b,x)$/;" f CHfactor chfactor.c /^MAT *CHfactor(A)$/;" f CHsolve chfactor.c /^VEC *CHsolve(A,b,x)$/;" f COL torture.c 700;" d file: DIM mfuntort.c 40;" d file: Dsolve solve.c /^VEC *Dsolve(A,b,x)$/;" f Dv_mlt itertort.c /^VEC *Dv_mlt(d, x, out)$/;" f EF_ABORT err.c 53;" d file: EF_EXIT err.c 52;" d file: EF_JUMP err.c 54;" d file: EF_SILENT err.c 55;" d file: EPS itertort.c 45;" d file: EPS itertort.c 48;" d file: EPS sptort.c 43;" d file: EPS sptort.c 45;" d file: E_SIGNAL err.c 58;" d file: Err_list err.c /^} Err_list;$/;" t file: FAC init.c 243;" d file: FALSE err.c 49;" d file: FOO_1 memtort.c /^} FOO_1;$/;" t file: FOO_2 memtort.c /^} FOO_2;$/;" t file: FOO_LIST memtort.c 49;" d file: FOO_NUM_TYPES memtort.c 158;" d file: Hfactor hessen.c /^MAT *Hfactor(A, diag, beta)$/;" f KK itertort.c 46;" d file: KK itertort.c 49;" d file: LDIAG torture.c 702;" d file: LDLfactor chfactor.c /^MAT *LDLfactor(A)$/;" f LDLsolve chfactor.c /^VEC *LDLsolve(LDL,b,x)$/;" f LDLupdate update.c /^MAT *LDLupdate(CHmat,w,alpha)$/;" f LTsolve solve.c /^VEC *LTsolve(L,b,out,diag)$/;" f LUTsolve lufactor.c /^VEC *LUTsolve(LU,pivot,b,x)$/;" f LUcondest lufactor.c /^double LUcondest(LU,pivot)$/;" f LUfactor lufactor.c /^MAT *LUfactor(A,pivot)$/;" f LUsolve lufactor.c /^VEC *LUsolve(LU,pivot,b,x)$/;" f Lsolve solve.c /^VEC *Lsolve(matrix,b,out,diag)$/;" f M3D_LIST tutadv.c 6;" d file: M3D_NUM tutadv.c 129;" d file: MAT3D tutadv.c /^} MAT3D;$/;" t file: MATLAB_NAME torture.c 92;" d file: MATLAB_NAME ztorture.c 87;" d file: MAXERR err.c 86;" d file: MAXWARN err.c 96;" d file: MAX_ERRS err.c 100;" d file: MAX_STACK ivecop.c 245;" d file: MAX_STACK svd.c 42;" d file: MAX_STACK vecop.c 508;" d file: MAX_TEST_ERR torture.c 48;" d file: MCHfactor chfactor.c /^MAT *MCHfactor(A,tol)$/;" f MEMCHK torture.c 54;" d file: MEMCHK ztorture.c 47;" d file: MEM_COPY extras.c /^void MEM_COPY(from,to,len)$/;" f MEM_NUM_STD_TYPES meminfo.c 70;" d file: MEM_STAT_STRUCT memstat.c /^} MEM_STAT_STRUCT;$/;" t file: MEM_ZERO extras.c /^void MEM_ZERO(ptr,len)$/;" f MINROWLEN sparse.c 39;" d file: MINROWLEN sprow.c 39;" d file: MINSCRATCH sparseio.c 187;" d file: MODULUS init.c 154;" d file: MODULUS init.c 156;" d file: MODULUS init.c 241;" d file: MTX_FN conjgrad.c /^typedef VEC *(*MTX_FN)();$/;" t file: MZ init.c 158;" d file: MZ init.c 242;" d file: Maxpy extras.c /^void Maxpy(len,alpha,x,y)$/;" f Mcopy extras.c /^void Mcopy(len,x,y)$/;" f Mdot extras.c /^double Mdot(len,x,y)$/;" f Mmm extras.c /^void Mmm(m,n,p,alpha,A,Aj0,B,Bj0,C,Cj0)$/;" f Mmmtr extras.c /^void Mmmtr(m,n,p,alpha,A,Aj0,B,Bj0,C,Cj0)$/;" f Mmtrm extras.c /^void Mmtrm(m,n,p,alpha,A,Aj0,B,Bj0,C,Cj0)$/;" f Mmtrmtr extras.c /^void Mmtrmtr(m,n,p,alpha,A,Aj0,B,Bj0,C,Cj0)$/;" f Mmv extras.c /^void Mmv(m,n,alpha,A,j0,x,beta,y)$/;" f Mnorm1 extras.c /^double Mnorm1(len,x)$/;" f Mnorm2 extras.c /^double Mnorm2(len,x)$/;" f Mnorminf extras.c /^double Mnorminf(len,x)$/;" f Mscale extras.c /^void Mscale(len,alpha,x)$/;" f Mswap extras.c /^void Mswap(len,x,y)$/;" f Mupdate extras.c /^void Mupdate(m,n,alpha,x,y,A,j0)$/;" f Mvm extras.c /^void Mvm(m,n,alpha,A,j0,x,beta,y)$/;" f N tutorial.c 202;" d file: PI tutorial.c 205;" d file: QRCPfactor qrfactor.c /^MAT *QRCPfactor(A,diag,px)$/;" f QRCPsolve qrfactor.c /^VEC *QRCPsolve(QR,diag,pivot,b,x)$/;" f QRTsolve qrfactor.c /^VEC *QRTsolve(A,diag,c,sc)$/;" f QRcondest qrfactor.c /^double QRcondest(QR)$/;" f QRfactor qrfactor.c /^MAT *QRfactor(A,diag)$/;" f QRsolve qrfactor.c /^VEC *QRsolve(QR,diag,b,x)$/;" f QRupdate update.c /^MAT *QRupdate(Q,R,u,v)$/;" f REGISTER_RICH extras.c 90;" d file: SAVE_FILE torture.c 91;" d file: SAVE_FILE ztorture.c 86;" d file: SQRT2 symmeig.c 41;" d file: TRUE err.c 50;" d file: TYPE_FOO_1 memtort.c 52;" d file: TYPE_FOO_2 memtort.c 53;" d file: TYPE_MAT3D tutadv.c 7;" d file: UDIAG torture.c 701;" d file: UTmlt qrfactor.c /^static VEC *UTmlt(U,x,out)$/;" f file: UTsolve solve.c /^VEC *UTsolve(U,b,out,diag)$/;" f Umlt qrfactor.c /^static VEC *Umlt(U,x,out)$/;" f file: Usolve solve.c /^VEC *Usolve(matrix,b,out,diag)$/;" f VEC2MAT tutorial.c 203;" d file: Z mfunc.c 292;" d file: Z mfunc.c 315;" d file: Z mfunc.c 392;" d file: Z mfunc.c 59;" d file: Z mfunc.c 98;" d file: ZZ mfunc.c 393;" d file: _Qsolve qrfactor.c /^VEC *_Qsolve(QR,diag,b,x,tmp)$/;" f __add__ machine.c /^void __add__(dp1,dp2,out,len)$/;" f __ip__ machine.c /^double __ip__(dp1,dp2,len)$/;" f __mltadd__ machine.c /^void __mltadd__(dp1,dp2,s,len)$/;" f __smlt__ machine.c /^void __smlt__(dp,s,out,len)$/;" f __sub__ machine.c /^void __sub__(dp1,dp2,out,len)$/;" f __zadd__ zmachine.c /^void __zadd__(zp1,zp2,out,len)$/;" f __zconj__ zmachine.c /^void __zconj__(zp,len)$/;" f __zero__ machine.c /^void __zero__(dp,len)$/;" f __zip__ zmachine.c /^complex __zip__(zp1,zp2,len,flag)$/;" f __zmlt__ zmachine.c /^void __zmlt__(zp,s,out,len)$/;" f __zmltadd__ zmachine.c /^void __zmltadd__(zp1,zp2,s,len,flag)$/;" f __zsub__ zmachine.c /^void __zsub__(zp1,zp2,out,len)$/;" f __zzero__ zmachine.c /^void __zzero__(zp,len)$/;" f _hhtrcols hsehldr.c /^MAT *_hhtrcols(M,i0,j0,hh,beta,w)$/;" f _in_prod vecop.c /^double _in_prod(a,b,i0)$/;" f _m_copy copy.c /^MAT *_m_copy(in,out,i0,j0)$/;" f _m_exp mfunc.c /^MAT *_m_exp(A,eps,out,q_out,j_out)$/;" f _m_pow mfunc.c /^MAT *_m_pow(A, p, tmp, out)$/;" f _set_col submat.c /^MAT *_set_col(mat,col,vec,i0)$/;" f _set_row submat.c /^MAT *_set_row(mat,row,vec,j0)$/;" f _v_copy copy.c /^VEC *_v_copy(in,out,i0)$/;" f _v_map vecop.c /^VEC *_v_map(f,params,x,out)$/;" f _v_norm1 norm.c /^double _v_norm1(x,scale)$/;" f _v_norm2 norm.c /^double _v_norm2(x,scale)$/;" f _v_norm_inf norm.c /^double _v_norm_inf(x,scale)$/;" f _zQsolve zqrfctr.c /^ZVEC *_zQsolve(QR,diag,b,x,tmp)$/;" f _zhhtrcols zhsehldr.c /^ZMAT *_zhhtrcols(M,i0,j0,hh,beta,w)$/;" f _zin_prod zvecop.c /^complex _zin_prod(a,b,i0,flag)$/;" f _zm_copy zcopy.c /^ZMAT *_zm_copy(in,out,i0,j0)$/;" f _zv_copy zcopy.c /^ZVEC *_zv_copy(in,out,i0)$/;" f _zv_map zvecop.c /^ZVEC *_zv_map(f,params,x,out)$/;" f _zv_norm1 znorm.c /^double _zv_norm1(x,scale)$/;" f _zv_norm2 znorm.c /^double _zv_norm2(x,scale)$/;" f _zv_norm_inf znorm.c /^double _zv_norm_inf(x,scale)$/;" f a memtort.c /^ Real (*a)[10];$/;" m file: a memtort.c /^ Real (*a)[2];$/;" m file: alpha bkpfacto.c 42;" d file: alpha spbkp.c 45;" d file: arnoldi arnoldi.c /^MAT *arnoldi(A,A_param,x0,m,h_rem,Q,H)$/;" f b2s zschur.c 42;" d file: band2mat bdfactor.c /^MAT *band2mat(bA,A)$/;" f base tutadv.c /^ Real *base, **me2d; \/* me and me2d are additional pointers $/;" m file: bdLDLfactor bdfactor.c /^BAND *bdLDLfactor(A)$/;" f bdLDLsolve bdfactor.c /^VEC *bdLDLsolve(A,b,x)$/;" f bdLUfactor bdfactor.c /^BAND *bdLUfactor(bA,pivot)$/;" f bdLUsolve bdfactor.c /^VEC *bdLUsolve(bA,pivot,b,x)$/;" f bd_copy bdfactor.c /^BAND *bd_copy(A,B)$/;" f bd_free bdfactor.c /^int bd_free(A)$/;" f bd_get bdfactor.c /^BAND *bd_get(lb,ub,n)$/;" f bd_mv_mlt bdfactor.c /^VEC *bd_mv_mlt(A, x, out)$/;" f bd_resize bdfactor.c /^BAND *bd_resize(A,new_lb,new_ub,new_n)$/;" f bd_transp bdfactor.c /^BAND *bd_transp(in,out)$/;" f bd_zero bdfactor.c /^BAND *bd_zero(A)$/;" f bds_mltadd bdfactor.c /^BAND *bds_mltadd(A,B,alpha,OUT)$/;" f bdv_mltadd bdfactor.c /^VEC *bdv_mltadd(x,y,bA,s,out)$/;" f bfin_vec matrixio.c /^VEC *bfin_vec(fp,vec)$/;" f bifactor svd.c /^MAT *bifactor(A,U,V)$/;" f bisvd svd.c /^VEC *bisvd(d,f,U,V)$/;" f biv_finput matrixio.c /^IVEC *biv_finput(fp,iv)$/;" f bkp_bump_col spbkp.c /^row_elt *bkp_bump_col(A, j, row, idx)$/;" f bkp_interchange spbkp.c /^SPMAT *bkp_interchange(A, i1, i2)$/;" f bkp_swap_elt spbkp.c /^static SPMAT *bkp_swap_elt(A,i1,j1,idx1,i2,j2,idx2)$/;" f file: bm_finput matrixio.c /^MAT *bm_finput(fp,mat)$/;" f bpx_finput matrixio.c /^PERM *bpx_finput(fp,px)$/;" f btos bkpfacto.c 38;" d file: btos spbkp.c 48;" d file: btos spswap.c 40;" d file: bump_col spswap.c /^row_elt *bump_col(A, col, row_num, idx)$/;" f bzm_finput zmatio.c /^ZMAT *bzm_finput(fp,mat)$/;" f bzv_finput zmatio.c /^ZVEC *bzv_finput(fp,vec)$/;" f catch_FPE err.c /^void catch_FPE()$/;" f cg_num_iters conjgrad.c /^int cg_num_iters;$/;" v cg_set_maxiter conjgrad.c /^int cg_set_maxiter(numiter)$/;" f cgs conjgrad.c /^VEC *cgs(A,A_params,b,r0,tol,x)$/;" f chase_col spswap.c /^row_elt *chase_col(A, col, row_num, idx, max_row)$/;" f chase_past spswap.c /^row_elt *chase_past(A, col, row_num, idx, min_row)$/;" f checkpt ztorture.c 49;" d file: chk_col_access spbkp.c /^int chk_col_access(A)$/;" f chk_col_accessSPT sptort.c /^int chk_col_accessSPT(A)$/;" f cmp_perm torture.c /^int cmp_perm(pi1, pi2)$/;" f cmp_perm ztorture.c /^int cmp_perm(pi1, pi2)$/;" f cnt_errs err.c /^static int err_flag = EF_EXIT, num_errs = 0, cnt_errs = 1;$/;" v file: col_cmp spbkp.c /^static int col_cmp(e1,e2)$/;" f file: col_list spchfctr.c /^ *col_list = (int *)NULL;$/;" v file: comp_AAT spchfctr.c /^SPMAT *comp_AAT(A)$/;" f count_errs err.c /^int count_errs(flag)$/;" f cube norm.c /^double cube(x)$/;" f d_save matlab.c /^double d_save(fp,x,name)$/;" f dbl_cmp itersym.c /^static int dbl_cmp(x,y)$/;" f file: dbl_cmp lanczos.c /^static int dbl_cmp(x,y)$/;" f file: dclean dmacheps.c /^double dclean(x)$/;" f dim memtort.c /^ int dim;$/;" m file: dim memtort.c /^ int dim;$/;" m file: err_flag err.c /^static int err_flag = EF_EXIT, num_errs = 0, cnt_errs = 1;$/;" v file: err_is_list_attached err.c /^int err_is_list_attached(list_num)$/;" f err_list err.c /^static Err_list err_list[ERR_LIST_MAX_LEN] = {$/;" v file: err_list_attach err.c /^int err_list_attach(list_num, list_len,err_ptr,warn)$/;" f err_list_end err.c /^static int err_list_end = 2; \/* number of elements in err_list *\/$/;" v file: err_list_free err.c /^int err_list_free(list_num)$/;" f err_mesg err.c /^static char *err_mesg[] =$/;" v file: errmesg iotort.c 36;" d file: errmesg itertort.c 39;" d file: errmesg memtort.c 40;" d file: errmesg mfuntort.c 37;" d file: errmesg sptort.c 37;" d file: errmesg torture.c 38;" d file: errmesg ztorture.c 40;" d file: ev_err err.c /^int ev_err(file,err_num,line_num,fn_name,list_num)$/;" f ex_sol itertort.c /^static VEC *ex_sol = VNULL;$/;" v file: f tutorial.c /^VEC *f(t,x,out)$/;" f f1 tutorial.c /^double f1(x,y)$/;" f fclean fmacheps.c /^double fclean(x)$/;" f fft fft.c /^void fft(x_re,x_im)$/;" f fin_double otherio.c /^double fin_double(fp,s,low,high)$/;" f fin_int otherio.c /^int fin_int(fp,s,low,high)$/;" f fix_dim memtort.c /^ int fix_dim;$/;" m file: fix_dim memtort.c /^ int fix_dim;$/;" m file: fixsvd svd.c /^static void fixsvd(d,U,V)$/;" f file: float_error err.c /^static void float_error(num)$/;" f file: fname memstat.c /^ char *fname; \/* source file name where last registered *\/$/;" m file: foo_1_free memtort.c /^int foo_1_free(f)$/;" f foo_1_get memtort.c /^FOO_1 *foo_1_get(dim)$/;" f foo_2_free memtort.c /^int foo_2_free(f)$/;" f foo_2_get memtort.c /^FOO_2 *foo_2_get(dim)$/;" f foo_free_func memtort.c /^int (*foo_free_func[FOO_NUM_TYPES])() = {$/;" v foo_info_sum memtort.c /^static MEM_ARRAY foo_info_sum[FOO_NUM_TYPES];$/;" v file: foo_type_name memtort.c /^char *foo_type_name[] = {$/;" v format matrixio.c /^static const char *format = "%14.9g ";$/;" v file: fy_or_n otherio.c /^int fy_or_n(fp,s)$/;" f gen_non_symm memtort.c /^SPMAT *gen_non_symm(m,n)$/;" f gen_sym_precond itertort.c /^SPMAT *gen_sym_precond(A)$/;" f get_col submat.c /^VEC *get_col(mat,col,vec)$/;" f get_row submat.c /^VEC *get_row(mat,row,vec)$/;" f givens givens.c /^void givens(x,y,c,s)$/;" f gmres arnoldi.c /^VEC *gmres(A,A_param,m,Q,R,b,tol,x)$/;" f hhldr3 schur.c /^static void hhldr3(x,y,z,nu1,beta,newval)$/;" f file: hhldr3cols schur.c /^static void hhldr3cols(A,k,j0,beta,nu1,nu2,nu3)$/;" f file: hhldr3rows schur.c /^static void hhldr3rows(A,k,i0,beta,nu1,nu2,nu3)$/;" f file: hhtrcols hsehldr.c /^MAT *hhtrcols(M,i0,j0,hh,beta)$/;" f hhtrrows hsehldr.c /^MAT *hhtrrows(M,i0,j0,hh,beta)$/;" f hhtrvec hsehldr.c /^VEC *hhtrvec(hh,beta,i0,in,out)$/;" f hhvec hsehldr.c /^VEC *hhvec(vec,i0,beta,out,newval)$/;" f ifft fft.c /^void ifft(x_re,x_im)$/;" f ifin_vec matrixio.c /^VEC *ifin_vec(fp,vec)$/;" f iiv_finput matrixio.c /^IVEC *iiv_finput(fp,iv)$/;" f im_finput matrixio.c /^MAT *im_finput(fp,mat)$/;" f index tutorial.c 206;" d file: inext init.c /^static int inext = 0, inextp = 31;$/;" v file: inextp init.c /^static int inext = 0, inextp = 31;$/;" v file: interchange bkpfacto.c /^static void interchange(A,i,j)$/;" f file: ipx_finput matrixio.c /^PERM *ipx_finput(fp,px)$/;" f is_zero zhsehldr.c 44;" d file: is_zero zlufctr.c 38;" d file: is_zero zmatop.c 34;" d file: is_zero zqrfctr.c 49;" d file: is_zero zschur.c 41;" d file: is_zero zsolve.c 39;" d file: iter_arnoldi iternsym.c /^MAT *iter_arnoldi(ip,h_rem,Q,H)$/;" f iter_arnoldi_iref iternsym.c /^MAT *iter_arnoldi_iref(ip,h_rem,Q,H)$/;" f iter_cg itersym.c /^VEC *iter_cg(ip)$/;" f iter_cg1 itersym.c /^VEC *iter_cg1(ip)$/;" f iter_cgne iternsym.c /^VEC *iter_cgne(ip)$/;" f iter_cgs iternsym.c /^VEC *iter_cgs(ip,r0)$/;" f iter_copy iter0.c /^ITER *iter_copy(ip1,ip2)$/;" f iter_copy2 iter0.c /^ITER *iter_copy2(ip1,ip2)$/;" f iter_dump iter0.c /^void iter_dump(fp,ip)$/;" f iter_free iter0.c /^int iter_free(ip)$/;" f iter_gen_nonsym iter0.c /^SPMAT *iter_gen_nonsym(m,n,nrow,diag)$/;" f iter_gen_nonsym_posdef iter0.c /^SPMAT *iter_gen_nonsym_posdef(n,nrow)$/;" f iter_gen_sym iter0.c /^SPMAT *iter_gen_sym(n,nrow)$/;" f iter_get iter0.c /^ITER *iter_get(lenb, lenx)$/;" f iter_gmres iternsym.c /^VEC *iter_gmres(ip)$/;" f iter_lanczos itersym.c /^void iter_lanczos(ip,a,b,beta2,Q)$/;" f iter_lanczos2 itersym.c /^VEC *iter_lanczos2(ip,evals,err_est)$/;" f iter_lsqr iternsym.c /^VEC *iter_lsqr(ip)$/;" f iter_mgcr iternsym.c /^VEC *iter_mgcr(ip)$/;" f iter_mod_info itertort.c /^void iter_mod_info(ip,nres,res,Bres)$/;" f iter_resize iter0.c /^ITER *iter_resize(ip,new_lenb,new_lenx)$/;" f iter_sparnoldi iternsym.c /^MAT *iter_sparnoldi(A,x0,m,h_rem,Q,H)$/;" f iter_spcg itersym.c /^VEC *iter_spcg(A,LLT,b,eps,x,limit,steps)$/;" f iter_spcgne iternsym.c /^VEC *iter_spcgne(A,B,b,eps,x,limit,steps)$/;" f iter_spcgs iternsym.c /^VEC *iter_spcgs(A,B,b,r0,tol,x,limit,steps)$/;" f iter_spgmres iternsym.c /^VEC *iter_spgmres(A,B,b,tol,x,k,limit,steps)$/;" f iter_splanczos itersym.c /^void iter_splanczos(A,m,x0,a,b,beta2,Q)$/;" f iter_splanczos2 itersym.c /^VEC *iter_splanczos2(A,m,x0,evals,err_est)$/;" f iter_splsqr iternsym.c /^VEC *iter_splsqr(A,b,tol,x,limit,steps)$/;" f iter_spmgcr iternsym.c /^VEC *iter_spmgcr(A,B,b,tol,x,k,limit,steps)$/;" f iter_std_info iter0.c /^void iter_std_info(ip,nres,res,Bres)$/;" f iter_std_stop_crit iter0.c /^int iter_std_stop_crit(ip, nres, res, Bres)$/;" f iv_add ivecop.c /^IVEC *iv_add(iv1,iv2,out)$/;" f iv_copy ivecop.c /^IVEC *iv_copy(in,out)$/;" f iv_dump matrixio.c /^void iv_dump(fp,iv)$/;" f iv_finput matrixio.c /^IVEC *iv_finput(fp,x)$/;" f iv_foutput matrixio.c /^void iv_foutput(fp,iv)$/;" f iv_free ivecop.c /^int iv_free(iv)$/;" f iv_free_vars memory.c /^int iv_free_vars(IVEC **ipv,...)$/;" f iv_free_vars memory.c /^int iv_free_vars(va_alist) va_dcl$/;" f iv_get ivecop.c /^IVEC *iv_get(dim)$/;" f iv_get_vars memory.c /^int iv_get_vars(int dim,...) $/;" f iv_get_vars memory.c /^int iv_get_vars(va_alist) va_dcl$/;" f iv_min spbkp.c /^int iv_min(iv,index)$/;" f iv_move ivecop.c /^IVEC *iv_move(in,i0,dim0,out,i1)$/;" f iv_resize ivecop.c /^IVEC *iv_resize(iv,new_dim)$/;" f iv_resize_vars memory.c /^int iv_resize_vars(int new_dim,...) $/;" f iv_resize_vars memory.c /^int iv_resize_vars(va_alist) va_dcl$/;" f iv_sort ivecop.c /^IVEC *iv_sort(x, order)$/;" f iv_sub ivecop.c /^IVEC *iv_sub(iv1,iv2,out)$/;" f iv_zero init.c /^IVEC *iv_zero(ix)$/;" f izm_finput zmatio.c /^ZMAT *izm_finput(fp,mat)$/;" f izv_finput zmatio.c /^ZVEC *izv_finput(fp,vec)$/;" f l tutadv.c /^ int l,m,n; \/* actual dimensions *\/$/;" m file: lanczos lanczos.c /^void lanczos(A_fn,A_params,m,x0,a,b,beta2,Q)$/;" f lanczos2 lanczos.c /^VEC *lanczos2(A_fn,A_params,m,x0,evals,err_est)$/;" f laplacian tutorial.c /^SPMAT *laplacian(A)$/;" f len err.c /^ unsigned len; \/* length of the list *\/$/;" m file: line ivecop.c /^static char line[MAXLINE];$/;" v file: line matrixio.c /^static char line[MAXLINE];$/;" v file: line memstat.c /^ int line; \/* line # of file where last registered *\/$/;" m file: line sparseio.c /^static char line[MAXLINE];$/;" v file: line zmatio.c /^static char line[MAXLINE];$/;" v file: listp err.c /^ char **listp; \/* pointer to a list of errors *\/$/;" m file: lsqr conjgrad.c /^VEC *lsqr(A,AT,A_params,b,tol,x)$/;" f m tutadv.c /^ int l,m,n; \/* actual dimensions *\/$/;" m file: m3d_free tutadv.c /^int m3d_free(mat)$/;" f m3d_free_funcs tutadv.c /^int (*m3d_free_funcs[M3D_NUM])() = {$/;" v m3d_get tutadv.c /^MAT3D *m3d_get(l,m,n)$/;" f m3d_names tutadv.c /^char *m3d_names[] = {$/;" v m3d_sum tutadv.c /^static MEM_ARRAY m3d_sum[M3D_NUM];$/;" v file: m_add matop.c /^MAT *m_add(mat1,mat2,out)$/;" f m_dump matrixio.c /^void m_dump(fp,a)$/;" f m_exp mfunc.c /^MAT *m_exp(A,eps,out)$/;" f m_finput matrixio.c /^MAT *m_finput(fp,a)$/;" f m_foutput matrixio.c /^void m_foutput(fp,a)$/;" f m_free memory.c /^int m_free(mat)$/;" f m_free_vars memory.c /^int m_free_vars(MAT **va,...)$/;" f m_free_vars memory.c /^int m_free_vars(va_alist) va_dcl$/;" f m_get memory.c /^MAT *m_get(m,n)$/;" f m_get_vars memory.c /^int m_get_vars(int m,int n,...) $/;" f m_get_vars memory.c /^int m_get_vars(va_alist) va_dcl$/;" f m_ident init.c /^MAT *m_ident(A)$/;" f m_inverse lufactor.c /^MAT *m_inverse(A,out)$/;" f m_load matlab.c /^MAT *m_load(fp,name)$/;" f m_mlt matop.c /^MAT *m_mlt(A,B,OUT)$/;" f m_move copy.c /^MAT *m_move(in,i0,j0,m0,n0,out,i1,j1)$/;" f m_norm1 norm.c /^double m_norm1(A)$/;" f m_norm_frob norm.c /^double m_norm_frob(A)$/;" f m_norm_inf norm.c /^double m_norm_inf(A)$/;" f m_ones init.c /^MAT *m_ones(A)$/;" f m_poly mfunc.c /^MAT *m_poly(A,a,out)$/;" f m_pow mfunc.c /^MAT *m_pow(A, p, out)$/;" f m_rand init.c /^MAT *m_rand(A)$/;" f m_resize memory.c /^MAT *m_resize(A,new_m,new_n)$/;" f m_resize_vars memory.c /^int m_resize_vars(int m,int n,...) $/;" f m_resize_vars memory.c /^int m_resize_vars(va_alist) va_dcl$/;" f m_save matlab.c /^MAT *m_save(fp,A,name)$/;" f m_sub matop.c /^MAT *m_sub(mat1,mat2,out)$/;" f m_transp matop.c /^MAT *m_transp(in,out)$/;" f m_version version.c /^void m_version()$/;" f m_zero init.c /^MAT *m_zero(A)$/;" f main dmacheps.c /^main()$/;" f main fmacheps.c /^main()$/;" f main iotort.c /^void main()$/;" f main itertort.c /^void main(argc, argv)$/;" f main maxint.c /^main()$/;" f main memtort.c /^void main(argc, argv)$/;" f main mfuntort.c /^void main()$/;" f main sptort.c /^void main(argc, argv)$/;" f main torture.c /^int main(argc, argv)$/;" f main tutadv.c /^void main()$/;" f main tutorial.c /^void main()$/;" f main ztorture.c /^void main(argc, argv)$/;" f makeH hessen.c /^MAT *makeH(H,Hout)$/;" f makeHQ hessen.c /^MAT *makeHQ(H, diag, beta, Qout)$/;" f makeQ qrfactor.c /^MAT *makeQ(QR,diag,Qout)$/;" f makeR qrfactor.c /^MAT *makeR(QR,Rout)$/;" f mark memstat.c /^ int mark; \/* what mark is chosen *\/$/;" m file: mat2band bdfactor.c /^BAND *mat2band(A,lb,ub,bA)$/;" f max norm.c 116;" d file: max znorm.c 105;" d file: max_iter conjgrad.c /^static int max_iter = 10000;$/;" v file: max_l tutadv.c /^ int max_l, max_m, max_n; \/* maximal dimensions *\/$/;" m file: max_m tutadv.c /^ int max_l, max_m, max_n; \/* maximal dimensions *\/$/;" m file: max_n tutadv.c /^ int max_l, max_m, max_n; \/* maximal dimensions *\/$/;" m file: max_row_col spbkp.c /^static double max_row_col(A,i,j,l)$/;" f file: me tutadv.c /^ Real ***me; \/* pointer to matrix elements *\/$/;" m file: me2d tutadv.c /^ Real *base, **me2d; \/* me and me2d are additional pointers $/;" m file: mem_attach_list meminfo.c /^int mem_attach_list(list, ntypes, type_names, free_funcs, info_sum)$/;" f mem_bytes_list meminfo.c /^void mem_bytes_list(type,old_size,new_size,list)$/;" f mem_connect meminfo.c /^MEM_CONNECT mem_connect[MEM_CONNECT_MAX_LISTS] = {$/;" v mem_dump_list meminfo.c /^void mem_dump_list(fp,list)$/;" f mem_free_funcs meminfo.c /^static int (*mem_free_funcs[MEM_NUM_STD_TYPES])() = {$/;" v file: mem_free_vars meminfo.c /^int mem_free_vars(list)$/;" f mem_hash memstat.c /^static unsigned int mem_hash(ptr)$/;" f file: mem_hash_idx memstat.c /^static unsigned int mem_hash_idx[MEM_HASHSIZE];$/;" v file: mem_hash_idx_end memstat.c /^static unsigned int mem_hash_idx_end = 0;$/;" v file: mem_info_bytes meminfo.c /^long mem_info_bytes(type,list)$/;" f mem_info_file meminfo.c /^void mem_info_file(fp,list)$/;" f mem_info_is_on meminfo.c /^int mem_info_is_on(void)$/;" f mem_info_numvar meminfo.c /^int mem_info_numvar(type,list)$/;" f mem_info_on meminfo.c /^int mem_info_on(sw)$/;" f mem_info_sum meminfo.c /^static MEM_ARRAY mem_info_sum[MEM_NUM_STD_TYPES]; $/;" v file: mem_is_list_attached meminfo.c /^int mem_is_list_attached(list)$/;" f mem_lookup memstat.c /^static int mem_lookup(var)$/;" f file: mem_numvar_list meminfo.c /^void mem_numvar_list(type,num,list)$/;" f mem_stat_dump memstat.c /^void mem_stat_dump(fp,list)$/;" f mem_stat_free_list memstat.c /^int mem_stat_free_list(mark,list)$/;" f mem_stat_mark memstat.c /^int mem_stat_mark(mark)$/;" f mem_stat_mark_curr memstat.c /^static int mem_stat_mark_curr = 0;$/;" v file: mem_stat_mark_many memstat.c /^static int mem_stat_mark_many = 0;$/;" v file: mem_stat_reg_list memstat.c /^int mem_stat_reg_list(var,type,list,fname,line)$/;" f mem_stat_reg_vars memstat.c /^int mem_stat_reg_vars(int list,int type,char *fname,int line, ...)$/;" f mem_stat_reg_vars memstat.c /^int mem_stat_reg_vars(va_alist) va_dcl$/;" f mem_stat_show_mark memstat.c /^int mem_stat_show_mark(void)$/;" f mem_stat_var memstat.c /^static MEM_STAT_STRUCT mem_stat_var[MEM_HASHSIZE];$/;" v file: mem_switched_on meminfo.c /^static int mem_switched_on = MEM_SWITCH_ON_DEF; \/* on\/off *\/$/;" v file: mem_type_names meminfo.c /^static char *mem_type_names[] = {$/;" v file: mmtr_mlt matop.c /^MAT *mmtr_mlt(A,B,OUT)$/;" f mrand init.c /^double mrand(void)$/;" f mrand_list init.c /^static long mrand_list[56];$/;" v file: mrandlist init.c /^void mrandlist(a, len)$/;" f ms_mltadd matop.c /^MAT *ms_mltadd(A1,A2,s,out)$/;" f mtrm_mlt matop.c /^MAT *mtrm_mlt(A,B,OUT)$/;" f mv_mlt matop.c /^VEC *mv_mlt(A,b,out)$/;" f mv_mltadd matop.c /^VEC *mv_mltadd(v1,v2,A,alpha,out)$/;" f mv_move copy.c /^VEC *mv_move(in,i0,j0,m0,n0,out,i1)$/;" f myqsort pxop.c /^static int myqsort(a,num)$/;" f file: mz_mltadd zmatop.c /^ZMAT *mz_mltadd(A1,A2,s,out)$/;" f n tutadv.c /^ int l,m,n; \/* actual dimensions *\/$/;" m file: name torture.c /^char name[81] = MATLAB_NAME;$/;" v name ztorture.c /^char name[81] = MATLAB_NAME;$/;" v nonzeros spbkp.c /^static int nonzeros(A)$/;" f file: norm_equ itertort.c /^VEC *norm_equ(A,x,out)$/;" f notice iotort.c 37;" d file: notice itertort.c 40;" d file: notice memtort.c 41;" d file: notice mfuntort.c 38;" d file: notice sptort.c 38;" d file: notice torture.c 39;" d file: notice ztorture.c 41;" d file: num_errs err.c /^static int err_flag = EF_EXIT, num_errs = 0, cnt_errs = 1;$/;" v file: patch_col spswap.c /^void patch_col(A, col, old_row, old_idx, row_num, idx)$/;" f pccg conjgrad.c /^VEC *pccg(A,A_params,M_inv,M_params,b,eps,x)$/;" f product itersym.c /^static double product(a,offset,expt)$/;" f file: product lanczos.c /^static double product(a,offset,expt)$/;" f file: product2 itersym.c /^static double product2(a,k,expt)$/;" f file: product2 lanczos.c /^static double product2(a,k,expt)$/;" f file: px_cols pxop.c /^MAT *px_cols(px,A,out)$/;" f px_copy copy.c /^PERM *px_copy(in,out)$/;" f px_dump matrixio.c /^void px_dump(fp,px)$/;" f px_finput matrixio.c /^PERM *px_finput(fp,px)$/;" f px_foutput matrixio.c /^void px_foutput(fp,px)$/;" f px_free memory.c /^int px_free(px)$/;" f px_free_vars memory.c /^int px_free_vars(PERM **vpx,...)$/;" f px_free_vars memory.c /^int px_free_vars(va_alist) va_dcl$/;" f px_get memory.c /^PERM *px_get(size)$/;" f px_get_vars memory.c /^int px_get_vars(int dim,...) $/;" f px_get_vars memory.c /^int px_get_vars(va_alist) va_dcl$/;" f px_ident init.c /^PERM *px_ident(px)$/;" f px_inv pxop.c /^PERM *px_inv(px,out)$/;" f px_mlt pxop.c /^PERM *px_mlt(px1,px2,out)$/;" f px_rand memtort.c /^PERM *px_rand(pi)$/;" f px_rand torture.c /^PERM *px_rand(pi)$/;" f px_rand ztorture.c /^PERM *px_rand(pi)$/;" f px_resize memory.c /^PERM *px_resize(px,new_size)$/;" f px_resize_vars memory.c /^int px_resize_vars(int new_dim,...) $/;" f px_resize_vars memory.c /^int px_resize_vars(va_alist) va_dcl$/;" f px_rows pxop.c /^MAT *px_rows(px,A,out)$/;" f px_sign pxop.c /^int px_sign(px)$/;" f px_transp pxop.c /^PERM *px_transp(px,i1,i2)$/;" f px_vec pxop.c /^VEC *px_vec(px,vector,out)$/;" f px_zvec zvecop.c /^ZVEC *px_zvec(px,vector,out)$/;" f pxinv_vec pxop.c /^VEC *pxinv_vec(px,x,out)$/;" f pxinv_zvec zvecop.c /^ZVEC *pxinv_zvec(px,x,out)$/;" f rcsid arnoldi.c /^static char rcsid[] = "$Id: arnoldi.c,v 1.3 1994\/01\/13 05:45:40 des Exp $";$/;" v file: rcsid bdfactor.c /^static char rcsid[] = "$Id: ";$/;" v file: rcsid bkpfacto.c /^static char rcsid[] = "$Id: bkpfacto.c,v 1.7 1994\/01\/13 05:45:50 des Exp $";$/;" v file: rcsid chfactor.c /^static char rcsid[] = "$Id: chfactor.c,v 1.2 1994\/01\/13 05:36:36 des Exp $";$/;" v file: rcsid conjgrad.c /^static char rcsid[] = "$Id: conjgrad.c,v 1.4 1994\/01\/13 05:36:45 des Exp $";$/;" v file: rcsid copy.c /^static char rcsid[] = "$Id: copy.c,v 1.2 1994\/01\/13 05:37:14 des Exp $";$/;" v file: rcsid err.c /^static char rcsid[] = "$Id: err.c,v 1.6 1995\/01\/30 14:49:14 des Exp $";$/;" v file: rcsid extras.c /^static char rcsid[] = "$Id: extras.c,v 1.4 1995\/06\/08 15:13:15 des Exp $";$/;" v file: rcsid fft.c /^static char rcsid[] = "$Id: fft.c,v 1.4 1996\/08\/20 14:21:05 stewart Exp $";$/;" v file: rcsid givens.c /^static char rcsid[] = "$Id: givens.c,v 1.3 1995\/03\/27 15:41:15 des Exp $";$/;" v file: rcsid hessen.c /^static char rcsid[] = "$Id: hessen.c,v 1.2 1994\/01\/13 05:36:24 des Exp $";$/;" v file: rcsid hsehldr.c /^static char rcsid[] = "$Id: hsehldr.c,v 1.2 1994\/01\/13 05:36:29 des Exp $";$/;" v file: rcsid init.c /^static char rcsid[] = "$Id: init.c,v 1.6 1994\/01\/13 05:36:58 des Exp $";$/;" v file: rcsid iotort.c /^static char rcsid[] = "$Id: $";$/;" v file: rcsid iter0.c /^static char rcsid[] = "$Id: iter0.c,v 1.3 1995\/01\/30 14:50:56 des Exp $";$/;" v file: rcsid iternsym.c /^static char rcsid[] = "$Header: iternsym.c,v 1.6 1995\/01\/30 14:53:01 des Exp $";$/;" v file: rcsid itersym.c /^static char rcsid[] = "$Id: itersym.c,v 1.2 1995\/01\/30 14:55:54 des Exp $";$/;" v file: rcsid ivecop.c /^static char rcsid[] = "$Id: ivecop.c,v 1.6 1996\/08\/20 18:19:21 stewart Exp $";$/;" v file: rcsid lanczos.c /^static char rcsid[] = "$Id: lanczos.c,v 1.4 1994\/01\/13 05:28:24 des Exp $";$/;" v file: rcsid lufactor.c /^static char rcsid[] = "$Id: lufactor.c,v 1.10 1995\/05\/16 17:26:44 des Exp $";$/;" v file: rcsid machine.c /^static char *rcsid = "$Id: machine.c,v 1.4 1994\/01\/13 05:28:56 des Exp $";$/;" v file: rcsid matlab.c /^static char rcsid[] = "$Id: matlab.c,v 1.8 1995\/02\/14 20:12:36 des Exp $";$/;" v file: rcsid matop.c /^static char rcsid[] = "$Id: matop.c,v 1.4 1995\/03\/27 15:43:57 des Exp $";$/;" v file: rcsid matrixio.c /^static char rcsid[] = "$Id: matrixio.c,v 1.4 1994\/01\/13 05:31:10 des Exp $";$/;" v file: rcsid meminfo.c /^static char rcsid[] = "$Id: meminfo.c,v 1.1 1994\/01\/13 05:31:39 des Exp $";$/;" v file: rcsid memory.c /^static char rcsid[] = "$Id: memory.c,v 1.13 1994\/04\/05 02:10:37 des Exp $";$/;" v file: rcsid memstat.c /^static char rcsid[] = "$Id: memstat.c,v 1.1 1994\/01\/13 05:32:44 des Exp $";$/;" v file: rcsid memtort.c /^static char rcsid[] = "$Id: $";$/;" v file: rcsid mfunc.c /^static char rcsid[] = "$Id: mfunc.c,v 1.2 1994\/11\/01 05:57:56 des Exp $";$/;" v file: rcsid mfuntort.c /^static char rcsid[] = "$Id: mfuntort.c,v 1.2 1994\/01\/14 01:08:06 des Exp $";$/;" v file: rcsid norm.c /^static char rcsid[] = "$Id: norm.c,v 1.6 1994\/01\/13 05:34:35 des Exp $";$/;" v file: rcsid otherio.c /^static char rcsid[] = "$Id: otherio.c,v 1.2 1994\/01\/13 05:34:52 des Exp $";$/;" v file: rcsid pxop.c /^static char rcsid[] = "$Id: pxop.c,v 1.6 1995\/06\/08 14:57:11 des Exp $";$/;" v file: rcsid qrfactor.c /^static char rcsid[] = "$Id: qrfactor.c,v 1.5 1994\/01\/13 05:35:07 des Exp $";$/;" v file: rcsid schur.c /^static char rcsid[] = "$Id: schur.c,v 1.7 1994\/03\/17 05:36:53 des Exp $";$/;" v file: rcsid solve.c /^static char rcsid[] = "$Id: solve.c,v 1.3 1994\/01\/13 05:29:57 des Exp $";$/;" v file: rcsid sparse.c /^static char rcsid[] = "$Id: sparse.c,v 1.10 1994\/03\/08 05:46:07 des Exp $";$/;" v file: rcsid sparseio.c /^static char rcsid[] = "$Id: sparseio.c,v 1.4 1994\/01\/13 05:34:25 des Exp $";$/;" v file: rcsid spbkp.c /^static char rcsid[] = "$Id: spbkp.c,v 1.6 1996\/08\/20 19:53:10 stewart Exp $";$/;" v file: rcsid spchfctr.c /^static char rcsid[] = "$Id: spchfctr.c,v 1.5 1996\/08\/20 19:45:33 stewart Exp $";$/;" v file: rcsid sprow.c /^static char rcsid[] = "$Id: sprow.c,v 1.1 1994\/01\/13 05:35:36 des Exp $";$/;" v file: rcsid spswap.c /^static char rcsid[] = "$Id: spswap.c,v 1.3 1994\/01\/13 05:44:43 des Exp $";$/;" v file: rcsid submat.c /^static char rcsid[] = "$Id: submat.c,v 1.2 1994\/01\/13 05:28:12 des Exp $";$/;" v file: rcsid svd.c /^static char rcsid[] = "$Id: svd.c,v 1.7 1995\/09\/08 14:45:43 des Exp $";$/;" v file: rcsid symmeig.c /^static char rcsid[] = "$Id: symmeig.c,v 1.6 1995\/03\/27 15:45:55 des Exp $";$/;" v file: rcsid torture.c /^static char rcsid[] = "$Id: torture.c,v 1.6 1994\/08\/25 15:22:11 des Exp $";$/;" v file: rcsid tutorial.c /^static char rcsid[] = "$Id: tutorial.c,v 1.3 1994\/01\/16 22:53:09 des Exp $";$/;" v file: rcsid update.c /^static char rcsid[] = "$Id: update.c,v 1.2 1994\/01\/13 05:26:06 des Exp $";$/;" v file: rcsid vecop.c /^static char rcsid[] = "$Id: vecop.c,v 1.5 1996\/08\/20 18:18:10 stewart Exp $";$/;" v file: rcsid zcopy.c /^static char rcsid[] = "$Id: zcopy.c,v 1.1 1994\/01\/13 04:28:42 des Exp $";$/;" v file: rcsid zfunc.c /^static char rcsid[] = "$Id: zfunc.c,v 1.3 1995\/04\/07 16:27:25 des Exp $";$/;" v file: rcsid zgivens.c /^static char rcsid[] = "$Id: ";$/;" v file: rcsid zhessen.c /^static char rcsid[] = "$Id: zhessen.c,v 1.2 1995\/03\/27 15:47:50 des Exp $";$/;" v file: rcsid zhsehldr.c /^static char rcsid[] = "$Id: zhsehldr.c,v 1.2 1994\/04\/07 01:43:47 des Exp $";$/;" v file: rcsid zlufctr.c /^static char rcsid[] = "$Id: zlufctr.c,v 1.3 1996\/08\/20 20:07:09 stewart Exp $";$/;" v file: rcsid zmachine.c /^static char *rcsid = "$Id: zmachine.c,v 1.1 1994\/01\/13 04:25:41 des Exp $";$/;" v file: rcsid zmatio.c /^static char rcsid[] = "$Id: zmatio.c,v 1.1 1994\/01\/13 04:25:18 des Exp $";$/;" v file: rcsid zmatlab.c /^static char rcsid[] = "$Id: zmatlab.c,v 1.2 1995\/02\/14 20:13:27 des Exp $";$/;" v file: rcsid zmatop.c /^static char rcsid[] = "$Id: zmatop.c,v 1.2 1995\/03\/27 15:49:03 des Exp $";$/;" v file: rcsid zmemory.c /^static char rcsid[] = "$Id: zmemory.c,v 1.2 1994\/04\/05 02:13:14 des Exp $";$/;" v file: rcsid znorm.c /^static char rcsid[] = "$Id: znorm.c,v 1.1 1994\/01\/13 04:21:31 des Exp $";$/;" v file: rcsid zqrfctr.c /^static char rcsid[] = "$Id: zqrfctr.c,v 1.1 1994\/01\/13 04:21:22 des Exp $";$/;" v file: rcsid zschur.c /^static char rcsid[] = "$Id: zschur.c,v 1.4 1995\/04\/07 16:28:58 des Exp $";$/;" v file: rcsid zsolve.c /^static char rcsid[] = "$Id: zsolve.c,v 1.1 1994\/01\/13 04:20:33 des Exp $";$/;" v file: rcsid ztorture.c /^static char rcsid[] = "$Id: $";$/;" v file: rcsid zvecop.c /^static char rcsid[] = "$Id: zvecop.c,v 1.3 1997\/10\/07 16:13:54 stewart Exp stewart $";$/;" v file: restart err.c /^jmp_buf restart;$/;" v rhs_lap tutorial.c /^VEC *rhs_lap(b)$/;" f rk4 tutorial.c /^double rk4(f,t,x,h)$/;" f rk4_var tutorial.c /^double rk4_var(f,t,x,h)$/;" f rot_cols givens.c /^MAT *rot_cols(mat,i,k,c,s,out)$/;" f rot_rows givens.c /^MAT *rot_rows(mat,i,k,c,s,out)$/;" f rot_vec givens.c /^VEC *rot_vec(x,i,k,c,s,out)$/;" f rot_zvec zgivens.c /^ZVEC *rot_zvec(x,i,k,c,s,out)$/;" f sbd_mlt bdfactor.c /^BAND *sbd_mlt(Real s, BAND *A, BAND *OUT)$/;" f scan_idx spchfctr.c /^static int *scan_row = (int *)NULL, *scan_idx = (int *)NULL,$/;" v file: scan_len spchfctr.c /^static int scan_len = 0;$/;" v file: scan_row spchfctr.c /^static int *scan_row = (int *)NULL, *scan_idx = (int *)NULL,$/;" v file: scan_to spswap.c /^void scan_to(A, scan_row, scan_idx, col_list, max_row)$/;" f schur schur.c /^MAT *schur(A,Q)$/;" f schur_evals schur.c /^void schur_evals(T,real_pt,imag_pt)$/;" f schur_vecs schur.c /^MAT *schur_vecs(T,Q,X_re,X_im)$/;" f scratch otherio.c /^static char scratch[MAXLINE+1];$/;" v file: set_err_flag err.c /^int set_err_flag(flag)$/;" f set_scan spchfctr.c /^int set_scan(new_len)$/;" f setformat matrixio.c /^char *setformat(f_string)$/;" f setzformat zmatio.c /^char *setzformat(f_string)$/;" f sgn svd.c 41;" d file: sgn symmeig.c 42;" d file: sign qrfactor.c 51;" d file: sign zqrfctr.c 52;" d file: skipjunk matrixio.c /^int skipjunk(fp)$/;" f sm_mlt matop.c /^MAT *sm_mlt(scalar,matrix,out)$/;" f smrand init.c /^void smrand(seed)$/;" f spBKPfactor spbkp.c /^SPMAT *spBKPfactor(A,pivot,blocks,tol)$/;" f spBKPsolve spbkp.c /^VEC *spBKPsolve(A,pivot,block,b,x)$/;" f spCHfactor spchfctr.c /^SPMAT *spCHfactor(A)$/;" f spCHsolve spchfctr.c /^VEC *spCHsolve(L,b,out)$/;" f spCHsymb spchfctr.c /^SPMAT *spCHsymb(A)$/;" f spICHfactor spchfctr.c /^SPMAT *spICHfactor(A)$/;" f spILUfactor splufctr.c /^SPMAT *spILUfactor(A,alpha)$/;" f spLUTsolve splufctr.c /^VEC *spLUTsolve(A,pivot,b,x)$/;" f spLUfactor splufctr.c /^SPMAT *spLUfactor(A,px,alpha)$/;" f spLUsolve splufctr.c /^VEC *spLUsolve(A,pivot,b,x)$/;" f sp_add sparse.c /^SPMAT *sp_add(A,B,C)$/;" f sp_arnoldi arnoldi.c /^MAT *sp_arnoldi(A,x0,m,h_rem,Q,H)$/;" f sp_cgs conjgrad.c /^VEC *sp_cgs(A,b,r0,tol,x)$/;" f sp_col_access sparse.c /^SPMAT *sp_col_access(A)$/;" f sp_compact sparse.c /^SPMAT *sp_compact(A,tol)$/;" f sp_copy sparse.c /^SPMAT *sp_copy(A)$/;" f sp_copy2 sparse.c /^SPMAT *sp_copy2(A,OUT)$/;" f sp_diag_access sparse.c /^SPMAT *sp_diag_access(A)$/;" f sp_dump sparseio.c /^void sp_dump(fp,A)$/;" f sp_finput sparseio.c /^SPMAT *sp_finput(fp)$/;" f sp_foutput sparseio.c /^void sp_foutput(fp,A)$/;" f sp_free sparse.c /^int sp_free(A)$/;" f sp_free_vars sparse.c /^int sp_free_vars(SPMAT **va,...)$/;" f sp_free_vars sparse.c /^int sp_free_vars(va_alist) va_dcl$/;" f sp_get sparse.c /^SPMAT *sp_get(m,n,maxlen)$/;" f sp_get_val sparse.c /^double sp_get_val(A,i,j)$/;" f sp_get_vars sparse.c /^int sp_get_vars(int m,int n,int deg,...) $/;" f sp_get_vars sparse.c /^int sp_get_vars(va_alist) va_dcl$/;" f sp_lanczos lanczos.c /^void sp_lanczos(A,m,x0,a,b,beta2,Q)$/;" f sp_lanczos2 lanczos.c /^VEC *sp_lanczos2(A,m,x0,evals,err_est)$/;" f sp_lsqr conjgrad.c /^VEC *sp_lsqr(A,b,tol,x)$/;" f sp_m2dense sparse.c /^MAT *sp_m2dense(A,out)$/;" f sp_mlt sparse.c /^SPMAT *sp_mlt(const SPMAT *A, const SPMAT *B, SPMAT *out)$/;" f sp_mltadd sparse.c /^SPMAT *sp_mltadd(A,B,alpha,C)$/;" f sp_mv_mlt sparse.c /^VEC *sp_mv_mlt(A,x,out)$/;" f sp_pccg conjgrad.c /^VEC *sp_pccg(A,LLT,b,eps,x)$/;" f sp_resize sparse.c /^SPMAT *sp_resize(A,m,n)$/;" f sp_resize_vars sparse.c /^int sp_resize_vars(int m,int n,...) $/;" f sp_resize_vars sparse.c /^int sp_resize_vars(va_alist) va_dcl$/;" f sp_set_val sparse.c /^double sp_set_val(A,i,j,val)$/;" f sp_smlt sparse.c /^SPMAT *sp_smlt(A,alpha,B)$/;" f sp_sub sparse.c /^SPMAT *sp_sub(A,B,C)$/;" f sp_vm_mlt sparse.c /^VEC *sp_vm_mlt(A,x,out)$/;" f sp_zero sparse.c /^SPMAT *sp_zero(A)$/;" f sprow_add sprow.c /^SPROW *sprow_add(r1,r2,j0,r_out,type)$/;" f sprow_copy sprow.c /^SPROW *sprow_copy(r1,r2,r_out,type)$/;" f sprow_dump sprow.c /^void sprow_dump(fp,r)$/;" f sprow_foutput sprow.c /^void sprow_foutput(fp,r)$/;" f sprow_free sprow.c /^int sprow_free(r)$/;" f sprow_get sprow.c /^SPROW *sprow_get(maxlen)$/;" f sprow_idx sprow.c /^int sprow_idx(r,col)$/;" f sprow_ip spchfctr.c /^static double sprow_ip(row1, row2, lim)$/;" f file: sprow_merge sprow.c /^SPROW *sprow_merge(r1,r2,r_out,type)$/;" f sprow_mltadd sprow.c /^SPROW *sprow_mltadd(r1,r2,alpha,j0,r_out,type)$/;" f sprow_resize sprow.c /^SPROW *sprow_resize(r,n,type)$/;" f sprow_set_val sprow.c /^double sprow_set_val(r,j,val)$/;" f sprow_smlt sprow.c /^SPROW *sprow_smlt(r1,alpha,j0,r_out,type)$/;" f sprow_sqr spchfctr.c /^static double sprow_sqr(row, lim)$/;" f file: sprow_sub sprow.c /^SPROW *sprow_sub(r1,r2,j0,r_out,type)$/;" f sprow_xpd sprow.c /^SPROW *sprow_xpd(r,n,type)$/;" f sqr bkpfacto.c /^double sqr(x)$/;" f sqr spbkp.c 51;" d file: square norm.c /^double square(x)$/;" f square znorm.c 74;" d file: started init.c /^static int started = FALSE;$/;" v file: stat_test1 memtort.c /^void stat_test1(par)$/;" f stat_test2 memtort.c /^void stat_test2(par)$/;" f stat_test3 memtort.c /^void stat_test3(par)$/;" f stat_test4 memtort.c /^void stat_test4(par)$/;" f sub_mat submat.c /^MAT *sub_mat(old,row1,col1,row2,col2,new)$/;" f sub_vec submat.c /^VEC *sub_vec(old,i1,i2,new)$/;" f sv_mlt vecop.c /^VEC *sv_mlt(scalar,vector,out)$/;" f svd svd.c /^VEC *svd(A,U,V,d)$/;" f swap_cols matop.c /^MAT *swap_cols(A,i,j,lo,hi)$/;" f swap_rows matop.c /^MAT *swap_rows(A,i,j,lo,hi)$/;" f symmeig symmeig.c /^VEC *symmeig(A,Q,out)$/;" f test_err_list torture.c /^static char *test_err_list[] = {$/;" v file: test_gmres iternsym.c /^static void test_gmres(ip,i,Q,R,givc,givs,h_val)$/;" f file: test_mgcr iternsym.c /^static void test_mgcr(ip,i,Q,R)$/;" f file: test_stat tutadv.c /^void test_stat(k)$/;" f trieig symmeig.c /^VEC *trieig(a,b,Q)$/;" f tut_lap tutorial.c /^void tut_lap()$/;" f tutor_ls tutorial.c /^void tutor_ls()$/;" f tutor_rk4 tutorial.c /^void tutor_rk4()$/;" f type memstat.c /^ int type; \/* type of A *\/$/;" m file: unord_get_idx spbkp.c /^int unord_get_idx(r,j)$/;" f unord_get_val spbkp.c /^double unord_get_val(A,i,j)$/;" f v_add vecop.c /^VEC *v_add(vec1,vec2,out)$/;" f v_conv vecop.c /^VEC *v_conv(x1, x2, out)$/;" f v_count init.c /^VEC *v_count(x)$/;" f v_dump matrixio.c /^void v_dump(fp,x)$/;" f v_finput matrixio.c /^VEC *v_finput(fp,x)$/;" f v_foutput matrixio.c /^void v_foutput(fp,x)$/;" f v_free memory.c /^int v_free(vec)$/;" f v_free_vars memory.c /^int v_free_vars(VEC **pv,...)$/;" f v_free_vars memory.c /^int v_free_vars(va_alist) va_dcl$/;" f v_get memory.c /^VEC *v_get(size)$/;" f v_get_vars memory.c /^int v_get_vars(int dim,...) $/;" f v_get_vars memory.c /^int v_get_vars(va_alist) va_dcl$/;" f v_lincomb vecop.c /^VEC *v_lincomb(n,v,a,out)$/;" f v_linlist vecop.c /^VEC *v_linlist(VEC *out,VEC *v1,double a1,...)$/;" f v_linlist vecop.c /^VEC *v_linlist(va_alist) va_dcl$/;" f v_map vecop.c /^VEC *v_map(f,x,out)$/;" f v_max vecop.c /^double v_max(x, max_idx)$/;" f v_min vecop.c /^double v_min(x, min_idx)$/;" f v_mltadd vecop.c /^VEC *v_mltadd(v1,v2,scale,out)$/;" f v_move copy.c /^VEC *v_move(in,i0,dim0,out,i1)$/;" f v_ones init.c /^VEC *v_ones(x)$/;" f v_pconv vecop.c /^VEC *v_pconv(x1, x2, out)$/;" f v_rand init.c /^VEC *v_rand(x)$/;" f v_resize memory.c /^VEC *v_resize(x,new_dim)$/;" f v_resize_vars memory.c /^int v_resize_vars(int new_dim,...)$/;" f v_resize_vars memory.c /^int v_resize_vars(va_alist) va_dcl$/;" f v_save matlab.c /^VEC *v_save(fp,x,name)$/;" f v_slash vecop.c /^VEC *v_slash(x1, x2, out)$/;" f v_sort vecop.c /^VEC *v_sort(x, order)$/;" f v_star vecop.c /^VEC *v_star(x1, x2, out)$/;" f v_sub vecop.c /^VEC *v_sub(vec1,vec2,out)$/;" f v_sum vecop.c /^double v_sum(x)$/;" f v_zero init.c /^VEC *v_zero(x)$/;" f var memstat.c /^ void **var; \/* for &A, where A is a pointer *\/$/;" m file: vbd_mltadd bdfactor.c /^VEC *vbd_mltadd(x,y,bA,s,out)$/;" f vm_mlt matop.c /^VEC *vm_mlt(A,b,out)$/;" f vm_mltadd matop.c /^VEC *vm_mltadd(v1,v2,A,alpha,out)$/;" f vm_move copy.c /^MAT *vm_move(in,i0,out,i1,j1,m1,n1)$/;" f warn err.c /^ unsigned warn; \/* =FALSE - errors, =TRUE - warnings *\/$/;" m file: warn_mesg err.c /^static char *warn_mesg[] = {$/;" v file: y_n_dflt otherio.c /^static int y_n_dflt = TRUE;$/;" v file: yn_dflt otherio.c /^int yn_dflt(val)$/;" f zDsolve zsolve.c /^ZVEC *zDsolve(A,b,x)$/;" f zHQunpack zhessen.c /^ZMAT *zHQunpack(HQ,diag,Q,H)$/;" f zHfactor zhessen.c /^ZMAT *zHfactor(A, diag)$/;" f zLAsolve zsolve.c /^ZVEC *zLAsolve(L,b,out,diag)$/;" f zLUAsolve zlufctr.c /^ZVEC *zLUAsolve(LU,pivot,b,x)$/;" f zLUcondest zlufctr.c /^double zLUcondest(LU,pivot)$/;" f zLUfactor zlufctr.c /^ZMAT *zLUfactor(A,pivot)$/;" f zLUsolve zlufctr.c /^ZVEC *zLUsolve(A,pivot,b,x)$/;" f zLsolve zsolve.c /^ZVEC *zLsolve(matrix,b,out,diag)$/;" f zQRAsolve zqrfctr.c /^ZVEC *zQRAsolve(QR,diag,b,x)$/;" f zQRCPfactor zqrfctr.c /^ZMAT *zQRCPfactor(A,diag,px)$/;" f zQRCPsolve zqrfctr.c /^ZVEC *zQRCPsolve(QR,diag,pivot,b,x)$/;" f zQRcondest zqrfctr.c /^double zQRcondest(QR)$/;" f zQRfactor zqrfctr.c /^ZMAT *zQRfactor(A,diag)$/;" f zQRsolve zqrfctr.c /^ZVEC *zQRsolve(QR,diag,b,x)$/;" f zUAmlt zqrfctr.c /^ZVEC *zUAmlt(U,x,out)$/;" f zUAsolve zsolve.c /^ZVEC *zUAsolve(U,b,out,diag)$/;" f zUmlt zqrfctr.c /^ZVEC *zUmlt(U,x,out)$/;" f zUsolve zsolve.c /^ZVEC *zUsolve(matrix,b,out,diag)$/;" f z_finput zmatio.c /^complex z_finput(fp)$/;" f z_foutput zmatio.c /^void z_foutput(fp,z)$/;" f z_save zmatlab.c /^complex z_save(fp,z,name)$/;" f zabs zfunc.c /^double zabs(z)$/;" f zadd zfunc.c /^complex zadd(z1,z2)$/;" f zconj zfunc.c /^complex zconj(z)$/;" f zdiv zfunc.c /^complex zdiv(z1,z2)$/;" f zexp zfunc.c /^complex zexp(z)$/;" f zformat zmatio.c /^static const char *zformat = " (%14.9g, %14.9g) ";$/;" v file: zget_col zmatop.c /^ZVEC *zget_col(mat,col,vec)$/;" f zget_row zmatop.c /^ZVEC *zget_row(mat,row,vec)$/;" f zgivens zgivens.c /^void zgivens(x,y,c,s)$/;" f zhhtrcols zhsehldr.c /^ZMAT *zhhtrcols(M,i0,j0,hh,beta)$/;" f zhhtrrows zhsehldr.c /^ZMAT *zhhtrrows(M,i0,j0,hh,beta)$/;" f zhhtrvec zhsehldr.c /^ZVEC *zhhtrvec(hh,beta,i0,in,out)$/;" f zhhvec zhsehldr.c /^ZVEC *zhhvec(vec,i0,beta,out,newval)$/;" f zinv zfunc.c /^complex zinv(z)$/;" f zlog zfunc.c /^complex zlog(z)$/;" f zm_add zmatop.c /^ZMAT *zm_add(mat1,mat2,out)$/;" f zm_adjoint zmatop.c /^ZMAT *zm_adjoint(in,out)$/;" f zm_dump zmatio.c /^void zm_dump(fp,a)$/;" f zm_finput zmatio.c /^ZMAT *zm_finput(fp,a)$/;" f zm_foutput zmatio.c /^void zm_foutput(fp,a)$/;" f zm_free zmemory.c /^int zm_free(mat)$/;" f zm_free_vars zmemory.c /^int zm_free_vars(ZMAT **va,...)$/;" f zm_free_vars zmemory.c /^int zm_free_vars(va_alist) va_dcl$/;" f zm_get zmemory.c /^ZMAT *zm_get(m,n)$/;" f zm_get_vars zmemory.c /^int zm_get_vars(int m,int n,...) $/;" f zm_get_vars zmemory.c /^int zm_get_vars(va_alist) va_dcl$/;" f zm_inverse zlufctr.c /^ZMAT *zm_inverse(A,out)$/;" f zm_load zmatlab.c /^ZMAT *zm_load(fp,name)$/;" f zm_mlt zmatop.c /^ZMAT *zm_mlt(A,B,OUT)$/;" f zm_move zcopy.c /^ZMAT *zm_move(in,i0,j0,m0,n0,out,i1,j1)$/;" f zm_norm1 znorm.c /^double zm_norm1(A)$/;" f zm_norm_frob znorm.c /^double zm_norm_frob(A)$/;" f zm_norm_inf znorm.c /^double zm_norm_inf(A)$/;" f zm_rand zmatop.c /^ZMAT *zm_rand(A)$/;" f zm_resize zmemory.c /^ZMAT *zm_resize(A,new_m,new_n)$/;" f zm_resize_vars zmemory.c /^int zm_resize_vars(int m,int n,...) $/;" f zm_resize_vars zmemory.c /^int zm_resize_vars(va_alist) va_dcl$/;" f zm_save zmatlab.c /^ZMAT *zm_save(fp,A,name)$/;" f zm_sub zmatop.c /^ZMAT *zm_sub(mat1,mat2,out)$/;" f zm_zero zmemory.c /^ZMAT *zm_zero(A)$/;" f zmake zfunc.c /^complex zmake(real,imag)$/;" f zmakeQ zqrfctr.c /^ZMAT *zmakeQ(QR,diag,Qout)$/;" f zmakeR zqrfctr.c /^ZMAT *zmakeR(QR,Rout)$/;" f zmam_mlt zmatop.c /^ZMAT *zmam_mlt(A,B,OUT)$/;" f zmlt zfunc.c /^complex zmlt(z1,z2)$/;" f zmma_mlt zmatop.c /^ZMAT *zmma_mlt(A,B,OUT)$/;" f zmv_mlt zmatop.c /^ZVEC *zmv_mlt(A,b,out)$/;" f zmv_mltadd zmatop.c /^ZVEC *zmv_mltadd(v1,v2,A,alpha,out)$/;" f zmv_move zcopy.c /^ZVEC *zmv_move(in,i0,j0,m0,n0,out,i1)$/;" f zneg zfunc.c /^complex zneg(z)$/;" f zrot_cols zgivens.c /^ZMAT *zrot_cols(mat,i,k,c,s,out)$/;" f zrot_rows zgivens.c /^ZMAT *zrot_rows(mat,i,k,c,s,out)$/;" f zschur zschur.c /^ZMAT *zschur(A,Q)$/;" f zset_col zmatop.c /^ZMAT *zset_col(mat,col,vec)$/;" f zset_row zmatop.c /^ZMAT *zset_row(mat,row,vec)$/;" f zsm_mlt zmatop.c /^ZMAT *zsm_mlt(scalar,matrix,out)$/;" f zsqrt zfunc.c /^complex zsqrt(z)$/;" f zsub zfunc.c /^complex zsub(z1,z2)$/;" f zswap_cols zmatop.c /^ZMAT *zswap_cols(A,i,j,lo,hi)$/;" f zswap_rows zmatop.c /^ZMAT *zswap_rows(A,i,j,lo,hi)$/;" f zv_add zvecop.c /^ZVEC *zv_add(vec1,vec2,out)$/;" f zv_dump zmatio.c /^void zv_dump(fp,x)$/;" f zv_finput zmatio.c /^ZVEC *zv_finput(fp,x)$/;" f zv_foutput zmatio.c /^void zv_foutput(fp,x)$/;" f zv_free zmemory.c /^int zv_free(vec)$/;" f zv_free_vars zmemory.c /^int zv_free_vars(ZVEC **pv,...)$/;" f zv_free_vars zmemory.c /^int zv_free_vars(va_alist) va_dcl$/;" f zv_get zmemory.c /^ZVEC *zv_get(size)$/;" f zv_get_vars zmemory.c /^int zv_get_vars(int dim,...) $/;" f zv_get_vars zmemory.c /^int zv_get_vars(va_alist) va_dcl$/;" f zv_lincomb zvecop.c /^ZVEC *zv_lincomb(n,v,a,out)$/;" f zv_linlist zvecop.c /^ZVEC *zv_linlist(ZVEC *out,ZVEC *v1,complex a1,...)$/;" f zv_linlist zvecop.c /^ZVEC *zv_linlist(va_alist) va_dcl$/;" f zv_map zvecop.c /^ZVEC *zv_map(f,x,out)$/;" f zv_mlt zvecop.c /^ZVEC *zv_mlt(scalar,vector,out)$/;" f zv_mltadd zvecop.c /^ZVEC *zv_mltadd(v1,v2,scale,out)$/;" f zv_move zcopy.c /^ZVEC *zv_move(in,i0,dim0,out,i1)$/;" f zv_rand zvecop.c /^ZVEC *zv_rand(x)$/;" f zv_resize zmemory.c /^ZVEC *zv_resize(x,new_dim)$/;" f zv_resize_vars zmemory.c /^int zv_resize_vars(int new_dim,...)$/;" f zv_resize_vars zmemory.c /^int zv_resize_vars(va_alist) va_dcl$/;" f zv_save zmatlab.c /^ZVEC *zv_save(fp,x,name)$/;" f zv_slash zvecop.c /^ZVEC *zv_slash(x1, x2, out)$/;" f zv_star zvecop.c /^ZVEC *zv_star(x1, x2, out)$/;" f zv_sub zvecop.c /^ZVEC *zv_sub(vec1,vec2,out)$/;" f zv_sum zvecop.c /^complex zv_sum(x)$/;" f zv_zero zmemory.c /^ZVEC *zv_zero(x)$/;" f zvm_mlt zmatop.c /^ZVEC *zvm_mlt(A,b,out)$/;" f zvm_mltadd zmatop.c /^ZVEC *zvm_mltadd(v1,v2,A,alpha,out)$/;" f zvm_move zcopy.c /^ZMAT *zvm_move(in,i0,out,i1,j1,m1,n1)$/;" f gtk-wave-cleaner-0.22-04/meschach/torture.c0000777000175000017500000006672513120075107021650 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Stewart & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains a series of tests for the Meschach matrix library, parts 1 and 2 */ static char rcsid[] = "$Id: torture.c,v 1.6 1994/08/25 15:22:11 des Exp $"; #include #include #include "matrix2.h" #include "matlab.h" #define errmesg(mesg) printf("Error: %s error: line %d\n",mesg,__LINE__) #define notice(mesg) printf("# Testing %s...\n",mesg); static char *test_err_list[] = { "unknown error", /* 0 */ "testing error messages", /* 1 */ "unexpected end-of-file" /* 2 */ }; #define MAX_TEST_ERR (sizeof(test_err_list)/sizeof(char *)) /* extern int malloc_chain_check(); */ /* #define MEMCHK() if ( malloc_chain_check(0) ) \ { printf("Error in malloc chain: \"%s\", line %d\n", \ __FILE__, __LINE__); exit(0); } */ #define MEMCHK() /* cmp_perm -- returns 1 if pi1 == pi2, 0 otherwise */ int cmp_perm(pi1, pi2) PERM *pi1, *pi2; { int i; if ( ! pi1 || ! pi2 ) error(E_NULL,"cmp_perm"); if ( pi1->size != pi2->size ) return 0; for ( i = 0; i < pi1->size; i++ ) if ( pi1->pe[i] != pi2->pe[i] ) return 0; return 1; } /* px_rand -- generates sort-of random permutation */ PERM *px_rand(pi) PERM *pi; { int i, j, k; if ( ! pi ) error(E_NULL,"px_rand"); for ( i = 0; i < 3*pi->size; i++ ) { j = (rand() >> 8) % pi->size; k = (rand() >> 8) % pi->size; px_transp(pi,j,k); } return pi; } #define SAVE_FILE "asx5213a.mat" #define MATLAB_NAME "alpha" char name[81] = MATLAB_NAME; int main(argc, argv) int argc; char *argv[]; { VEC *x = VNULL, *y = VNULL, *z = VNULL, *u = VNULL, *v = VNULL, *w = VNULL; VEC *diag = VNULL, *beta = VNULL; PERM *pi1 = PNULL, *pi2 = PNULL, *pi3 = PNULL, *pivot = PNULL, *blocks = PNULL; MAT *A = MNULL, *B = MNULL, *C = MNULL, *D = MNULL, *Q = MNULL, *U = MNULL; BAND *bA, *bB, *bC; Real cond_est, s1, s2, s3; int i, j, seed; FILE *fp; char *cp; mem_info_on(TRUE); setbuf(stdout,(char *)NULL); seed = 1111; if ( argc > 2 ) { printf("usage: %s [seed]\n",argv[0]); exit(0); } else if ( argc == 2 ) sscanf(argv[1], "%d", &seed); /* set seed for rand() */ smrand(seed); mem_stat_mark(1); /* print version information */ m_version(); printf("# grep \"^Error\" the output for a listing of errors\n"); printf("# Don't panic if you see \"Error\" appearing; \n"); printf("# Also check the reported size of error\n"); printf("# This program uses randomly generated problems and therefore\n"); printf("# may occasionally produce ill-conditioned problems\n"); printf("# Therefore check the size of the error compared with MACHEPS\n"); printf("# If the error is within 1000*MACHEPS then don't worry\n"); printf("# If you get an error of size 0.1 or larger there is \n"); printf("# probably a bug in the code or the compilation procedure\n\n"); printf("# seed = %d\n",seed); printf("# Check: MACHEPS = %g\n",MACHEPS); /* allocate, initialise, copy and resize operations */ /* VEC */ notice("vector initialise, copy & resize"); x = v_get(12); y = v_get(15); z = v_get(12); v_rand(x); v_rand(y); z = v_copy(x,z); if ( v_norm2(v_sub(x,z,z)) >= MACHEPS ) errmesg("VEC copy"); v_copy(x,y); x = v_resize(x,10); y = v_resize(y,10); if ( v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("VEC copy/resize"); x = v_resize(x,15); y = v_resize(y,15); if ( v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("VEC resize"); /* MAT */ notice("matrix initialise, copy & resize"); A = m_get(8,5); B = m_get(3,9); C = m_get(8,5); m_rand(A); m_rand(B); C = m_copy(A,C); if ( m_norm_inf(m_sub(A,C,C)) >= MACHEPS ) errmesg("MAT copy"); m_copy(A,B); A = m_resize(A,3,5); B = m_resize(B,3,5); if ( m_norm_inf(m_sub(A,B,C)) >= MACHEPS ) errmesg("MAT copy/resize"); A = m_resize(A,10,10); B = m_resize(B,10,10); if ( m_norm_inf(m_sub(A,B,C)) >= MACHEPS ) errmesg("MAT resize"); MEMCHK(); /* PERM */ notice("permutation initialise, inverting & permuting vectors"); pi1 = px_get(15); pi2 = px_get(12); px_rand(pi1); v_rand(x); px_vec(pi1,x,z); y = v_resize(y,x->dim); pxinv_vec(pi1,z,y); if ( v_norm2(v_sub(x,y,z)) >= MACHEPS ) errmesg("PERMute vector"); pi2 = px_inv(pi1,pi2); pi3 = px_mlt(pi1,pi2,PNULL); for ( i = 0; i < pi3->size; i++ ) if ( pi3->pe[i] != i ) errmesg("PERM inverse/multiply"); /* testing catch() etc */ notice("error handling routines"); catch(E_NULL, catchall(v_add(VNULL,VNULL,VNULL); errmesg("tracecatch() failure"), printf("# tracecatch() caught error\n"); error(E_NULL,"main")); errmesg("catch() failure"), printf("# catch() caught E_NULL error\n")); /* testing attaching a new error list (error list 2) */ notice("attaching error lists"); printf("# IT IS NOT A REAL WARNING ... \n"); err_list_attach(2,MAX_TEST_ERR,test_err_list,TRUE); if (!err_is_list_attached(2)) errmesg("attaching the error list 2"); ev_err(__FILE__,1,__LINE__,"main",2); err_list_free(2); if (err_is_list_attached(2)) errmesg("detaching the error list 2"); /* testing inner products and v_mltadd() etc */ notice("inner products and linear combinations"); u = v_get(x->dim); v_rand(u); v_rand(x); v_resize(y,x->dim); v_rand(y); v_mltadd(y,x,-in_prod(x,y)/in_prod(x,x),z); if ( fabs(in_prod(x,z)) >= MACHEPS*x->dim ) errmesg("v_mltadd()/in_prod()"); s1 = -in_prod(x,y)/(v_norm2(x)*v_norm2(x)); sv_mlt(s1,x,u); v_add(y,u,u); if ( v_norm2(v_sub(u,z,u)) >= MACHEPS*x->dim ) errmesg("sv_mlt()/v_norm2()"); #ifdef ANSI_C v_linlist(u,x,s1,y,1.0,VNULL); if ( v_norm2(v_sub(u,z,u)) >= MACHEPS*x->dim ) errmesg("v_linlist()"); #endif #ifdef VARARGS v_linlist(u,x,s1,y,1.0,VNULL); if ( v_norm2(v_sub(u,z,u)) >= MACHEPS*x->dim ) errmesg("v_linlist()"); #endif MEMCHK(); /* vector norms */ notice("vector norms"); x = v_resize(x,12); v_rand(x); for ( i = 0; i < x->dim; i++ ) if ( v_entry(x,i) >= 0.5 ) v_set_val(x,i,1.0); else v_set_val(x,i,-1.0); s1 = v_norm1(x); s2 = v_norm2(x); s3 = v_norm_inf(x); if ( fabs(s1 - x->dim) >= MACHEPS*x->dim || fabs(s2 - sqrt((Real)(x->dim))) >= MACHEPS*x->dim || fabs(s3 - 1.0) >= MACHEPS ) errmesg("v_norm1/2/_inf()"); /* test matrix multiply etc */ notice("matrix multiply and invert"); A = m_resize(A,10,10); B = m_resize(B,10,10); m_rand(A); m_inverse(A,B); m_mlt(A,B,C); for ( i = 0; i < C->m; i++ ) m_set_val(C,i,i,m_entry(C,i,i)-1.0); if ( m_norm_inf(C) >= MACHEPS*m_norm_inf(A)*m_norm_inf(B)*5 ) errmesg("m_inverse()/m_mlt()"); MEMCHK(); /* ... and transposes */ notice("transposes and transpose-multiplies"); m_transp(A,A); /* can do square matrices in situ */ mtrm_mlt(A,B,C); for ( i = 0; i < C->m; i++ ) m_set_val(C,i,i,m_entry(C,i,i)-1.0); if ( m_norm_inf(C) >= MACHEPS*m_norm_inf(A)*m_norm_inf(B)*5 ) errmesg("m_transp()/mtrm_mlt()"); m_transp(A,A); m_transp(B,B); mmtr_mlt(A,B,C); for ( i = 0; i < C->m; i++ ) m_set_val(C,i,i,m_entry(C,i,i)-1.0); if ( m_norm_inf(C) >= MACHEPS*m_norm_inf(A)*m_norm_inf(B)*5 ) errmesg("m_transp()/mmtr_mlt()"); sm_mlt(3.71,B,B); mmtr_mlt(A,B,C); for ( i = 0; i < C->m; i++ ) m_set_val(C,i,i,m_entry(C,i,i)-3.71); if ( m_norm_inf(C) >= MACHEPS*m_norm_inf(A)*m_norm_inf(B)*5 ) errmesg("sm_mlt()/mmtr_mlt()"); m_transp(B,B); sm_mlt(1.0/3.71,B,B); MEMCHK(); /* ... and matrix-vector multiplies */ notice("matrix-vector multiplies"); x = v_resize(x,A->n); y = v_resize(y,A->m); z = v_resize(z,A->m); u = v_resize(u,A->n); v_rand(x); v_rand(y); mv_mlt(A,x,z); s1 = in_prod(y,z); vm_mlt(A,y,u); s2 = in_prod(u,x); if ( fabs(s1 - s2) >= (MACHEPS*x->dim)*x->dim ) errmesg("mv_mlt()/vm_mlt()"); mv_mlt(B,z,u); if ( v_norm2(v_sub(u,x,u)) >= MACHEPS*m_norm_inf(A)*m_norm_inf(B)*5 ) errmesg("mv_mlt()/m_inverse()"); MEMCHK(); /* get/set row/col */ notice("getting and setting rows and cols"); x = v_resize(x,A->n); y = v_resize(y,B->m); x = get_row(A,3,x); y = get_col(B,3,y); if ( fabs(in_prod(x,y) - 1.0) >= MACHEPS*m_norm_inf(A)*m_norm_inf(B)*5 ) errmesg("get_row()/get_col()"); sv_mlt(-1.0,x,x); sv_mlt(-1.0,y,y); set_row(A,3,x); set_col(B,3,y); m_mlt(A,B,C); for ( i = 0; i < C->m; i++ ) m_set_val(C,i,i,m_entry(C,i,i)-1.0); if ( m_norm_inf(C) >= MACHEPS*m_norm_inf(A)*m_norm_inf(B)*5 ) errmesg("set_row()/set_col()"); MEMCHK(); /* matrix norms */ notice("matrix norms"); A = m_resize(A,11,15); m_rand(A); s1 = m_norm_inf(A); B = m_transp(A,B); s2 = m_norm1(B); if ( fabs(s1 - s2) >= MACHEPS*A->m ) errmesg("m_norm1()/m_norm_inf()"); C = mtrm_mlt(A,A,C); s1 = 0.0; for ( i = 0; i < C->m && i < C->n; i++ ) s1 += m_entry(C,i,i); if ( fabs(sqrt(s1) - m_norm_frob(A)) >= MACHEPS*A->m*A->n ) errmesg("m_norm_frob"); MEMCHK(); /* permuting rows and columns */ notice("permuting rows & cols"); A = m_resize(A,11,15); B = m_resize(B,11,15); pi1 = px_resize(pi1,A->m); px_rand(pi1); x = v_resize(x,A->n); y = mv_mlt(A,x,y); px_rows(pi1,A,B); px_vec(pi1,y,z); mv_mlt(B,x,u); if ( v_norm2(v_sub(z,u,u)) >= MACHEPS*A->m ) errmesg("px_rows()"); pi1 = px_resize(pi1,A->n); px_rand(pi1); px_cols(pi1,A,B); pxinv_vec(pi1,x,z); mv_mlt(B,z,u); if ( v_norm2(v_sub(y,u,u)) >= MACHEPS*A->n ) errmesg("px_cols()"); MEMCHK(); /* MATLAB save/load */ notice("MATLAB save/load"); A = m_resize(A,12,11); if ( (fp=fopen(SAVE_FILE,"w")) == (FILE *)NULL ) printf("Cannot perform MATLAB save/load test\n"); else { m_rand(A); m_save(fp, A, name); fclose(fp); if ( (fp=fopen(SAVE_FILE,"r")) == (FILE *)NULL ) printf("Cannot open save file \"%s\"\n",SAVE_FILE); else { M_FREE(B); B = m_load(fp,&cp); if ( strcmp(name,cp) || m_norm1(m_sub(A,B,B)) >= MACHEPS*A->m ) errmesg("mload()/m_save()"); } } MEMCHK(); /* Now, onto matrix factorisations */ A = m_resize(A,10,10); B = m_resize(B,A->m,A->n); m_copy(A,B); x = v_resize(x,A->n); y = v_resize(y,A->m); z = v_resize(z,A->n); u = v_resize(u,A->m); v_rand(x); mv_mlt(B,x,y); z = v_copy(x,z); notice("LU factor/solve"); pivot = px_get(A->m); LUfactor(A,pivot); tracecatch(LUsolve(A,pivot,y,x),"main"); tracecatch(cond_est = LUcondest(A,pivot),"main"); printf("# cond(A) approx= %g\n", cond_est); if ( v_norm2(v_sub(x,z,u)) >= MACHEPS*v_norm2(x)*cond_est) { errmesg("LUfactor()/LUsolve()"); printf("# LU solution error = %g [cf MACHEPS = %g]\n", v_norm2(v_sub(x,z,u)), MACHEPS); } v_copy(y,x); tracecatch(LUsolve(A,pivot,x,x),"main"); tracecatch(cond_est = LUcondest(A,pivot),"main"); if ( v_norm2(v_sub(x,z,u)) >= MACHEPS*v_norm2(x)*cond_est) { errmesg("LUfactor()/LUsolve()"); printf("# LU solution error = %g [cf MACHEPS = %g]\n", v_norm2(v_sub(x,z,u)), MACHEPS); } vm_mlt(B,z,y); v_copy(y,x); tracecatch(LUTsolve(A,pivot,x,x),"main"); if ( v_norm2(v_sub(x,z,u)) >= MACHEPS*v_norm2(x)*cond_est) { errmesg("LUfactor()/LUTsolve()"); printf("# LU solution error = %g [cf MACHEPS = %g]\n", v_norm2(v_sub(x,z,u)), MACHEPS); } MEMCHK(); /* QR factorisation */ m_copy(B,A); mv_mlt(B,z,y); notice("QR factor/solve:"); diag = v_get(A->m); beta = v_get(A->m); QRfactor(A,diag); QRsolve(A,diag,y,x); if ( v_norm2(v_sub(x,z,u)) >= MACHEPS*v_norm2(x)*cond_est ) { errmesg("QRfactor()/QRsolve()"); printf("# QR solution error = %g [cf MACHEPS = %g]\n", v_norm2(v_sub(x,z,u)), MACHEPS); } Q = m_get(A->m,A->m); makeQ(A,diag,Q); makeR(A,A); m_mlt(Q,A,C); m_sub(B,C,C); if ( m_norm1(C) >= MACHEPS*m_norm1(Q)*m_norm1(B) ) { errmesg("QRfactor()/makeQ()/makeR()"); printf("# QR reconstruction error = %g [cf MACHEPS = %g]\n", m_norm1(C), MACHEPS); } MEMCHK(); /* now try with a non-square matrix */ A = m_resize(A,15,7); m_rand(A); B = m_copy(A,B); diag = v_resize(diag,A->n); beta = v_resize(beta,A->n); x = v_resize(x,A->n); y = v_resize(y,A->m); v_rand(y); QRfactor(A,diag); x = QRsolve(A,diag,y,x); /* z is the residual vector */ mv_mlt(B,x,z); v_sub(z,y,z); /* check B^T.z = 0 */ vm_mlt(B,z,u); if ( v_norm2(u) >= MACHEPS*m_norm1(B)*v_norm2(y) ) { errmesg("QRfactor()/QRsolve()"); printf("# QR solution error = %g [cf MACHEPS = %g]\n", v_norm2(u), MACHEPS); } Q = m_resize(Q,A->m,A->m); makeQ(A,diag,Q); makeR(A,A); m_mlt(Q,A,C); m_sub(B,C,C); if ( m_norm1(C) >= MACHEPS*m_norm1(Q)*m_norm1(B) ) { errmesg("QRfactor()/makeQ()/makeR()"); printf("# QR reconstruction error = %g [cf MACHEPS = %g]\n", m_norm1(C), MACHEPS); } D = m_get(A->m,Q->m); mtrm_mlt(Q,Q,D); for ( i = 0; i < D->m; i++ ) m_set_val(D,i,i,m_entry(D,i,i)-1.0); if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q) ) { errmesg("QRfactor()/makeQ()/makeR()"); printf("# QR orthogonality error = %g [cf MACHEPS = %g]\n", m_norm1(D), MACHEPS); } MEMCHK(); /* QRCP factorisation */ m_copy(B,A); notice("QR factor/solve with column pivoting"); pivot = px_resize(pivot,A->n); QRCPfactor(A,diag,pivot); z = v_resize(z,A->n); QRCPsolve(A,diag,pivot,y,z); /* pxinv_vec(pivot,z,x); */ /* now compute residual (z) vector */ mv_mlt(B,x,z); v_sub(z,y,z); /* check B^T.z = 0 */ vm_mlt(B,z,u); if ( v_norm2(u) >= MACHEPS*m_norm1(B)*v_norm2(y) ) { errmesg("QRCPfactor()/QRsolve()"); printf("# QR solution error = %g [cf MACHEPS = %g]\n", v_norm2(u), MACHEPS); } Q = m_resize(Q,A->m,A->m); makeQ(A,diag,Q); makeR(A,A); m_mlt(Q,A,C); M_FREE(D); D = m_get(B->m,B->n); px_cols(pivot,C,D); m_sub(B,D,D); if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm1(B) ) { errmesg("QRCPfactor()/makeQ()/makeR()"); printf("# QR reconstruction error = %g [cf MACHEPS = %g]\n", m_norm1(D), MACHEPS); } MEMCHK(); /* Cholesky and LDL^T factorisation */ /* Use these for normal equations approach */ notice("Cholesky factor/solve"); mtrm_mlt(B,B,A); CHfactor(A); u = v_resize(u,B->n); vm_mlt(B,y,u); z = v_resize(z,B->n); CHsolve(A,u,z); v_sub(x,z,z); if ( v_norm2(z) >= MACHEPS*v_norm2(x)*100 ) { errmesg("CHfactor()/CHsolve()"); printf("# Cholesky solution error = %g [cf MACHEPS = %g]\n", v_norm2(z), MACHEPS); } /* modified Cholesky factorisation should be identical with Cholesky factorisation provided the matrix is "sufficiently positive definite" */ mtrm_mlt(B,B,C); MCHfactor(C,MACHEPS); m_sub(A,C,C); if ( m_norm1(C) >= MACHEPS*m_norm1(A) ) { errmesg("MCHfactor()"); printf("# Modified Cholesky error = %g [cf MACHEPS = %g]\n", m_norm1(C), MACHEPS); } /* now test the LDL^T factorisation -- using a negative def. matrix */ mtrm_mlt(B,B,A); sm_mlt(-1.0,A,A); m_copy(A,C); LDLfactor(A); LDLsolve(A,u,z); w = v_get(A->m); mv_mlt(C,z,w); v_sub(w,u,w); if ( v_norm2(w) >= MACHEPS*v_norm2(u)*m_norm1(C) ) { errmesg("LDLfactor()/LDLsolve()"); printf("# LDL^T residual = %g [cf MACHEPS = %g]\n", v_norm2(w), MACHEPS); } v_add(x,z,z); if ( v_norm2(z) >= MACHEPS*v_norm2(x)*100 ) { errmesg("LDLfactor()/LDLsolve()"); printf("# LDL^T solution error = %g [cf MACHEPS = %g]\n", v_norm2(z), MACHEPS); } MEMCHK(); /* and now the Bunch-Kaufman-Parlett method */ /* set up D to be an indefinite diagonal matrix */ notice("Bunch-Kaufman-Parlett factor/solve"); D = m_resize(D,B->m,B->m); m_zero(D); w = v_resize(w,B->m); v_rand(w); for ( i = 0; i < w->dim; i++ ) if ( v_entry(w,i) >= 0.5 ) m_set_val(D,i,i,1.0); else m_set_val(D,i,i,-1.0); /* set A <- B^T.D.B */ C = m_resize(C,B->n,B->n); C = mtrm_mlt(B,D,C); A = m_mlt(C,B,A); C = m_resize(C,B->n,B->n); C = m_copy(A,C); /* ... and use BKPfactor() */ blocks = px_get(A->m); pivot = px_resize(pivot,A->m); x = v_resize(x,A->m); y = v_resize(y,A->m); z = v_resize(z,A->m); v_rand(x); mv_mlt(A,x,y); BKPfactor(A,pivot,blocks); printf("# BKP pivot =\n"); px_output(pivot); printf("# BKP blocks =\n"); px_output(blocks); BKPsolve(A,pivot,blocks,y,z); /* compute & check residual */ mv_mlt(C,z,w); v_sub(w,y,w); if ( v_norm2(w) >= MACHEPS*m_norm1(C)*v_norm2(z) ) { errmesg("BKPfactor()/BKPsolve()"); printf("# BKP residual size = %g [cf MACHEPS = %g]\n", v_norm2(w), MACHEPS); } /* check update routines */ /* check LDLupdate() first */ notice("update L.D.L^T routine"); A = mtrm_mlt(B,B,A); m_resize(C,A->m,A->n); C = m_copy(A,C); LDLfactor(A); s1 = 3.7; w = v_resize(w,A->m); v_rand(w); for ( i = 0; i < C->m; i++ ) for ( j = 0; j < C->n; j++ ) m_set_val(C,i,j,m_entry(C,i,j)+s1*v_entry(w,i)*v_entry(w,j)); LDLfactor(C); LDLupdate(A,w,s1); /* zero out strictly upper triangular parts of A and C */ for ( i = 0; i < A->m; i++ ) for ( j = i+1; j < A->n; j++ ) { m_set_val(A,i,j,0.0); m_set_val(C,i,j,0.0); } if ( m_norm1(m_sub(A,C,C)) >= sqrt(MACHEPS)*m_norm1(A) ) { errmesg("LDLupdate()"); printf("# LDL update matrix error = %g [cf MACHEPS = %g]\n", m_norm1(C), MACHEPS); } /* BAND MATRICES */ #define COL 40 #define UDIAG 5 #define LDIAG 2 smrand(101); bA = bd_get(LDIAG,UDIAG,COL); bB = bd_get(LDIAG,UDIAG,COL); bC = bd_get(LDIAG,UDIAG,COL); A = m_resize(A,COL,COL); B = m_resize(B,COL,COL); pivot = px_resize(pivot,COL); x = v_resize(x,COL); w = v_resize(w,COL); z = v_resize(z,COL); m_rand(A); /* generate band matrix */ mat2band(A,LDIAG,UDIAG,bA); band2mat(bA,A); /* now A is banded */ bB = bd_copy(bA,bB); v_rand(x); mv_mlt(A,x,w); /* test of bd_mv_mlt */ notice("bd_mv_mlt"); bd_mv_mlt(bA,x,z); v_sub(z,w,z); if (v_norm2(z) > v_norm2(x)*sqrt(MACHEPS)) { errmesg("incorrect vector (bd_mv_mlt)"); printf(" ||exact vector. - computed vector.|| = %g [MACHEPS = %g]\n", v_norm2(z),MACHEPS); } z = v_copy(w,z); notice("band LU factorization"); bdLUfactor(bA,pivot); /* pivot will be changed */ bdLUsolve(bA,pivot,z,z); v_sub(x,z,z); if (v_norm2(z) > v_norm2(x)*sqrt(MACHEPS)) { errmesg("incorrect solution (band LU factorization)"); printf(" ||exact sol. - computed sol.|| = %g [MACHEPS = %g]\n", v_norm2(z),MACHEPS); } /* solve transpose system */ notice("band LU factorization for transpose system"); m_transp(A,B); mv_mlt(B,x,w); bd_copy(bB,bA); bd_transp(bA,bA); /* transposition in situ */ bd_transp(bA,bB); bd_transp(bB,bB); bdLUfactor(bB,pivot); bdLUsolve(bB,pivot,w,z); v_sub(x,z,z); if (v_norm2(z) > v_norm2(x)*sqrt(MACHEPS)) { errmesg("incorrect solution (band transposed LU factorization)"); printf(" ||exact sol. - computed sol.|| = %g [MACHEPS = %g]\n", v_norm2(z),MACHEPS); } /* Cholesky factorization */ notice("band Choleski LDL' factorization"); m_add(A,B,A); /* symmetric matrix */ for (i=0; i < COL; i++) /* positive definite */ A->me[i][i] += 2*LDIAG; mat2band(A,LDIAG,LDIAG,bA); band2mat(bA,A); /* corresponding matrix A */ v_rand(x); mv_mlt(A,x,w); z = v_copy(w,z); bdLDLfactor(bA); z = bdLDLsolve(bA,z,z); v_sub(x,z,z); if (v_norm2(z) > v_norm2(x)*sqrt(MACHEPS)) { errmesg("incorrect solution (band LDL' factorization)"); printf(" ||exact sol. - computed sol.|| = %g [MACHEPS = %g]\n", v_norm2(z),MACHEPS); } /* new bandwidths */ m_rand(A); bA = bd_resize(bA,UDIAG,LDIAG,COL); bB = bd_resize(bB,UDIAG,LDIAG,COL); mat2band(A,UDIAG,LDIAG,bA); band2mat(bA,A); bd_copy(bA,bB); mv_mlt(A,x,w); notice("band LU factorization (resized)"); bdLUfactor(bA,pivot); /* pivot will be changed */ bdLUsolve(bA,pivot,w,z); v_sub(x,z,z); if (v_norm2(z) > v_norm2(x)*sqrt(MACHEPS)) { errmesg("incorrect solution (band LU factorization)"); printf(" ||exact sol. - computed sol.|| = %g [MACHEPS = %g]\n", v_norm2(z),MACHEPS); } /* testing transposition */ notice("band matrix transposition"); m_zero(bA->mat); bd_copy(bB,bA); m_zero(bB->mat); bd_copy(bA,bB); bd_transp(bB,bB); bd_transp(bB,bB); m_zero(bC->mat); bd_copy(bB,bC); m_sub(bA->mat,bC->mat,bC->mat); if (m_norm_inf(bC->mat) > MACHEPS*bC->mat->n) { errmesg("band transposition"); printf(" difference ||A - (A')'|| = %g\n",m_norm_inf(bC->mat)); } bd_free(bA); bd_free(bB); bd_free(bC); MEMCHK(); /* now check QRupdate() routine */ notice("update QR routine"); B = m_resize(B,15,7); A = m_resize(A,B->m,B->n); m_copy(B,A); diag = v_resize(diag,A->n); beta = v_resize(beta,A->n); QRfactor(A,diag); Q = m_resize(Q,A->m,A->m); makeQ(A,diag,Q); makeR(A,A); m_resize(C,A->m,A->n); w = v_resize(w,A->m); v = v_resize(v,A->n); u = v_resize(u,A->m); v_rand(w); v_rand(v); vm_mlt(Q,w,u); QRupdate(Q,A,u,v); m_mlt(Q,A,C); for ( i = 0; i < B->m; i++ ) for ( j = 0; j < B->n; j++ ) m_set_val(B,i,j,m_entry(B,i,j)+v_entry(w,i)*v_entry(v,j)); m_sub(B,C,C); if ( m_norm1(C) >= MACHEPS*m_norm1(A)*m_norm1(Q)*2 ) { errmesg("QRupdate()"); printf("# Reconstruction error in QR update = %g [cf MACHEPS = %g]\n", m_norm1(C), MACHEPS); } m_resize(D,Q->m,Q->n); mtrm_mlt(Q,Q,D); for ( i = 0; i < D->m; i++ ) m_set_val(D,i,i,m_entry(D,i,i)-1.0); if ( m_norm1(D) >= 10*MACHEPS*m_norm1(Q)*m_norm_inf(Q) ) { errmesg("QRupdate()"); printf("# QR update orthogonality error = %g [cf MACHEPS = %g]\n", m_norm1(D), MACHEPS); } /* Now check eigenvalue/SVD routines */ notice("eigenvalue and SVD routines"); A = m_resize(A,11,11); B = m_resize(B,A->m,A->n); C = m_resize(C,A->m,A->n); D = m_resize(D,A->m,A->n); Q = m_resize(Q,A->m,A->n); m_rand(A); /* A <- A + A^T for symmetric case */ m_add(A,m_transp(A,C),A); u = v_resize(u,A->m); u = symmeig(A,Q,u); m_zero(B); for ( i = 0; i < B->m; i++ ) m_set_val(B,i,i,v_entry(u,i)); m_mlt(Q,B,C); mmtr_mlt(C,Q,D); m_sub(A,D,D); if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q)*v_norm_inf(u)*3 ) { errmesg("symmeig()"); printf("# Reconstruction error = %g [cf MACHEPS = %g]\n", m_norm1(D), MACHEPS); } mtrm_mlt(Q,Q,D); for ( i = 0; i < D->m; i++ ) m_set_val(D,i,i,m_entry(D,i,i)-1.0); if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q)*3 ) { errmesg("symmeig()"); printf("# symmeig() orthogonality error = %g [cf MACHEPS = %g]\n", m_norm1(D), MACHEPS); } MEMCHK(); /* now test (real) Schur decomposition */ /* m_copy(A,B); */ M_FREE(A); A = m_get(11,11); m_rand(A); B = m_copy(A,B); MEMCHK(); B = schur(B,Q); MEMCHK(); m_mlt(Q,B,C); mmtr_mlt(C,Q,D); MEMCHK(); m_sub(A,D,D); if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q)*m_norm1(B)*5 ) { errmesg("schur()"); printf("# Schur reconstruction error = %g [cf MACHEPS = %g]\n", m_norm1(D), MACHEPS); } /* orthogonality check */ mmtr_mlt(Q,Q,D); for ( i = 0; i < D->m; i++ ) m_set_val(D,i,i,m_entry(D,i,i)-1.0); if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q)*10 ) { errmesg("schur()"); printf("# Schur orthogonality error = %g [cf MACHEPS = %g]\n", m_norm1(D), MACHEPS); } MEMCHK(); /* now test SVD */ A = m_resize(A,11,7); m_rand(A); U = m_get(A->n,A->n); Q = m_resize(Q,A->m,A->m); u = v_resize(u,max(A->m,A->n)); svd(A,Q,U,u); /* check reconstruction of A */ D = m_resize(D,A->m,A->n); C = m_resize(C,A->m,A->n); m_zero(D); for ( i = 0; i < min(A->m,A->n); i++ ) m_set_val(D,i,i,v_entry(u,i)); mtrm_mlt(Q,D,C); m_mlt(C,U,D); m_sub(A,D,D); if ( m_norm1(D) >= MACHEPS*m_norm1(U)*m_norm_inf(Q)*m_norm1(A) ) { errmesg("svd()"); printf("# SVD reconstruction error = %g [cf MACHEPS = %g]\n", m_norm1(D), MACHEPS); } /* check orthogonality of Q and U */ D = m_resize(D,Q->n,Q->n); mtrm_mlt(Q,Q,D); for ( i = 0; i < D->m; i++ ) m_set_val(D,i,i,m_entry(D,i,i)-1.0); if ( m_norm1(D) >= MACHEPS*m_norm1(Q)*m_norm_inf(Q)*5 ) { errmesg("svd()"); printf("# SVD orthognality error (Q) = %g [cf MACHEPS = %g\n", m_norm1(D), MACHEPS); } D = m_resize(D,U->n,U->n); mtrm_mlt(U,U,D); for ( i = 0; i < D->m; i++ ) m_set_val(D,i,i,m_entry(D,i,i)-1.0); if ( m_norm1(D) >= MACHEPS*m_norm1(U)*m_norm_inf(U)*5 ) { errmesg("svd()"); printf("# SVD orthognality error (U) = %g [cf MACHEPS = %g\n", m_norm1(D), MACHEPS); } for ( i = 0; i < u->dim; i++ ) if ( v_entry(u,i) < 0 || (i < u->dim-1 && v_entry(u,i+1) > v_entry(u,i)) ) break; if ( i < u->dim ) { errmesg("svd()"); printf("# SVD sorting error\n"); } /* test of long vectors */ notice("Long vectors"); x = v_resize(x,100000); y = v_resize(y,100000); z = v_resize(z,100000); v_rand(x); v_rand(y); v_mltadd(x,y,3.0,z); sv_mlt(1.0/3.0,z,z); v_mltadd(z,x,-1.0/3.0,z); v_sub(z,y,x); if (v_norm2(x) >= MACHEPS*(x->dim)) { errmesg("long vectors"); printf(" norm = %g\n",v_norm2(x)); } mem_stat_free(1); MEMCHK(); /************************************************** VEC *x, *y, *z, *u, *v, *w; VEC *diag, *beta; PERM *pi1, *pi2, *pi3, *pivot, *blocks; MAT *A, *B, *C, *D, *Q, *U; **************************************************/ V_FREE(x); V_FREE(y); V_FREE(z); V_FREE(u); V_FREE(v); V_FREE(w); V_FREE(diag); V_FREE(beta); PX_FREE(pi1); PX_FREE(pi2); PX_FREE(pi3); PX_FREE(pivot); PX_FREE(blocks); M_FREE(A); M_FREE(B); M_FREE(C); M_FREE(D); M_FREE(Q); M_FREE(U); MEMCHK(); printf("# Finished torture test\n"); mem_info(); return 0; } gtk-wave-cleaner-0.22-04/meschach/tutadv.c0000777000175000017500000001063413120075107021437 0ustar00alisteralister00000000000000 /* routines from the section 8 of tutorial.txt */ #include "matrix.h" #define M3D_LIST 3 /* list number */ #define TYPE_MAT3D 0 /* the number of a type */ /* type for 3 dimensional matrices */ typedef struct { int l,m,n; /* actual dimensions */ int max_l, max_m, max_n; /* maximal dimensions */ Real ***me; /* pointer to matrix elements */ /* we do not consider segmented memory */ Real *base, **me2d; /* me and me2d are additional pointers to base */ } MAT3D; /* function for creating a variable of MAT3D type */ MAT3D *m3d_get(l,m,n) int l,m,n; { MAT3D *mat; int i,j,k; /* check if arguments are positive */ if (l <= 0 || m <= 0 || n <= 0) error(E_NEG,"m3d_get"); /* new structure */ if ((mat = NEW(MAT3D)) == (MAT3D *)NULL) error(E_MEM,"m3d_get"); else if (mem_info_is_on()) { /* record how many bytes is allocated */ mem_bytes_list(TYPE_MAT3D,0,sizeof(MAT3D),M3D_LIST); /* record a new allocated variable */ mem_numvar_list(TYPE_MAT3D,1,M3D_LIST); } mat->l = mat->max_l = l; mat->m = mat->max_m = m; mat->n = mat->max_n = n; /* allocate memory for 3D array */ if ((mat->base = NEW_A(l*m*n,Real)) == (Real *)NULL) error(E_MEM,"m3d_get"); else if (mem_info_is_on()) mem_bytes_list(TYPE_MAT3D,0,l*m*n*sizeof(Real),M3D_LIST); /* allocate memory for 2D pointers */ if ((mat->me2d = NEW_A(l*m,Real *)) == (Real **)NULL) error(E_MEM,"m3d_get"); else if (mem_info_is_on()) mem_bytes_list(TYPE_MAT3D,0,l*m*sizeof(Real *),M3D_LIST); /* allocate memory for 1D pointers */ if ((mat->me = NEW_A(l,Real **)) == (Real ***)NULL) error(E_MEM,"m3d_get"); else if (mem_info_is_on()) mem_bytes_list(TYPE_MAT3D,0,l*sizeof(Real **),M3D_LIST); /* pointers to 2D matrices */ for (i=0,k=0; i < l; i++) for (j=0; j < m; j++) mat->me2d[k++] = &mat->base[(i*m+j)*n]; /* pointers to rows */ for (i=0; i < l; i++) mat->me[i] = &mat->me2d[i*m]; return mat; } /* deallocate a variable of type MAT3D */ int m3d_free(mat) MAT3D *mat; { /* do not try to deallocate the NULL pointer */ if (mat == (MAT3D *)NULL) return -1; /* first deallocate base */ if (mat->base != (Real *)NULL) { if (mem_info_is_on()) /* record how many bytes is deallocated */ mem_bytes_list(TYPE_MAT3D,mat->max_l*mat->max_m*mat->max_n*sizeof(Real), 0,M3D_LIST); free((char *)mat->base); } /* deallocate array of 2D pointers */ if (mat->me2d != (Real **)NULL) { if (mem_info_is_on()) /* record how many bytes is deallocated */ mem_bytes_list(TYPE_MAT3D,mat->max_l*mat->max_m*sizeof(Real *), 0,M3D_LIST); free((char *)mat->me2d); } /* deallocate array of 1D pointers */ if (mat->me != (Real ***)NULL) { if (mem_info_is_on()) /* record how many bytes is deallocated */ mem_bytes_list(TYPE_MAT3D,mat->max_l*sizeof(Real **),0,M3D_LIST); free((char *)mat->me); } /* deallocate MAT3D structure */ if (mem_info_is_on()) { mem_bytes_list(TYPE_MAT3D,sizeof(MAT3D),0,M3D_LIST); mem_numvar_list(TYPE_MAT3D,-1,M3D_LIST); } free((char *)mat); return 0; } /*=============================================*/ char *m3d_names[] = { "MAT3D" }; #define M3D_NUM (sizeof(m3d_names)/sizeof(*m3d_names)) int (*m3d_free_funcs[M3D_NUM])() = { m3d_free }; static MEM_ARRAY m3d_sum[M3D_NUM]; /* test routing for allocating/deallocating static variables */ void test_stat(k) int k; { static MAT3D *work; if (!work) { work = m3d_get(10,10,10); mem_stat_reg_list((void **)&work,TYPE_MAT3D,M3D_LIST); work->me[9][9][9] = -3.14; } if (k == 9) printf(" work[9][9][9] = %g\n",work->me[9][9][9]); } void main() { MAT3D *M; int i,j,k; mem_info_on(TRUE); /* can be the first command */ mem_attach_list(M3D_LIST,M3D_NUM,m3d_names,m3d_free_funcs,m3d_sum); M = m3d_get(3,4,5); mem_info_file(stdout,M3D_LIST); /* make use of M->me[i][j][k], where i,j,k are non-negative and i < 3, j < 4, k < 5 */ mem_stat_mark(1); for (i=0; i < 3; i++) for (j=0; j < 4; j++) for (k=0; k < 5; k++) { test_stat(i+j+k); M->me[i][j][k] = i+j+k; } mem_stat_free_list(1,M3D_LIST); mem_info_file(stdout,M3D_LIST); printf(" M[%d][%d][%d] = %g\n",2,3,4,M->me[2][3][4]); mem_stat_mark(2); test_stat(9); mem_stat_free_list(2,M3D_LIST); m3d_free(M); /* if M is not necessary */ mem_info_file(stdout,M3D_LIST); } gtk-wave-cleaner-0.22-04/meschach/tutorial.c0000777000175000017500000001716213120075107021776 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* tutorial.c 10/12/1993 */ /* routines from Chapter 1 of Meschach */ static char rcsid[] = "$Id: tutorial.c,v 1.3 1994/01/16 22:53:09 des Exp $"; #include #include "matrix.h" /* rk4 -- 4th order Runge--Kutta method */ double rk4(f,t,x,h) double t, h; VEC *(*f)(), *x; { static VEC *v1=VNULL, *v2=VNULL, *v3=VNULL, *v4=VNULL; static VEC *temp=VNULL; /* do not work with NULL initial vector */ if ( x == VNULL ) error(E_NULL,"rk4"); /* ensure that v1, ..., v4, temp are of the correct size */ v1 = v_resize(v1,x->dim); v2 = v_resize(v2,x->dim); v3 = v_resize(v3,x->dim); v4 = v_resize(v4,x->dim); temp = v_resize(temp,x->dim); /* register workspace variables */ MEM_STAT_REG(v1,TYPE_VEC); MEM_STAT_REG(v2,TYPE_VEC); MEM_STAT_REG(v3,TYPE_VEC); MEM_STAT_REG(v4,TYPE_VEC); MEM_STAT_REG(temp,TYPE_VEC); /* end of memory allocation */ (*f)(t,x,v1); /* most compilers allow: "f(t,x,v1);" */ v_mltadd(x,v1,0.5*h,temp); /* temp = x+.5*h*v1 */ (*f)(t+0.5*h,temp,v2); v_mltadd(x,v2,0.5*h,temp); /* temp = x+.5*h*v2 */ (*f)(t+0.5*h,temp,v3); v_mltadd(x,v3,h,temp); /* temp = x+h*v3 */ (*f)(t+h,temp,v4); /* now add: v1+2*v2+2*v3+v4 */ v_copy(v1,temp); /* temp = v1 */ v_mltadd(temp,v2,2.0,temp); /* temp = v1+2*v2 */ v_mltadd(temp,v3,2.0,temp); /* temp = v1+2*v2+2*v3 */ v_add(temp,v4,temp); /* temp = v1+2*v2+2*v3+v4 */ /* adjust x */ v_mltadd(x,temp,h/6.0,x); /* x = x+(h/6)*temp */ return t+h; /* return the new time */ } /* rk4 -- 4th order Runge-Kutta method */ /* another variant */ double rk4_var(f,t,x,h) double t, h; VEC *(*f)(), *x; { static VEC *v1, *v2, *v3, *v4, *temp; /* do not work with NULL initial vector */ if ( x == VNULL ) error(E_NULL,"rk4"); /* ensure that v1, ..., v4, temp are of the correct size */ v_resize_vars(x->dim, &v1, &v2, &v3, &v4, &temp, NULL); /* register workspace variables */ mem_stat_reg_vars(0, TYPE_VEC, __FILE__, __LINE__, &v1, &v2, &v3, &v4, &temp, NULL); /* end of memory allocation */ (*f)(t,x,v1); v_mltadd(x,v1,0.5*h,temp); (*f)(t+0.5*h,temp,v2); v_mltadd(x,v2,0.5*h,temp); (*f)(t+0.5*h,temp,v3); v_mltadd(x,v3,h,temp); (*f)(t+h,temp,v4); /* now add: temp = v1+2*v2+2*v3+v4 */ v_linlist(temp, v1, 1.0, v2, 2.0, v3, 2.0, v4, 1.0, VNULL); /* adjust x */ v_mltadd(x,temp,h/6.0,x); /* x = x+(h/6)*temp */ return t+h; /* return the new time */ } /* f -- right-hand side of ODE solver */ VEC *f(t,x,out) VEC *x, *out; double t; { if ( x == VNULL || out == VNULL ) error(E_NULL,"f"); if ( x->dim != 2 || out->dim != 2 ) error(E_SIZES,"f"); out->ve[0] = x->ve[1]; out->ve[1] = - x->ve[0]; return out; } void tutor_rk4() { VEC *x; VEC *f(); double h, t, t_fin; double rk4(); input("Input initial time: ","%lf",&t); input("Input final time: ", "%lf",&t_fin); x = v_get(2); /* this is the size needed by f() */ prompter("Input initial state:\n"); x = v_input(VNULL); input("Input step size: ", "%lf",&h); printf("# At time %g, the state is\n",t); v_output(x); while (t < t_fin) { /* you can use t = rk4_var(f,t,x,min(h,t_fin-t)); */ t = rk4(f,t,x,min(h,t_fin-t)); /* new t is returned */ printf("# At time %g, the state is\n",t); v_output(x); } } #include "matrix2.h" void tutor_ls() { MAT *A, *QR; VEC *b, *x, *diag; /* read in A matrix */ printf("Input A matrix:\n"); A = m_input(MNULL); /* A has whatever size is input */ if ( A->m < A->n ) { printf("Need m >= n to obtain least squares fit\n"); exit(0); } printf("# A =\n"); m_output(A); diag = v_get(A->m); /* QR is to be the QR factorisation of A */ QR = m_copy(A,MNULL); QRfactor(QR,diag); /* read in b vector */ printf("Input b vector:\n"); b = v_get(A->m); b = v_input(b); printf("# b =\n"); v_output(b); /* solve for x */ x = QRsolve(QR,diag,b,VNULL); printf("Vector of best fit parameters is\n"); v_output(x); /* ... and work out norm of errors... */ printf("||A*x-b|| = %g\n", v_norm2(v_sub(mv_mlt(A,x,VNULL),b,VNULL))); } #include "iter.h" #define N 50 #define VEC2MAT(v,m) vm_move((v),0,(m),0,0,N,N); #define PI 3.141592653589793116 #define index(i,j) (N*((i)-1)+(j)-1) /* right hand side function (for generating b) */ double f1(x,y) double x,y; { /* return 2.0*PI*PI*sin(PI*x)*sin(PI*y); */ return exp(x*y); } /* discrete laplacian */ SPMAT *laplacian(A) SPMAT *A; { Real h; int i,j; if (!A) A = sp_get(N*N,N*N,5); for ( i = 1; i <= N; i++ ) for ( j = 1; j <= N; j++ ) { if ( i < N ) sp_set_val(A,index(i,j),index(i+1,j),-1.0); if ( i > 1 ) sp_set_val(A,index(i,j),index(i-1,j),-1.0); if ( j < N ) sp_set_val(A,index(i,j),index(i,j+1),-1.0); if ( j > 1 ) sp_set_val(A,index(i,j),index(i,j-1),-1.0); sp_set_val(A,index(i,j),index(i,j),4.0); } return A; } /* generating right hand side */ VEC *rhs_lap(b) VEC *b; { Real h,h2,x,y; int i,j; if (!b) b = v_get(N*N); h = 1.0/(N+1); /* for a unit square */ h2 = h*h; x = 0.0; for ( i = 1; i <= N; i++ ) { x += h; y = 0.0; for ( j = 1; j <= N; j++ ) { y += h; b->ve[index(i,j)] = h2*f1(x,y); } } return b; } void tut_lap() { SPMAT *A, *LLT; VEC *b, *out, *x; MAT *B; int num_steps; FILE *fp; A = sp_get(N*N,N*N,5); b = v_get(N*N); laplacian(A); LLT = sp_copy(A); spICHfactor(LLT); out = v_get(A->m); x = v_get(A->m); rhs_lap(b); /* new rhs */ iter_spcg(A,LLT,b,1e-6,out,1000,&num_steps); printf("Number of iterations = %d\n",num_steps); /* save b as a MATLAB matrix */ fp = fopen("laplace.mat","w"); /* b will be saved in laplace.mat */ if (fp == NULL) { printf("Cannot open %s\n","laplace.mat"); exit(1); } /* b must be transformed to a matrix */ B = m_get(N,N); VEC2MAT(out,B); m_save(fp,B,"sol"); /* sol is an internal name in MATLAB */ } void main() { int i; input("Choose the problem (1=Runge-Kutta, 2=least squares,3=laplace): ", "%d",&i); switch (i) { case 1: tutor_rk4(); break; case 2: tutor_ls(); break; case 3: tut_lap(); break; default: printf(" Wrong value of i (only 1, 2 or 3)\n\n"); break; } } gtk-wave-cleaner-0.22-04/meschach/update.c0000777000175000017500000000701713120075107021413 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Matrix factorisation routines to work with the other matrix files. */ /* update.c 1.3 11/25/87 */ static char rcsid[] = "$Id: update.c,v 1.2 1994/01/13 05:26:06 des Exp $"; #include #include #include "matrix.h" #include "matrix2.h" /* Most matrix factorisation routines are in-situ unless otherwise specified */ /* LDLupdate -- updates a CHolesky factorisation, replacing LDL' by MD~M' = LDL' + alpha.w.w' Note: w is overwritten Ref: Gill et al Math Comp 28, p516 Algorithm C1 */ #ifndef ANSI_C MAT *LDLupdate(CHmat,w,alpha) MAT *CHmat; VEC *w; double alpha; #else MAT *LDLupdate(MAT *CHmat, VEC *w, double alpha) #endif { unsigned int i,j; Real diag,new_diag,beta,p; if ( CHmat==(MAT *)NULL || w==(VEC *)NULL ) error(E_NULL,"LDLupdate"); if ( CHmat->m != CHmat->n || w->dim != CHmat->m ) error(E_SIZES,"LDLupdate"); for ( j=0; j < w->dim; j++ ) { p = w->ve[j]; diag = CHmat->me[j][j]; new_diag = CHmat->me[j][j] = diag + alpha*p*p; if ( new_diag <= 0.0 ) error(E_POSDEF,"LDLupdate"); beta = p*alpha/new_diag; alpha *= diag/new_diag; for ( i=j+1; i < w->dim; i++ ) { w->ve[i] -= p*CHmat->me[i][j]; CHmat->me[i][j] += beta*w->ve[i]; CHmat->me[j][i] = CHmat->me[i][j]; } } return (CHmat); } /* QRupdate -- updates QR factorisation in expanded form (seperate matrices) Finds Q+, R+ s.t. Q+.R+ = Q.(R+u.v') and Q+ orthogonal, R+ upper triang Ref: Golub & van Loan Matrix Computations pp437-443 -- does not update Q if it is NULL */ #ifndef ANSI_C MAT *QRupdate(Q,R,u,v) MAT *Q,*R; VEC *u,*v; #else MAT *QRupdate(MAT *Q, MAT *R, VEC *u, VEC *v) #endif { int i,j,k; Real c,s,temp; if ( ! R || ! u || ! v ) error(E_NULL,"QRupdate"); if ( ( Q && ( Q->m != Q->n || R->m != Q->n ) ) || u->dim != R->m || v->dim != R->n ) error(E_SIZES,"QRupdate"); /* find largest k s.t. u[k] != 0 */ for ( k=R->m-1; k>=0; k-- ) if ( u->ve[k] != 0.0 ) break; /* transform R+u.v' to Hessenberg form */ for ( i=k-1; i>=0; i-- ) { /* get Givens rotation */ givens(u->ve[i],u->ve[i+1],&c,&s); rot_rows(R,i,i+1,c,s,R); if ( Q ) rot_cols(Q,i,i+1,c,s,Q); rot_vec(u,i,i+1,c,s,u); } /* add into R */ temp = u->ve[0]; for ( j=0; jn; j++ ) R->me[0][j] += temp*v->ve[j]; /* transform Hessenberg to upper triangular */ for ( i=0; ime[i][i],R->me[i+1][i],&c,&s); rot_rows(R,i,i+1,c,s,R); if ( Q ) rot_cols(Q,i,i+1,c,s,Q); } return R; } gtk-wave-cleaner-0.22-04/meschach/vecop.c0000777000175000017500000003523513120075107021250 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* vecop.c 1.3 8/18/87 */ #include #include "matrix.h" static char rcsid[] = "$Id: vecop.c,v 1.5 1996/08/20 18:18:10 stewart Exp $"; /* _in_prod -- inner product of two vectors from i0 downwards -- that is, returns a(i0:dim)^T.b(i0:dim) */ #ifndef ANSI_C double _in_prod(a,b,i0) VEC *a,*b; unsigned int i0; #else double _in_prod(const VEC *a, const VEC *b, unsigned int i0) #endif { unsigned int limit; /* Real *a_v, *b_v; */ /* register Real sum; */ if ( a==(VEC *)NULL || b==(VEC *)NULL ) error(E_NULL,"_in_prod"); limit = min(a->dim,b->dim); if ( i0 > limit ) error(E_BOUNDS,"_in_prod"); return __ip__(&(a->ve[i0]),&(b->ve[i0]),(int)(limit-i0)); /***************************************** a_v = &(a->ve[i0]); b_v = &(b->ve[i0]); for ( i=i0; idim != vector->dim ) out = v_resize(out,vector->dim); if ( scalar == 0.0 ) return v_zero(out); if ( scalar == 1.0 ) return v_copy(vector,out); __smlt__(vector->ve,(double)scalar,out->ve,(int)(vector->dim)); /************************************************** dim = vector->dim; out_ve = out->ve; vec_ve = vector->ve; for ( i=0; ive[i] = scalar*vector->ve[i]; (*out_ve++) = scalar*(*vec_ve++); **************************************************/ return (out); } /* v_add -- vector addition -- out <- v1+v2 -- may be in-situ */ #ifndef ANSI_C VEC *v_add(vec1,vec2,out) VEC *vec1,*vec2,*out; #else VEC *v_add(const VEC *vec1, const VEC *vec2, VEC *out) #endif { unsigned int dim; /* Real *out_ve, *vec1_ve, *vec2_ve; */ if ( vec1==(VEC *)NULL || vec2==(VEC *)NULL ) error(E_NULL,"v_add"); if ( vec1->dim != vec2->dim ) error(E_SIZES,"v_add"); if ( out==(VEC *)NULL || out->dim != vec1->dim ) out = v_resize(out,vec1->dim); dim = vec1->dim; __add__(vec1->ve,vec2->ve,out->ve,(int)dim); /************************************************************ out_ve = out->ve; vec1_ve = vec1->ve; vec2_ve = vec2->ve; for ( i=0; ive[i] = vec1->ve[i]+vec2->ve[i]; (*out_ve++) = (*vec1_ve++) + (*vec2_ve++); ************************************************************/ return (out); } /* v_mltadd -- scalar/vector multiplication and addition -- out = v1 + scale.v2 */ #ifndef ANSI_C VEC *v_mltadd(v1,v2,scale,out) VEC *v1,*v2,*out; double scale; #else VEC *v_mltadd(const VEC *v1, const VEC *v2, double scale, VEC *out) #endif { /* register unsigned int dim, i; */ /* Real *out_ve, *v1_ve, *v2_ve; */ if ( v1==(VEC *)NULL || v2==(VEC *)NULL ) error(E_NULL,"v_mltadd"); if ( v1->dim != v2->dim ) error(E_SIZES,"v_mltadd"); if ( scale == 0.0 ) return v_copy(v1,out); if ( scale == 1.0 ) return v_add(v1,v2,out); if ( v2 != out ) { tracecatch(out = v_copy(v1,out),"v_mltadd"); /* dim = v1->dim; */ __mltadd__(out->ve,v2->ve,scale,(int)(v1->dim)); } else { tracecatch(out = sv_mlt(scale,v2,out),"v_mltadd"); out = v_add(v1,out,out); } /************************************************************ out_ve = out->ve; v1_ve = v1->ve; v2_ve = v2->ve; for ( i=0; i < dim ; i++ ) out->ve[i] = v1->ve[i] + scale*v2->ve[i]; (*out_ve++) = (*v1_ve++) + scale*(*v2_ve++); ************************************************************/ return (out); } /* v_sub -- vector subtraction -- may be in-situ */ #ifndef ANSI_C VEC *v_sub(vec1,vec2,out) VEC *vec1,*vec2,*out; #else VEC *v_sub(const VEC *vec1, const VEC *vec2, VEC *out) #endif { /* unsigned int i, dim; */ /* Real *out_ve, *vec1_ve, *vec2_ve; */ if ( vec1==(VEC *)NULL || vec2==(VEC *)NULL ) error(E_NULL,"v_sub"); if ( vec1->dim != vec2->dim ) error(E_SIZES,"v_sub"); if ( out==(VEC *)NULL || out->dim != vec1->dim ) out = v_resize(out,vec1->dim); __sub__(vec1->ve,vec2->ve,out->ve,(int)(vec1->dim)); /************************************************************ dim = vec1->dim; out_ve = out->ve; vec1_ve = vec1->ve; vec2_ve = vec2->ve; for ( i=0; ive[i] = vec1->ve[i]-vec2->ve[i]; (*out_ve++) = (*vec1_ve++) - (*vec2_ve++); ************************************************************/ return (out); } /* v_map -- maps function f over components of x: out[i] = f(x[i]) -- v_map sets out[i] = f(params,x[i]) */ #ifndef ANSI_C VEC *v_map(f,x,out) double (*f)(); VEC *x, *out; #else #ifdef PROTOTYPES_IN_STRUCT VEC *v_map(double (*f)(double), const VEC *x, VEC *out) #else VEC *v_map(double (*f)(), const VEC *x, VEC *out) #endif #endif { Real *x_ve, *out_ve; int i, dim; if ( ! x || ! f ) error(E_NULL,"v_map"); if ( ! out || out->dim != x->dim ) out = v_resize(out,x->dim); dim = x->dim; x_ve = x->ve; out_ve = out->ve; for ( i = 0; i < dim; i++ ) *out_ve++ = (*f)(*x_ve++); return out; } /* _v_map -- sets out[i] <- f(params, x[i]), i = 0, 1, .., dim-1 */ #ifndef ANSI_C VEC *_v_map(f,params,x,out) double (*f)(); void *params; VEC *x, *out; #else #ifdef PROTOTYPES_IN_STRUCT VEC *_v_map(double (*f)(void *,double), void *params, const VEC *x, VEC *out) #else VEC *_v_map(double (*f)(), void *params, const VEC *x, VEC *out) #endif #endif { Real *x_ve, *out_ve; int i, dim; if ( ! x || ! f ) error(E_NULL,"_v_map"); if ( ! out || out->dim != x->dim ) out = v_resize(out,x->dim); dim = x->dim; x_ve = x->ve; out_ve = out->ve; for ( i = 0; i < dim; i++ ) *out_ve++ = (*f)(params,*x_ve++); return out; } /* v_lincomb -- returns sum_i a[i].v[i], a[i] real, v[i] vectors */ #ifndef ANSI_C VEC *v_lincomb(n,v,a,out) int n; /* number of a's and v's */ Real a[]; VEC *v[], *out; #else VEC *v_lincomb(int n, const VEC *v[], const Real a[], VEC *out) #endif { int i; if ( ! a || ! v ) error(E_NULL,"v_lincomb"); if ( n <= 0 ) return VNULL; for ( i = 1; i < n; i++ ) if ( out == v[i] ) error(E_INSITU,"v_lincomb"); out = sv_mlt(a[0],v[0],out); for ( i = 1; i < n; i++ ) { if ( ! v[i] ) error(E_NULL,"v_lincomb"); if ( v[i]->dim != out->dim ) error(E_SIZES,"v_lincomb"); out = v_mltadd(out,v[i],a[i],out); } return out; } #ifdef ANSI_C /* v_linlist -- linear combinations taken from a list of arguments; calling: v_linlist(out,v1,a1,v2,a2,...,vn,an,NULL); where vi are vectors (VEC *) and ai are numbers (double) */ VEC *v_linlist(VEC *out,VEC *v1,double a1,...) { va_list ap; VEC *par; double a_par; if ( ! v1 ) return VNULL; va_start(ap, a1); out = sv_mlt(a1,v1,out); while (par = va_arg(ap,VEC *)) { /* NULL ends the list*/ a_par = va_arg(ap,double); if (a_par == 0.0) continue; if ( out == par ) error(E_INSITU,"v_linlist"); if ( out->dim != par->dim ) error(E_SIZES,"v_linlist"); if (a_par == 1.0) out = v_add(out,par,out); else if (a_par == -1.0) out = v_sub(out,par,out); else out = v_mltadd(out,par,a_par,out); } va_end(ap); return out; } #elif VARARGS /* v_linlist -- linear combinations taken from a list of arguments; calling: v_linlist(out,v1,a1,v2,a2,...,vn,an,NULL); where vi are vectors (VEC *) and ai are numbers (double) */ VEC *v_linlist(va_alist) va_dcl { va_list ap; VEC *par, *out; double a_par; va_start(ap); out = va_arg(ap,VEC *); par = va_arg(ap,VEC *); if ( ! par ) { va_end(ap); return VNULL; } a_par = va_arg(ap,double); out = sv_mlt(a_par,par,out); while (par = va_arg(ap,VEC *)) { /* NULL ends the list*/ a_par = va_arg(ap,double); if (a_par == 0.0) continue; if ( out == par ) error(E_INSITU,"v_linlist"); if ( out->dim != par->dim ) error(E_SIZES,"v_linlist"); if (a_par == 1.0) out = v_add(out,par,out); else if (a_par == -1.0) out = v_sub(out,par,out); else out = v_mltadd(out,par,a_par,out); } va_end(ap); return out; } #endif /* v_star -- computes componentwise (Hadamard) product of x1 and x2 -- result out is returned */ #ifndef ANSI_C VEC *v_star(x1, x2, out) VEC *x1, *x2, *out; #else VEC *v_star(const VEC *x1, const VEC *x2, VEC *out) #endif { int i; if ( ! x1 || ! x2 ) error(E_NULL,"v_star"); if ( x1->dim != x2->dim ) error(E_SIZES,"v_star"); out = v_resize(out,x1->dim); for ( i = 0; i < x1->dim; i++ ) out->ve[i] = x1->ve[i] * x2->ve[i]; return out; } /* v_slash -- computes componentwise ratio of x2 and x1 -- out[i] = x2[i] / x1[i] -- if x1[i] == 0 for some i, then raise E_SING error -- result out is returned */ #ifndef ANSI_C VEC *v_slash(x1, x2, out) VEC *x1, *x2, *out; #else VEC *v_slash(const VEC *x1, const VEC *x2, VEC *out) #endif { int i; Real tmp; if ( ! x1 || ! x2 ) error(E_NULL,"v_slash"); if ( x1->dim != x2->dim ) error(E_SIZES,"v_slash"); out = v_resize(out,x1->dim); for ( i = 0; i < x1->dim; i++ ) { tmp = x1->ve[i]; if ( tmp == 0.0 ) error(E_SING,"v_slash"); out->ve[i] = x2->ve[i] / tmp; } return out; } /* v_min -- computes minimum component of x, which is returned -- also sets min_idx to the index of this minimum */ #ifndef ANSI_C double v_min(x, min_idx) VEC *x; int *min_idx; #else double v_min(const VEC *x, int *min_idx) #endif { int i, i_min; Real min_val, tmp; if ( ! x ) error(E_NULL,"v_min"); if ( x->dim <= 0 ) error(E_SIZES,"v_min"); i_min = 0; min_val = x->ve[0]; for ( i = 1; i < x->dim; i++ ) { tmp = x->ve[i]; if ( tmp < min_val ) { min_val = tmp; i_min = i; } } if ( min_idx != NULL ) *min_idx = i_min; return min_val; } /* v_max -- computes maximum component of x, which is returned -- also sets max_idx to the index of this maximum */ #ifndef ANSI_C double v_max(x, max_idx) VEC *x; int *max_idx; #else double v_max(const VEC *x, int *max_idx) #endif { int i, i_max; Real max_val, tmp; if ( ! x ) error(E_NULL,"v_max"); if ( x->dim <= 0 ) error(E_SIZES,"v_max"); i_max = 0; max_val = x->ve[0]; for ( i = 1; i < x->dim; i++ ) { tmp = x->ve[i]; if ( tmp > max_val ) { max_val = tmp; i_max = i; } } if ( max_idx != NULL ) *max_idx = i_max; return max_val; } #define MAX_STACK 60 /* v_sort -- sorts vector x, and generates permutation that gives the order of the components; x = [1.3, 3.7, 0.5] -> [0.5, 1.3, 3.7] and the permutation is order = [2, 0, 1]. -- if order is NULL on entry then it is ignored -- the sorted vector x is returned */ #ifndef ANSI_C VEC *v_sort(x, order) VEC *x; PERM *order; #else VEC *v_sort(VEC *x, PERM *order) #endif { Real *x_ve, tmp, v; /* int *order_pe; */ int dim, i, j, l, r, tmp_i; int stack[MAX_STACK], sp; if ( ! x ) error(E_NULL,"v_sort"); if ( order != PNULL && order->size != x->dim ) order = px_resize(order, x->dim); x_ve = x->ve; dim = x->dim; if ( order != PNULL ) px_ident(order); if ( dim <= 1 ) return x; /* using quicksort algorithm in Sedgewick, "Algorithms in C", Ch. 9, pp. 118--122 (1990) */ sp = 0; l = 0; r = dim-1; v = x_ve[0]; for ( ; ; ) { while ( r > l ) { /* "i = partition(x_ve,l,r);" */ v = x_ve[r]; i = l-1; j = r; for ( ; ; ) { while ( x_ve[++i] < v ) ; --j; while ( x_ve[j] > v && j != 0 ) --j; if ( i >= j ) break; tmp = x_ve[i]; x_ve[i] = x_ve[j]; x_ve[j] = tmp; if ( order != PNULL ) { tmp_i = order->pe[i]; order->pe[i] = order->pe[j]; order->pe[j] = tmp_i; } } tmp = x_ve[i]; x_ve[i] = x_ve[r]; x_ve[r] = tmp; if ( order != PNULL ) { tmp_i = order->pe[i]; order->pe[i] = order->pe[r]; order->pe[r] = tmp_i; } if ( i-l > r-i ) { stack[sp++] = l; stack[sp++] = i-1; l = i+1; } else { stack[sp++] = i+1; stack[sp++] = r; r = i-1; } } /* recursion elimination */ if ( sp == 0 ) break; r = stack[--sp]; l = stack[--sp]; } return x; } /* v_sum -- returns sum of entries of a vector */ #ifndef ANSI_C double v_sum(x) VEC *x; #else double v_sum(const VEC *x) #endif { int i; Real sum; if ( ! x ) error(E_NULL,"v_sum"); sum = 0.0; for ( i = 0; i < x->dim; i++ ) sum += x->ve[i]; return sum; } /* v_conv -- computes convolution product of two vectors */ #ifndef ANSI_C VEC *v_conv(x1, x2, out) VEC *x1, *x2, *out; #else VEC *v_conv(const VEC *x1, const VEC *x2, VEC *out) #endif { int i; if ( ! x1 || ! x2 ) error(E_NULL,"v_conv"); if ( x1 == out || x2 == out ) error(E_INSITU,"v_conv"); if ( x1->dim == 0 || x2->dim == 0 ) return out = v_resize(out,0); out = v_resize(out,x1->dim + x2->dim - 1); v_zero(out); for ( i = 0; i < x1->dim; i++ ) __mltadd__(&(out->ve[i]),x2->ve,x1->ve[i],x2->dim); return out; } /* v_pconv -- computes a periodic convolution product -- the period is the dimension of x2 */ #ifndef ANSI_C VEC *v_pconv(x1, x2, out) VEC *x1, *x2, *out; #else VEC *v_pconv(const VEC *x1, const VEC *x2, VEC *out) #endif { int i; if ( ! x1 || ! x2 ) error(E_NULL,"v_pconv"); if ( x1 == out || x2 == out ) error(E_INSITU,"v_pconv"); out = v_resize(out,x2->dim); if ( x2->dim == 0 ) return out; v_zero(out); for ( i = 0; i < x1->dim; i++ ) { __mltadd__(&(out->ve[i]),x2->ve,x1->ve[i],x2->dim - i); if ( i > 0 ) __mltadd__(out->ve,&(x2->ve[x2->dim - i]),x1->ve[i],i); } return out; } gtk-wave-cleaner-0.22-04/meschach/version.c0000777000175000017500000000504713120075107021617 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Version routine */ /* This routine must be modified whenever modifications are made to Meschach by persons other than the original authors (David E. Stewart & Zbigniew Leyk); when new releases of Meschach are made the version number will also be updated */ #include void m_version() { static char rcsid[] = "$Id: version.c,v 1.9 1994/03/24 00:04:05 des Exp $"; printf("Meshach matrix library version 1.2b\n"); printf("RCS id: %s\n",rcsid); printf("Changes since 1.2a:\n"); printf("\t Fixed bug in schur() for 2x2 blocks with real e-vals\n"); printf("\t Fixed bug in schur() reading beyond end of array\n"); printf("\t Fixed some installation bugs\n"); printf("\t Fixed bugs & improved efficiency in spILUfactor()\n"); printf("\t px_inv() doesn't crash inverting non-permutations\n"); printf("\t Fixed bug in ifft()\n"); /**** List of modifications ****/ /* Example below is for illustration only */ /* printf("Modified by %s, routine(s) %s, file %s on date %s\n", "Joe Bloggs", "m_version", "version.c", "Fri Apr 5 16:00:38 EST 1994"); */ /* printf("Purpose: %s\n", "To update the version number"); */ } /* $Log: version.c,v $ * Revision 1.9 1994/03/24 00:04:05 des * Added notes on changes to spILUfactor() and px_inv(). * * Revision 1.8 1994/02/21 04:32:25 des * Set version to 1.2b with bug fixes in schur() and installation. * * Revision 1.7 1994/01/13 05:43:57 des * Version 1.2 update * * */ gtk-wave-cleaner-0.22-04/meschach/zcopy.c0000777000175000017500000001332213120075107021271 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ static char rcsid[] = "$Id: zcopy.c,v 1.1 1994/01/13 04:28:42 des Exp $"; #include #include "zmatrix.h" /* _zm_copy -- copies matrix into new area */ #ifndef ANSI_C ZMAT *_zm_copy(in,out,i0,j0) ZMAT *in,*out; unsigned int i0,j0; #else ZMAT *_zm_copy(const ZMAT *in, ZMAT *out, int i0, int j0) #endif { unsigned int i /* ,j */; if ( in==ZMNULL ) error(E_NULL,"_zm_copy"); if ( in==out ) return (out); if ( out==ZMNULL || out->m < in->m || out->n < in->n ) out = zm_resize(out,in->m,in->n); for ( i=i0; i < in->m; i++ ) MEM_COPY(&(in->me[i][j0]),&(out->me[i][j0]), (in->n - j0)*sizeof(complex)); /* for ( j=j0; j < in->n; j++ ) out->me[i][j] = in->me[i][j]; */ return (out); } /* _zv_copy -- copies vector into new area */ #ifndef ANSI_C ZVEC *_zv_copy(in,out,i0) ZVEC *in,*out; unsigned int i0; #else ZVEC *_zv_copy(const ZVEC *in, ZVEC *out, int i0) #endif { /* unsigned int i,j; */ if ( in==ZVNULL ) error(E_NULL,"_zv_copy"); if ( in==out ) return (out); if ( out==ZVNULL || out->dim < in->dim ) out = zv_resize(out,in->dim); MEM_COPY(&(in->ve[i0]),&(out->ve[i0]),(in->dim - i0)*sizeof(complex)); /* for ( i=i0; i < in->dim; i++ ) out->ve[i] = in->ve[i]; */ return (out); } /* The z._move() routines are for moving blocks of memory around within Meschach data structures and for re-arranging matrices, vectors etc. */ /* zm_move -- copies selected pieces of a matrix -- moves the m0 x n0 submatrix with top-left cor-ordinates (i0,j0) to the corresponding submatrix of out with top-left co-ordinates (i1,j1) -- out is resized (& created) if necessary */ #ifndef ANSI_C ZMAT *zm_move(in,i0,j0,m0,n0,out,i1,j1) ZMAT *in, *out; int i0, j0, m0, n0, i1, j1; #else ZMAT *zm_move(const ZMAT *in, int i0, int j0, int m0, int n0, ZMAT *out, int i1, int j1) #endif { int i; if ( ! in ) error(E_NULL,"zm_move"); if ( i0 < 0 || j0 < 0 || i1 < 0 || j1 < 0 || m0 < 0 || n0 < 0 || i0+m0 > in->m || j0+n0 > in->n ) error(E_BOUNDS,"zm_move"); if ( ! out ) out = zm_resize(out,i1+m0,j1+n0); else if ( i1+m0 > out->m || j1+n0 > out->n ) out = zm_resize(out,max(out->m,i1+m0),max(out->n,j1+n0)); for ( i = 0; i < m0; i++ ) MEM_COPY(&(in->me[i0+i][j0]),&(out->me[i1+i][j1]), n0*sizeof(complex)); return out; } /* zv_move -- copies selected pieces of a vector -- moves the length dim0 subvector with initial index i0 to the corresponding subvector of out with initial index i1 -- out is resized if necessary */ #ifndef ANSI_C ZVEC *zv_move(in,i0,dim0,out,i1) ZVEC *in, *out; int i0, dim0, i1; #else ZVEC *zv_move(const ZVEC *in, int i0, int dim0, ZVEC *out, int i1) #endif { if ( ! in ) error(E_NULL,"zv_move"); if ( i0 < 0 || dim0 < 0 || i1 < 0 || i0+dim0 > in->dim ) error(E_BOUNDS,"zv_move"); if ( (! out) || i1+dim0 > out->dim ) out = zv_resize(out,i1+dim0); MEM_COPY(&(in->ve[i0]),&(out->ve[i1]),dim0*sizeof(complex)); return out; } /* zmv_move -- copies selected piece of matrix to a vector -- moves the m0 x n0 submatrix with top-left co-ordinate (i0,j0) to the subvector with initial index i1 (and length m0*n0) -- rows are copied contiguously -- out is resized if necessary */ #ifndef ANSI_C ZVEC *zmv_move(in,i0,j0,m0,n0,out,i1) ZMAT *in; ZVEC *out; int i0, j0, m0, n0, i1; #else ZVEC *zmv_move(const ZMAT *in, int i0, int j0, int m0, int n0, ZVEC *out, int i1) #endif { int dim1, i; if ( ! in ) error(E_NULL,"zmv_move"); if ( i0 < 0 || j0 < 0 || m0 < 0 || n0 < 0 || i1 < 0 || i0+m0 > in->m || j0+n0 > in->n ) error(E_BOUNDS,"zmv_move"); dim1 = m0*n0; if ( (! out) || i1+dim1 > out->dim ) out = zv_resize(out,i1+dim1); for ( i = 0; i < m0; i++ ) MEM_COPY(&(in->me[i0+i][j0]),&(out->ve[i1+i*n0]),n0*sizeof(complex)); return out; } /* zvm_move -- copies selected piece of vector to a matrix -- moves the subvector with initial index i0 and length m1*n1 to the m1 x n1 submatrix with top-left co-ordinate (i1,j1) -- copying is done by rows -- out is resized if necessary */ #ifndef ANSI_C ZMAT *zvm_move(in,i0,out,i1,j1,m1,n1) ZVEC *in; ZMAT *out; int i0, i1, j1, m1, n1; #else ZMAT *zvm_move(const ZVEC *in, int i0, ZMAT *out, int i1, int j1, int m1, int n1) #endif { int dim0, i; if ( ! in ) error(E_NULL,"zvm_move"); if ( i0 < 0 || i1 < 0 || j1 < 0 || m1 < 0 || n1 < 0 || i0+m1*n1 > in->dim ) error(E_BOUNDS,"zvm_move"); if ( ! out ) out = zm_resize(out,i1+m1,j1+n1); else out = zm_resize(out,max(i1+m1,out->m),max(j1+n1,out->n)); dim0 = m1*n1; for ( i = 0; i < m1; i++ ) MEM_COPY(&(in->ve[i0+i*n1]),&(out->me[i1+i][j1]),n1*sizeof(complex)); return out; } gtk-wave-cleaner-0.22-04/meschach/zfunc.c0000777000175000017500000001071413120075107021254 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Elementary functions for complex numbers -- if not already defined */ #include #include "zmatrix.h" static char rcsid[] = "$Id: zfunc.c,v 1.3 1995/04/07 16:27:25 des Exp $"; #ifndef COMPLEX_H #ifndef zmake /* zmake -- create complex number real + i*imag */ complex zmake(real,imag) double real, imag; { complex w; /* == real + i*imag */ w.re = real; w.im = imag; return w; } #endif #ifndef zneg /* zneg -- returns negative of z */ complex zneg(z) complex z; { z.re = - z.re; z.im = - z.im; return z; } #endif #ifndef zabs /* zabs -- returns |z| */ double zabs(z) complex z; { Real x, y, tmp; int x_expt, y_expt; /* Note: we must ensure that overflow does not occur! */ x = ( z.re >= 0.0 ) ? z.re : -z.re; y = ( z.im >= 0.0 ) ? z.im : -z.im; if ( x < y ) { tmp = x; x = y; y = tmp; } if ( x == 0.0 ) /* then y == 0.0 as well */ return 0.0; x = frexp(x,&x_expt); y = frexp(y,&y_expt); y = ldexp(y,y_expt-x_expt); tmp = sqrt(x*x+y*y); return ldexp(tmp,x_expt); } #endif #ifndef zadd /* zadd -- returns z1+z2 */ complex zadd(z1,z2) complex z1, z2; { complex z; z.re = z1.re + z2.re; z.im = z1.im + z2.im; return z; } #endif #ifndef zsub /* zsub -- returns z1-z2 */ complex zsub(z1,z2) complex z1, z2; { complex z; z.re = z1.re - z2.re; z.im = z1.im - z2.im; return z; } #endif #ifndef zmlt /* zmlt -- returns z1*z2 */ complex zmlt(z1,z2) complex z1, z2; { complex z; z.re = z1.re * z2.re - z1.im * z2.im; z.im = z1.re * z2.im + z1.im * z2.re; return z; } #endif #ifndef zinv /* zmlt -- returns 1/z */ complex zinv(z) complex z; { Real x, y, tmp; int x_expt, y_expt; if ( z.re == 0.0 && z.im == 0.0 ) error(E_SING,"zinv"); /* Note: we must ensure that overflow does not occur! */ x = ( z.re >= 0.0 ) ? z.re : -z.re; y = ( z.im >= 0.0 ) ? z.im : -z.im; if ( x < y ) { tmp = x; x = y; y = tmp; } x = frexp(x,&x_expt); y = frexp(y,&y_expt); y = ldexp(y,y_expt-x_expt); tmp = 1.0/(x*x + y*y); z.re = z.re*tmp*ldexp(1.0,-2*x_expt); z.im = -z.im*tmp*ldexp(1.0,-2*x_expt); return z; } #endif #ifndef zdiv /* zdiv -- returns z1/z2 */ complex zdiv(z1,z2) complex z1, z2; { return zmlt(z1,zinv(z2)); } #endif #ifndef zsqrt /* zsqrt -- returns sqrt(z); uses branch with Re sqrt(z) >= 0 */ complex zsqrt(z) complex z; { complex w; /* == sqrt(z) at end */ Real alpha; alpha = sqrt(0.5*(fabs(z.re) + zabs(z))); if (alpha!=0) { if (z.re>=0.0) { w.re = alpha; w.im = z.im / (2.0*alpha); } else { w.re = fabs(z.im)/(2.0*alpha); w.im = ( z.im >= 0 ) ? alpha : - alpha; } } else w.re = w.im = 0.0; return w; } #endif #ifndef zexp /* zexp -- returns exp(z) */ complex zexp(z) complex z; { complex w; /* == exp(z) at end */ Real r; r = exp(z.re); w.re = r*cos(z.im); w.im = r*sin(z.im); return w; } #endif #ifndef zlog /* zlog -- returns log(z); uses principal branch with -pi <= Im log(z) <= pi */ complex zlog(z) complex z; { complex w; /* == log(z) at end */ w.re = log(zabs(z)); w.im = atan2(z.im,z.re); return w; } #endif #ifndef zconj complex zconj(z) complex z; { complex w; /* == conj(z) */ w.re = z.re; w.im = - z.im; return w; } #endif #endif gtk-wave-cleaner-0.22-04/meschach/zgivens.c0000777000175000017500000001145313120075107021615 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Givens operations file. Contains routines for calculating and applying givens rotations for/to vectors and also to matrices by row and by column. Complex version. */ static char rcsid[] = "$Id: "; #include #include #include "zmatrix.h" #include "zmatrix2.h" /* (Complex) Givens rotation matrix: [ c -s ] [ s* c ] Note that c is real and s is complex */ /* zgivens -- returns c,s parameters for Givens rotation to eliminate y in the **column** vector [ x y ] */ void zgivens(x,y,c,s) complex x,y,*s; Real *c; { Real inv_norm, norm; complex tmp; /* this is a safe way of computing sqrt(|x|^2+|y|^2) */ tmp.re = zabs(x); tmp.im = zabs(y); norm = zabs(tmp); if ( norm == 0.0 ) { *c = 1.0; s->re = s->im = 0.0; } /* identity */ else { inv_norm = 1.0 / tmp.re; /* inv_norm = 1/|x| */ x.re *= inv_norm; x.im *= inv_norm; /* normalise x */ inv_norm = 1.0/norm; /* inv_norm = 1/||[x,y]||2 */ *c = tmp.re * inv_norm; /* now compute - conj(normalised x).y/||[x,y]||2 */ s->re = - inv_norm*(x.re*y.re + x.im*y.im); s->im = inv_norm*(x.re*y.im - x.im*y.re); } } /* rot_zvec -- apply Givens rotation to x's i & k components */ ZVEC *rot_zvec(x,i,k,c,s,out) ZVEC *x,*out; int i,k; double c; complex s; { complex temp1, temp2; if ( x==ZVNULL ) error(E_NULL,"rot_zvec"); if ( i < 0 || i >= x->dim || k < 0 || k >= x->dim ) error(E_RANGE,"rot_zvec"); if ( x != out ) out = zv_copy(x,out); /* temp1 = c*out->ve[i] - s*out->ve[k]; */ temp1.re = c*out->ve[i].re - s.re*out->ve[k].re + s.im*out->ve[k].im; temp1.im = c*out->ve[i].im - s.re*out->ve[k].im - s.im*out->ve[k].re; /* temp2 = c*out->ve[k] + zconj(s)*out->ve[i]; */ temp2.re = c*out->ve[k].re + s.re*out->ve[i].re + s.im*out->ve[i].im; temp2.im = c*out->ve[k].im + s.re*out->ve[i].im - s.im*out->ve[i].re; out->ve[i] = temp1; out->ve[k] = temp2; return (out); } /* zrot_rows -- premultiply mat by givens rotation described by c,s */ ZMAT *zrot_rows(mat,i,k,c,s,out) ZMAT *mat,*out; int i,k; double c; complex s; { unsigned int j; complex temp1, temp2; if ( mat==ZMNULL ) error(E_NULL,"zrot_rows"); if ( i < 0 || i >= mat->m || k < 0 || k >= mat->m ) error(E_RANGE,"zrot_rows"); if ( mat != out ) out = zm_copy(mat,zm_resize(out,mat->m,mat->n)); /* temp1 = c*out->me[i][j] - s*out->me[k][j]; */ for ( j=0; jn; j++ ) { /* temp1 = c*out->me[i][j] - s*out->me[k][j]; */ temp1.re = c*out->me[i][j].re - s.re*out->me[k][j].re + s.im*out->me[k][j].im; temp1.im = c*out->me[i][j].im - s.re*out->me[k][j].im - s.im*out->me[k][j].re; /* temp2 = c*out->me[k][j] + conj(s)*out->me[i][j]; */ temp2.re = c*out->me[k][j].re + s.re*out->me[i][j].re + s.im*out->me[i][j].im; temp2.im = c*out->me[k][j].im + s.re*out->me[i][j].im - s.im*out->me[i][j].re; out->me[i][j] = temp1; out->me[k][j] = temp2; } return (out); } /* zrot_cols -- postmultiply mat by adjoint Givens rotation described by c,s */ ZMAT *zrot_cols(mat,i,k,c,s,out) ZMAT *mat,*out; int i,k; double c; complex s; { unsigned int j; complex x, y; if ( mat==ZMNULL ) error(E_NULL,"zrot_cols"); if ( i < 0 || i >= mat->n || k < 0 || k >= mat->n ) error(E_RANGE,"zrot_cols"); if ( mat != out ) out = zm_copy(mat,zm_resize(out,mat->m,mat->n)); for ( j=0; jm; j++ ) { x = out->me[j][i]; y = out->me[j][k]; /* out->me[j][i] = c*x - conj(s)*y; */ out->me[j][i].re = c*x.re - s.re*y.re - s.im*y.im; out->me[j][i].im = c*x.im - s.re*y.im + s.im*y.re; /* out->me[j][k] = c*y + s*x; */ out->me[j][k].re = c*y.re + s.re*x.re - s.im*x.im; out->me[j][k].im = c*y.im + s.re*x.im + s.im*x.re; } return (out); } gtk-wave-cleaner-0.22-04/meschach/zhessen.c0000777000175000017500000001007713120075107021610 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* File containing routines for determining Hessenberg factorisations. Complex version */ static char rcsid[] = "$Id: zhessen.c,v 1.2 1995/03/27 15:47:50 des Exp $"; #include #include "zmatrix.h" #include "zmatrix2.h" /* zHfactor -- compute Hessenberg factorisation in compact form. -- factorisation performed in situ -- for details of the compact form see zQRfactor.c and zmatrix2.doc */ ZMAT *zHfactor(A, diag) ZMAT *A; ZVEC *diag; { STATIC ZVEC *tmp1 = ZVNULL, *w = ZVNULL; Real beta; int k, limit; if ( ! A || ! diag ) error(E_NULL,"zHfactor"); if ( diag->dim < A->m - 1 ) error(E_SIZES,"zHfactor"); if ( A->m != A->n ) error(E_SQUARE,"zHfactor"); limit = A->m - 1; tmp1 = zv_resize(tmp1,A->m); w = zv_resize(w, A->n); MEM_STAT_REG(tmp1,TYPE_ZVEC); MEM_STAT_REG(w, TYPE_ZVEC); for ( k = 0; k < limit; k++ ) { zget_col(A,k,tmp1); zhhvec(tmp1,k+1,&beta,tmp1,&A->me[k+1][k]); diag->ve[k] = tmp1->ve[k+1]; /* printf("zHfactor: k = %d, beta = %g, tmp1 =\n",k,beta); zv_output(tmp1); */ _zhhtrcols(A,k+1,k+1,tmp1,beta,w); zhhtrrows(A,0 ,k+1,tmp1,beta); /* printf("# at stage k = %d, A =\n",k); zm_output(A); */ } #ifdef THREADSAFE ZV_FREE(tmp1); ZV_FREE(w); #endif return (A); } /* zHQunpack -- unpack the compact representation of H and Q of a Hessenberg factorisation -- if either H or Q is NULL, then it is not unpacked -- it can be in situ with HQ == H -- returns HQ */ ZMAT *zHQunpack(HQ,diag,Q,H) ZMAT *HQ, *Q, *H; ZVEC *diag; { int i, j, limit; Real beta, r_ii, tmp_val; STATIC ZVEC *tmp1 = ZVNULL, *tmp2 = ZVNULL; if ( HQ==ZMNULL || diag==ZVNULL ) error(E_NULL,"zHQunpack"); if ( HQ == Q || H == Q ) error(E_INSITU,"zHQunpack"); limit = HQ->m - 1; if ( diag->dim < limit ) error(E_SIZES,"zHQunpack"); if ( HQ->m != HQ->n ) error(E_SQUARE,"zHQunpack"); if ( Q != ZMNULL ) { Q = zm_resize(Q,HQ->m,HQ->m); tmp1 = zv_resize(tmp1,H->m); tmp2 = zv_resize(tmp2,H->m); MEM_STAT_REG(tmp1,TYPE_ZVEC); MEM_STAT_REG(tmp2,TYPE_ZVEC); for ( i = 0; i < H->m; i++ ) { /* tmp1 = i'th basis vector */ for ( j = 0; j < H->m; j++ ) tmp1->ve[j].re = tmp1->ve[j].im = 0.0; tmp1->ve[i].re = 1.0; /* apply H/h transforms in reverse order */ for ( j = limit-1; j >= 0; j-- ) { zget_col(HQ,j,tmp2); r_ii = zabs(tmp2->ve[j+1]); tmp2->ve[j+1] = diag->ve[j]; tmp_val = (r_ii*zabs(diag->ve[j])); beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val; /* printf("zHQunpack: j = %d, beta = %g, tmp2 =\n", j,beta); zv_output(tmp2); */ zhhtrvec(tmp2,beta,j+1,tmp1,tmp1); } /* insert into Q */ zset_col(Q,i,tmp1); } } if ( H != ZMNULL ) { H = zm_copy(HQ,zm_resize(H,HQ->m,HQ->n)); limit = H->m; for ( i = 1; i < limit; i++ ) for ( j = 0; j < i-1; j++ ) H->me[i][j].re = H->me[i][j].im = 0.0; } #ifdef THREADSAFE ZV_FREE(tmp1); ZV_FREE(tmp2); #endif return HQ; } gtk-wave-cleaner-0.22-04/meschach/zhsehldr.c0000777000175000017500000001477313120075107021763 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Files for matrix computations Householder transformation file. Contains routines for calculating householder transformations, applying them to vectors and matrices by both row & column. Complex version */ static char rcsid[] = "$Id: zhsehldr.c,v 1.2 1994/04/07 01:43:47 des Exp $"; #include #include #include "zmatrix.h" #include "zmatrix2.h" #define is_zero(z) ((z).re == 0.0 && (z).im == 0.0) /* zhhvec -- calulates Householder vector to eliminate all entries after the i0 entry of the vector vec. It is returned as out. May be in-situ */ ZVEC *zhhvec(vec,i0,beta,out,newval) ZVEC *vec,*out; int i0; Real *beta; complex *newval; { complex tmp; Real norm, abs_val; if ( i0 < 0 || i0 >= vec->dim ) error(E_BOUNDS,"zhhvec"); out = _zv_copy(vec,out,i0); tmp = _zin_prod(out,out,i0,Z_CONJ); if ( tmp.re <= 0.0 ) { *beta = 0.0; *newval = out->ve[i0]; return (out); } norm = sqrt(tmp.re); abs_val = zabs(out->ve[i0]); *beta = 1.0/(norm * (norm+abs_val)); if ( abs_val == 0.0 ) { newval->re = norm; newval->im = 0.0; } else { abs_val = -norm / abs_val; newval->re = abs_val*out->ve[i0].re; newval->im = abs_val*out->ve[i0].im; } abs_val = -norm / abs_val; out->ve[i0].re -= newval->re; out->ve[i0].im -= newval->im; return (out); } /* zhhtrvec -- apply Householder transformation to vector -- may be in-situ */ ZVEC *zhhtrvec(hh,beta,i0,in,out) ZVEC *hh,*in,*out; /* hh = Householder vector */ int i0; double beta; { complex scale, tmp; /* unsigned int i; */ if ( hh==ZVNULL || in==ZVNULL ) error(E_NULL,"zhhtrvec"); if ( in->dim != hh->dim ) error(E_SIZES,"zhhtrvec"); if ( i0 < 0 || i0 > in->dim ) error(E_BOUNDS,"zhhvec"); tmp = _zin_prod(hh,in,i0,Z_CONJ); scale.re = -beta*tmp.re; scale.im = -beta*tmp.im; out = zv_copy(in,out); __zmltadd__(&(out->ve[i0]),&(hh->ve[i0]),scale, (int)(in->dim-i0),Z_NOCONJ); /************************************************************ for ( i=i0; idim; i++ ) out->ve[i] = in->ve[i] - scale*hh->ve[i]; ************************************************************/ return (out); } /* zhhtrrows -- transform a matrix by a Householder vector by rows starting at row i0 from column j0 -- in-situ -- that is, M(i0:m,j0:n) <- M(i0:m,j0:n)(I-beta.hh(j0:n).hh(j0:n)^T) */ ZMAT *zhhtrrows(M,i0,j0,hh,beta) ZMAT *M; int i0, j0; ZVEC *hh; double beta; { complex ip, scale; int i /*, j */; if ( M==ZMNULL || hh==ZVNULL ) error(E_NULL,"zhhtrrows"); if ( M->n != hh->dim ) error(E_RANGE,"zhhtrrows"); if ( i0 < 0 || i0 > M->m || j0 < 0 || j0 > M->n ) error(E_BOUNDS,"zhhtrrows"); if ( beta == 0.0 ) return (M); /* for each row ... */ for ( i = i0; i < M->m; i++ ) { /* compute inner product */ ip = __zip__(&(M->me[i][j0]),&(hh->ve[j0]), (int)(M->n-j0),Z_NOCONJ); /************************************************** ip = 0.0; for ( j = j0; j < M->n; j++ ) ip += M->me[i][j]*hh->ve[j]; **************************************************/ scale.re = -beta*ip.re; scale.im = -beta*ip.im; /* if ( scale == 0.0 ) */ if ( is_zero(scale) ) continue; /* do operation */ __zmltadd__(&(M->me[i][j0]),&(hh->ve[j0]),scale, (int)(M->n-j0),Z_CONJ); /************************************************** for ( j = j0; j < M->n; j++ ) M->me[i][j] -= scale*hh->ve[j]; **************************************************/ } return (M); } /* zhhtrcols -- transform a matrix by a Householder vector by columns starting at row i0 from column j0 -- that is, M(i0:m,j0:n) <- (I-beta.hh(i0:m).hh(i0:m)^T)M(i0:m,j0:n) -- in-situ -- calls _zhhtrcols() with the scratch vector w -- Meschach internal routines should call _zhhtrcols() to avoid excessive memory allocation/de-allocation */ ZMAT *zhhtrcols(M,i0,j0,hh,beta) ZMAT *M; int i0, j0; ZVEC *hh; double beta; { /* Real ip, scale; */ complex scale; int i /*, k */; STATIC ZVEC *w = ZVNULL; if ( M==ZMNULL || hh==ZVNULL ) error(E_NULL,"zhhtrcols"); if ( M->m != hh->dim ) error(E_SIZES,"zhhtrcols"); if ( i0 < 0 || i0 > M->m || j0 < 0 || j0 > M->n ) error(E_BOUNDS,"zhhtrcols"); if ( beta == 0.0 ) return (M); if ( ! w || w->dim < M->n ) w = zv_resize(w,M->n); MEM_STAT_REG(w,TYPE_ZVEC); M = _zhhtrcols(M,i0,j0,hh,beta,w); #ifdef THREADSAFE ZV_FREE(w); #endif return M; } /* _zhhtrcols -- transform a matrix by a Householder vector by columns starting at row i0 from column j0 -- that is, M(i0:m,j0:n) <- (I-beta.hh(i0:m).hh(i0:m)^T)M(i0:m,j0:n) -- in-situ -- scratch vector w passed as argument -- raises error if w == NULL */ ZMAT *_zhhtrcols(M,i0,j0,hh,beta,w) ZMAT *M; int i0, j0; ZVEC *hh; double beta; ZVEC *w; { /* Real ip, scale; */ complex scale; int i /*, k */; if ( M==ZMNULL || hh==ZVNULL ) error(E_NULL,"zhhtrcols"); if ( M->m != hh->dim ) error(E_SIZES,"zhhtrcols"); if ( i0 < 0 || i0 > M->m || j0 < 0 || j0 > M->n ) error(E_BOUNDS,"zhhtrcols"); if ( beta == 0.0 ) return (M); if ( w->dim < M->n ) w = zv_resize(w,M->n); zv_zero(w); for ( i = i0; i < M->m; i++ ) /* if ( hh->ve[i] != 0.0 ) */ if ( ! is_zero(hh->ve[i]) ) __zmltadd__(&(w->ve[j0]),&(M->me[i][j0]),hh->ve[i], (int)(M->n-j0),Z_CONJ); for ( i = i0; i < M->m; i++ ) /* if ( hh->ve[i] != 0.0 ) */ if ( ! is_zero(hh->ve[i]) ) { scale.re = -beta*hh->ve[i].re; scale.im = -beta*hh->ve[i].im; __zmltadd__(&(M->me[i][j0]),&(w->ve[j0]),scale, (int)(M->n-j0),Z_CONJ); } return (M); } gtk-wave-cleaner-0.22-04/meschach/zlufctr.c0000777000175000017500000001613313120075107021621 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Matrix factorisation routines to work with the other matrix files. Complex version */ static char rcsid[] = "$Id: zlufctr.c,v 1.3 1996/08/20 20:07:09 stewart Exp $"; #include #include #include "zmatrix.h" #include "zmatrix2.h" #define is_zero(z) ((z).re == 0.0 && (z).im == 0.0) /* Most matrix factorisation routines are in-situ unless otherwise specified */ /* zLUfactor -- Gaussian elimination with scaled partial pivoting -- Note: returns LU matrix which is A */ ZMAT *zLUfactor(A,pivot) ZMAT *A; PERM *pivot; { unsigned int i, j, m, n; int i_max, k, k_max; Real dtemp, max1; complex **A_v, *A_piv, *A_row, temp; STATIC VEC *scale = VNULL; if ( A==ZMNULL || pivot==PNULL ) error(E_NULL,"zLUfactor"); if ( pivot->size != A->m ) error(E_SIZES,"zLUfactor"); m = A->m; n = A->n; scale = v_resize(scale,A->m); MEM_STAT_REG(scale,TYPE_VEC); A_v = A->me; /* initialise pivot with identity permutation */ for ( i=0; ipe[i] = i; /* set scale parameters */ for ( i=0; ive[i] = max1; } /* main loop */ k_max = min(m,n)-1; for ( k=0; kve[i] > 0.0 ) { dtemp = zabs(A_v[i][k])/scale->ve[i]; if ( dtemp > max1 ) { max1 = dtemp; i_max = i; } } /* if no pivot then ignore column k... */ if ( i_max == -1 ) continue; /* do we pivot ? */ if ( i_max != k ) /* yes we do... */ { px_transp(pivot,i_max,k); for ( j=0; jm != A->n || A->n != b->dim ) error(E_SIZES,"zLUsolve"); x = px_zvec(pivot,b,x); /* x := P.b */ zLsolve(A,x,x,1.0); /* implicit diagonal = 1 */ zUsolve(A,x,x,0.0); /* explicit diagonal */ return (x); } /* zLUAsolve -- given an LU factorisation in A, solve A^*.x=b */ ZVEC *zLUAsolve(LU,pivot,b,x) ZMAT *LU; PERM *pivot; ZVEC *b,*x; { if ( ! LU || ! b || ! pivot ) error(E_NULL,"zLUAsolve"); if ( LU->m != LU->n || LU->n != b->dim ) error(E_SIZES,"zLUAsolve"); x = zv_copy(b,x); zUAsolve(LU,x,x,0.0); /* explicit diagonal */ zLAsolve(LU,x,x,1.0); /* implicit diagonal = 1 */ pxinv_zvec(pivot,x,x); /* x := P^*.x */ return (x); } /* zm_inverse -- returns inverse of A, provided A is not too rank deficient -- uses LU factorisation */ ZMAT *zm_inverse(A,out) ZMAT *A, *out; { int i; STATIC ZVEC *tmp=ZVNULL, *tmp2=ZVNULL; STATIC ZMAT *A_cp=ZMNULL; STATIC PERM *pivot=PNULL; if ( ! A ) error(E_NULL,"zm_inverse"); if ( A->m != A->n ) error(E_SQUARE,"zm_inverse"); if ( ! out || out->m < A->m || out->n < A->n ) out = zm_resize(out,A->m,A->n); A_cp = zm_resize(A_cp,A->m,A->n); A_cp = zm_copy(A,A_cp); tmp = zv_resize(tmp,A->m); tmp2 = zv_resize(tmp2,A->m); pivot = px_resize(pivot,A->m); MEM_STAT_REG(A_cp,TYPE_ZMAT); MEM_STAT_REG(tmp, TYPE_ZVEC); MEM_STAT_REG(tmp2,TYPE_ZVEC); MEM_STAT_REG(pivot,TYPE_PERM); tracecatch(zLUfactor(A_cp,pivot),"zm_inverse"); for ( i = 0; i < A->n; i++ ) { zv_zero(tmp); tmp->ve[i].re = 1.0; tmp->ve[i].im = 0.0; tracecatch(zLUsolve(A_cp,pivot,tmp,tmp2),"zm_inverse"); zset_col(out,i,tmp2); } #ifdef THREADSAFE ZV_FREE(tmp); ZV_FREE(tmp2); ZM_FREE(A_cp); PX_FREE(pivot); #endif return out; } /* zLUcondest -- returns an estimate of the condition number of LU given the LU factorisation in compact form */ double zLUcondest(LU,pivot) ZMAT *LU; PERM *pivot; { STATIC ZVEC *y = ZVNULL, *z = ZVNULL; Real cond_est, L_norm, U_norm, norm, sn_inv; complex sum; int i, j, n; if ( ! LU || ! pivot ) error(E_NULL,"zLUcondest"); if ( LU->m != LU->n ) error(E_SQUARE,"zLUcondest"); if ( LU->n != pivot->size ) error(E_SIZES,"zLUcondest"); n = LU->n; y = zv_resize(y,n); z = zv_resize(z,n); MEM_STAT_REG(y,TYPE_ZVEC); MEM_STAT_REG(z,TYPE_ZVEC); cond_est = 0.0; /* should never be returned */ for ( i = 0; i < n; i++ ) { sum.re = 1.0; sum.im = 0.0; for ( j = 0; j < i; j++ ) /* sum -= LU->me[j][i]*y->ve[j]; */ sum = zsub(sum,zmlt(LU->me[j][i],y->ve[j])); /* sum -= (sum < 0.0) ? 1.0 : -1.0; */ sn_inv = 1.0 / zabs(sum); sum.re += sum.re * sn_inv; sum.im += sum.im * sn_inv; if ( is_zero(LU->me[i][i]) ) return HUGE_VAL; /* y->ve[i] = sum / LU->me[i][i]; */ y->ve[i] = zdiv(sum,LU->me[i][i]); } zLAsolve(LU,y,y,1.0); zLUsolve(LU,pivot,y,z); /* now estimate norm of A (even though it is not directly available) */ /* actually computes ||L||_inf.||U||_inf */ U_norm = 0.0; for ( i = 0; i < n; i++ ) { norm = 0.0; for ( j = i; j < n; j++ ) norm += zabs(LU->me[i][j]); if ( norm > U_norm ) U_norm = norm; } L_norm = 0.0; for ( i = 0; i < n; i++ ) { norm = 1.0; for ( j = 0; j < i; j++ ) norm += zabs(LU->me[i][j]); if ( norm > L_norm ) L_norm = norm; } tracecatch(cond_est = U_norm*L_norm*zv_norm_inf(z)/zv_norm_inf(y), "zLUcondest"); #ifdef THREADSAFE ZV_FREE(y); ZV_FREE(z); #endif return cond_est; } gtk-wave-cleaner-0.22-04/meschach/zmachine.c0000777000175000017500000001145513120075107021730 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains basic routines which are used by the functions involving complex vectors. These are the routines that should be modified in order to take full advantage of specialised architectures (pipelining, vector processors etc). */ static char *rcsid = "$Id: zmachine.c,v 1.1 1994/01/13 04:25:41 des Exp $"; #include #include "machine.h" #include "zmatrix.h" /* __zconj__ -- complex conjugate */ #ifndef ANSI_C void __zconj__(zp,len) complex *zp; int len; #else void __zconj__(complex zp[], int len) #endif { int i; for ( i = 0; i < len; i++ ) zp[i].im = - zp[i].im; } /* __zip__ -- inner product -- computes sum_i zp1[i].zp2[i] if flag == 0 sum_i zp1[i]*.zp2[i] if flag != 0 */ #ifndef ANSI_C complex __zip__(zp1,zp2,len,flag) complex *zp1, *zp2; int flag, len; #else complex __zip__(const complex *zp1, const complex *zp2, int len, int flag) #endif { complex sum; int i; sum.re = sum.im = 0.0; if ( flag ) { for ( i = 0; i < len; i++ ) { sum.re += zp1[i].re*zp2[i].re + zp1[i].im*zp2[i].im; sum.im += zp1[i].re*zp2[i].im - zp1[i].im*zp2[i].re; } } else { for ( i = 0; i < len; i++ ) { sum.re += zp1[i].re*zp2[i].re - zp1[i].im*zp2[i].im; sum.im += zp1[i].re*zp2[i].im + zp1[i].im*zp2[i].re; } } return sum; } /* __zmltadd__ -- scalar multiply and add i.e. complex saxpy -- computes zp1[i] += s.zp2[i] if flag == 0 -- computes zp1[i] += s.zp2[i]* if flag != 0 */ #ifndef ANSI_C void __zmltadd__(zp1,zp2,s,len,flag) complex *zp1, *zp2, s; int flag, len; #else void __zmltadd__(complex *zp1, const complex *zp2, complex s, int len, int flag) #endif { int i; LongReal t_re, t_im; if ( ! flag ) { for ( i = 0; i < len; i++ ) { t_re = zp1[i].re + s.re*zp2[i].re - s.im*zp2[i].im; t_im = zp1[i].im + s.re*zp2[i].im + s.im*zp2[i].re; zp1[i].re = t_re; zp1[i].im = t_im; } } else { for ( i = 0; i < len; i++ ) { t_re = zp1[i].re + s.re*zp2[i].re + s.im*zp2[i].im; t_im = zp1[i].im - s.re*zp2[i].im + s.im*zp2[i].re; zp1[i].re = t_re; zp1[i].im = t_im; } } } /* __zmlt__ scalar complex multiply array c.f. sv_mlt() */ #ifndef ANSI_C void __zmlt__(zp,s,out,len) complex *zp, s, *out; register int len; #else void __zmlt__(const complex *zp, complex s, complex *out, int len) #endif { int i; LongReal t_re, t_im; for ( i = 0; i < len; i++ ) { t_re = s.re*zp[i].re - s.im*zp[i].im; t_im = s.re*zp[i].im + s.im*zp[i].re; out[i].re = t_re; out[i].im = t_im; } } /* __zadd__ -- add complex arrays c.f. v_add() */ #ifndef ANSI_C void __zadd__(zp1,zp2,out,len) complex *zp1, *zp2, *out; int len; #else void __zadd__(const complex *zp1, const complex *zp2, complex *out, int len) #endif { int i; for ( i = 0; i < len; i++ ) { out[i].re = zp1[i].re + zp2[i].re; out[i].im = zp1[i].im + zp2[i].im; } } /* __zsub__ -- subtract complex arrays c.f. v_sub() */ #ifndef ANSI_C void __zsub__(zp1,zp2,out,len) complex *zp1, *zp2, *out; int len; #else void __zsub__(const complex *zp1, const complex *zp2, complex *out, int len) #endif { int i; for ( i = 0; i < len; i++ ) { out[i].re = zp1[i].re - zp2[i].re; out[i].im = zp1[i].im - zp2[i].im; } } /* __zzero__ -- zeros an array of complex numbers */ #ifndef ANSI_C void __zzero__(zp,len) complex *zp; int len; #else void __zzero__(complex *zp, int len) #endif { /* if a Real precision zero is equivalent to a string of nulls */ MEM_ZERO((char *)zp,len*sizeof(complex)); /* else, need to zero the array entry by entry */ /****************************** while ( len-- ) { zp->re = zp->im = 0.0; zp++; } ******************************/ } gtk-wave-cleaner-0.22-04/meschach/zmatio.c0000777000175000017500000002645613120075107021444 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ #include #include #include "zmatrix.h" static char rcsid[] = "$Id: zmatio.c,v 1.1 1994/01/13 04:25:18 des Exp $"; /* local variables */ static char line[MAXLINE]; /************************************************************************** Input routines **************************************************************************/ #ifndef ANSI_C complex z_finput(fp) FILE *fp; #else complex z_finput(FILE *fp) #endif { int io_code; complex z; skipjunk(fp); if ( isatty(fileno(fp)) ) { do { fprintf(stderr,"real and imag parts: "); if ( fgets(line,MAXLINE,fp) == NULL ) error(E_EOF,"z_finput"); #if REAL == DOUBLE io_code = sscanf(line,"%lf%lf",&z.re,&z.im); #elif REAL == FLOAT io_code = sscanf(line,"%f%f",&z.re,&z.im); #endif } while ( io_code != 2 ); } else #if REAL == DOUBLE if ( (io_code=fscanf(fp," (%lf,%lf)",&z.re,&z.im)) < 2 ) #elif REAL == FLOAT if ( (io_code=fscanf(fp," (%f,%f)",&z.re,&z.im)) < 2 ) #endif error((io_code == EOF) ? E_EOF : E_FORMAT,"z_finput"); return z; } #ifndef ANSI_C ZMAT *zm_finput(fp,a) FILE *fp; ZMAT *a; #else ZMAT *zm_finput(FILE *fp,ZMAT *a) #endif { ZMAT *izm_finput(),*bzm_finput(); if ( isatty(fileno(fp)) ) return izm_finput(fp,a); else return bzm_finput(fp,a); } /* izm_finput -- interactive input of matrix */ #ifndef ANSI_C ZMAT *izm_finput(fp,mat) FILE *fp; ZMAT *mat; #else ZMAT *izm_finput(FILE *fp, ZMAT *mat) #endif { char c; unsigned int i, j, m, n, dynamic; /* dynamic set to TRUE if memory allocated here */ /* get matrix size */ if ( mat != ZMNULL && mat->mnm; n = mat->n; dynamic = FALSE; } else { dynamic = TRUE; do { fprintf(stderr,"ComplexMatrix: rows cols:"); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"izm_finput"); } while ( sscanf(line,"%u%u",&m,&n)<2 || m>MAXDIM || n>MAXDIM ); mat = zm_get(m,n); } /* input elements */ for ( i=0; ime[i][j].re,mat->me[i][j].im); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"izm_finput"); if ( (*line == 'b' || *line == 'B') && j > 0 ) { j--; dynamic = FALSE; goto redo2; } if ( (*line == 'f' || *line == 'F') && j < n-1 ) { j++; dynamic = FALSE; goto redo2; } } while ( *line=='\0' || #if REAL == DOUBLE sscanf(line,"%lf%lf", #elif REAL == FLOAT sscanf(line,"%f%f", #endif &mat->me[i][j].re,&mat->me[i][j].im)<1 ); fprintf(stderr,"Continue: "); fscanf(fp,"%c",&c); if ( c == 'n' || c == 'N' ) { dynamic = FALSE; goto redo; } if ( (c == 'b' || c == 'B') /* && i > 0 */ ) { if ( i > 0 ) i--; dynamic = FALSE; goto redo; } } return (mat); } /* bzm_finput -- batch-file input of matrix */ #ifndef ANSI_C ZMAT *bzm_finput(fp,mat) FILE *fp; ZMAT *mat; #else ZMAT *bzm_finput(FILE *fp,ZMAT *mat) #endif { unsigned int i,j,m,n,dummy; int io_code; /* get dimension */ skipjunk(fp); if ((io_code=fscanf(fp," ComplexMatrix: %u by %u",&m,&n)) < 2 || m>MAXDIM || n>MAXDIM ) error(io_code==EOF ? E_EOF : E_FORMAT,"bzm_finput"); /* allocate memory if necessary */ if ( mat==ZMNULL || mat->mnme[i][j].re,&mat->me[i][j].im)) < 2 ) error(io_code==EOF ? E_EOF : E_FORMAT,"bzm_finput"); } } return (mat); } #ifndef ANSI_C ZVEC *zv_finput(fp,x) FILE *fp; ZVEC *x; #else ZVEC *zv_finput(FILE *fp,ZVEC *x) #endif { ZVEC *izv_finput(),*bzv_finput(); if ( isatty(fileno(fp)) ) return izv_finput(fp,x); else return bzv_finput(fp,x); } /* izv_finput -- interactive input of vector */ #ifndef ANSI_C ZVEC *izv_finput(fp,vec) FILE *fp; ZVEC *vec; #else ZVEC *izv_finput(FILE *fp,ZVEC *vec) #endif { unsigned int i,dim,dynamic; /* dynamic set if memory allocated here */ /* get vector dimension */ if ( vec != ZVNULL && vec->dimdim; dynamic = FALSE; } else { dynamic = TRUE; do { fprintf(stderr,"ComplexVector: dim: "); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"izv_finput"); } while ( sscanf(line,"%u",&dim)<1 || dim>MAXDIM ); vec = zv_get(dim); } /* input elements */ for ( i=0; ive[i].re,vec->ve[i].im); if ( fgets(line,MAXLINE,fp)==NULL ) error(E_INPUT,"izv_finput"); if ( (*line == 'b' || *line == 'B') && i > 0 ) { i--; dynamic = FALSE; goto redo; } if ( (*line == 'f' || *line == 'F') && i < dim-1 ) { i++; dynamic = FALSE; goto redo; } } while ( *line=='\0' || #if REAL == DOUBLE sscanf(line,"%lf%lf", #elif REAL == FLOAT sscanf(line,"%f%f", #endif &vec->ve[i].re,&vec->ve[i].im) < 2 ); return (vec); } /* bzv_finput -- batch-file input of vector */ #ifndef ANSI_C ZVEC *bzv_finput(fp,vec) FILE *fp; ZVEC *vec; #else ZVEC *bzv_finput(FILE *fp, ZVEC *vec) #endif { unsigned int i,dim; int io_code; /* get dimension */ skipjunk(fp); if ((io_code=fscanf(fp," ComplexVector: dim:%u",&dim)) < 1 || dim>MAXDIM ) error(io_code==EOF ? 7 : 6,"bzv_finput"); /* allocate memory if necessary */ if ( vec==ZVNULL || vec->dimve[i].re,&vec->ve[i].im)) < 2 ) error(io_code==EOF ? 7 : 6,"bzv_finput"); return (vec); } /************************************************************************** Output routines **************************************************************************/ static const char *zformat = " (%14.9g, %14.9g) "; #ifndef ANSI_C char *setzformat(f_string) char *f_string; #else const char *setzformat(const char *f_string) #endif { const char *old_f_string; old_f_string = zformat; if ( f_string != (char *)NULL && *f_string != '\0' ) zformat = f_string; return old_f_string; } #ifndef ANSI_C void z_foutput(fp,z) FILE *fp; complex z; #else void z_foutput(FILE *fp,complex z) #endif { fprintf(fp,zformat,z.re,z.im); putc('\n',fp); } #ifndef ANSI_C void zm_foutput(fp,a) FILE *fp; ZMAT *a; #else void zm_foutput(FILE *fp,ZMAT *a) #endif { unsigned int i, j, tmp; if ( a == ZMNULL ) { fprintf(fp,"ComplexMatrix: NULL\n"); return; } fprintf(fp,"ComplexMatrix: %d by %d\n",a->m,a->n); if ( a->me == (complex **)NULL ) { fprintf(fp,"NULL\n"); return; } for ( i=0; im; i++ ) /* for each row... */ { fprintf(fp,"row %u: ",i); for ( j=0, tmp=1; jn; j++, tmp++ ) { /* for each col in row... */ fprintf(fp,zformat,a->me[i][j].re,a->me[i][j].im); if ( ! (tmp % 2) ) putc('\n',fp); } if ( tmp % 2 != 1 ) putc('\n',fp); } } #ifndef ANSI_C void zv_foutput(fp,x) FILE *fp; ZVEC *x; #else void zv_foutput(FILE *fp,ZVEC *x) #endif { unsigned int i, tmp; if ( x == ZVNULL ) { fprintf(fp,"ComplexVector: NULL\n"); return; } fprintf(fp,"ComplexVector: dim: %d\n",x->dim); if ( x->ve == (complex *)NULL ) { fprintf(fp,"NULL\n"); return; } for ( i=0, tmp=0; idim; i++, tmp++ ) { fprintf(fp,zformat,x->ve[i].re,x->ve[i].im); if ( (tmp % 2) == 1 ) putc('\n',fp); } if ( (tmp % 2) != 0 ) putc('\n',fp); } #ifndef ANSI_C void zm_dump(fp,a) FILE *fp; ZMAT *a; #else void zm_dump(FILE *fp, ZMAT *a) #endif { unsigned int i, j, tmp; if ( a == ZMNULL ) { fprintf(fp,"ComplexMatrix: NULL\n"); return; } fprintf(fp,"ComplexMatrix: %d by %d @ 0x%lx\n",a->m,a->n,(long)a); fprintf(fp,"\tmax_m = %d, max_n = %d, max_size = %d\n", a->max_m, a->max_n, a->max_size); if ( a->me == (complex **)NULL ) { fprintf(fp,"NULL\n"); return; } fprintf(fp,"a->me @ 0x%lx\n",(long)(a->me)); fprintf(fp,"a->base @ 0x%lx\n",(long)(a->base)); for ( i=0; im; i++ ) /* for each row... */ { fprintf(fp,"row %u: @ 0x%lx ",i,(long)(a->me[i])); for ( j=0, tmp=1; jn; j++, tmp++ ) { /* for each col in row... */ fprintf(fp,zformat,a->me[i][j].re,a->me[i][j].im); if ( ! (tmp % 2) ) putc('\n',fp); } if ( tmp % 2 != 1 ) putc('\n',fp); } } #ifndef ANSI_C void zv_dump(fp,x) FILE *fp; ZVEC *x; #else void zv_dump(FILE *fp,ZVEC *x) #endif { unsigned int i, tmp; if ( ! x ) { fprintf(fp,"ComplexVector: NULL\n"); return; } fprintf(fp,"ComplexVector: dim: %d @ 0x%lx\n",x->dim,(long)(x)); if ( ! x->ve ) { fprintf(fp,"NULL\n"); return; } fprintf(fp,"x->ve @ 0x%lx\n",(long)(x->ve)); for ( i=0, tmp=0; idim; i++, tmp++ ) { fprintf(fp,zformat,x->ve[i].re,x->ve[i].im); if ( tmp % 2 == 1 ) putc('\n',fp); } if ( tmp % 2 != 0 ) putc('\n',fp); } gtk-wave-cleaner-0.22-04/meschach/zmatlab.c0000777000175000017500000001401313120075107021555 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains routines for import/exporting complex data to/from MATLAB. The main routines are: ZMAT *zm_save(FILE *fp,ZMAT *A,char *name) ZVEC *zv_save(FILE *fp,ZVEC *x,char *name) complex z_save(FILE *fp,complex z,char *name) ZMAT *zm_load(FILE *fp,char **name) */ #include #include "zmatrix.h" #include "matlab.h" static char rcsid[] = "$Id: zmatlab.c,v 1.2 1995/02/14 20:13:27 des Exp $"; /* zm_save -- save matrix in ".mat" file for MATLAB -- returns matrix to be saved */ ZMAT *zm_save(fp,A,name) FILE *fp; ZMAT *A; char *name; { int i, j; matlab mat; if ( ! A ) error(E_NULL,"zm_save"); mat.type = 1000*MACH_ID + 100*ORDER + 10*PRECISION + 0; mat.m = A->m; mat.n = A->n; mat.imag = TRUE; mat.namlen = (name == (char *)NULL) ? 1 : strlen(name)+1; /* write header */ fwrite(&mat,sizeof(matlab),1,fp); /* write name */ if ( name == (char *)NULL ) fwrite("",sizeof(char),1,fp); else fwrite(name,sizeof(char),(int)(mat.namlen),fp); /* write actual data */ #if ORDER == ROW_ORDER for ( i = 0; i < A->m; i++ ) for ( j = 0; j < A->n; j++ ) fwrite(&(A->me[i][j].re),sizeof(Real),1,fp); for ( i = 0; i < A->m; i++ ) for ( j = 0; j < A->n; j++ ) fwrite(&(A->me[i][j].im),sizeof(Real),1,fp); #else /* column major order: ORDER == COL_ORDER */ for ( j = 0; j < A->n; j++ ) for ( i = 0; i < A->m; i++ ) fwrite(&(A->me[i][j].re),sizeof(Real),1,fp); for ( j = 0; j < A->n; j++ ) for ( i = 0; i < A->m; i++ ) fwrite(&(A->me[i][j].im),sizeof(Real),1,fp); #endif return A; } /* zv_save -- save vector in ".mat" file for MATLAB -- saves it as a row vector -- returns vector to be saved */ ZVEC *zv_save(fp,x,name) FILE *fp; ZVEC *x; char *name; { int i, j; matlab mat; if ( ! x ) error(E_NULL,"zv_save"); mat.type = 1000*MACH_ID + 100*ORDER + 10*PRECISION + 0; mat.m = x->dim; mat.n = 1; mat.imag = TRUE; mat.namlen = (name == (char *)NULL) ? 1 : strlen(name)+1; /* write header */ fwrite(&mat,sizeof(matlab),1,fp); /* write name */ if ( name == (char *)NULL ) fwrite("",sizeof(char),1,fp); else fwrite(name,sizeof(char),(int)(mat.namlen),fp); /* write actual data */ for ( i = 0; i < x->dim; i++ ) fwrite(&(x->ve[i].re),sizeof(Real),1,fp); for ( i = 0; i < x->dim; i++ ) fwrite(&(x->ve[i].im),sizeof(Real),1,fp); return x; } /* z_save -- saves complex number in ".mat" file for MATLAB -- returns complex number to be saved */ complex z_save(fp,z,name) FILE *fp; complex z; char *name; { matlab mat; mat.type = 1000*MACH_ID + 100*ORDER + 10*PRECISION + 0; mat.m = 1; mat.n = 1; mat.imag = TRUE; mat.namlen = (name == (char *)NULL) ? 1 : strlen(name)+1; /* write header */ fwrite(&mat,sizeof(matlab),1,fp); /* write name */ if ( name == (char *)NULL ) fwrite("",sizeof(char),1,fp); else fwrite(name,sizeof(char),(int)(mat.namlen),fp); /* write actual data */ fwrite(&z,sizeof(complex),1,fp); return z; } /* zm_load -- loads in a ".mat" file variable as produced by MATLAB -- matrix returned; imaginary parts ignored */ ZMAT *zm_load(fp,name) FILE *fp; char **name; { ZMAT *A; int i; int m_flag, o_flag, p_flag, t_flag; float f_temp; double d_temp; matlab mat; if ( fread(&mat,sizeof(matlab),1,fp) != 1 ) error(E_FORMAT,"zm_load"); if ( mat.type >= 10000 ) /* don't load a sparse matrix! */ error(E_FORMAT,"zm_load"); m_flag = (mat.type/1000) % 10; o_flag = (mat.type/100) % 10; p_flag = (mat.type/10) % 10; t_flag = (mat.type) % 10; if ( m_flag != MACH_ID ) error(E_FORMAT,"zm_load"); if ( t_flag != 0 ) error(E_FORMAT,"zm_load"); if ( p_flag != DOUBLE_PREC && p_flag != SINGLE_PREC ) error(E_FORMAT,"zm_load"); *name = (char *)malloc((unsigned)(mat.namlen)+1); if ( fread(*name,sizeof(char),(unsigned)(mat.namlen),fp) == 0 ) error(E_FORMAT,"zm_load"); A = zm_get((unsigned)(mat.m),(unsigned)(mat.n)); for ( i = 0; i < A->m*A->n; i++ ) { if ( p_flag == DOUBLE_PREC ) fread(&d_temp,sizeof(double),1,fp); else { fread(&f_temp,sizeof(float),1,fp); d_temp = f_temp; } if ( o_flag == ROW_ORDER ) A->me[i / A->n][i % A->n].re = d_temp; else if ( o_flag == COL_ORDER ) A->me[i % A->m][i / A->m].re = d_temp; else error(E_FORMAT,"zm_load"); } if ( mat.imag ) /* skip imaginary part */ for ( i = 0; i < A->m*A->n; i++ ) { if ( p_flag == DOUBLE_PREC ) fread(&d_temp,sizeof(double),1,fp); else { fread(&f_temp,sizeof(float),1,fp); d_temp = f_temp; } if ( o_flag == ROW_ORDER ) A->me[i / A->n][i % A->n].im = d_temp; else if ( o_flag == COL_ORDER ) A->me[i % A->m][i / A->m].im = d_temp; else error(E_FORMAT,"zm_load"); } return A; } gtk-wave-cleaner-0.22-04/meschach/zmatop.c0000777000175000017500000003601113120075107021437 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ #include #include "zmatrix.h" static char rcsid[] = "$Id: zmatop.c,v 1.2 1995/03/27 15:49:03 des Exp $"; #define is_zero(z) ((z).re == 0.0 && (z).im == 0.0) /* zm_add -- matrix addition -- may be in-situ */ ZMAT *zm_add(mat1,mat2,out) ZMAT *mat1,*mat2,*out; { unsigned int m,n,i; if ( mat1==ZMNULL || mat2==ZMNULL ) error(E_NULL,"zm_add"); if ( mat1->m != mat2->m || mat1->n != mat2->n ) error(E_SIZES,"zm_add"); if ( out==ZMNULL || out->m != mat1->m || out->n != mat1->n ) out = zm_resize(out,mat1->m,mat1->n); m = mat1->m; n = mat1->n; for ( i=0; ime[i],mat2->me[i],out->me[i],(int)n); /************************************************** for ( j=0; jme[i][j] = mat1->me[i][j]+mat2->me[i][j]; **************************************************/ } return (out); } /* zm_sub -- matrix subtraction -- may be in-situ */ ZMAT *zm_sub(mat1,mat2,out) ZMAT *mat1,*mat2,*out; { unsigned int m,n,i; if ( mat1==ZMNULL || mat2==ZMNULL ) error(E_NULL,"zm_sub"); if ( mat1->m != mat2->m || mat1->n != mat2->n ) error(E_SIZES,"zm_sub"); if ( out==ZMNULL || out->m != mat1->m || out->n != mat1->n ) out = zm_resize(out,mat1->m,mat1->n); m = mat1->m; n = mat1->n; for ( i=0; ime[i],mat2->me[i],out->me[i],(int)n); /************************************************** for ( j=0; jme[i][j] = mat1->me[i][j]-mat2->me[i][j]; **************************************************/ } return (out); } /* Note: In the following routines, "adjoint" means complex conjugate transpose: A* = conjugate(A^T) */ /* zm_mlt -- matrix-matrix multiplication */ ZMAT *zm_mlt(A,B,OUT) ZMAT *A,*B,*OUT; { unsigned int i, /* j, */ k, m, n, p; complex **A_v, **B_v /*, *B_row, *OUT_row, sum, tmp */; if ( A==ZMNULL || B==ZMNULL ) error(E_NULL,"zm_mlt"); if ( A->n != B->m ) error(E_SIZES,"zm_mlt"); if ( A == OUT || B == OUT ) error(E_INSITU,"zm_mlt"); m = A->m; n = A->n; p = B->n; A_v = A->me; B_v = B->me; if ( OUT==ZMNULL || OUT->m != A->m || OUT->n != B->n ) OUT = zm_resize(OUT,A->m,B->n); /**************************************************************** for ( i=0; ime[i][j] = sum; } ****************************************************************/ zm_zero(OUT); for ( i=0; ime[i],B_v[k],A_v[i][k],(int)p,Z_NOCONJ); /************************************************** B_row = B_v[k]; OUT_row = OUT->me[i]; for ( j=0; jn != B->n ) error(E_SIZES,"zmma_mlt"); if ( ! OUT || OUT->m != A->m || OUT->n != B->m ) OUT = zm_resize(OUT,A->m,B->m); limit = A->n; for ( i = 0; i < A->m; i++ ) for ( j = 0; j < B->m; j++ ) { OUT->me[i][j] = __zip__(B->me[j],A->me[i],(int)limit,Z_CONJ); /************************************************** sum = 0.0; A_row = A->me[i]; B_row = B->me[j]; for ( k = 0; k < limit; k++ ) sum += (*A_row++)*(*B_row++); OUT->me[i][j] = sum; **************************************************/ } return OUT; } /* zmam_mlt -- matrix adjoint-matrix multiplication -- A*.B is returned, result stored in OUT */ ZMAT *zmam_mlt(A,B,OUT) ZMAT *A, *B, *OUT; { int i, k, limit; /* complex *B_row, *OUT_row, multiplier; */ complex tmp; if ( ! A || ! B ) error(E_NULL,"zmam_mlt"); if ( A == OUT || B == OUT ) error(E_INSITU,"zmam_mlt"); if ( A->m != B->m ) error(E_SIZES,"zmam_mlt"); if ( ! OUT || OUT->m != A->n || OUT->n != B->n ) OUT = zm_resize(OUT,A->n,B->n); limit = B->n; zm_zero(OUT); for ( k = 0; k < A->m; k++ ) for ( i = 0; i < A->n; i++ ) { tmp.re = A->me[k][i].re; tmp.im = - A->me[k][i].im; if ( ! is_zero(tmp) ) __zmltadd__(OUT->me[i],B->me[k],tmp,(int)limit,Z_NOCONJ); } return OUT; } /* zmv_mlt -- matrix-vector multiplication -- Note: b is treated as a column vector */ ZVEC *zmv_mlt(A,b,out) ZMAT *A; ZVEC *b,*out; { unsigned int i, m, n; complex **A_v, *b_v /*, *A_row */; /* register complex sum; */ if ( A==ZMNULL || b==ZVNULL ) error(E_NULL,"zmv_mlt"); if ( A->n != b->dim ) error(E_SIZES,"zmv_mlt"); if ( b == out ) error(E_INSITU,"zmv_mlt"); if ( out == ZVNULL || out->dim != A->m ) out = zv_resize(out,A->m); m = A->m; n = A->n; A_v = A->me; b_v = b->ve; for ( i=0; ive[i] = __zip__(A_v[i],b_v,(int)n,Z_NOCONJ); /************************************************** A_row = A_v[i]; b_v = b->ve; for ( j=0; jve[i] = sum; **************************************************/ } return out; } /* zsm_mlt -- scalar-matrix multiply -- may be in-situ */ ZMAT *zsm_mlt(scalar,matrix,out) complex scalar; ZMAT *matrix,*out; { unsigned int m,n,i; if ( matrix==ZMNULL ) error(E_NULL,"zsm_mlt"); if ( out==ZMNULL || out->m != matrix->m || out->n != matrix->n ) out = zm_resize(out,matrix->m,matrix->n); m = matrix->m; n = matrix->n; for ( i=0; ime[i],scalar,out->me[i],(int)n); /************************************************** for ( j=0; jme[i][j] = scalar*matrix->me[i][j]; **************************************************/ return (out); } /* zvm_mlt -- vector adjoint-matrix multiplication */ ZVEC *zvm_mlt(A,b,out) ZMAT *A; ZVEC *b,*out; { unsigned int j,m,n; /* complex sum,**A_v,*b_v; */ if ( A==ZMNULL || b==ZVNULL ) error(E_NULL,"zvm_mlt"); if ( A->m != b->dim ) error(E_SIZES,"zvm_mlt"); if ( b == out ) error(E_INSITU,"zvm_mlt"); if ( out == ZVNULL || out->dim != A->n ) out = zv_resize(out,A->n); m = A->m; n = A->n; zv_zero(out); for ( j = 0; j < m; j++ ) if ( b->ve[j].re != 0.0 || b->ve[j].im != 0.0 ) __zmltadd__(out->ve,A->me[j],b->ve[j],(int)n,Z_CONJ); /************************************************** A_v = A->me; b_v = b->ve; for ( j=0; jve[j] = sum; } **************************************************/ return out; } /* zm_adjoint -- adjoint matrix */ ZMAT *zm_adjoint(in,out) ZMAT *in, *out; { int i, j; int in_situ; complex tmp; if ( in == ZMNULL ) error(E_NULL,"zm_adjoint"); if ( in == out && in->n != in->m ) error(E_INSITU2,"zm_adjoint"); in_situ = ( in == out ); if ( out == ZMNULL || out->m != in->n || out->n != in->m ) out = zm_resize(out,in->n,in->m); if ( ! in_situ ) { for ( i = 0; i < in->m; i++ ) for ( j = 0; j < in->n; j++ ) { out->me[j][i].re = in->me[i][j].re; out->me[j][i].im = - in->me[i][j].im; } } else { for ( i = 0 ; i < in->m; i++ ) { for ( j = 0; j < i; j++ ) { tmp.re = in->me[i][j].re; tmp.im = in->me[i][j].im; in->me[i][j].re = in->me[j][i].re; in->me[i][j].im = - in->me[j][i].im; in->me[j][i].re = tmp.re; in->me[j][i].im = - tmp.im; } in->me[i][i].im = - in->me[i][i].im; } } return out; } /* zswap_rows -- swaps rows i and j of matrix A upto column lim */ ZMAT *zswap_rows(A,i,j,lo,hi) ZMAT *A; int i, j, lo, hi; { int k; complex **A_me, tmp; if ( ! A ) error(E_NULL,"swap_rows"); if ( i < 0 || j < 0 || i >= A->m || j >= A->m ) error(E_SIZES,"swap_rows"); lo = max(0,lo); hi = min(hi,A->n-1); A_me = A->me; for ( k = lo; k <= hi; k++ ) { tmp = A_me[k][i]; A_me[k][i] = A_me[k][j]; A_me[k][j] = tmp; } return A; } /* zswap_cols -- swap columns i and j of matrix A upto row lim */ ZMAT *zswap_cols(A,i,j,lo,hi) ZMAT *A; int i, j, lo, hi; { int k; complex **A_me, tmp; if ( ! A ) error(E_NULL,"swap_cols"); if ( i < 0 || j < 0 || i >= A->n || j >= A->n ) error(E_SIZES,"swap_cols"); lo = max(0,lo); hi = min(hi,A->m-1); A_me = A->me; for ( k = lo; k <= hi; k++ ) { tmp = A_me[i][k]; A_me[i][k] = A_me[j][k]; A_me[j][k] = tmp; } return A; } /* mz_mltadd -- matrix-scalar multiply and add -- may be in situ -- returns out == A1 + s*A2 */ ZMAT *mz_mltadd(A1,A2,s,out) ZMAT *A1, *A2, *out; complex s; { /* register complex *A1_e, *A2_e, *out_e; */ /* register int j; */ int i, m, n; if ( ! A1 || ! A2 ) error(E_NULL,"mz_mltadd"); if ( A1->m != A2->m || A1->n != A2->n ) error(E_SIZES,"mz_mltadd"); if ( out != A1 && out != A2 ) out = zm_resize(out,A1->m,A1->n); if ( s.re == 0.0 && s.im == 0.0 ) return zm_copy(A1,out); if ( s.re == 1.0 && s.im == 0.0 ) return zm_add(A1,A2,out); out = zm_copy(A1,out); m = A1->m; n = A1->n; for ( i = 0; i < m; i++ ) { __zmltadd__(out->me[i],A2->me[i],s,(int)n,Z_NOCONJ); /************************************************** A1_e = A1->me[i]; A2_e = A2->me[i]; out_e = out->me[i]; for ( j = 0; j < n; j++ ) out_e[j] = A1_e[j] + s*A2_e[j]; **************************************************/ } return out; } /* zmv_mltadd -- matrix-vector multiply and add -- may not be in situ -- returns out == v1 + alpha*A*v2 */ ZVEC *zmv_mltadd(v1,v2,A,alpha,out) ZVEC *v1, *v2, *out; ZMAT *A; complex alpha; { /* register int j; */ int i, m, n; complex tmp, *v2_ve, *out_ve; if ( ! v1 || ! v2 || ! A ) error(E_NULL,"zmv_mltadd"); if ( out == v2 ) error(E_INSITU,"zmv_mltadd"); if ( v1->dim != A->m || v2->dim != A-> n ) error(E_SIZES,"zmv_mltadd"); tracecatch(out = zv_copy(v1,out),"zmv_mltadd"); v2_ve = v2->ve; out_ve = out->ve; m = A->m; n = A->n; if ( alpha.re == 0.0 && alpha.im == 0.0 ) return out; for ( i = 0; i < m; i++ ) { tmp = __zip__(A->me[i],v2_ve,(int)n,Z_NOCONJ); out_ve[i].re += alpha.re*tmp.re - alpha.im*tmp.im; out_ve[i].im += alpha.re*tmp.im + alpha.im*tmp.re; /************************************************** A_e = A->me[i]; sum = 0.0; for ( j = 0; j < n; j++ ) sum += A_e[j]*v2_ve[j]; out_ve[i] = v1->ve[i] + alpha*sum; **************************************************/ } return out; } /* zvm_mltadd -- vector-matrix multiply and add a la zvm_mlt() -- may not be in situ -- returns out == v1 + v2*.A */ ZVEC *zvm_mltadd(v1,v2,A,alpha,out) ZVEC *v1, *v2, *out; ZMAT *A; complex alpha; { int /* i, */ j, m, n; complex tmp, /* *A_e, */ *out_ve; if ( ! v1 || ! v2 || ! A ) error(E_NULL,"zvm_mltadd"); if ( v2 == out ) error(E_INSITU,"zvm_mltadd"); if ( v1->dim != A->n || A->m != v2->dim ) error(E_SIZES,"zvm_mltadd"); tracecatch(out = zv_copy(v1,out),"zvm_mltadd"); out_ve = out->ve; m = A->m; n = A->n; for ( j = 0; j < m; j++ ) { /* tmp = zmlt(v2->ve[j],alpha); */ tmp.re = v2->ve[j].re*alpha.re - v2->ve[j].im*alpha.im; tmp.im = v2->ve[j].re*alpha.im + v2->ve[j].im*alpha.re; if ( tmp.re != 0.0 || tmp.im != 0.0 ) __zmltadd__(out_ve,A->me[j],tmp,(int)n,Z_CONJ); /************************************************** A_e = A->me[j]; for ( i = 0; i < n; i++ ) out_ve[i] += A_e[i]*tmp; **************************************************/ } return out; } /* zget_col -- gets a specified column of a matrix; returned as a vector */ ZVEC *zget_col(mat,col,vec) int col; ZMAT *mat; ZVEC *vec; { unsigned int i; if ( mat==ZMNULL ) error(E_NULL,"zget_col"); if ( col < 0 || col >= mat->n ) error(E_RANGE,"zget_col"); if ( vec==ZVNULL || vec->dimm ) vec = zv_resize(vec,mat->m); for ( i=0; im; i++ ) vec->ve[i] = mat->me[i][col]; return (vec); } /* zget_row -- gets a specified row of a matrix and retruns it as a vector */ ZVEC *zget_row(mat,row,vec) int row; ZMAT *mat; ZVEC *vec; { int /* i, */ lim; if ( mat==ZMNULL ) error(E_NULL,"zget_row"); if ( row < 0 || row >= mat->m ) error(E_RANGE,"zget_row"); if ( vec==ZVNULL || vec->dimn ) vec = zv_resize(vec,mat->n); lim = min(mat->n,vec->dim); /* for ( i=0; in; i++ ) */ /* vec->ve[i] = mat->me[row][i]; */ MEMCOPY(mat->me[row],vec->ve,lim,complex); return (vec); } /* zset_col -- sets column of matrix to values given in vec (in situ) */ ZMAT *zset_col(mat,col,vec) ZMAT *mat; ZVEC *vec; int col; { unsigned int i,lim; if ( mat==ZMNULL || vec==ZVNULL ) error(E_NULL,"zset_col"); if ( col < 0 || col >= mat->n ) error(E_RANGE,"zset_col"); lim = min(mat->m,vec->dim); for ( i=0; ime[i][col] = vec->ve[i]; return (mat); } /* zset_row -- sets row of matrix to values given in vec (in situ) */ ZMAT *zset_row(mat,row,vec) ZMAT *mat; ZVEC *vec; int row; { unsigned int /* j, */ lim; if ( mat==ZMNULL || vec==ZVNULL ) error(E_NULL,"zset_row"); if ( row < 0 || row >= mat->m ) error(E_RANGE,"zset_row"); lim = min(mat->n,vec->dim); /* for ( j=j0; jme[row][j] = vec->ve[j]; */ MEMCOPY(vec->ve,mat->me[row],lim,complex); return (mat); } /* zm_rand -- randomise a complex matrix; uniform in [0,1)+[0,1)*i */ ZMAT *zm_rand(A) ZMAT *A; { int i; if ( ! A ) error(E_NULL,"zm_rand"); for ( i = 0; i < A->m; i++ ) mrandlist((Real *)(A->me[i]),2*A->n); return A; } gtk-wave-cleaner-0.22-04/meschach/zmatrix.h0000777000175000017500000002503313120075107021632 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Main include file for zmeschach library -- complex vectors and matrices */ #ifndef ZMATRIXH #define ZMATRIXH #include "matrix.h" /* Type definitions for complex vectors and matrices */ /* complex definition */ typedef struct { Real re,im; } complex; /* complex vector definition */ typedef struct { unsigned int dim, max_dim; complex *ve; } ZVEC; /* complex matrix definition */ typedef struct { unsigned int m, n; unsigned int max_m, max_n, max_size; complex *base; /* base is base of alloc'd mem */ complex **me; } ZMAT; #define ZVNULL ((ZVEC *)NULL) #define ZMNULL ((ZMAT *)NULL) #define Z_CONJ 1 #define Z_NOCONJ 0 #define zm_entry(A,i,j) zm_get_val(A,i,j) #define zv_entry(x,i) zv_get_val(x,i) #ifdef DEBUG #define zm_set_val(A,i,j,val) ( m_chk_idx(A,i,j) ? \ (A)->me[(i)][(j)] = (val) : (error(E_BOUNDS,"zm_set_val"), zmake(0.0,0.0))) #define zm_add_val(A,i,j,val) ( m_chk_idx(A,i,j) ? \ (A)->me[(i)][(j)] = zadd((A)->me[(i)][(j)],(val)) : \ (error(E_BOUNDS,"zm_add_val"), zmake(0.0,0.0))) #define zm_sub_val(A,i,j,val) ( m_chk_idx(A,i,j) ? \ (A)->me[(i)][(j)] = zsub((A)->me[(i)][(j)],(val)) : \ (error(E_BOUNDS,"zm_sub_val"), zmake(0.0,0.0))) #define zm_get_val(A,i,j) ( m_chk_idx(A,i,j) ? \ (A)->me[(i)][(j)] : (error(E_BOUNDS,"zm_get_val"), zmake(0.0,0.0))) #define zv_set_val(x,i,val) ( v_chk_idx(x,i) ? (x)->ve[(i)] = (val) : \ (error(E_BOUNDS,"zv_set_val"), zmake(0.0,0.0))) #define zv_add_val(x,i,val) ( v_chk_idx(x,i) ? \ (x)->ve[(i)] = zadd((x)->ve[(i)],(val)) : \ (error(E_BOUNDS,"zv_set_val"), zmake(0.0,0.0))) #define zv_sub_val(x,i,val) ( v_chk_idx(x,i) ? \ (x)->ve[(i)] = zsub((x)->ve[(i)],(val)) : \ (error(E_BOUNDS,"zv_set_val"), zmake(0.0,0.0))) #define zv_get_val(x,i) ( v_chk_idx(x,i) ? (x)->ve[(i)] : \ (error(E_BOUNDS,"zv_get_val"), zmake(0.0,0.0))) #else /* no DEBUG */ #define zm_set_val(A,i,j,val) ((A)->me[(i)][(j)] = (val)) #define zm_add_val(A,i,j,val) ((A)->me[(i)][(j)] = zadd((A)->me[(i)][(j)],(val))) #define zm_sub_val(A,i,j,val) ((A)->me[(i)][(j)] = zsub((A)->me[(i)][(j)],(val))) #define zm_get_val(A,i,j) ((A)->me[(i)][(j)]) #define zv_set_val(x,i,val) ((x)->ve[(i)] = (val)) #define zv_add_val(x,i,val) ((x)->ve[(i)] = zadd((x)->ve[(i)],(val))) #define zv_sub_val(x,i,val) ((x)->ve[(i)] = zsub((x)->ve[(i)],(val))) #define zv_get_val(x,i) ((x)->ve[(i)]) #endif /* DEBUG */ /* memory functions */ #ifdef ANSI_C int zv_get_vars(int dim,...); int zm_get_vars(int m,int n,...); int zv_resize_vars(int new_dim,...); int zm_resize_vars(int m,int n,...); int zv_free_vars(ZVEC **,...); int zm_free_vars(ZMAT **,...); #elif VARARGS int zv_get_vars(); int zm_get_vars(); int zv_resize_vars(); int zm_resize_vars(); int zv_free_vars(); int zm_free_vars(); #endif #ifdef ANSI_C extern ZMAT *_zm_copy(const ZMAT *in,ZMAT *out, int i0, int j0); extern ZMAT * zm_move(const ZMAT *, int, int, int, int, ZMAT *, int, int); extern ZMAT *zvm_move(const ZVEC *, int, ZMAT *, int, int, int, int); extern ZVEC *_zv_copy(const ZVEC *in,ZVEC *out,int i0); extern ZVEC * zv_move(const ZVEC *, int, int, ZVEC *, int); extern ZVEC *zmv_move(const ZMAT *, int, int, int, int, ZVEC *, int); extern complex z_finput(FILE *fp); extern ZMAT *zm_finput(FILE *fp,ZMAT *a); extern ZVEC *zv_finput(FILE *fp,ZVEC *x); extern ZMAT *zm_add(ZMAT *mat1,ZMAT *mat2,ZMAT *out); extern ZMAT *zm_sub(ZMAT *mat1,ZMAT *mat2,ZMAT *out); extern ZMAT *zm_mlt(ZMAT *A,ZMAT *B,ZMAT *OUT); extern ZMAT *zmma_mlt(ZMAT *A,ZMAT *B,ZMAT *OUT); extern ZMAT *zmam_mlt(ZMAT *A,ZMAT *B,ZMAT *OUT); extern ZVEC *zmv_mlt(ZMAT *A,ZVEC *b,ZVEC *out); extern ZMAT *zsm_mlt(complex scalar,ZMAT *matrix,ZMAT *out); extern ZVEC *zvm_mlt(ZMAT *A,ZVEC *b,ZVEC *out); extern ZMAT *zm_adjoint(ZMAT *in,ZMAT *out); extern ZMAT *zswap_rows(ZMAT *A,int i,int j,int lo,int hi); extern ZMAT *zswap_cols(ZMAT *A,int i,int j,int lo,int hi); extern ZMAT *mz_mltadd(ZMAT *A1,ZMAT *A2,complex s,ZMAT *out); extern ZVEC *zmv_mltadd(ZVEC *v1,ZVEC *v2,ZMAT *A,complex alpha,ZVEC *out); extern ZVEC *zvm_mltadd(ZVEC *v1,ZVEC *v2,ZMAT *A,complex alpha,ZVEC *out); extern ZVEC *zv_zero(ZVEC *x); extern ZMAT *zm_zero(ZMAT *A); extern ZMAT *zm_get(int m,int n); extern ZVEC *zv_get(int dim); extern ZMAT *zm_resize(ZMAT *A,int new_m,int new_n); extern complex _zin_prod(const ZVEC *x, const ZVEC *y,unsigned int i0,unsigned int flag); extern ZVEC *zv_resize(ZVEC *x,int new_dim); extern ZVEC *zv_mlt(complex scalar,const ZVEC *vector,ZVEC *out); extern ZVEC *zv_add(const ZVEC *vec1,const ZVEC *vec2,ZVEC *out); extern ZVEC *zv_mltadd(const ZVEC *v1,const ZVEC *v2,complex scale,ZVEC *out); extern ZVEC *zv_sub(const ZVEC *vec1,const ZVEC *vec2,ZVEC *out); #ifdef PROTOTYPES_IN_STRUCT extern ZVEC *zv_map(complex (*f)(),const ZVEC *x,ZVEC *out); extern ZVEC *_zv_map(complex (*f)(),void *params,const ZVEC *x,ZVEC *out); #else extern ZVEC *zv_map(complex (*f)(complex),const ZVEC *x,ZVEC *out); extern ZVEC *_zv_map(complex (*f)(void *,complex),void *params,const ZVEC *x,ZVEC *out); #endif extern ZVEC *zv_lincomb(int n,const ZVEC *v[],const complex a[],ZVEC *out); extern ZVEC *zv_linlist(ZVEC *out,ZVEC *v1,complex a1,...); extern ZVEC *zv_star(const ZVEC *x1, const ZVEC *x2, ZVEC *out); extern ZVEC *zv_slash(const ZVEC *x1, const ZVEC *x2, ZVEC *out); extern complex zv_sum(const ZVEC *x); extern int zm_free(ZMAT *mat); extern int zv_free(ZVEC *vec); extern ZVEC *zv_rand(ZVEC *x); extern ZMAT *zm_rand(ZMAT *A); extern ZVEC *zget_row(ZMAT *A, int i, ZVEC *out); extern ZVEC *zget_col(ZMAT *A, int j, ZVEC *out); extern ZMAT *zset_row(ZMAT *A, int i, ZVEC *in); extern ZMAT *zset_col(ZMAT *A, int j, ZVEC *in); extern ZVEC *px_zvec(PERM *pi, ZVEC *in, ZVEC *out); extern ZVEC *pxinv_zvec(PERM *pi, ZVEC *in, ZVEC *out); extern void __zconj__(complex zp[], int len); extern complex __zip__(const complex zp1[], const complex zp2[], int len,int flag); extern void __zmltadd__(complex zp1[], const complex zp2[], complex s,int len,int flag); extern void __zmlt__(const complex zp[],complex s,complex out[],int len); extern void __zadd__(const complex zp1[],const complex zp2[], complex out[],int len); extern void __zsub__(const complex zp1[],const complex zp2[], complex out[],int len); extern void __zzero__(complex zp[],int len); extern void z_foutput(FILE *fp,complex z); extern void zm_foutput(FILE *fp,ZMAT *a); extern void zv_foutput(FILE *fp,ZVEC *x); extern void zm_dump(FILE *fp,ZMAT *a); extern void zv_dump(FILE *fp,ZVEC *x); extern double _zv_norm1(ZVEC *x, VEC *scale); extern double _zv_norm2(ZVEC *x, VEC *scale); extern double _zv_norm_inf(ZVEC *x, VEC *scale); extern double zm_norm1(ZMAT *A); extern double zm_norm_inf(ZMAT *A); extern double zm_norm_frob(ZMAT *A); complex zmake(double real, double imag); double zabs(complex z); complex zadd(complex z1,complex z2); complex zsub(complex z1,complex z2); complex zmlt(complex z1,complex z2); complex zinv(complex z); complex zdiv(complex z1,complex z2); complex zsqrt(complex z); complex zexp(complex z); complex zlog(complex z); complex zconj(complex z); complex zneg(complex z); #else extern ZMAT *_zm_copy(); extern ZVEC *_zv_copy(); extern ZMAT *zm_finput(); extern ZVEC *zv_finput(); extern ZMAT *zm_add(); extern ZMAT *zm_sub(); extern ZMAT *zm_mlt(); extern ZMAT *zmma_mlt(); extern ZMAT *zmam_mlt(); extern ZVEC *zmv_mlt(); extern ZMAT *zsm_mlt(); extern ZVEC *zvm_mlt(); extern ZMAT *zm_adjoint(); extern ZMAT *zswap_rows(); extern ZMAT *zswap_cols(); extern ZMAT *mz_mltadd(); extern ZVEC *zmv_mltadd(); extern ZVEC *zvm_mltadd(); extern ZVEC *zv_zero(); extern ZMAT *zm_zero(); extern ZMAT *zm_get(); extern ZVEC *zv_get(); extern ZMAT *zm_resize(); extern ZVEC *zv_resize(); extern complex _zin_prod(); extern ZVEC *zv_mlt(); extern ZVEC *zv_add(); extern ZVEC *zv_mltadd(); extern ZVEC *zv_sub(); extern ZVEC *zv_map(); extern ZVEC *_zv_map(); extern ZVEC *zv_lincomb(); extern ZVEC *zv_linlist(); extern ZVEC *zv_star(); extern ZVEC *zv_slash(); extern ZVEC *px_zvec(); extern ZVEC *pxinv_zvec(); extern ZVEC *zv_rand(); extern ZMAT *zm_rand(); extern ZVEC *zget_row(); extern ZVEC *zget_col(); extern ZMAT *zset_row(); extern ZMAT *zset_col(); extern int zm_free(); extern int zv_free(); extern void __zconj__(); extern complex __zip__(); extern void __zmltadd__(); extern void __zmlt__(); extern void __zadd__(); extern void __zsub__(); extern void __zzero__(); extern void zm_foutput(); extern void zv_foutput(); extern void zm_dump(); extern void zv_dump(); extern double _zv_norm1(); extern double _zv_norm2(); extern double _zv_norm_inf(); extern double zm_norm1(); extern double zm_norm_inf(); extern double zm_norm_frob(); complex zmake(); double zabs(); complex zadd(); complex zsub(); complex zmlt(); complex zinv(); complex zdiv(); complex zsqrt(); complex zexp(); complex zlog(); complex zconj(); complex zneg(); #endif #define zv_copy(x,y) _zv_copy(x,y,0) #define zm_copy(A,B) _zm_copy(A,B,0,0) #define z_input() z_finput(stdin) #define zv_input(x) zv_finput(stdin,x) #define zm_input(A) zm_finput(stdin,A) #define z_output(z) z_foutput(stdout,z) #define zv_output(x) zv_foutput(stdout,x) #define zm_output(A) zm_foutput(stdout,A) #define ZV_FREE(x) ( zv_free(x), (x) = ZVNULL ) #define ZM_FREE(A) ( zm_free(A), (A) = ZMNULL ) #define zin_prod(x,y) _zin_prod(x,y,0,Z_CONJ) #define zv_norm1(x) _zv_norm1(x,VNULL) #define zv_norm2(x) _zv_norm2(x,VNULL) #define zv_norm_inf(x) _zv_norm_inf(x,VNULL) #endif gtk-wave-cleaner-0.22-04/meschach/zmatrix2.h0000777000175000017500000001026113120075107021711 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* 2nd header file for Meschach's complex routines. This file contains declarations for complex factorisation/solve routines. */ #ifndef ZMATRIX2H #define ZMATRIX2H #include "zmatrix.h" #ifdef ANSI_C extern ZVEC *zUsolve(ZMAT *matrix, ZVEC *b, ZVEC *out, double diag); extern ZVEC *zLsolve(ZMAT *matrix, ZVEC *b, ZVEC *out, double diag); extern ZVEC *zUAsolve(ZMAT *U, ZVEC *b, ZVEC *out, double diag); extern ZVEC *zDsolve(ZMAT *A, ZVEC *b, ZVEC *x); extern ZVEC *zLAsolve(ZMAT *L, ZVEC *b, ZVEC *out, double diag); extern ZVEC *zhhvec(ZVEC *,int,Real *,ZVEC *,complex *); extern ZVEC *zhhtrvec(ZVEC *,double,int,ZVEC *,ZVEC *); extern ZMAT *zhhtrrows(ZMAT *,int,int,ZVEC *,double); extern ZMAT *zhhtrcols(ZMAT *,int,int,ZVEC *,double); extern ZMAT *_zhhtrcols(ZMAT *,int,int,ZVEC *,double,ZVEC *); extern ZMAT *zHfactor(ZMAT *,ZVEC *); extern ZMAT *zHQunpack(ZMAT *,ZVEC *,ZMAT *,ZMAT *); extern ZMAT *zQRfactor(ZMAT *A, ZVEC *diag); extern ZMAT *zQRCPfactor(ZMAT *A, ZVEC *diag, PERM *px); extern ZVEC *_zQsolve(ZMAT *QR, ZVEC *diag, ZVEC *b, ZVEC *x, ZVEC *tmp); extern ZMAT *zmakeQ(ZMAT *QR, ZVEC *diag, ZMAT *Qout); extern ZMAT *zmakeR(ZMAT *QR, ZMAT *Rout); extern ZVEC *zQRsolve(ZMAT *QR, ZVEC *diag, ZVEC *b, ZVEC *x); extern ZVEC *zQRAsolve(ZMAT *QR, ZVEC *diag, ZVEC *b, ZVEC *x); extern ZVEC *zQRCPsolve(ZMAT *QR,ZVEC *diag,PERM *pivot,ZVEC *b,ZVEC *x); extern ZVEC *zUmlt(ZMAT *U, ZVEC *x, ZVEC *out); extern ZVEC *zUAmlt(ZMAT *U, ZVEC *x, ZVEC *out); extern double zQRcondest(ZMAT *QR); extern ZVEC *zLsolve(ZMAT *, ZVEC *, ZVEC *, double); extern ZMAT *zset_col(ZMAT *, int, ZVEC *); extern ZMAT *zLUfactor(ZMAT *A, PERM *pivot); extern ZVEC *zLUsolve(ZMAT *A, PERM *pivot, ZVEC *b, ZVEC *x); extern ZVEC *zLUAsolve(ZMAT *LU, PERM *pivot, ZVEC *b, ZVEC *x); extern ZMAT *zm_inverse(ZMAT *A, ZMAT *out); extern double zLUcondest(ZMAT *LU, PERM *pivot); extern void zgivens(complex, complex, Real *, complex *); extern ZMAT *zrot_rows(ZMAT *A, int i, int k, double c, complex s, ZMAT *out); extern ZMAT *zrot_cols(ZMAT *A, int i, int k, double c, complex s, ZMAT *out); extern ZVEC *rot_zvec(ZVEC *x, int i, int k, double c, complex s, ZVEC *out); extern ZMAT *zschur(ZMAT *A,ZMAT *Q); /* extern ZMAT *schur_vecs(ZMAT *T,ZMAT *Q,X_re,X_im) */ #else extern ZVEC *zUsolve(), *zLsolve(), *zUAsolve(), *zDsolve(), *zLAsolve(); extern ZVEC *zhhvec(); extern ZVEC *zhhtrvec(); extern ZMAT *zhhtrrows(); extern ZMAT *zhhtrcols(); extern ZMAT *_zhhtrcols(); extern ZMAT *zHfactor(); extern ZMAT *zHQunpack(); extern ZMAT *zQRfactor(), *zQRCPfactor(); extern ZVEC *_zQsolve(); extern ZMAT *zmakeQ(), *zmakeR(); extern ZVEC *zQRsolve(), *zQRAsolve(), *zQRCPsolve(); extern ZVEC *zUmlt(), *zUAmlt(); extern double zQRcondest(); extern ZVEC *zLsolve(); extern ZMAT *zset_col(); extern ZMAT *zLUfactor(); extern ZVEC *zLUsolve(), *zLUAsolve(); extern ZMAT *zm_inverse(); extern double zLUcondest(); extern void zgivens(); extern ZMAT *zrot_rows(), *zrot_cols(); extern ZVEC *rot_zvec(); extern ZMAT *zschur(); /* extern ZMAT *schur_vecs(); */ #endif /* ANSI_C */ #endif /* ZMATRIX2H */ gtk-wave-cleaner-0.22-04/meschach/zmemory.c0000777000175000017500000003657613120075107021647 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Memory allocation and de-allocation for complex matrices and vectors */ #include #include "zmatrix.h" static char rcsid[] = "$Id: zmemory.c,v 1.2 1994/04/05 02:13:14 des Exp $"; /* zv_zero -- zeros all entries of a complex vector -- uses __zzero__() */ #ifndef ANSI_C ZVEC *zv_zero(x) ZVEC *x; #else ZVEC *zv_zero(ZVEC *x) #endif { if ( ! x ) error(E_NULL,"zv_zero"); __zzero__(x->ve,x->dim); return x; } /* zm_zero -- zeros all entries of a complex matrix -- uses __zzero__() */ #ifndef ANSI_C ZMAT *zm_zero(A) ZMAT *A; #else ZMAT *zm_zero(ZMAT *A) #endif { int i; if ( ! A ) error(E_NULL,"zm_zero"); for ( i = 0; i < A->m; i++ ) __zzero__(A->me[i],A->n); return A; } /* zm_get -- gets an mxn complex matrix (in ZMAT form) */ #ifndef ANSI_C ZMAT *zm_get(m,n) int m,n; #else ZMAT *zm_get(int m, int n) #endif { ZMAT *matrix; unsigned int i; if (m < 0 || n < 0) error(E_NEG,"zm_get"); if ((matrix=NEW(ZMAT)) == (ZMAT *)NULL ) error(E_MEM,"zm_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,0,sizeof(ZMAT)); mem_numvar(TYPE_ZMAT,1); } matrix->m = m; matrix->n = matrix->max_n = n; matrix->max_m = m; matrix->max_size = m*n; #ifndef SEGMENTED if ((matrix->base = NEW_A(m*n,complex)) == (complex *)NULL ) { free(matrix); error(E_MEM,"zm_get"); } else if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,0,m*n*sizeof(complex)); } #else matrix->base = (complex *)NULL; #endif if ((matrix->me = (complex **)calloc(m,sizeof(complex *))) == (complex **)NULL ) { free(matrix->base); free(matrix); error(E_MEM,"zm_get"); } else if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,0,m*sizeof(complex *)); } #ifndef SEGMENTED /* set up pointers */ for ( i=0; ime[i] = &(matrix->base[i*n]); #else for ( i = 0; i < m; i++ ) if ( (matrix->me[i]=NEW_A(n,complex)) == (complex *)NULL ) error(E_MEM,"zm_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,0,n*sizeof(complex)); } #endif return (matrix); } /* zv_get -- gets a ZVEC of dimension 'dim' -- Note: initialized to zero */ #ifndef ANSI_C ZVEC *zv_get(size) int size; #else ZVEC *zv_get(int size) #endif { ZVEC *vector; if (size < 0) error(E_NEG,"zv_get"); if ((vector=NEW(ZVEC)) == (ZVEC *)NULL ) error(E_MEM,"zv_get"); else if (mem_info_is_on()) { mem_bytes(TYPE_ZVEC,0,sizeof(ZVEC)); mem_numvar(TYPE_ZVEC,1); } vector->dim = vector->max_dim = size; if ((vector->ve=NEW_A(size,complex)) == (complex *)NULL ) { free(vector); error(E_MEM,"zv_get"); } else if (mem_info_is_on()) { mem_bytes(TYPE_ZVEC,0,size*sizeof(complex)); } return (vector); } /* zm_free -- returns ZMAT & asoociated memory back to memory heap */ #ifndef ANSI_C int zm_free(mat) ZMAT *mat; #else int zm_free(ZMAT *mat) #endif { #ifdef SEGMENTED int i; #endif if ( mat==(ZMAT *)NULL || (int)(mat->m) < 0 || (int)(mat->n) < 0 ) /* don't trust it */ return (-1); #ifndef SEGMENTED if ( mat->base != (complex *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,mat->max_m*mat->max_n*sizeof(complex),0); } free((char *)(mat->base)); } #else for ( i = 0; i < mat->max_m; i++ ) if ( mat->me[i] != (complex *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,mat->max_n*sizeof(complex),0); } free((char *)(mat->me[i])); } #endif if ( mat->me != (complex **)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,mat->max_m*sizeof(complex *),0); } free((char *)(mat->me)); } if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,sizeof(ZMAT),0); mem_numvar(TYPE_ZMAT,-1); } free((char *)mat); return (0); } /* zv_free -- returns ZVEC & asoociated memory back to memory heap */ #ifndef ANSI_C int zv_free(vec) ZVEC *vec; #else int zv_free(ZVEC *vec) #endif { if ( vec==(ZVEC *)NULL || (int)(vec->dim) < 0 ) /* don't trust it */ return (-1); if ( vec->ve == (complex *)NULL ) { if (mem_info_is_on()) { mem_bytes(TYPE_ZVEC,sizeof(ZVEC),0); mem_numvar(TYPE_ZVEC,-1); } free((char *)vec); } else { if (mem_info_is_on()) { mem_bytes(TYPE_ZVEC,vec->max_dim*sizeof(complex)+ sizeof(ZVEC),0); mem_numvar(TYPE_ZVEC,-1); } free((char *)vec->ve); free((char *)vec); } return (0); } /* zm_resize -- returns the matrix A of size new_m x new_n; A is zeroed -- if A == NULL on entry then the effect is equivalent to m_get() */ #ifndef ANSI_C ZMAT *zm_resize(A,new_m,new_n) ZMAT *A; int new_m, new_n; #else ZMAT *zm_resize(ZMAT *A, int new_m, int new_n) #endif { unsigned int i, new_max_m, new_max_n, new_size, old_m, old_n; if (new_m < 0 || new_n < 0) error(E_NEG,"zm_resize"); if ( ! A ) return zm_get(new_m,new_n); if (new_m == A->m && new_n == A->n) return A; old_m = A->m; old_n = A->n; if ( new_m > A->max_m ) { /* re-allocate A->me */ if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,A->max_m*sizeof(complex *), new_m*sizeof(complex *)); } A->me = RENEW(A->me,new_m,complex *); if ( ! A->me ) error(E_MEM,"zm_resize"); } new_max_m = max(new_m,A->max_m); new_max_n = max(new_n,A->max_n); #ifndef SEGMENTED new_size = new_max_m*new_max_n; if ( new_size > A->max_size ) { /* re-allocate A->base */ if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,A->max_m*A->max_n*sizeof(complex), new_size*sizeof(complex)); } A->base = RENEW(A->base,new_size,complex); if ( ! A->base ) error(E_MEM,"zm_resize"); A->max_size = new_size; } /* now set up A->me[i] */ for ( i = 0; i < new_m; i++ ) A->me[i] = &(A->base[i*new_n]); /* now shift data in matrix */ if ( old_n > new_n ) { for ( i = 1; i < min(old_m,new_m); i++ ) MEM_COPY((char *)&(A->base[i*old_n]), (char *)&(A->base[i*new_n]), sizeof(complex)*new_n); } else if ( old_n < new_n ) { for ( i = min(old_m,new_m)-1; i > 0; i-- ) { /* copy & then zero extra space */ MEM_COPY((char *)&(A->base[i*old_n]), (char *)&(A->base[i*new_n]), sizeof(complex)*old_n); __zzero__(&(A->base[i*new_n+old_n]),(new_n-old_n)); } __zzero__(&(A->base[old_n]),(new_n-old_n)); A->max_n = new_n; } /* zero out the new rows.. */ for ( i = old_m; i < new_m; i++ ) __zzero__(&(A->base[i*new_n]),new_n); #else if ( A->max_n < new_n ) { complex *tmp; for ( i = 0; i < A->max_m; i++ ) { if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,A->max_n*sizeof(complex), new_max_n*sizeof(complex)); } if ( (tmp = RENEW(A->me[i],new_max_n,complex)) == NULL ) error(E_MEM,"zm_resize"); else { A->me[i] = tmp; } } for ( i = A->max_m; i < new_max_m; i++ ) { if ( (tmp = NEW_A(new_max_n,complex)) == NULL ) error(E_MEM,"zm_resize"); else { A->me[i] = tmp; if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,0,new_max_n*sizeof(complex)); } } } } else if ( A->max_m < new_m ) { for ( i = A->max_m; i < new_m; i++ ) if ( (A->me[i] = NEW_A(new_max_n,complex)) == NULL ) error(E_MEM,"zm_resize"); else if (mem_info_is_on()) { mem_bytes(TYPE_ZMAT,0,new_max_n*sizeof(complex)); } } if ( old_n < new_n ) { for ( i = 0; i < old_m; i++ ) __zzero__(&(A->me[i][old_n]),new_n-old_n); } /* zero out the new rows.. */ for ( i = old_m; i < new_m; i++ ) __zzero__(A->me[i],new_n); #endif A->max_m = new_max_m; A->max_n = new_max_n; A->max_size = A->max_m*A->max_n; A->m = new_m; A->n = new_n; return A; } /* zv_resize -- returns the (complex) vector x with dim new_dim -- x is set to the zero vector */ #ifndef ANSI_C ZVEC *zv_resize(x,new_dim) ZVEC *x; int new_dim; #else ZVEC *zv_resize(ZVEC *x, int new_dim) #endif { if (new_dim < 0) error(E_NEG,"zv_resize"); if ( ! x ) return zv_get(new_dim); if (new_dim == x->dim) return x; if ( x->max_dim == 0 ) /* assume that it's from sub_zvec */ return zv_get(new_dim); if ( new_dim > x->max_dim ) { if (mem_info_is_on()) { mem_bytes(TYPE_ZVEC,x->max_dim*sizeof(complex), new_dim*sizeof(complex)); } x->ve = RENEW(x->ve,new_dim,complex); if ( ! x->ve ) error(E_MEM,"zv_resize"); x->max_dim = new_dim; } if ( new_dim > x->dim ) __zzero__(&(x->ve[x->dim]),new_dim - x->dim); x->dim = new_dim; return x; } /* varying arguments */ #ifdef ANSI_C #include /* To allocate memory to many arguments. The function should be called: zv_get_vars(dim,&x,&y,&z,...,NULL); where int dim; ZVEC *x, *y, *z,...; The last argument should be NULL ! dim is the length of vectors x,y,z,... returned value is equal to the number of allocated variables Other gec_... functions are similar. */ int zv_get_vars(int dim,...) { va_list ap; int i=0; ZVEC **par; va_start(ap, dim); while (par = va_arg(ap,ZVEC **)) { /* NULL ends the list*/ *par = zv_get(dim); i++; } va_end(ap); return i; } int zm_get_vars(int m,int n,...) { va_list ap; int i=0; ZMAT **par; va_start(ap, n); while (par = va_arg(ap,ZMAT **)) { /* NULL ends the list*/ *par = zm_get(m,n); i++; } va_end(ap); return i; } /* To resize memory for many arguments. The function should be called: v_resize_vars(new_dim,&x,&y,&z,...,NULL); where int new_dim; ZVEC *x, *y, *z,...; The last argument should be NULL ! rdim is the resized length of vectors x,y,z,... returned value is equal to the number of allocated variables. If one of x,y,z,.. arguments is NULL then memory is allocated to this argument. Other *_resize_list() functions are similar. */ int zv_resize_vars(int new_dim,...) { va_list ap; int i=0; ZVEC **par; va_start(ap, new_dim); while (par = va_arg(ap,ZVEC **)) { /* NULL ends the list*/ *par = zv_resize(*par,new_dim); i++; } va_end(ap); return i; } int zm_resize_vars(int m,int n,...) { va_list ap; int i=0; ZMAT **par; va_start(ap, n); while (par = va_arg(ap,ZMAT **)) { /* NULL ends the list*/ *par = zm_resize(*par,m,n); i++; } va_end(ap); return i; } /* To deallocate memory for many arguments. The function should be called: v_free_vars(&x,&y,&z,...,NULL); where ZVEC *x, *y, *z,...; The last argument should be NULL ! There must be at least one not NULL argument. returned value is equal to the number of allocated variables. Returned value of x,y,z,.. is VNULL. Other *_free_list() functions are similar. */ int zv_free_vars(ZVEC **pv,...) { va_list ap; int i=1; ZVEC **par; zv_free(*pv); *pv = ZVNULL; va_start(ap, pv); while (par = va_arg(ap,ZVEC **)) { /* NULL ends the list*/ zv_free(*par); *par = ZVNULL; i++; } va_end(ap); return i; } int zm_free_vars(ZMAT **va,...) { va_list ap; int i=1; ZMAT **par; zm_free(*va); *va = ZMNULL; va_start(ap, va); while (par = va_arg(ap,ZMAT **)) { /* NULL ends the list*/ zm_free(*par); *par = ZMNULL; i++; } va_end(ap); return i; } #elif VARARGS #include /* To allocate memory to many arguments. The function should be called: v_get_vars(dim,&x,&y,&z,...,NULL); where int dim; ZVEC *x, *y, *z,...; The last argument should be NULL ! dim is the length of vectors x,y,z,... returned value is equal to the number of allocated variables Other gec_... functions are similar. */ int zv_get_vars(va_alist) va_dcl { va_list ap; int dim,i=0; ZVEC **par; va_start(ap); dim = va_arg(ap,int); while (par = va_arg(ap,ZVEC **)) { /* NULL ends the list*/ *par = zv_get(dim); i++; } va_end(ap); return i; } int zm_get_vars(va_alist) va_dcl { va_list ap; int i=0, n, m; ZMAT **par; va_start(ap); m = va_arg(ap,int); n = va_arg(ap,int); while (par = va_arg(ap,ZMAT **)) { /* NULL ends the list*/ *par = zm_get(m,n); i++; } va_end(ap); return i; } /* To resize memory for many arguments. The function should be called: v_resize_vars(new_dim,&x,&y,&z,...,NULL); where int new_dim; ZVEC *x, *y, *z,...; The last argument should be NULL ! rdim is the resized length of vectors x,y,z,... returned value is equal to the number of allocated variables. If one of x,y,z,.. arguments is NULL then memory is allocated to this argument. Other *_resize_list() functions are similar. */ int zv_resize_vars(va_alist) va_dcl { va_list ap; int i=0, new_dim; ZVEC **par; va_start(ap); new_dim = va_arg(ap,int); while (par = va_arg(ap,ZVEC **)) { /* NULL ends the list*/ *par = zv_resize(*par,new_dim); i++; } va_end(ap); return i; } int zm_resize_vars(va_alist) va_dcl { va_list ap; int i=0, m, n; ZMAT **par; va_start(ap); m = va_arg(ap,int); n = va_arg(ap,int); while (par = va_arg(ap,ZMAT **)) { /* NULL ends the list*/ *par = zm_resize(*par,m,n); i++; } va_end(ap); return i; } /* To deallocate memory for many arguments. The function should be called: v_free_vars(&x,&y,&z,...,NULL); where ZVEC *x, *y, *z,...; The last argument should be NULL ! There must be at least one not NULL argument. returned value is equal to the number of allocated variables. Returned value of x,y,z,.. is VNULL. Other *_free_list() functions are similar. */ int zv_free_vars(va_alist) va_dcl { va_list ap; int i=0; ZVEC **par; va_start(ap); while (par = va_arg(ap,ZVEC **)) { /* NULL ends the list*/ zv_free(*par); *par = ZVNULL; i++; } va_end(ap); return i; } int zm_free_vars(va_alist) va_dcl { va_list ap; int i=0; ZMAT **par; va_start(ap); while (par = va_arg(ap,ZMAT **)) { /* NULL ends the list*/ zm_free(*par); *par = ZMNULL; i++; } va_end(ap); return i; } #endif gtk-wave-cleaner-0.22-04/meschach/znorm.c0000777000175000017500000001102013120075107021263 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* A collection of functions for computing norms: scaled and unscaled Complex version */ static char rcsid[] = "$Id: znorm.c,v 1.1 1994/01/13 04:21:31 des Exp $"; #include #include #include "zmatrix.h" /* _zv_norm1 -- computes (scaled) 1-norms of vectors */ double _zv_norm1(x,scale) ZVEC *x; VEC *scale; { int i, dim; Real s, sum; if ( x == ZVNULL ) error(E_NULL,"_zv_norm1"); dim = x->dim; sum = 0.0; if ( scale == VNULL ) for ( i = 0; i < dim; i++ ) sum += zabs(x->ve[i]); else if ( scale->dim < dim ) error(E_SIZES,"_zv_norm1"); else for ( i = 0; i < dim; i++ ) { s = scale->ve[i]; sum += ( s== 0.0 ) ? zabs(x->ve[i]) : zabs(x->ve[i])/fabs(s); } return sum; } /* square -- returns x^2 */ /****************************** double square(x) double x; { return x*x; } ******************************/ #define square(x) ((x)*(x)) /* _zv_norm2 -- computes (scaled) 2-norm (Euclidean norm) of vectors */ double _zv_norm2(x,scale) ZVEC *x; VEC *scale; { int i, dim; Real s, sum; if ( x == ZVNULL ) error(E_NULL,"_zv_norm2"); dim = x->dim; sum = 0.0; if ( scale == VNULL ) for ( i = 0; i < dim; i++ ) sum += square(x->ve[i].re) + square(x->ve[i].im); else if ( scale->dim < dim ) error(E_SIZES,"_v_norm2"); else for ( i = 0; i < dim; i++ ) { s = scale->ve[i]; sum += ( s== 0.0 ) ? square(x->ve[i].re) + square(x->ve[i].im) : (square(x->ve[i].re) + square(x->ve[i].im))/square(s); } return sqrt(sum); } #define max(a,b) ((a) > (b) ? (a) : (b)) /* _zv_norm_inf -- computes (scaled) infinity-norm (supremum norm) of vectors */ double _zv_norm_inf(x,scale) ZVEC *x; VEC *scale; { int i, dim; Real s, maxval, tmp; if ( x == ZVNULL ) error(E_NULL,"_zv_norm_inf"); dim = x->dim; maxval = 0.0; if ( scale == VNULL ) for ( i = 0; i < dim; i++ ) { tmp = zabs(x->ve[i]); maxval = max(maxval,tmp); } else if ( scale->dim < dim ) error(E_SIZES,"_zv_norm_inf"); else for ( i = 0; i < dim; i++ ) { s = scale->ve[i]; tmp = ( s == 0.0 ) ? zabs(x->ve[i]) : zabs(x->ve[i])/fabs(s); maxval = max(maxval,tmp); } return maxval; } /* zm_norm1 -- compute matrix 1-norm -- unscaled -- complex version */ double zm_norm1(A) ZMAT *A; { int i, j, m, n; Real maxval, sum; if ( A == ZMNULL ) error(E_NULL,"zm_norm1"); m = A->m; n = A->n; maxval = 0.0; for ( j = 0; j < n; j++ ) { sum = 0.0; for ( i = 0; i < m; i ++ ) sum += zabs(A->me[i][j]); maxval = max(maxval,sum); } return maxval; } /* zm_norm_inf -- compute matrix infinity-norm -- unscaled -- complex version */ double zm_norm_inf(A) ZMAT *A; { int i, j, m, n; Real maxval, sum; if ( A == ZMNULL ) error(E_NULL,"zm_norm_inf"); m = A->m; n = A->n; maxval = 0.0; for ( i = 0; i < m; i++ ) { sum = 0.0; for ( j = 0; j < n; j ++ ) sum += zabs(A->me[i][j]); maxval = max(maxval,sum); } return maxval; } /* zm_norm_frob -- compute matrix frobenius-norm -- unscaled */ double zm_norm_frob(A) ZMAT *A; { int i, j, m, n; Real sum; if ( A == ZMNULL ) error(E_NULL,"zm_norm_frob"); m = A->m; n = A->n; sum = 0.0; for ( i = 0; i < m; i++ ) for ( j = 0; j < n; j ++ ) sum += square(A->me[i][j].re) + square(A->me[i][j].im); return sqrt(sum); } gtk-wave-cleaner-0.22-04/meschach/zqrfctr.c0000777000175000017500000003355213120075107021627 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains the routines needed to perform QR factorisation of matrices, as well as Householder transformations. The internal "factored form" of a matrix A is not quite standard. The diagonal of A is replaced by the diagonal of R -- not by the 1st non-zero entries of the Householder vectors. The 1st non-zero entries are held in the diag parameter of QRfactor(). The reason for this non-standard representation is that it enables direct use of the Usolve() function rather than requiring that a seperate function be written just for this case. See, e.g., QRsolve() below for more details. Complex version */ static char rcsid[] = "$Id: zqrfctr.c,v 1.1 1994/01/13 04:21:22 des Exp $"; #include #include #include "zmatrix.h" #include "zmatrix2.h" #define is_zero(z) ((z).re == 0.0 && (z).im == 0.0) #define sign(x) ((x) > 0.0 ? 1 : ((x) < 0.0 ? -1 : 0 )) /* Note: The usual representation of a Householder transformation is taken to be: P = I - beta.u.u* where beta = 2/(u*.u) and u is called the Householder vector (u* is the conjugate transposed vector of u */ /* zQRfactor -- forms the QR factorisation of A -- factorisation stored in compact form as described above (not quite standard format) */ ZMAT *zQRfactor(A,diag) ZMAT *A; ZVEC *diag; { unsigned int k,limit; Real beta; STATIC ZVEC *tmp1=ZVNULL, *w=ZVNULL; if ( ! A || ! diag ) error(E_NULL,"zQRfactor"); limit = min(A->m,A->n); if ( diag->dim < limit ) error(E_SIZES,"zQRfactor"); tmp1 = zv_resize(tmp1,A->m); w = zv_resize(w, A->n); MEM_STAT_REG(tmp1,TYPE_ZVEC); MEM_STAT_REG(w, TYPE_ZVEC); for ( k=0; kme[k][k]); diag->ve[k] = tmp1->ve[k]; /* apply H/holder vector to remaining columns */ tracecatch(_zhhtrcols(A,k,k+1,tmp1,beta,w),"zQRfactor"); } #ifdef THREADSAFE ZV_FREE(tmp1); ZV_FREE(w); #endif return (A); } /* zQRCPfactor -- forms the QR factorisation of A with column pivoting -- factorisation stored in compact form as described above ( not quite standard format ) */ ZMAT *zQRCPfactor(A,diag,px) ZMAT *A; ZVEC *diag; PERM *px; { unsigned int i, i_max, j, k, limit; STATIC ZVEC *tmp1=ZVNULL, *tmp2=ZVNULL, *w=ZVNULL; STATIC VEC *gamma=VNULL; Real beta; Real maxgamma, sum, tmp; complex ztmp; if ( ! A || ! diag || ! px ) error(E_NULL,"QRCPfactor"); limit = min(A->m,A->n); if ( diag->dim < limit || px->size != A->n ) error(E_SIZES,"QRCPfactor"); tmp1 = zv_resize(tmp1,A->m); tmp2 = zv_resize(tmp2,A->m); gamma = v_resize(gamma,A->n); w = zv_resize(w,A->n); MEM_STAT_REG(tmp1,TYPE_ZVEC); MEM_STAT_REG(tmp2,TYPE_ZVEC); MEM_STAT_REG(gamma,TYPE_VEC); MEM_STAT_REG(w, TYPE_ZVEC); /* initialise gamma and px */ for ( j=0; jn; j++ ) { px->pe[j] = j; sum = 0.0; for ( i=0; im; i++ ) sum += square(A->me[i][j].re) + square(A->me[i][j].im); gamma->ve[j] = sum; } for ( k=0; kve[k]; for ( i=k+1; in; i++ ) /* Loop invariant:maxgamma=gamma[i_max] >=gamma[l];l=k,...,i-1 */ if ( gamma->ve[i] > maxgamma ) { maxgamma = gamma->ve[i]; i_max = i; } /* swap columns if necessary */ if ( i_max != k ) { /* swap gamma values */ tmp = gamma->ve[k]; gamma->ve[k] = gamma->ve[i_max]; gamma->ve[i_max] = tmp; /* update column permutation */ px_transp(px,k,i_max); /* swap columns of A */ for ( i=0; im; i++ ) { ztmp = A->me[i][k]; A->me[i][k] = A->me[i][i_max]; A->me[i][i_max] = ztmp; } } /* get H/holder vector for the k-th column */ zget_col(A,k,tmp1); /* hhvec(tmp1,k,&beta->ve[k],tmp1,&A->me[k][k]); */ zhhvec(tmp1,k,&beta,tmp1,&A->me[k][k]); diag->ve[k] = tmp1->ve[k]; /* apply H/holder vector to remaining columns */ _zhhtrcols(A,k,k+1,tmp1,beta,w); /* update gamma values */ for ( j=k+1; jn; j++ ) gamma->ve[j] -= square(A->me[k][j].re)+square(A->me[k][j].im); } #ifdef THREADSAFE ZV_FREE(tmp1); ZV_FREE(tmp2); V_FREE(gamma); ZV_FREE(w); #endif return (A); } /* zQsolve -- solves Qx = b, Q is an orthogonal matrix stored in compact form a la QRfactor() -- may be in-situ */ ZVEC *_zQsolve(QR,diag,b,x,tmp) ZMAT *QR; ZVEC *diag, *b, *x, *tmp; { unsigned int dynamic; int k, limit; Real beta, r_ii, tmp_val; limit = min(QR->m,QR->n); dynamic = FALSE; if ( ! QR || ! diag || ! b ) error(E_NULL,"_zQsolve"); if ( diag->dim < limit || b->dim != QR->m ) error(E_SIZES,"_zQsolve"); x = zv_resize(x,QR->m); if ( tmp == ZVNULL ) dynamic = TRUE; tmp = zv_resize(tmp,QR->m); /* apply H/holder transforms in normal order */ x = zv_copy(b,x); for ( k = 0 ; k < limit ; k++ ) { zget_col(QR,k,tmp); r_ii = zabs(tmp->ve[k]); tmp->ve[k] = diag->ve[k]; tmp_val = (r_ii*zabs(diag->ve[k])); beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val; /* hhtrvec(tmp,beta->ve[k],k,x,x); */ zhhtrvec(tmp,beta,k,x,x); } if ( dynamic ) ZV_FREE(tmp); return (x); } /* zmakeQ -- constructs orthogonal matrix from Householder vectors stored in compact QR form */ ZMAT *zmakeQ(QR,diag,Qout) ZMAT *QR,*Qout; ZVEC *diag; { STATIC ZVEC *tmp1=ZVNULL,*tmp2=ZVNULL; unsigned int i, limit; Real beta, r_ii, tmp_val; int j; limit = min(QR->m,QR->n); if ( ! QR || ! diag ) error(E_NULL,"zmakeQ"); if ( diag->dim < limit ) error(E_SIZES,"zmakeQ"); Qout = zm_resize(Qout,QR->m,QR->m); tmp1 = zv_resize(tmp1,QR->m); /* contains basis vec & columns of Q */ tmp2 = zv_resize(tmp2,QR->m); /* contains H/holder vectors */ MEM_STAT_REG(tmp1,TYPE_ZVEC); MEM_STAT_REG(tmp2,TYPE_ZVEC); for ( i=0; im ; i++ ) { /* get i-th column of Q */ /* set up tmp1 as i-th basis vector */ for ( j=0; jm ; j++ ) tmp1->ve[j].re = tmp1->ve[j].im = 0.0; tmp1->ve[i].re = 1.0; /* apply H/h transforms in reverse order */ for ( j=limit-1; j>=0; j-- ) { zget_col(QR,j,tmp2); r_ii = zabs(tmp2->ve[j]); tmp2->ve[j] = diag->ve[j]; tmp_val = (r_ii*zabs(diag->ve[j])); beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val; /* hhtrvec(tmp2,beta->ve[j],j,tmp1,tmp1); */ zhhtrvec(tmp2,beta,j,tmp1,tmp1); } /* insert into Q */ zset_col(Qout,i,tmp1); } #ifdef THREADSAFE ZV_FREE(tmp1); ZV_FREE(tmp2); #endif return (Qout); } /* zmakeR -- constructs upper triangular matrix from QR (compact form) -- may be in-situ (all it does is zero the lower 1/2) */ ZMAT *zmakeR(QR,Rout) ZMAT *QR,*Rout; { unsigned int i,j; if ( QR==ZMNULL ) error(E_NULL,"zmakeR"); Rout = zm_copy(QR,Rout); for ( i=1; im; i++ ) for ( j=0; jn && jme[i][j].re = Rout->me[i][j].im = 0.0; return (Rout); } /* zQRsolve -- solves the system Q.R.x=b where Q & R are stored in compact form -- returns x, which is created if necessary */ ZVEC *zQRsolve(QR,diag,b,x) ZMAT *QR; ZVEC *diag, *b, *x; { int limit; STATIC ZVEC *tmp = ZVNULL; if ( ! QR || ! diag || ! b ) error(E_NULL,"zQRsolve"); limit = min(QR->m,QR->n); if ( diag->dim < limit || b->dim != QR->m ) error(E_SIZES,"zQRsolve"); tmp = zv_resize(tmp,limit); MEM_STAT_REG(tmp,TYPE_ZVEC); x = zv_resize(x,QR->n); _zQsolve(QR,diag,b,x,tmp); x = zUsolve(QR,x,x,0.0); x = zv_resize(x,QR->n); #ifdef THREADSAFE ZV_FREE(tmp); #endif return x; } /* zQRAsolve -- solves the system (Q.R)*.x = b -- Q & R are stored in compact form -- returns x, which is created if necessary */ ZVEC *zQRAsolve(QR,diag,b,x) ZMAT *QR; ZVEC *diag, *b, *x; { int j, limit; Real beta, r_ii, tmp_val; STATIC ZVEC *tmp = ZVNULL; if ( ! QR || ! diag || ! b ) error(E_NULL,"zQRAsolve"); limit = min(QR->m,QR->n); if ( diag->dim < limit || b->dim != QR->n ) error(E_SIZES,"zQRAsolve"); x = zv_resize(x,QR->m); x = zUAsolve(QR,b,x,0.0); x = zv_resize(x,QR->m); tmp = zv_resize(tmp,x->dim); MEM_STAT_REG(tmp,TYPE_ZVEC); /* printf("zQRAsolve: tmp->dim = %d, x->dim = %d\n", tmp->dim, x->dim); */ /* apply H/h transforms in reverse order */ for ( j=limit-1; j>=0; j-- ) { zget_col(QR,j,tmp); tmp = zv_resize(tmp,QR->m); r_ii = zabs(tmp->ve[j]); tmp->ve[j] = diag->ve[j]; tmp_val = (r_ii*zabs(diag->ve[j])); beta = ( tmp_val == 0.0 ) ? 0.0 : 1.0/tmp_val; zhhtrvec(tmp,beta,j,x,x); } #ifdef THREADSAFE ZV_FREE(tmp); #endif return x; } /* zQRCPsolve -- solves A.x = b where A is factored by QRCPfactor() -- assumes that A is in the compact factored form */ ZVEC *zQRCPsolve(QR,diag,pivot,b,x) ZMAT *QR; ZVEC *diag; PERM *pivot; ZVEC *b, *x; { if ( ! QR || ! diag || ! pivot || ! b ) error(E_NULL,"zQRCPsolve"); if ( (QR->m > diag->dim && QR->n > diag->dim) || QR->n != pivot->size ) error(E_SIZES,"zQRCPsolve"); x = zQRsolve(QR,diag,b,x); x = pxinv_zvec(pivot,x,x); return x; } /* zUmlt -- compute out = upper_triang(U).x -- may be in situ */ ZVEC *zUmlt(U,x,out) ZMAT *U; ZVEC *x, *out; { int i, limit; if ( U == ZMNULL || x == ZVNULL ) error(E_NULL,"zUmlt"); limit = min(U->m,U->n); if ( limit != x->dim ) error(E_SIZES,"zUmlt"); if ( out == ZVNULL || out->dim < limit ) out = zv_resize(out,limit); for ( i = 0; i < limit; i++ ) out->ve[i] = __zip__(&(x->ve[i]),&(U->me[i][i]),limit - i,Z_NOCONJ); return out; } /* zUAmlt -- returns out = upper_triang(U)^T.x */ ZVEC *zUAmlt(U,x,out) ZMAT *U; ZVEC *x, *out; { /* complex sum; */ complex tmp; int i, limit; if ( U == ZMNULL || x == ZVNULL ) error(E_NULL,"zUAmlt"); limit = min(U->m,U->n); if ( out == ZVNULL || out->dim < limit ) out = zv_resize(out,limit); for ( i = limit-1; i >= 0; i-- ) { tmp = x->ve[i]; out->ve[i].re = out->ve[i].im = 0.0; __zmltadd__(&(out->ve[i]),&(U->me[i][i]),tmp,limit-i-1,Z_CONJ); } return out; } /* zQRcondest -- returns an estimate of the 2-norm condition number of the matrix factorised by QRfactor() or QRCPfactor() -- note that as Q does not affect the 2-norm condition number, it is not necessary to pass the diag, beta (or pivot) vectors -- generates a lower bound on the true condition number -- if the matrix is exactly singular, HUGE_VAL is returned -- note that QRcondest() is likely to be more reliable for matrices factored using QRCPfactor() */ double zQRcondest(QR) ZMAT *QR; { STATIC ZVEC *y=ZVNULL; Real norm, norm1, norm2, tmp1, tmp2; complex sum, tmp; int i, j, limit; if ( QR == ZMNULL ) error(E_NULL,"zQRcondest"); limit = min(QR->m,QR->n); for ( i = 0; i < limit; i++ ) /* if ( QR->me[i][i] == 0.0 ) */ if ( is_zero(QR->me[i][i]) ) return HUGE_VAL; y = zv_resize(y,limit); MEM_STAT_REG(y,TYPE_ZVEC); /* use the trick for getting a unit vector y with ||R.y||_inf small from the LU condition estimator */ for ( i = 0; i < limit; i++ ) { sum.re = sum.im = 0.0; for ( j = 0; j < i; j++ ) /* sum -= QR->me[j][i]*y->ve[j]; */ sum = zsub(sum,zmlt(QR->me[j][i],y->ve[j])); /* sum -= (sum < 0.0) ? 1.0 : -1.0; */ norm1 = zabs(sum); if ( norm1 == 0.0 ) sum.re = 1.0; else { sum.re += sum.re / norm1; sum.im += sum.im / norm1; } /* y->ve[i] = sum / QR->me[i][i]; */ y->ve[i] = zdiv(sum,QR->me[i][i]); } zUAmlt(QR,y,y); /* now apply inverse power method to R*.R */ for ( i = 0; i < 3; i++ ) { tmp1 = zv_norm2(y); zv_mlt(zmake(1.0/tmp1,0.0),y,y); zUAsolve(QR,y,y,0.0); tmp2 = zv_norm2(y); zv_mlt(zmake(1.0/tmp2,0.0),y,y); zUsolve(QR,y,y,0.0); } /* now compute approximation for ||R^{-1}||_2 */ norm1 = sqrt(tmp1)*sqrt(tmp2); /* now use complementary approach to compute approximation to ||R||_2 */ for ( i = limit-1; i >= 0; i-- ) { sum.re = sum.im = 0.0; for ( j = i+1; j < limit; j++ ) sum = zadd(sum,zmlt(QR->me[i][j],y->ve[j])); if ( is_zero(QR->me[i][i]) ) return HUGE_VAL; tmp = zdiv(sum,QR->me[i][i]); if ( is_zero(tmp) ) { y->ve[i].re = 1.0; y->ve[i].im = 0.0; } else { norm = zabs(tmp); y->ve[i].re = sum.re / norm; y->ve[i].im = sum.im / norm; } /* y->ve[i] = (sum >= 0.0) ? 1.0 : -1.0; */ /* y->ve[i] = (QR->me[i][i] >= 0.0) ? y->ve[i] : - y->ve[i]; */ } /* now apply power method to R*.R */ for ( i = 0; i < 3; i++ ) { tmp1 = zv_norm2(y); zv_mlt(zmake(1.0/tmp1,0.0),y,y); zUmlt(QR,y,y); tmp2 = zv_norm2(y); zv_mlt(zmake(1.0/tmp2,0.0),y,y); zUAmlt(QR,y,y); } norm2 = sqrt(tmp1)*sqrt(tmp2); /* printf("QRcondest: norm1 = %g, norm2 = %g\n",norm1,norm2); */ #ifdef THREADSAFE ZV_FREE(y); #endif return norm1*norm2; } gtk-wave-cleaner-0.22-04/meschach/zschur.c0000777000175000017500000002600313120075107021443 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* File containing routines for computing the Schur decomposition of a complex non-symmetric matrix See also: hessen.c Complex version */ #include #include #include "zmatrix.h" #include "zmatrix2.h" static char rcsid[] = "$Id: zschur.c,v 1.4 1995/04/07 16:28:58 des Exp $"; #define is_zero(z) ((z).re == 0.0 && (z).im == 0.0) #define b2s(t_or_f) ((t_or_f) ? "TRUE" : "FALSE") /* zschur -- computes the Schur decomposition of the matrix A in situ -- optionally, gives Q matrix such that Q^*.A.Q is upper triangular -- returns upper triangular Schur matrix */ ZMAT *zschur(A,Q) ZMAT *A, *Q; { int i, j, iter, k, k_min, k_max, k_tmp, n, split; Real c; complex det, discrim, lambda, lambda0, lambda1, s, sum, ztmp; complex x, y; /* for chasing algorithm */ complex **A_me; STATIC ZVEC *diag=ZVNULL; if ( ! A ) error(E_NULL,"zschur"); if ( A->m != A->n || ( Q && Q->m != Q->n ) ) error(E_SQUARE,"zschur"); if ( Q != ZMNULL && Q->m != A->m ) error(E_SIZES,"zschur"); n = A->n; diag = zv_resize(diag,A->n); MEM_STAT_REG(diag,TYPE_ZVEC); /* compute Hessenberg form */ zHfactor(A,diag); /* save Q if necessary, and make A explicitly Hessenberg */ zHQunpack(A,diag,Q,A); k_min = 0; A_me = A->me; while ( k_min < n ) { /* find k_max to suit: submatrix k_min..k_max should be irreducible */ k_max = n-1; for ( k = k_min; k < k_max; k++ ) if ( is_zero(A_me[k+1][k]) ) { k_max = k; break; } if ( k_max <= k_min ) { k_min = k_max + 1; continue; /* outer loop */ } /* now have r x r block with r >= 2: apply Francis QR step until block splits */ split = FALSE; iter = 0; while ( ! split ) { complex a00, a01, a10, a11; iter++; /* set up Wilkinson/Francis complex shift */ /* use the smallest eigenvalue of the bottom 2 x 2 submatrix */ k_tmp = k_max - 1; a00 = A_me[k_tmp][k_tmp]; a01 = A_me[k_tmp][k_max]; a10 = A_me[k_max][k_tmp]; a11 = A_me[k_max][k_max]; ztmp.re = 0.5*(a00.re - a11.re); ztmp.im = 0.5*(a00.im - a11.im); discrim = zsqrt(zadd(zmlt(ztmp,ztmp),zmlt(a01,a10))); sum.re = 0.5*(a00.re + a11.re); sum.im = 0.5*(a00.im + a11.im); lambda0 = zadd(sum,discrim); lambda1 = zsub(sum,discrim); det = zsub(zmlt(a00,a11),zmlt(a01,a10)); if ( is_zero(lambda0) && is_zero(lambda1) ) { lambda.re = lambda.im = 0.0; } else if ( zabs(lambda0) > zabs(lambda1) ) lambda = zdiv(det,lambda0); else lambda = zdiv(det,lambda1); /* perturb shift if convergence is slow */ if ( (iter % 10) == 0 ) { lambda.re += iter*0.02; lambda.im += iter*0.02; } /* set up Householder transformations */ k_tmp = k_min + 1; x = zsub(A->me[k_min][k_min],lambda); y = A->me[k_min+1][k_min]; /* use Givens' rotations to "chase" off-Hessenberg entry */ for ( k = k_min; k <= k_max-1; k++ ) { zgivens(x,y,&c,&s); zrot_cols(A,k,k+1,c,s,A); zrot_rows(A,k,k+1,c,s,A); if ( Q != ZMNULL ) zrot_cols(Q,k,k+1,c,s,Q); /* zero things that should be zero */ if ( k > k_min ) A->me[k+1][k-1].re = A->me[k+1][k-1].im = 0.0; /* get next entry to chase along sub-diagonal */ x = A->me[k+1][k]; if ( k <= k_max - 2 ) y = A->me[k+2][k]; else y.re = y.im = 0.0; } for ( k = k_min; k <= k_max-2; k++ ) { /* zero appropriate sub-diagonals */ A->me[k+2][k].re = A->me[k+2][k].im = 0.0; } /* test to see if matrix should split */ for ( k = k_min; k < k_max; k++ ) if ( zabs(A_me[k+1][k]) < MACHEPS* (zabs(A_me[k][k])+zabs(A_me[k+1][k+1])) ) { A_me[k+1][k].re = A_me[k+1][k].im = 0.0; split = TRUE; } } } /* polish up A by zeroing strictly lower triangular elements and small sub-diagonal elements */ for ( i = 0; i < A->m; i++ ) for ( j = 0; j < i-1; j++ ) A_me[i][j].re = A_me[i][j].im = 0.0; for ( i = 0; i < A->m - 1; i++ ) if ( zabs(A_me[i+1][i]) < MACHEPS* (zabs(A_me[i][i])+zabs(A_me[i+1][i+1])) ) A_me[i+1][i].re = A_me[i+1][i].im = 0.0; #ifdef THREADSAFE ZV_FREE(diag); #endif return A; } #if 0 /* schur_vecs -- returns eigenvectors computed from the real Schur decomposition of a matrix -- T is the block upper triangular Schur matrix -- Q is the orthognal matrix where A = Q.T.Q^T -- if Q is null, the eigenvectors of T are returned -- X_re is the real part of the matrix of eigenvectors, and X_im is the imaginary part of the matrix. -- X_re is returned */ MAT *schur_vecs(T,Q,X_re,X_im) MAT *T, *Q, *X_re, *X_im; { int i, j, limit; Real t11_re, t11_im, t12, t21, t22_re, t22_im; Real l_re, l_im, det_re, det_im, invdet_re, invdet_im, val1_re, val1_im, val2_re, val2_im, tmp_val1_re, tmp_val1_im, tmp_val2_re, tmp_val2_im, **T_me; Real sum, diff, discrim, magdet, norm, scale; STATIC VEC *tmp1_re=VNULL, *tmp1_im=VNULL, *tmp2_re=VNULL, *tmp2_im=VNULL; if ( ! T || ! X_re ) error(E_NULL,"schur_vecs"); if ( T->m != T->n || X_re->m != X_re->n || ( Q != MNULL && Q->m != Q->n ) || ( X_im != MNULL && X_im->m != X_im->n ) ) error(E_SQUARE,"schur_vecs"); if ( T->m != X_re->m || ( Q != MNULL && T->m != Q->m ) || ( X_im != MNULL && T->m != X_im->m ) ) error(E_SIZES,"schur_vecs"); tmp1_re = v_resize(tmp1_re,T->m); tmp1_im = v_resize(tmp1_im,T->m); tmp2_re = v_resize(tmp2_re,T->m); tmp2_im = v_resize(tmp2_im,T->m); MEM_STAT_REG(tmp1_re,TYPE_VEC); MEM_STAT_REG(tmp1_im,TYPE_VEC); MEM_STAT_REG(tmp2_re,TYPE_VEC); MEM_STAT_REG(tmp2_im,TYPE_VEC); T_me = T->me; i = 0; while ( i < T->m ) { if ( i+1 < T->m && T->me[i+1][i] != 0.0 ) { /* complex eigenvalue */ sum = 0.5*(T_me[i][i]+T_me[i+1][i+1]); diff = 0.5*(T_me[i][i]-T_me[i+1][i+1]); discrim = diff*diff + T_me[i][i+1]*T_me[i+1][i]; l_re = l_im = 0.0; if ( discrim < 0.0 ) { /* yes -- complex e-vals */ l_re = sum; l_im = sqrt(-discrim); } else /* not correct Real Schur form */ error(E_RANGE,"schur_vecs"); } else { l_re = T_me[i][i]; l_im = 0.0; } v_zero(tmp1_im); v_rand(tmp1_re); sv_mlt(MACHEPS,tmp1_re,tmp1_re); /* solve (T-l.I)x = tmp1 */ limit = ( l_im != 0.0 ) ? i+1 : i; /* printf("limit = %d\n",limit); */ for ( j = limit+1; j < T->m; j++ ) tmp1_re->ve[j] = 0.0; j = limit; while ( j >= 0 ) { if ( j > 0 && T->me[j][j-1] != 0.0 ) { /* 2 x 2 diagonal block */ /* printf("checkpoint A\n"); */ val1_re = tmp1_re->ve[j-1] - __ip__(&(tmp1_re->ve[j+1]),&(T->me[j-1][j+1]),limit-j); /* printf("checkpoint B\n"); */ val1_im = tmp1_im->ve[j-1] - __ip__(&(tmp1_im->ve[j+1]),&(T->me[j-1][j+1]),limit-j); /* printf("checkpoint C\n"); */ val2_re = tmp1_re->ve[j] - __ip__(&(tmp1_re->ve[j+1]),&(T->me[j][j+1]),limit-j); /* printf("checkpoint D\n"); */ val2_im = tmp1_im->ve[j] - __ip__(&(tmp1_im->ve[j+1]),&(T->me[j][j+1]),limit-j); /* printf("checkpoint E\n"); */ t11_re = T_me[j-1][j-1] - l_re; t11_im = - l_im; t22_re = T_me[j][j] - l_re; t22_im = - l_im; t12 = T_me[j-1][j]; t21 = T_me[j][j-1]; scale = fabs(T_me[j-1][j-1]) + fabs(T_me[j][j]) + fabs(t12) + fabs(t21) + fabs(l_re) + fabs(l_im); det_re = t11_re*t22_re - t11_im*t22_im - t12*t21; det_im = t11_re*t22_im + t11_im*t22_re; magdet = det_re*det_re+det_im*det_im; if ( sqrt(magdet) < MACHEPS*scale ) { det_re = MACHEPS*scale; magdet = det_re*det_re+det_im*det_im; } invdet_re = det_re/magdet; invdet_im = - det_im/magdet; tmp_val1_re = t22_re*val1_re-t22_im*val1_im-t12*val2_re; tmp_val1_im = t22_im*val1_re+t22_re*val1_im-t12*val2_im; tmp_val2_re = t11_re*val2_re-t11_im*val2_im-t21*val1_re; tmp_val2_im = t11_im*val2_re+t11_re*val2_im-t21*val1_im; tmp1_re->ve[j-1] = invdet_re*tmp_val1_re - invdet_im*tmp_val1_im; tmp1_im->ve[j-1] = invdet_im*tmp_val1_re + invdet_re*tmp_val1_im; tmp1_re->ve[j] = invdet_re*tmp_val2_re - invdet_im*tmp_val2_im; tmp1_im->ve[j] = invdet_im*tmp_val2_re + invdet_re*tmp_val2_im; j -= 2; } else { t11_re = T_me[j][j] - l_re; t11_im = - l_im; magdet = t11_re*t11_re + t11_im*t11_im; scale = fabs(T_me[j][j]) + fabs(l_re); if ( sqrt(magdet) < MACHEPS*scale ) { t11_re = MACHEPS*scale; magdet = t11_re*t11_re + t11_im*t11_im; } invdet_re = t11_re/magdet; invdet_im = - t11_im/magdet; /* printf("checkpoint F\n"); */ val1_re = tmp1_re->ve[j] - __ip__(&(tmp1_re->ve[j+1]),&(T->me[j][j+1]),limit-j); /* printf("checkpoint G\n"); */ val1_im = tmp1_im->ve[j] - __ip__(&(tmp1_im->ve[j+1]),&(T->me[j][j+1]),limit-j); /* printf("checkpoint H\n"); */ tmp1_re->ve[j] = invdet_re*val1_re - invdet_im*val1_im; tmp1_im->ve[j] = invdet_im*val1_re + invdet_re*val1_im; j -= 1; } } norm = v_norm_inf(tmp1_re) + v_norm_inf(tmp1_im); sv_mlt(1/norm,tmp1_re,tmp1_re); if ( l_im != 0.0 ) sv_mlt(1/norm,tmp1_im,tmp1_im); mv_mlt(Q,tmp1_re,tmp2_re); if ( l_im != 0.0 ) mv_mlt(Q,tmp1_im,tmp2_im); if ( l_im != 0.0 ) norm = sqrt(in_prod(tmp2_re,tmp2_re)+in_prod(tmp2_im,tmp2_im)); else norm = v_norm2(tmp2_re); sv_mlt(1/norm,tmp2_re,tmp2_re); if ( l_im != 0.0 ) sv_mlt(1/norm,tmp2_im,tmp2_im); if ( l_im != 0.0 ) { if ( ! X_im ) error(E_NULL,"schur_vecs"); set_col(X_re,i,tmp2_re); set_col(X_im,i,tmp2_im); sv_mlt(-1.0,tmp2_im,tmp2_im); set_col(X_re,i+1,tmp2_re); set_col(X_im,i+1,tmp2_im); i += 2; } else { set_col(X_re,i,tmp2_re); if ( X_im != MNULL ) set_col(X_im,i,tmp1_im); /* zero vector */ i += 1; } } return X_re; } #endif gtk-wave-cleaner-0.22-04/meschach/zsolve.c0000777000175000017500000001667013120075107021460 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* Matrix factorisation routines to work with the other matrix files. Complex case */ static char rcsid[] = "$Id: zsolve.c,v 1.1 1994/01/13 04:20:33 des Exp $"; #include #include #include "zmatrix2.h" #define is_zero(z) ((z).re == 0.0 && (z).im == 0.0 ) /* Most matrix factorisation routines are in-situ unless otherwise specified */ /* zUsolve -- back substitution with optional over-riding diagonal -- can be in-situ but doesn't need to be */ ZVEC *zUsolve(matrix,b,out,diag) ZMAT *matrix; ZVEC *b, *out; double diag; { unsigned int dim /* , j */; int i, i_lim; complex **mat_ent, *mat_row, *b_ent, *out_ent, *out_col, sum; if ( matrix==ZMNULL || b==ZVNULL ) error(E_NULL,"zUsolve"); dim = min(matrix->m,matrix->n); if ( b->dim < dim ) error(E_SIZES,"zUsolve"); if ( out==ZVNULL || out->dim < dim ) out = zv_resize(out,matrix->n); mat_ent = matrix->me; b_ent = b->ve; out_ent = out->ve; for ( i=dim-1; i>=0; i-- ) if ( ! is_zero(b_ent[i]) ) break; else out_ent[i].re = out_ent[i].im = 0.0; i_lim = i; for ( i = i_lim; i>=0; i-- ) { sum = b_ent[i]; mat_row = &(mat_ent[i][i+1]); out_col = &(out_ent[i+1]); sum = zsub(sum,__zip__(mat_row,out_col,i_lim-i,Z_NOCONJ)); /****************************************************** for ( j=i+1; j<=i_lim; j++ ) sum -= mat_ent[i][j]*out_ent[j]; sum -= (*mat_row++)*(*out_col++); ******************************************************/ if ( diag == 0.0 ) { if ( is_zero(mat_ent[i][i]) ) error(E_SING,"zUsolve"); else /* out_ent[i] = sum/mat_ent[i][i]; */ out_ent[i] = zdiv(sum,mat_ent[i][i]); } else { /* out_ent[i] = sum/diag; */ out_ent[i].re = sum.re / diag; out_ent[i].im = sum.im / diag; } } return (out); } /* zLsolve -- forward elimination with (optional) default diagonal value */ ZVEC *zLsolve(matrix,b,out,diag) ZMAT *matrix; ZVEC *b,*out; double diag; { unsigned int dim, i, i_lim /* , j */; complex **mat_ent, *mat_row, *b_ent, *out_ent, *out_col, sum; if ( matrix==ZMNULL || b==ZVNULL ) error(E_NULL,"zLsolve"); dim = min(matrix->m,matrix->n); if ( b->dim < dim ) error(E_SIZES,"zLsolve"); if ( out==ZVNULL || out->dim < dim ) out = zv_resize(out,matrix->n); mat_ent = matrix->me; b_ent = b->ve; out_ent = out->ve; for ( i=0; im,U->n); if ( b->dim < dim ) error(E_SIZES,"zUAsolve"); out = zv_resize(out,U->n); U_me = U->me; b_ve = b->ve; out_ve = out->ve; for ( i=0; idim); /* MEM_COPY(&(b_ve[i_lim]),&(out_ve[i_lim]), (dim-i_lim)*sizeof(complex)); */ MEMCOPY(&(b_ve[i_lim]),&(out_ve[i_lim]),dim-i_lim,complex); } if ( diag == 0.0 ) { for ( ; im,A->n); if ( b->dim < dim ) error(E_SIZES,"zDsolve"); x = zv_resize(x,A->n); dim = b->dim; for ( i=0; ime[i][i]) ) error(E_SING,"zDsolve"); else x->ve[i] = zdiv(b->ve[i],A->me[i][i]); return (x); } /* zLAsolve -- back substitution with optional over-riding diagonal using the LOWER triangular part of matrix -- can be in-situ but doesn't need to be */ ZVEC *zLAsolve(L,b,out,diag) ZMAT *L; ZVEC *b, *out; double diag; { unsigned int dim; int i, i_lim; complex **L_me, *b_ve, *out_ve, tmp; Real invdiag; if ( ! L || ! b ) error(E_NULL,"zLAsolve"); dim = min(L->m,L->n); if ( b->dim < dim ) error(E_SIZES,"zLAsolve"); out = zv_resize(out,L->n); L_me = L->me; b_ve = b->ve; out_ve = out->ve; for ( i=dim-1; i>=0; i-- ) if ( ! is_zero(b_ve[i]) ) break; i_lim = i; if ( b != out ) { __zzero__(out_ve,out->dim); /* MEM_COPY(b_ve,out_ve,(i_lim+1)*sizeof(complex)); */ MEMCOPY(b_ve,out_ve,i_lim+1,complex); } if ( diag == 0.0 ) { for ( ; i>=0; i-- ) { tmp = zconj(L_me[i][i]); if ( is_zero(tmp) ) error(E_SING,"zLAsolve"); out_ve[i] = zdiv(out_ve[i],tmp); tmp.re = - out_ve[i].re; tmp.im = - out_ve[i].im; __zmltadd__(out_ve,L_me[i],tmp,i,Z_CONJ); } } else { invdiag = 1.0/diag; for ( ; i>=0; i-- ) { out_ve[i].re *= invdiag; out_ve[i].im *= invdiag; tmp.re = - out_ve[i].re; tmp.im = - out_ve[i].im; __zmltadd__(out_ve,L_me[i],tmp,i,Z_CONJ); } } return (out); } gtk-wave-cleaner-0.22-04/meschach/ztorture.c0000777000175000017500000004723013120075107022030 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ /* This file contains a series of tests for the Meschach matrix library, complex routines */ static char rcsid[] = "$Id: $"; #include #include #include "zmatrix2.h" #include "matlab.h" #define errmesg(mesg) printf("Error: %s error: line %d\n",mesg,__LINE__) #define notice(mesg) printf("# Testing %s...\n",mesg); /* extern int malloc_chain_check(); */ /* #define MEMCHK() if ( malloc_chain_check(0) ) \ { printf("Error in malloc chain: \"%s\", line %d\n", \ __FILE__, __LINE__); exit(0); } */ #define MEMCHK() #define checkpt() printf("At line %d in file \"%s\"\n",__LINE__,__FILE__) /* cmp_perm -- returns 1 if pi1 == pi2, 0 otherwise */ int cmp_perm(pi1, pi2) PERM *pi1, *pi2; { int i; if ( ! pi1 || ! pi2 ) error(E_NULL,"cmp_perm"); if ( pi1->size != pi2->size ) return 0; for ( i = 0; i < pi1->size; i++ ) if ( pi1->pe[i] != pi2->pe[i] ) return 0; return 1; } /* px_rand -- generates sort-of random permutation */ PERM *px_rand(pi) PERM *pi; { int i, j, k; if ( ! pi ) error(E_NULL,"px_rand"); for ( i = 0; i < 3*pi->size; i++ ) { j = (rand() >> 8) % pi->size; k = (rand() >> 8) % pi->size; px_transp(pi,j,k); } return pi; } #define SAVE_FILE "asx5213a.mat" #define MATLAB_NAME "alpha" char name[81] = MATLAB_NAME; void main(argc, argv) int argc; char *argv[]; { ZVEC *x = ZVNULL, *y = ZVNULL, *z = ZVNULL, *u = ZVNULL; ZVEC *diag = ZVNULL; PERM *pi1 = PNULL, *pi2 = PNULL, *pivot = PNULL; ZMAT *A = ZMNULL, *B = ZMNULL, *C = ZMNULL, *D = ZMNULL, *Q = ZMNULL; complex ONE; complex z1, z2, z3; Real cond_est, s1, s2, s3; int i, seed; FILE *fp; char *cp; mem_info_on(TRUE); setbuf(stdout,(char *)NULL); seed = 1111; if ( argc > 2 ) { printf("usage: %s [seed]\n",argv[0]); exit(0); } else if ( argc == 2 ) sscanf(argv[1], "%d", &seed); /* set seed for rand() */ smrand(seed); /* print out version information */ m_version(); printf("# Meschach Complex numbers & vectors torture test\n\n"); printf("# grep \"^Error\" the output for a listing of errors\n"); printf("# Don't panic if you see \"Error\" appearing; \n"); printf("# Also check the reported size of error\n"); printf("# This program uses randomly generated problems and therefore\n"); printf("# may occasionally produce ill-conditioned problems\n"); printf("# Therefore check the size of the error compared with MACHEPS\n"); printf("# If the error is within 1000*MACHEPS then don't worry\n"); printf("# If you get an error of size 0.1 or larger there is \n"); printf("# probably a bug in the code or the compilation procedure\n\n"); printf("# seed = %d\n",seed); printf("\n"); mem_stat_mark(1); notice("complex arithmetic & special functions"); ONE = zmake(1.0,0.0); printf("# ONE = "); z_output(ONE); z1.re = mrand(); z1.im = mrand(); z2.re = mrand(); z2.im = mrand(); z3 = zadd(z1,z2); if ( fabs(z1.re+z2.re-z3.re) + fabs(z1.im+z2.im-z3.im) > 10*MACHEPS ) errmesg("zadd"); z3 = zsub(z1,z2); if ( fabs(z1.re-z2.re-z3.re) + fabs(z1.im-z2.im-z3.im) > 10*MACHEPS ) errmesg("zadd"); z3 = zmlt(z1,z2); if ( fabs(z1.re*z2.re - z1.im*z2.im - z3.re) + fabs(z1.im*z2.re + z1.re*z2.im - z3.im) > 10*MACHEPS ) errmesg("zmlt"); s1 = zabs(z1); if ( fabs(s1*s1 - (z1.re*z1.re+z1.im*z1.im)) > 10*MACHEPS ) errmesg("zabs"); if ( zabs(zsub(z1,zmlt(z2,zdiv(z1,z2)))) > 10*MACHEPS || zabs(zsub(ONE,zdiv(z1,zmlt(z2,zdiv(z1,z2))))) > 10*MACHEPS ) errmesg("zdiv"); z3 = zsqrt(z1); if ( zabs(zsub(z1,zmlt(z3,z3))) > 10*MACHEPS ) errmesg("zsqrt"); if ( zabs(zsub(z1,zlog(zexp(z1)))) > 10*MACHEPS ) errmesg("zexp/zlog"); printf("# Check: MACHEPS = %g\n",MACHEPS); /* allocate, initialise, copy and resize operations */ /* ZVEC */ notice("vector initialise, copy & resize"); x = zv_get(12); y = zv_get(15); z = zv_get(12); zv_rand(x); zv_rand(y); z = zv_copy(x,z); if ( zv_norm2(zv_sub(x,z,z)) >= MACHEPS ) errmesg("ZVEC copy"); zv_copy(x,y); x = zv_resize(x,10); y = zv_resize(y,10); if ( zv_norm2(zv_sub(x,y,z)) >= MACHEPS ) errmesg("ZVEC copy/resize"); x = zv_resize(x,15); y = zv_resize(y,15); if ( zv_norm2(zv_sub(x,y,z)) >= MACHEPS ) errmesg("VZEC resize"); /* ZMAT */ notice("matrix initialise, copy & resize"); A = zm_get(8,5); B = zm_get(3,9); C = zm_get(8,5); zm_rand(A); zm_rand(B); C = zm_copy(A,C); if ( zm_norm_inf(zm_sub(A,C,C)) >= MACHEPS ) errmesg("ZMAT copy"); zm_copy(A,B); A = zm_resize(A,3,5); B = zm_resize(B,3,5); if ( zm_norm_inf(zm_sub(A,B,C)) >= MACHEPS ) errmesg("ZMAT copy/resize"); A = zm_resize(A,10,10); B = zm_resize(B,10,10); if ( zm_norm_inf(zm_sub(A,B,C)) >= MACHEPS ) errmesg("ZMAT resize"); MEMCHK(); /* PERM */ notice("permutation initialise, inverting & permuting vectors"); pi1 = px_get(15); pi2 = px_get(12); px_rand(pi1); zv_rand(x); px_zvec(pi1,x,z); y = zv_resize(y,x->dim); pxinv_zvec(pi1,z,y); if ( zv_norm2(zv_sub(x,y,z)) >= MACHEPS ) errmesg("PERMute vector"); /* testing catch() etc */ notice("error handling routines"); catch(E_NULL, catchall(zv_add(ZVNULL,ZVNULL,ZVNULL); errmesg("tracecatch() failure"), printf("# tracecatch() caught error\n"); error(E_NULL,"main")); errmesg("catch() failure"), printf("# catch() caught E_NULL error\n")); /* testing inner products and v_mltadd() etc */ notice("inner products and linear combinations"); u = zv_get(x->dim); zv_rand(u); zv_rand(x); zv_resize(y,x->dim); zv_rand(y); zv_mltadd(y,x,zneg(zdiv(zin_prod(x,y),zin_prod(x,x))),z); if ( zabs(zin_prod(x,z)) >= 5*MACHEPS*x->dim ) { errmesg("zv_mltadd()/zin_prod()"); printf("# error norm = %g\n", zabs(zin_prod(x,z))); } z1 = zneg(zdiv(zin_prod(x,y),zmake(zv_norm2(x)*zv_norm2(x),0.0))); zv_mlt(z1,x,u); zv_add(y,u,u); if ( zv_norm2(zv_sub(u,z,u)) >= MACHEPS*x->dim ) { errmesg("zv_mlt()/zv_norm2()"); printf("# error norm = %g\n", zv_norm2(u)); } #ifdef ANSI_C zv_linlist(u,x,z1,y,ONE,VNULL); if ( zv_norm2(zv_sub(u,z,u)) >= MACHEPS*x->dim ) errmesg("zv_linlist()"); #endif #ifdef VARARGS zv_linlist(u,x,z1,y,ONE,VNULL); if ( zv_norm2(zv_sub(u,z,u)) >= MACHEPS*x->dim ) errmesg("zv_linlist()"); #endif MEMCHK(); /* vector norms */ notice("vector norms"); x = zv_resize(x,12); zv_rand(x); for ( i = 0; i < x->dim; i++ ) if ( zabs(zv_entry(x,i)) >= 0.7 ) zv_set_val(x,i,ONE); else zv_set_val(x,i,zneg(ONE)); s1 = zv_norm1(x); s2 = zv_norm2(x); s3 = zv_norm_inf(x); if ( fabs(s1 - x->dim) >= MACHEPS*x->dim || fabs(s2 - sqrt((double)(x->dim))) >= MACHEPS*x->dim || fabs(s3 - 1.0) >= MACHEPS ) errmesg("zv_norm1/2/_inf()"); /* test matrix multiply etc */ notice("matrix multiply and invert"); A = zm_resize(A,10,10); B = zm_resize(B,10,10); zm_rand(A); zm_inverse(A,B); zm_mlt(A,B,C); for ( i = 0; i < C->m; i++ ) zm_sub_val(C,i,i,ONE); if ( zm_norm_inf(C) >= MACHEPS*zm_norm_inf(A)*zm_norm_inf(B)*5 ) errmesg("zm_inverse()/zm_mlt()"); MEMCHK(); /* ... and adjoints */ notice("adjoints and adjoint-multiplies"); zm_adjoint(A,A); /* can do square matrices in situ */ zmam_mlt(A,B,C); for ( i = 0; i < C->m; i++ ) zm_set_val(C,i,i,zsub(zm_entry(C,i,i),ONE)); if ( zm_norm_inf(C) >= MACHEPS*zm_norm_inf(A)*zm_norm_inf(B)*5 ) errmesg("zm_adjoint()/zmam_mlt()"); zm_adjoint(A,A); zm_adjoint(B,B); zmma_mlt(A,B,C); for ( i = 0; i < C->m; i++ ) zm_set_val(C,i,i,zsub(zm_entry(C,i,i),ONE)); if ( zm_norm_inf(C) >= MACHEPS*zm_norm_inf(A)*zm_norm_inf(B)*5 ) errmesg("zm_adjoint()/zmma_mlt()"); zsm_mlt(zmake(3.71,2.753),B,B); zmma_mlt(A,B,C); for ( i = 0; i < C->m; i++ ) zm_set_val(C,i,i,zsub(zm_entry(C,i,i),zmake(3.71,-2.753))); if ( zm_norm_inf(C) >= MACHEPS*zm_norm_inf(A)*zm_norm_inf(B)*5 ) errmesg("szm_mlt()/zmma_mlt()"); zm_adjoint(B,B); zsm_mlt(zdiv(ONE,zmake(3.71,-2.753)),B,B); MEMCHK(); /* ... and matrix-vector multiplies */ notice("matrix-vector multiplies"); x = zv_resize(x,A->n); y = zv_resize(y,A->m); z = zv_resize(z,A->m); u = zv_resize(u,A->n); zv_rand(x); zv_rand(y); zmv_mlt(A,x,z); z1 = zin_prod(y,z); zvm_mlt(A,y,u); z2 = zin_prod(u,x); if ( zabs(zsub(z1,z2)) >= (MACHEPS*x->dim)*x->dim ) { errmesg("zmv_mlt()/zvm_mlt()"); printf("# difference between inner products is %g\n", zabs(zsub(z1,z2))); } zmv_mlt(B,z,u); if ( zv_norm2(zv_sub(u,x,u)) >= MACHEPS*zm_norm_inf(A)*zm_norm_inf(B)*5 ) errmesg("zmv_mlt()/zvm_mlt()"); MEMCHK(); /* get/set row/col */ notice("getting and setting rows and cols"); x = zv_resize(x,A->n); y = zv_resize(y,B->m); x = zget_row(A,3,x); y = zget_col(B,3,y); if ( zabs(zsub(_zin_prod(x,y,0,Z_NOCONJ),ONE)) >= MACHEPS*zm_norm_inf(A)*zm_norm_inf(B)*5 ) errmesg("zget_row()/zget_col()"); zv_mlt(zmake(-1.0,0.0),x,x); zv_mlt(zmake(-1.0,0.0),y,y); zset_row(A,3,x); zset_col(B,3,y); zm_mlt(A,B,C); for ( i = 0; i < C->m; i++ ) zm_set_val(C,i,i,zsub(zm_entry(C,i,i),ONE)); if ( zm_norm_inf(C) >= MACHEPS*zm_norm_inf(A)*zm_norm_inf(B)*5 ) errmesg("zset_row()/zset_col()"); MEMCHK(); /* matrix norms */ notice("matrix norms"); A = zm_resize(A,11,15); zm_rand(A); s1 = zm_norm_inf(A); B = zm_adjoint(A,B); s2 = zm_norm1(B); if ( fabs(s1 - s2) >= MACHEPS*A->m ) errmesg("zm_norm1()/zm_norm_inf()"); C = zmam_mlt(A,A,C); z1.re = z1.im = 0.0; for ( i = 0; i < C->m && i < C->n; i++ ) z1 = zadd(z1,zm_entry(C,i,i)); if ( fabs(sqrt(z1.re) - zm_norm_frob(A)) >= MACHEPS*A->m*A->n ) errmesg("zm_norm_frob"); MEMCHK(); /* permuting rows and columns */ /****************************** notice("permuting rows & cols"); A = zm_resize(A,11,15); B = zm_resize(B,11,15); pi1 = px_resize(pi1,A->m); px_rand(pi1); x = zv_resize(x,A->n); y = zmv_mlt(A,x,y); px_rows(pi1,A,B); px_zvec(pi1,y,z); zmv_mlt(B,x,u); if ( zv_norm2(zv_sub(z,u,u)) >= MACHEPS*A->m ) errmesg("px_rows()"); pi1 = px_resize(pi1,A->n); px_rand(pi1); px_cols(pi1,A,B); pxinv_zvec(pi1,x,z); zmv_mlt(B,z,u); if ( zv_norm2(zv_sub(y,u,u)) >= MACHEPS*A->n ) errmesg("px_cols()"); ******************************/ MEMCHK(); /* MATLAB save/load */ notice("MATLAB save/load"); A = zm_resize(A,12,11); if ( (fp=fopen(SAVE_FILE,"w")) == (FILE *)NULL ) printf("Cannot perform MATLAB save/load test\n"); else { zm_rand(A); zm_save(fp, A, name); fclose(fp); if ( (fp=fopen(SAVE_FILE,"r")) == (FILE *)NULL ) printf("Cannot open save file \"%s\"\n",SAVE_FILE); else { ZM_FREE(B); B = zm_load(fp,&cp); if ( strcmp(name,cp) || zm_norm1(zm_sub(A,B,C)) >= MACHEPS*A->m ) { errmesg("zm_load()/zm_save()"); printf("# orig. name = %s, restored name = %s\n", name, cp); printf("# orig. A =\n"); zm_output(A); printf("# restored A =\n"); zm_output(B); } } } MEMCHK(); /* Now, onto matrix factorisations */ A = zm_resize(A,10,10); B = zm_resize(B,A->m,A->n); zm_copy(A,B); x = zv_resize(x,A->n); y = zv_resize(y,A->m); z = zv_resize(z,A->n); u = zv_resize(u,A->m); zv_rand(x); zmv_mlt(B,x,y); z = zv_copy(x,z); notice("LU factor/solve"); pivot = px_get(A->m); zLUfactor(A,pivot); tracecatch(zLUsolve(A,pivot,y,x),"main"); tracecatch(cond_est = zLUcondest(A,pivot),"main"); printf("# cond(A) approx= %g\n", cond_est); if ( zv_norm2(zv_sub(x,z,u)) >= MACHEPS*zv_norm2(x)*cond_est) { errmesg("zLUfactor()/zLUsolve()"); printf("# LU solution error = %g [cf MACHEPS = %g]\n", zv_norm2(zv_sub(x,z,u)), MACHEPS); } zv_copy(y,x); tracecatch(zLUsolve(A,pivot,x,x),"main"); tracecatch(cond_est = zLUcondest(A,pivot),"main"); if ( zv_norm2(zv_sub(x,z,u)) >= MACHEPS*zv_norm2(x)*cond_est) { errmesg("zLUfactor()/zLUsolve()"); printf("# LU solution error = %g [cf MACHEPS = %g]\n", zv_norm2(zv_sub(x,z,u)), MACHEPS); } zvm_mlt(B,z,y); zv_copy(y,x); tracecatch(zLUAsolve(A,pivot,x,x),"main"); if ( zv_norm2(zv_sub(x,z,u)) >= MACHEPS*zv_norm2(x)*cond_est) { errmesg("zLUfactor()/zLUAsolve()"); printf("# LU solution error = %g [cf MACHEPS = %g]\n", zv_norm2(zv_sub(x,z,u)), MACHEPS); } MEMCHK(); /* QR factorisation */ zm_copy(B,A); zmv_mlt(B,z,y); notice("QR factor/solve:"); diag = zv_get(A->m); zQRfactor(A,diag); zQRsolve(A,diag,y,x); if ( zv_norm2(zv_sub(x,z,u)) >= MACHEPS*zv_norm2(x)*cond_est ) { errmesg("zQRfactor()/zQRsolve()"); printf("# QR solution error = %g [cf MACHEPS = %g]\n", zv_norm2(zv_sub(x,z,u)), MACHEPS); } printf("# QR cond(A) approx= %g\n", zQRcondest(A)); Q = zm_get(A->m,A->m); zmakeQ(A,diag,Q); zmakeR(A,A); zm_mlt(Q,A,C); zm_sub(B,C,C); if ( zm_norm1(C) >= MACHEPS*zm_norm1(Q)*zm_norm1(B) ) { errmesg("zQRfactor()/zmakeQ()/zmakeR()"); printf("# QR reconstruction error = %g [cf MACHEPS = %g]\n", zm_norm1(C), MACHEPS); } MEMCHK(); /* now try with a non-square matrix */ A = zm_resize(A,15,7); zm_rand(A); B = zm_copy(A,B); diag = zv_resize(diag,A->n); x = zv_resize(x,A->n); y = zv_resize(y,A->m); zv_rand(y); zQRfactor(A,diag); x = zQRsolve(A,diag,y,x); /* z is the residual vector */ zmv_mlt(B,x,z); zv_sub(z,y,z); /* check B*.z = 0 */ zvm_mlt(B,z,u); if ( zv_norm2(u) >= 100*MACHEPS*zm_norm1(B)*zv_norm2(y) ) { errmesg("zQRfactor()/zQRsolve()"); printf("# QR solution error = %g [cf MACHEPS = %g]\n", zv_norm2(u), MACHEPS); } Q = zm_resize(Q,A->m,A->m); zmakeQ(A,diag,Q); zmakeR(A,A); zm_mlt(Q,A,C); zm_sub(B,C,C); if ( zm_norm1(C) >= MACHEPS*zm_norm1(Q)*zm_norm1(B) ) { errmesg("zQRfactor()/zmakeQ()/zmakeR()"); printf("# QR reconstruction error = %g [cf MACHEPS = %g]\n", zm_norm1(C), MACHEPS); } D = zm_get(A->m,Q->m); zmam_mlt(Q,Q,D); for ( i = 0; i < D->m; i++ ) zm_set_val(D,i,i,zsub(zm_entry(D,i,i),ONE)); if ( zm_norm1(D) >= MACHEPS*zm_norm1(Q)*zm_norm_inf(Q) ) { errmesg("QRfactor()/makeQ()/makeR()"); printf("# QR orthogonality error = %g [cf MACHEPS = %g]\n", zm_norm1(D), MACHEPS); } MEMCHK(); /* QRCP factorisation */ zm_copy(B,A); notice("QR factor/solve with column pivoting"); pivot = px_resize(pivot,A->n); zQRCPfactor(A,diag,pivot); z = zv_resize(z,A->n); zQRCPsolve(A,diag,pivot,y,z); /* pxinv_zvec(pivot,z,x); */ /* now compute residual (z) vector */ zmv_mlt(B,x,z); zv_sub(z,y,z); /* check B^T.z = 0 */ zvm_mlt(B,z,u); if ( zv_norm2(u) >= MACHEPS*zm_norm1(B)*zv_norm2(y) ) { errmesg("QRCPfactor()/QRsolve()"); printf("# QR solution error = %g [cf MACHEPS = %g]\n", zv_norm2(u), MACHEPS); } Q = zm_resize(Q,A->m,A->m); zmakeQ(A,diag,Q); zmakeR(A,A); zm_mlt(Q,A,C); ZM_FREE(D); D = zm_get(B->m,B->n); /****************************** px_cols(pivot,C,D); zm_sub(B,D,D); if ( zm_norm1(D) >= MACHEPS*zm_norm1(Q)*zm_norm1(B) ) { errmesg("QRCPfactor()/makeQ()/makeR()"); printf("# QR reconstruction error = %g [cf MACHEPS = %g]\n", zm_norm1(D), MACHEPS); } ******************************/ /* Now check eigenvalue/SVD routines */ notice("complex Schur routines"); A = zm_resize(A,11,11); B = zm_resize(B,A->m,A->n); C = zm_resize(C,A->m,A->n); D = zm_resize(D,A->m,A->n); Q = zm_resize(Q,A->m,A->n); MEMCHK(); /* now test complex Schur decomposition */ /* zm_copy(A,B); */ ZM_FREE(A); A = zm_get(11,11); zm_rand(A); B = zm_copy(A,B); MEMCHK(); B = zschur(B,Q); checkpt(); zm_mlt(Q,B,C); zmma_mlt(C,Q,D); MEMCHK(); zm_sub(A,D,D); if ( zm_norm1(D) >= MACHEPS*zm_norm1(Q)*zm_norm_inf(Q)*zm_norm1(B)*5 ) { errmesg("zschur()"); printf("# Schur reconstruction error = %g [cf MACHEPS = %g]\n", zm_norm1(D), MACHEPS); } /* orthogonality check */ zmma_mlt(Q,Q,D); for ( i = 0; i < D->m; i++ ) zm_set_val(D,i,i,zsub(zm_entry(D,i,i),ONE)); if ( zm_norm1(D) >= MACHEPS*zm_norm1(Q)*zm_norm_inf(Q)*10 ) { errmesg("zschur()"); printf("# Schur orthogonality error = %g [cf MACHEPS = %g]\n", zm_norm1(D), MACHEPS); } MEMCHK(); /* now test SVD */ /****************************** A = zm_resize(A,11,7); zm_rand(A); U = zm_get(A->n,A->n); Q = zm_resize(Q,A->m,A->m); u = zv_resize(u,max(A->m,A->n)); svd(A,Q,U,u); ******************************/ /* check reconstruction of A */ /****************************** D = zm_resize(D,A->m,A->n); C = zm_resize(C,A->m,A->n); zm_zero(D); for ( i = 0; i < min(A->m,A->n); i++ ) zm_set_val(D,i,i,v_entry(u,i)); zmam_mlt(Q,D,C); zm_mlt(C,U,D); zm_sub(A,D,D); if ( zm_norm1(D) >= MACHEPS*zm_norm1(U)*zm_norm_inf(Q)*zm_norm1(A) ) { errmesg("svd()"); printf("# SVD reconstruction error = %g [cf MACHEPS = %g]\n", zm_norm1(D), MACHEPS); } ******************************/ /* check orthogonality of Q and U */ /****************************** D = zm_resize(D,Q->n,Q->n); zmam_mlt(Q,Q,D); for ( i = 0; i < D->m; i++ ) m_set_val(D,i,i,m_entry(D,i,i)-1.0); if ( zm_norm1(D) >= MACHEPS*zm_norm1(Q)*zm_norm_inf(Q)*5 ) { errmesg("svd()"); printf("# SVD orthognality error (Q) = %g [cf MACHEPS = %g\n", zm_norm1(D), MACHEPS); } D = zm_resize(D,U->n,U->n); zmam_mlt(U,U,D); for ( i = 0; i < D->m; i++ ) m_set_val(D,i,i,m_entry(D,i,i)-1.0); if ( zm_norm1(D) >= MACHEPS*zm_norm1(U)*zm_norm_inf(U)*5 ) { errmesg("svd()"); printf("# SVD orthognality error (U) = %g [cf MACHEPS = %g\n", zm_norm1(D), MACHEPS); } for ( i = 0; i < u->dim; i++ ) if ( v_entry(u,i) < 0 || (i < u->dim-1 && v_entry(u,i+1) > v_entry(u,i)) ) break; if ( i < u->dim ) { errmesg("svd()"); printf("# SVD sorting error\n"); } ******************************/ ZV_FREE(x); ZV_FREE(y); ZV_FREE(z); ZV_FREE(u); ZV_FREE(diag); PX_FREE(pi1); PX_FREE(pi2); PX_FREE(pivot); ZM_FREE(A); ZM_FREE(B); ZM_FREE(C); ZM_FREE(D); ZM_FREE(Q); mem_stat_free(1); MEMCHK(); printf("# Finished torture test for complex numbers/vectors/matrices\n"); mem_info(); } gtk-wave-cleaner-0.22-04/meschach/zvecop.c0000777000175000017500000003034013120075107021432 0ustar00alisteralister00000000000000 /************************************************************************** ** ** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved. ** ** Meschach Library ** ** This Meschach Library is provided "as is" without any express ** or implied warranty of any kind with respect to this software. ** In particular the authors shall not be liable for any direct, ** indirect, special, incidental or consequential damages arising ** in any way from use of the software. ** ** Everyone is granted permission to copy, modify and redistribute this ** Meschach Library, provided: ** 1. All copies contain this copyright notice. ** 2. All modified copies shall carry a notice stating who ** made the last modification and the date of such modification. ** 3. No charge is made for this software or works derived from it. ** This clause shall not be construed as constraining other software ** distributed on the same medium as this software, nor is a ** distribution fee considered a charge. ** ***************************************************************************/ #include #include "matrix.h" #include "zmatrix.h" static char rcsid[] = "$Id: zvecop.c,v 1.3 1997/10/07 16:13:54 stewart Exp stewart $"; /* _zin_prod -- inner product of two vectors from i0 downwards -- flag != 0 means compute sum_i a[i]*.b[i]; -- flag == 0 means compute sum_i a[i].b[i] */ #ifndef ANSI_C complex _zin_prod(a,b,i0,flag) ZVEC *a,*b; unsigned int i0, flag; #else complex _zin_prod(const ZVEC *a, const ZVEC *b, unsigned int i0, unsigned int flag) #endif { unsigned int limit; if ( a==ZVNULL || b==ZVNULL ) error(E_NULL,"_zin_prod"); limit = min(a->dim,b->dim); if ( i0 > limit ) error(E_BOUNDS,"_zin_prod"); return __zip__(&(a->ve[i0]),&(b->ve[i0]),(int)(limit-i0),flag); } /* zv_mlt -- scalar-vector multiply -- may be in-situ */ #ifndef ANSI_C ZVEC *zv_mlt(scalar,vector,out) complex scalar; ZVEC *vector,*out; #else ZVEC *zv_mlt(complex scalar, const ZVEC *vector, ZVEC *out) #endif { /* unsigned int dim, i; */ /* complex *out_ve, *vec_ve; */ if ( vector==ZVNULL ) error(E_NULL,"zv_mlt"); if ( out==ZVNULL || out->dim != vector->dim ) out = zv_resize(out,vector->dim); if ( scalar.re == 0.0 && scalar.im == 0.0 ) return zv_zero(out); if ( scalar.re == 1.0 && scalar.im == 0.0 ) return zv_copy(vector,out); __zmlt__(vector->ve,scalar,out->ve,(int)(vector->dim)); return (out); } /* zv_add -- vector addition -- may be in-situ */ #ifndef ANSI_C ZVEC *zv_add(vec1,vec2,out) ZVEC *vec1,*vec2,*out; #else ZVEC *zv_add(const ZVEC *vec1, const ZVEC *vec2, ZVEC *out) #endif { unsigned int dim; if ( vec1==ZVNULL || vec2==ZVNULL ) error(E_NULL,"zv_add"); if ( vec1->dim != vec2->dim ) error(E_SIZES,"zv_add"); if ( out==ZVNULL || out->dim != vec1->dim ) out = zv_resize(out,vec1->dim); dim = vec1->dim; __zadd__(vec1->ve,vec2->ve,out->ve,(int)dim); return (out); } /* zv_mltadd -- scalar/vector multiplication and addition -- out = v1 + scale.v2 */ #ifndef ANSI_C ZVEC *zv_mltadd(v1,v2,scale,out) ZVEC *v1,*v2,*out; complex scale; #else ZVEC *zv_mltadd(const ZVEC *v1, const ZVEC *v2, complex scale, ZVEC *out) #endif { /* register unsigned int dim, i; */ /* complex *out_ve, *v1_ve, *v2_ve; */ if ( v1==ZVNULL || v2==ZVNULL ) error(E_NULL,"zv_mltadd"); if ( v1->dim != v2->dim ) error(E_SIZES,"zv_mltadd"); if ( scale.re == 0.0 && scale.im == 0.0 ) return zv_copy(v1,out); if ( scale.re == 1.0 && scale.im == 0.0 ) return zv_add(v1,v2,out); if ( v2 != out ) { tracecatch(out = zv_copy(v1,out),"zv_mltadd"); /* dim = v1->dim; */ __zmltadd__(out->ve,v2->ve,scale,(int)(v1->dim),0); } else { tracecatch(out = zv_mlt(scale,v2,out),"zv_mltadd"); out = zv_add(v1,out,out); } return (out); } /* zv_sub -- vector subtraction -- may be in-situ */ #ifndef ANSI_C ZVEC *zv_sub(vec1,vec2,out) ZVEC *vec1,*vec2,*out; #else ZVEC *zv_sub(const ZVEC *vec1, const ZVEC *vec2, ZVEC *out) #endif { /* unsigned int i, dim; */ /* complex *out_ve, *vec1_ve, *vec2_ve; */ if ( vec1==ZVNULL || vec2==ZVNULL ) error(E_NULL,"zv_sub"); if ( vec1->dim != vec2->dim ) error(E_SIZES,"zv_sub"); if ( out==ZVNULL || out->dim != vec1->dim ) out = zv_resize(out,vec1->dim); __zsub__(vec1->ve,vec2->ve,out->ve,(int)(vec1->dim)); return (out); } /* zv_map -- maps function f over components of x: out[i] = f(x[i]) -- _zv_map sets out[i] = f(x[i],params) */ #ifndef ANSI_C ZVEC *zv_map(f,x,out) #ifdef PROTOYPES_IN_STRUCT complex (*f)(complex); #else complex (*f)(); #endif ZVEC *x, *out; #else ZVEC *zv_map(complex (*f)(complex), const ZVEC *x, ZVEC *out) #endif { complex *x_ve, *out_ve; int i, dim; if ( ! x || ! f ) error(E_NULL,"zv_map"); if ( ! out || out->dim != x->dim ) out = zv_resize(out,x->dim); dim = x->dim; x_ve = x->ve; out_ve = out->ve; for ( i = 0; i < dim; i++ ) out_ve[i] = (*f)(x_ve[i]); return out; } #ifndef ANSI_C ZVEC *_zv_map(f,params,x,out) #ifdef PROTOTYPES_IN_STRUCT complex (*f)(void *,complex); #else complex (*f)(); #endif ZVEC *x, *out; void *params; #else ZVEC *_zv_map(complex (*f)(void *,complex), void *params, const ZVEC *x, ZVEC *out) #endif { complex *x_ve, *out_ve; int i, dim; if ( ! x || ! f ) error(E_NULL,"_zv_map"); if ( ! out || out->dim != x->dim ) out = zv_resize(out,x->dim); dim = x->dim; x_ve = x->ve; out_ve = out->ve; for ( i = 0; i < dim; i++ ) out_ve[i] = (*f)(params,x_ve[i]); return out; } /* zv_lincomb -- returns sum_i a[i].v[i], a[i] real, v[i] vectors */ #ifndef ANSI_C ZVEC *zv_lincomb(n,v,a,out) int n; /* number of a's and v's */ complex a[]; ZVEC *v[], *out; #else ZVEC *zv_lincomb(int n, const ZVEC *v[], const complex a[], ZVEC *out) #endif { int i; if ( ! a || ! v ) error(E_NULL,"zv_lincomb"); if ( n <= 0 ) return ZVNULL; for ( i = 1; i < n; i++ ) if ( out == v[i] ) error(E_INSITU,"zv_lincomb"); out = zv_mlt(a[0],v[0],out); for ( i = 1; i < n; i++ ) { if ( ! v[i] ) error(E_NULL,"zv_lincomb"); if ( v[i]->dim != out->dim ) error(E_SIZES,"zv_lincomb"); out = zv_mltadd(out,v[i],a[i],out); } return out; } #ifdef ANSI_C /* zv_linlist -- linear combinations taken from a list of arguments; calling: zv_linlist(out,v1,a1,v2,a2,...,vn,an,NULL); where vi are vectors (ZVEC *) and ai are numbers (complex) */ ZVEC *zv_linlist(ZVEC *out,ZVEC *v1,complex a1,...) { va_list ap; ZVEC *par; complex a_par; if ( ! v1 ) return ZVNULL; va_start(ap, a1); out = zv_mlt(a1,v1,out); while (par = va_arg(ap,ZVEC *)) { /* NULL ends the list*/ a_par = va_arg(ap,complex); if (a_par.re == 0.0 && a_par.im == 0.0) continue; if ( out == par ) error(E_INSITU,"zv_linlist"); if ( out->dim != par->dim ) error(E_SIZES,"zv_linlist"); if (a_par.re == 1.0 && a_par.im == 0.0) out = zv_add(out,par,out); else if (a_par.re == -1.0 && a_par.im == 0.0) out = zv_sub(out,par,out); else out = zv_mltadd(out,par,a_par,out); } va_end(ap); return out; } #elif VARARGS /* zv_linlist -- linear combinations taken from a list of arguments; calling: zv_linlist(out,v1,a1,v2,a2,...,vn,an,NULL); where vi are vectors (ZVEC *) and ai are numbers (complex) */ ZVEC *zv_linlist(va_alist) va_dcl { va_list ap; ZVEC *par, *out; complex a_par; va_start(ap); out = va_arg(ap,ZVEC *); par = va_arg(ap,ZVEC *); if ( ! par ) { va_end(ap); return ZVNULL; } a_par = va_arg(ap,complex); out = zv_mlt(a_par,par,out); while (par = va_arg(ap,ZVEC *)) { /* NULL ends the list*/ a_par = va_arg(ap,complex); if (a_par.re == 0.0 && a_par.im == 0.0) continue; if ( out == par ) error(E_INSITU,"zv_linlist"); if ( out->dim != par->dim ) error(E_SIZES,"zv_linlist"); if (a_par.re == 1.0 && a_par.im == 0.0) out = zv_add(out,par,out); else if (a_par.re == -1.0 && a_par.im == 0.0) out = zv_sub(out,par,out); else out = zv_mltadd(out,par,a_par,out); } va_end(ap); return out; } #endif /* zv_star -- computes componentwise (Hadamard) product of x1 and x2 -- result out is returned */ #ifndef ANSI_C ZVEC *zv_star(x1, x2, out) ZVEC *x1, *x2, *out; #else ZVEC *zv_star(const ZVEC *x1, const ZVEC *x2, ZVEC *out) #endif { int i; Real t_re, t_im; if ( ! x1 || ! x2 ) error(E_NULL,"zv_star"); if ( x1->dim != x2->dim ) error(E_SIZES,"zv_star"); out = zv_resize(out,x1->dim); for ( i = 0; i < x1->dim; i++ ) { /* out->ve[i] = x1->ve[i] * x2->ve[i]; */ t_re = x1->ve[i].re*x2->ve[i].re - x1->ve[i].im*x2->ve[i].im; t_im = x1->ve[i].re*x2->ve[i].im + x1->ve[i].im*x2->ve[i].re; out->ve[i].re = t_re; out->ve[i].im = t_im; } return out; } /* zv_slash -- computes componentwise ratio of x2 and x1 -- out[i] = x2[i] / x1[i] -- if x1[i] == 0 for some i, then raise E_SING error -- result out is returned */ #ifndef ANSI_C ZVEC *zv_slash(x1, x2, out) ZVEC *x1, *x2, *out; #else ZVEC *zv_slash(const ZVEC *x1, const ZVEC *x2, ZVEC *out) #endif { int i; Real r2, t_re, t_im; complex tmp; if ( ! x1 || ! x2 ) error(E_NULL,"zv_slash"); if ( x1->dim != x2->dim ) error(E_SIZES,"zv_slash"); out = zv_resize(out,x1->dim); for ( i = 0; i < x1->dim; i++ ) { r2 = x1->ve[i].re*x1->ve[i].re + x1->ve[i].im*x1->ve[i].im; if ( r2 == 0.0 ) error(E_SING,"zv_slash"); tmp.re = x1->ve[i].re / r2; tmp.im = - x1->ve[i].im / r2; t_re = tmp.re*x2->ve[i].re - tmp.im*x2->ve[i].im; t_im = tmp.re*x2->ve[i].im + tmp.im*x2->ve[i].re; out->ve[i].re = t_re; out->ve[i].im = t_im; } return out; } /* zv_sum -- returns sum of entries of a vector */ #ifndef ANSI_C complex zv_sum(x) ZVEC *x; #else complex zv_sum(const ZVEC *x) #endif { int i; complex sum; if ( ! x ) error(E_NULL,"zv_sum"); sum.re = sum.im = 0.0; for ( i = 0; i < x->dim; i++ ) { sum.re += x->ve[i].re; sum.im += x->ve[i].im; } return sum; } /* px_zvec -- permute vector */ #ifndef ANSI_C ZVEC *px_zvec(px,vector,out) PERM *px; ZVEC *vector,*out; #else ZVEC *px_zvec(PERM *px, ZVEC *vector, ZVEC *out) #endif { unsigned int old_i, i, size, start; complex tmp; if ( px==PNULL || vector==ZVNULL ) error(E_NULL,"px_zvec"); if ( px->size > vector->dim ) error(E_SIZES,"px_zvec"); if ( out==ZVNULL || out->dim < vector->dim ) out = zv_resize(out,vector->dim); size = px->size; if ( size == 0 ) return zv_copy(vector,out); if ( out != vector ) { for ( i=0; ipe[i] >= size ) error(E_BOUNDS,"px_vec"); else out->ve[i] = vector->ve[px->pe[i]]; } else { /* in situ algorithm */ start = 0; while ( start < size ) { old_i = start; i = px->pe[old_i]; if ( i >= size ) { start++; continue; } tmp = vector->ve[start]; while ( TRUE ) { vector->ve[old_i] = vector->ve[i]; px->pe[old_i] = i+size; old_i = i; i = px->pe[old_i]; if ( i >= size ) break; if ( i == start ) { vector->ve[old_i] = tmp; px->pe[old_i] = i+size; break; } } start++; } for ( i = 0; i < size; i++ ) if ( px->pe[i] < size ) error(E_BOUNDS,"px_vec"); else px->pe[i] = px->pe[i]-size; } return out; } /* pxinv_zvec -- apply the inverse of px to x, returning the result in out -- may NOT be in situ */ #ifndef ANSI_C ZVEC *pxinv_zvec(px,x,out) PERM *px; ZVEC *x, *out; #else ZVEC *pxinv_zvec(PERM *px, ZVEC *x, ZVEC *out) #endif { unsigned int i, size; if ( ! px || ! x ) error(E_NULL,"pxinv_zvec"); if ( px->size > x->dim ) error(E_SIZES,"pxinv_zvec"); if ( ! out || out->dim < x->dim ) out = zv_resize(out,x->dim); size = px->size; if ( size == 0 ) return zv_copy(x,out); if ( out != x ) { for ( i=0; ipe[i] >= size ) error(E_BOUNDS,"pxinv_vec"); else out->ve[px->pe[i]] = x->ve[i]; } else { /* in situ algorithm --- cheat's way out */ px_inv(px,px); px_zvec(px,x,out); px_inv(px,px); } return out; } /* zv_rand -- randomise a complex vector; uniform in [0,1)+[0,1)*i */ #ifndef ANSI_C ZVEC *zv_rand(x) ZVEC *x; #else ZVEC *zv_rand(ZVEC *x) #endif { if ( ! x ) error(E_NULL,"zv_rand"); mrandlist((Real *)(x->ve),2*x->dim); return x; } gtk-wave-cleaner-0.22-04/missing0000777000175000017500000001533013120075107017603 0ustar00alisteralister00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: gtk-wave-cleaner-0.22-04/mp3-duration.h0000777000175000017500000001542513120075107020707 0ustar00alisteralister00000000000000/* libSoX determine MP3 duration * Copyright (c) 2007 robs@users.sourceforge.net * Based on original ideas by Regis Boudin, Thibaut Varene & Pascal Giard * * This 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. * * This 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 this library; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #if HAVE_ID3TAG && HAVE_UNISTD_H static id3_utf8_t * utf8_id3tag_findframe( struct id3_tag * tag, const char * const frameid, unsigned index) { struct id3_frame const * frame = id3_tag_findframe(tag, frameid, index); if (frame) { union id3_field const * field = id3_frame_field(frame, 1); unsigned nstrings = id3_field_getnstrings(field); while (nstrings--){ id3_ucs4_t const * ucs4 = id3_field_getstrings(field, nstrings); if (ucs4) return id3_ucs4_utf8duplicate(ucs4); /* Must call free() on this */ } } return NULL; } static void read_comments(sox_format_t * ft) { static char const * list[][2] = { {ID3_FRAME_TITLE, "Title"}, {ID3_FRAME_ARTIST, "Artist"}, {ID3_FRAME_ALBUM, "Album"}, {ID3_FRAME_TRACK, "Tracknumber"}, {ID3_FRAME_YEAR, "Year"}, {ID3_FRAME_GENRE, "Genre"}, {ID3_FRAME_COMMENT, "Comment"}, {"TPOS", "Discnumber"}, {NULL, NULL} }; struct id3_file * id3struct; struct id3_tag * tag; id3_utf8_t * utf8; int i, fd = dup(fileno(ft->fp)); if ((id3struct = id3_file_fdopen(fd, ID3_FILE_MODE_READONLY))) { if ((tag = id3_file_tag(id3struct)) && tag->frames) for (i = 0; list[i][0]; ++i) if ((utf8 = utf8_id3tag_findframe(tag, list[i][0], 0))) { char * comment = lsx_malloc(strlen(list[i][1]) + 1 + strlen((char *)utf8) + 1); sprintf(comment, "%s=%s", list[i][1], utf8); sox_append_comment(&ft->oob.comments, comment); free(comment); free(utf8); } if ((utf8 = utf8_id3tag_findframe(tag, "TLEN", 0))) { if (atoi((char *)utf8) > 0) { ft->signal.length = atoi((char *)utf8); /* In ms; convert to samples later */ lsx_debug("got exact duration from ID3 TLEN"); } free(utf8); } id3_file_close(id3struct); } else close(fd); } #endif static unsigned long xing_frames(struct mad_bitptr ptr, unsigned bitlen) { #define XING_MAGIC ( ('X' << 24) | ('i' << 16) | ('n' << 8) | 'g' ) if (bitlen >= 96 && mad_bit_read(&ptr, 32) == XING_MAGIC && (mad_bit_read(&ptr, 32) & 1 )) /* XING_FRAMES */ return mad_bit_read(&ptr, 32); return 0; } static void mad_timer_mult(mad_timer_t * t, double d) { t->seconds = d *= (t->seconds + t->fraction * (1. / MAD_TIMER_RESOLUTION)); t->fraction = (d - t->seconds) * MAD_TIMER_RESOLUTION + .5; } static size_t mp3_duration_ms(FILE * fp, unsigned char *buffer) { struct mad_stream mad_stream; struct mad_header mad_header; struct mad_frame mad_frame; mad_timer_t time = mad_timer_zero; size_t initial_bitrate = 0; /* Initialised to prevent warning */ size_t tagsize = 0, consumed = 0, frames = 0; sox_bool vbr = sox_false, depadded = sox_false; mad_stream_init(&mad_stream); mad_header_init(&mad_header); mad_frame_init(&mad_frame); do { /* Read data from the MP3 file */ int read, padding = 0; size_t leftover = mad_stream.bufend - mad_stream.next_frame; memcpy(buffer, mad_stream.this_frame, leftover); read = fread(buffer + leftover, (size_t) 1, INPUT_BUFFER_SIZE - leftover, fp); if (read <= 0) { lsx_debug("got exact duration by scan to EOF (frames=%lu leftover=%lu)", (unsigned long)frames, (unsigned long)leftover); break; } for (; !depadded && padding < read && !buffer[padding]; ++padding); depadded = sox_true; mad_stream_buffer(&mad_stream, buffer + padding, leftover + read - padding); while (sox_true) { /* Decode frame headers */ mad_stream.error = MAD_ERROR_NONE; if (mad_header_decode(&mad_header, &mad_stream) == -1) { if (mad_stream.error == MAD_ERROR_BUFLEN) break; /* Normal behaviour; get some more data from the file */ if (!MAD_RECOVERABLE(mad_stream.error)) { lsx_warn("unrecoverable MAD error"); break; } if (mad_stream.error == MAD_ERROR_LOSTSYNC) { unsigned available = (mad_stream.bufend - mad_stream.this_frame); tagsize = tagtype(mad_stream.this_frame, (size_t) available); if (tagsize) { /* It's some ID3 tags, so just skip */ if (tagsize >= available) { fseeko(fp, (off_t)(tagsize - available), SEEK_CUR); depadded = sox_false; } mad_stream_skip(&mad_stream, min(tagsize, available)); } else lsx_warn("MAD lost sync"); } else lsx_warn("recoverable MAD error"); continue; /* Not an audio frame */ } mad_timer_add(&time, mad_header.duration); consumed += mad_stream.next_frame - mad_stream.this_frame; if (!frames) { initial_bitrate = mad_header.bitrate; /* Get the precise frame count from the XING header if present */ mad_frame.header = mad_header; if (mad_frame_decode(&mad_frame, &mad_stream) == -1) if (!MAD_RECOVERABLE(mad_stream.error)) { lsx_warn("unrecoverable MAD error"); break; } if ((frames = xing_frames(mad_stream.anc_ptr, mad_stream.anc_bitlen))) { mad_timer_multiply(&time, (signed long)frames); lsx_debug("got exact duration from XING frame count (%lu)", (unsigned long)frames); break; } } else vbr |= mad_header.bitrate != initial_bitrate; /* If not VBR, we can time just a few frames then extrapolate */ if (++frames == 10 && !vbr) { struct stat filestat; fstat(fileno(fp), &filestat); mad_timer_mult(&time, (double)(filestat.st_size - tagsize) / consumed); lsx_debug("got approx. duration by CBR extrapolation"); break; } } } while (mad_stream.error == MAD_ERROR_BUFLEN); mad_frame_finish(&mad_frame); mad_header_finish(&mad_header); mad_stream_finish(&mad_stream); rewind(fp); return mad_timer_count(time, MAD_UNITS_MILLISECONDS); } gtk-wave-cleaner-0.22-04/mp3.h0000777000175000017500000000076113120075107017061 0ustar00alisteralister00000000000000 Mp3_File mp3file ; struct Mp3_File { int rate ; int channels ; long position ; /* current, or rather last output sample number */ } void mp3_clear(Mp3File *) ; /* closes everything related to an open mp3file */ int mp3_open(FILE *fp_mp3, Mp3_File *mp3file) ; /* opens and mp3 file, returns 1 on success, -1 on failure, detects rate and #channels */ long mp3_pcm_total(Mp3File *) ; int mp3_pcm_seek(Mp3File *, int sample_number) ; long mp3_read(Mp3_File *, char *buf, int bufsize) ; gtk-wave-cleaner-0.22-04/osx_packaging/0000755000175000017500000000000013453574021021023 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/osx_packaging/Gtk Wave Cleaner.app/0000755000175000017500000000000013252653017024544 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/osx_packaging/Gtk Wave Cleaner.app/Contents/0000755000175000017500000000000013455315675026353 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/osx_packaging/Gtk Wave Cleaner.app/Contents/Info.plist0000666000175000017500000000112713455315675030330 0ustar00alisteralister00000000000000 CFBundleExecutable gtk-wave-cleaner CFBundleIconFile AppIcon CFBundleIdentifier com.alisterhood.gwc CFBundleName Gtk Wave Cleaner CFBundlePackageType APPL CFBundleSignature ???? CFBundleVersion 0.22.0 gtk-wave-cleaner-0.22-04/osx_packaging/Gtk Wave Cleaner.app/Contents/MacOS/0000755000175000017500000000000013453574021027303 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/osx_packaging/Gtk Wave Cleaner.app/Contents/MacOS/gtk-wave-cleaner0000777000175000017500000000423613453574021032376 0ustar00alisteralister00000000000000#!/bin/sh # Purpose: set up the runtime environment and run GWC (adapted from GIMP) echo "Setting up environment..." if test "x$GTK_DEBUG_LAUNCHER" != x; then set -x fi if test "x$GTK_DEBUG_GDB" != x; then EXEC="gdb --args" else EXEC=exec fi name=`basename "$0"` tmp="$0" tmp=`dirname "$tmp"` tmp=`dirname "$tmp"` bundle=`dirname "$tmp"` bundle_contents="$bundle"/Contents bundle_res="$bundle_contents"/Resources bundle_lib="$bundle_res"/lib bundle_bin="$bundle_res"/bin bundle_data="$bundle_res"/share bundle_etc="$bundle_res"/etc export DYLD_LIBRARY_PATH="$bundle_lib" #it could be useful to set some XDG environment variables - by default gwc uses ~/.cache and ~/.config #export XDG_CONFIG_DIRS="$bundle_etc"/xdg #export XDG_DATA_DIRS="$bundle_data" #we might need some of these for themes or whatever export GTK_DATA_PREFIX="$bundle_res" export GTK_EXE_PREFIX="$bundle_res" export GTK_PATH="$bundle_res" #we need XDG_CACHE_HOME to prevent terrible behaviour when running from a .dmg, caused by #falling back to the current working directory, which is read-only in that case. export XDG_CACHE_HOME="$HOME/Library/Caches" #it is tidier if we use this (unless there are users on osx who like to have stuff in ~/.config?) export XDG_CONFIG_HOME="$HOME/Library/gtk-wave-cleaner/" #not sure if this is needed export XDG_DATA_HOME="$HOME/Library/gtk-wave-cleaner/" # Set up PATH variable export PATH="$bundle_contents/MacOS:$PATH" # Set up generic configuration export GTK2_RC_FILES="$bundle_etc/gtk-2.0/gtkrc" export GDK_PIXBUF_MODULE_FILE="$bundle_lib/gdk-pixbuf-2.0/loaders.cache" # Alister: this doesn't actually seem to do anything: # export GDK_PIXBUF_MODULEDIR="$bundle_lib/gdk-pixbuf-2.0/loaders" # Extra arguments can be added in environment.sh. EXTRA_ARGS= if test -f "$bundle_res/environment.sh"; then source "$bundle_res/environment.sh" fi # Strip out the argument added by the OS. if /bin/expr "x$1" : '^x-psn_' > /dev/null; then shift 1 fi # change to the user's home directory so that anything written to the current working directory ends up there. cd $HOME echo "Launching Gtk Wave Cleaner..." $EXEC "$bundle_contents/MacOS/gtk-wave-cleaner-bin" "$@" $EXTRA_ARGS gtk-wave-cleaner-0.22-04/osx_packaging/Gtk Wave Cleaner.app/Contents/Resources/0000755000175000017500000000000013453574021030313 5ustar00alisteralister00000000000000gtk-wave-cleaner-0.22-04/osx_packaging/Gtk Wave Cleaner.app/Contents/Resources/AppIcon.icns0000777000175000017500000140624713122047751032545 0ustar00alisteralister00000000000000icns §is32™ÿ5b“£€d7„ÿT³ƒÿ¹Wÿbé€ÿ óÿ¯ÿÿïkÿÿNéÿ ~ÿZõÿÿñUÿ2«ÿöhÿ²¨€ÿ»2]ÿö€ÿ ²±ÿùbÿà›øe~i;ûÿÿmõÿÿnÓR²c†w‚œ¿ÿþc€ÿÛTéÿ‚}„ÿƒ~ÿÿdÿ~å…ÿ…_ÿÿ{ée†ÿf2±ÿÃY•…ÿ¿2ÿPëÿ¡…ÿóXÿÿdí…ÿóo€ÿUºƒÿÀZƒÿ9gƒ–¥„j<ÿÿ5b“(€d7„ÿT³€ÿÿÿ¹Wÿbé€ÿ ó¯ÿÿïkÿÿNéÿ ~ZõÿÿñUÿ2«ÿöh²¨€ÿ»2]ÿö€ÿ*²±ùbÿà›øe~i;ûÿÿmõÿnÓR²c†w‚œ¿ÿþcÿÿÛTéÿ‚}‹ ~ÿÿdÿ~åÿƒÿ …_ÿÿ{éeÿÿƒÿ f2±ÿÃY•ÿÿ‚ÿ¿2ÿPëÿ¡€ÿÿóXÿÿdíÿ€ÿóo€ÿUº€ÿÿÿÀZƒÿ9gƒ–%„j<ÿÿ5b“(€d7„ÿT³€ÿÿÿ¹Wÿbé€ÿ ó¯ÿÿïkÿÿNéÿ ~ZõÿÿñUÿ2«ÿöh²¨€ÿ»2]ÿö€ÿ2²±ùbÿà›øe~i;ûÿÿmõÿnÓR²c†w‚œ¿ÿþcÿÿÛTéÿ‚}hîëtÿʘÿ‚ÿ îh~ÿÿdÿ~åÿƒÿ …_ÿÿ{éeÿÿƒÿ f2±ÿÃY•ÿÿ‚ÿ¿2ÿPëÿ¡€ÿÿóXÿÿdíÿ€ÿóo€ÿUº€ÿÿÿÀZƒÿ9gƒ–%„j<ÿs8mk*­Îñ¯Ž/yåÿÿÿÿÿÿ瀭üÿÿÿÿÿÿÿÿþ³vüÿÿÿÿÿÿÿÿÿÿþ€$âÿÿÿÿÿÿÿÿÿÿÿÿå/‰ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ«ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚùÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°‰ÿÿÿÿÿÿÿÿÿÿÿÿÿÿŽ(äÿÿÿÿÿÿÿÿÿÿÿÿç3|ýÿÿÿÿÿÿÿÿÿÿÿ„²þÿÿÿÿÿÿÿÿÿ¸€èÿÿÿÿÿÿê†1’³Ôóµ“6il32ˆÿ'))&’ÿ &3}¶Ñìêжz3&ÿ#eä‡ÿã`#ŠÿHà‹ÿÞE‡ÿ#zŽÿþr …ÿ ‘ÿ–„ÿ x“ÿn‚ÿIþ“ÿþCÿ%ã•ÿÞ!€ÿ k—ÿ`ÿÿ'í‹ÿ[W¸†ÿã#ÿ;ŠÿñÿµÔPu†ÿ2ŒŠÿpÿj†…ÿzĉÿþ+ÿýP£ÿÿ®JÁÿÿ¶#ßÿü® ï„ÿÂc‚ÿö=°Å>Ç8¾ÿÐ"%ùúVm†4߃ÿj½ƒÿ ðD7ãÿÛ>ÿê%$j‹ÿŠ„$$Ò¥ÿÁOÿ¾gŠÿèÇÒ#ƃÿf¦€ÿmºŒÿ·‘ƒÿï-èÿÿ/ûŒÿ=„ÿ¶Nûžgÿ4ÿ'ñ„ÿŠ.@öŒÿè#ÿÿs…ÿàðÿh €ÿ%æ•ÿá"ÿP•ÿH‚ÿ†“ÿ}„ÿ ®‘ÿ¦…ÿ"ˆÿ€!‡ÿPç‹ÿäM Šÿ%vï‡ÿïq&ÿ ';ÅàúùßÄ<( ‘ÿ #*(()"ˆÿˆÿ'))&’ÿ &3}¶ÑìÛжz3&ÿ#eä‚ÿÿã`#ŠÿHà„ÿƒÿÞE‡ÿ#z†ÿ„ÿþr …ÿ ‡ÿ†ÿ–„ÿ xˆÿ‡ÿn‚ÿIþˆÿ‡ÿþCÿ%ã‰ÿˆÿÞ!€ÿ kŠÿ‰ÿ`ÿÿ'íŠÿ[W¸†ÿã#ÿ;ŠÿñµÔPu†ÿ2ŒŠÿp€ÿj†…ÿzĉÿþ+€ÿýP£ÿÿ®JÁÿÿ¶#ßÿü® ï„ÿÂcÿö=°Å>Ç8¾ÿÐ"%ùúVm†4߃ÿj½‚ÿ ðD7ãÿÛ>ÿê%$j™„$$Ò¥ÿÁOÿ¾gÿˆÿèÇÒ#ƃÿf¦€ÿmºÿŠÿ·‘ƒÿï-èÿÿ/ûÿŠÿ=„ÿ¶NûžgÿÿŠÿ4ÿ'ñ„ÿŠ.@öÿÿ‰ÿè#ÿÿs…ÿàð€ÿ‰ÿh €ÿ%æ‰ÿˆÿá"ÿP‰ÿˆÿH‚ÿ†ˆÿ‡ÿ}„ÿ ®‡ÿ†ÿ¦…ÿ"ˆ†ÿ…ÿ€!‡ÿPç„ÿƒÿäM Šÿ%vï‚ÿÿïq&ÿ ';ÅàúùßÄ<( ‘ÿ #*(()"ˆÿˆÿ'))&’ÿ &3}¶ÑìÛжz3&ÿ#eä‚ÿÿã`#ŠÿHà„ÿƒÿÞE‡ÿ#z†ÿ„ÿþr …ÿ ‡ÿ†ÿ–„ÿ xˆÿ‡ÿn‚ÿIþˆÿ‡ÿþCÿ%ã‰ÿˆÿÞ!€ÿ kŠÿ‰ÿ`ÿÿ'íŠÿ[W¸†ÿã#ÿ;ŠÿñµÔPu†ÿ2ŒŠÿp€ÿj†…ÿzĉÿþ+€ÿýP£ÿÿ®JÁÿÿ¶#ßÿü® ï„ÿÂcÿö=°Å>Ç8¾ÿÐ"%ùúVm†4߃ÿj½‚ÿðD7ãÿÛ>ÿê%$óNŽÿÿÐ2åÿü*ýˆÿi³ì$$Ò¥ÿÁOÿ¾gÿˆÿèÇÒ#ƃÿf¦€ÿmºÿŠÿ·‘ƒÿï-èÿÿ/ûÿŠÿ=„ÿ¶NûžgÿÿŠÿ4ÿ'ñ„ÿŠ.@öÿÿ‰ÿè#ÿÿs…ÿàð€ÿ‰ÿh €ÿ%æ‰ÿˆÿá"ÿP‰ÿˆÿH‚ÿ†ˆÿ‡ÿ}„ÿ ®‡ÿ†ÿ¦…ÿ"ˆ†ÿ…ÿ€!‡ÿPç„ÿƒÿäM Šÿ%vï‚ÿÿïq&ÿ ';ÅàúùßÄ<( ‘ÿ #*(()"ˆÿl8mk7j°¯Žh38°ÝïÿÿÿÿÿÿíÚª0"»êÿÿÿÿÿÿÿÿÿÿÿÿçµiåÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿä^›îÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë‘¢÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó–pðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì`)éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿå#Âÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹:íÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿç1¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°ÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜCïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿí5{ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿoŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ•¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµ½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ—}ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿqHñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï:ÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿݽÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµDîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿé:Çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾.éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿå'~ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿím¯ùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö¤«ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï¢|éÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèp.ÆíÿÿÿÿÿÿÿÿÿÿÿÿìÂ)D¿àõÿÿÿÿÿÿòÞº:I‚¥À¿£€Dih32 •ÿ‡ ÿ2PqqP2šÿl¿ü…ÿü¿l•ÿ OÐÿÐO ’ÿ6Ê‘ÿÊ6ÿ ­•ÿ­ ÿ ×—ÿ× Šÿ :î™ÿî: ‰ÿ :û›ÿû: ˆÿîÿî†ÿ ןÿ× „ÿ­¡ÿ­ƒÿ6£ÿ6‚ÿ Ê£ÿÊ ÿO¥ÿOÿÐ’ÿÔuf­ŒÿЀÿ’ÿú€—2Rê‹ÿÿÿl‘ÿåñÉÿÿú{ߊÿlÿÿ¿‘ÿbø‚ÿ–'ì‰ÿ¿ÿüÿøþƒÿz:ö‚ÿíýÿü‘ÿ¯H…ÿ ^Qýÿÿûu «ÿ2‚ÿôùŠÿV …ÿ úEiþÿyAëÒЀÿ2P€ÿ­ tü‡ÿôð†ÿ ò>W«éÿÿ™K€ÿ Pqÿÿn&ÃýáMXü†ÿ¦NˆÿùcÄ€ÿ û%ÃÿÿqqÒ † ñŽ ÃÿqPÚá‚ÿùG}„ÿõðÿ þ0ÅÿP2ÿæ„ÿçÔƒÿ®G’ÿðÿÿ2‡ÿœ8ý‚ÿ[™•ÿü‡ÿA‘ÿúè”ÿüÿ¿‡ÿÝÙ€ÿ·<•ÿ¿ÿÿlˆÿ–7üÿÿV•ÿlÿÿ‰ÿEoÿµ#ö•ÿ€ÿЈÿï> •ÿÐÿOŠÿÓî–ÿOÿ Ê£ÿÊ ‚ÿ6£ÿ6ƒÿ­¡ÿ­„ÿ ןÿ× †ÿîÿîˆÿ :û›ÿû: ‰ÿ :î™ÿî: Šÿ ×—ÿ× ÿ ­•ÿ­ ÿ6Ê‘ÿÊ6’ÿ OÐÿÐO •ÿl¿ü…ÿü¿lšÿ2PqqP2 ÿ‡ÿÿ‡ ÿ2PqqP2šÿl¿ü…ÿü¿l•ÿ OÐ…ÿi„ÿÐO ’ÿ6ʇÿ†ÿÊ6ÿ ­‰ÿˆÿ­ ÿ ׊ÿ‰ÿ× Šÿ :î‹ÿŠÿî: ‰ÿ :ûŒÿ‹ÿû: ˆÿîÿŒÿî†ÿ ׎ÿÿ× „ÿ­ÿŽÿ­ƒÿ6ÿÿ6‚ÿ ÊÿÿÊ ÿO‘ÿÿOÿБÿÔuf­ŒÿЀÿ’ÿ €—2Rê‹ÿÿÿl‘ÿåÉÿÿú{ߊÿlÿÿ¿‘ÿb‚ÿ–'ì‰ÿ¿ÿüÿøƒÿz:ö‚ÿíýÿü‘ÿ¯H„ÿ ^Qýÿÿûu «ÿ2‚ÿôùŠÿV „ÿ úEiþÿyAëÒЀÿ2P€ÿ­ tü‡ÿôð…ÿ ò>W«éÿÿ™K€ÿ Pqÿÿn&ÃýáMXü†ÿ¦Nÿ†ÿùcÄ€ÿ û%ÃÿÿqqÒ † Ž ÃÿqPÚá‚ÿùG}„ÿõðÿŽÿ þ0ÅÿP2ÿæ„ÿçÔƒÿ®Gÿÿÿðÿÿ2‡ÿœ8ý‚ÿ[™ÿÿ’ÿü‡ÿA‘ÿúèÿÿ‘ÿüÿ¿‡ÿÝÙ€ÿ·<€ÿ‘ÿ¿ÿÿlˆÿ–7üÿÿV€ÿ‘ÿlÿÿ‰ÿEoÿµ#ö€ÿ‘ÿ€ÿЈÿï> ÂÿÿÐÿOŠÿÓî‚ÿÿOÿ ÊÿÿÊ ‚ÿ6ÿÿ6ƒÿ­ÿŽÿ­„ÿ ׎ÿÿ× †ÿîÿŒÿîˆÿ :ûŒÿ‹ÿû: ‰ÿ :î‹ÿŠÿî: Šÿ ׊ÿ‰ÿ× ÿ ­‰ÿˆÿ­ ÿ6ʇÿ†ÿÊ6’ÿ OÐ…ÿ„ÿÐO •ÿl¿üÿ¥€ÿü¿lšÿ2PqqP2 ÿ‡ÿÿ‡ ÿ2PqqP2šÿl¿ü…ÿü¿l•ÿ OÐ…ÿi„ÿÐO ’ÿ6ʇÿ†ÿÊ6ÿ ­‰ÿˆÿ­ ÿ ׊ÿ‰ÿ× Šÿ :î‹ÿŠÿî: ‰ÿ :ûŒÿ‹ÿû: ˆÿîÿŒÿî†ÿ ׎ÿÿ× „ÿ­ÿŽÿ­ƒÿ6ÿÿ6‚ÿ ÊÿÿÊ ÿO‘ÿÿOÿБÿÔuf­ŒÿЀÿ’ÿ €—2Rê‹ÿÿÿl‘ÿåÉÿÿú{ߊÿlÿÿ¿‘ÿb‚ÿ–'ì‰ÿ¿ÿüÿøƒÿz:ö‚ÿíýÿü‘ÿ¯H„ÿ ^Qýÿÿûu «ÿ2‚ÿôùŠÿV „ÿ úEiþÿyAëÒЀÿ2P€ÿ­ tü‡ÿôð…ÿ ò>W«éÿÿ™K€ÿ Pqÿÿn&ÃýáMXü†ÿ¦Nÿ†ÿùcÄ€ÿ û%Ãÿÿqqÿ”2ô€ÿùNVû…ÿR¤ÿŽÿ §=ÿÿqPÚá‚ÿùG}„ÿõðÿŽÿ þ0ÅÿP2ÿæ„ÿçÔƒÿ®Gÿÿÿðÿÿ2‡ÿœ8ý‚ÿ[™ÿÿ’ÿü‡ÿA‘ÿúèÿÿ‘ÿüÿ¿‡ÿÝÙ€ÿ·<€ÿ‘ÿ¿ÿÿlˆÿ–7üÿÿV€ÿ‘ÿlÿÿ‰ÿEoÿµ#ö€ÿ‘ÿ€ÿЈÿï> ÂÿÿÐÿOŠÿÓî‚ÿÿOÿ ÊÿÿÊ ‚ÿ6ÿÿ6ƒÿ­ÿŽÿ­„ÿ ׎ÿÿ× †ÿîÿŒÿîˆÿ :ûŒÿ‹ÿû: ‰ÿ :î‹ÿŠÿî: Šÿ ׊ÿ‰ÿ× ÿ ­‰ÿˆÿ­ ÿ6ʇÿ†ÿÊ6’ÿ OÐ…ÿ„ÿÐO •ÿl¿üÿ¥€ÿü¿lšÿ2PqqP2 ÿ‡ÿh8mk  &@ZttZ@& 'xÕúòïòúúòïòúÕx'väóøÿÿÿÿÿÿÿÿÿÿÿÿøóäv^ëóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóë^:ÜòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÜ:cõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõc•ôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿô•ºóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóº•óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó•côÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôc:õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ:ÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜ^òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò^ëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿëvóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóväÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿä'óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó'xøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøxÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕ úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú &òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò&@ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï@ZòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòZtúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúttúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿútZòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòZ@ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿï@&òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò& úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕxøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøx'óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó'äÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿävóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóvëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë^òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿò^ÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜ:õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõ:côÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿôc•óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿó•ºóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóº•ôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿô•cõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõc:ÜòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòÜ:^ëóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóë^väóøÿÿÿÿÿÿÿÿÿÿÿÿøóäv'xÕúòïòúúòïòúÕx' &@ZttZ@& it32#2ÿÿ³ÿçÿ™Ýÿ¡Öÿˆäÿõ€ÿÓåÿ¬€Œÿ€Sæÿþ+€‹ÿ€Îçÿ¤€Šÿ€Jèÿü"€‰ÿ€Åéÿ—€ˆÿ€@ºÿþÖ½ï©ÿø€‡ÿ€¨¸ÿ¨N€#Yͧÿx€‡ÿ÷¸ÿ…\á¥ÿÖ€†ÿ€c¹ÿ‚’¥ÿ4€…ÿ€Á¹ÿ(ŸÝûËŽfú£ÿ‘€„ÿ€ þ¹ÿSò‚ÿ÷‡€?í¢ÿê„ÿ€sµÿ¨ŠÿÞ+€2ò¢ÿD€ƒÿ€µ´ÿç‹ÿñJ€Aø¡ÿ‡€ƒÿò´ÿUŒÿüR€Rü ÿÊ€‚ÿ€8´ÿßÿùD€e ÿü‚ÿ€y´ÿtŽÿó6€z ÿP€ÿ€»³ÿõÿì*€Ÿÿ’€ÿ€ð³ÿ˜ÿä «ÿÝÜï‹ÿÈ€ÿ´ÿ+[‘ÿÚ ʉÿù„$Vщÿï€ÿ>³ÿ¼€Ç’ÿÌ â‡ÿÞ4ƒ À‰ÿ€ÿ€e³ÿb4”ÿ¬.ó…ÿä… »ˆÿ;€ÿ€Œ²ÿþ•ÿ†€Kýƒÿü?€SÐê‹LJÿb€ÿÿ€³²ÿ΀ږÿ_€nƒÿ€~ÿ¤.û†ÿˆ€ÿÿ€Îˆÿó®b>:B”êŸÿ„$—ÿù=€zÿÀJþ‚ÿ¡€†ÿŸ€ÿÿ€Û†ÿõ‚ ƒH¬ÿ:m˜ÿë#€}ÿÿëê„ÿK ä…ÿ¬€ÿÿ€è…ÿňgúšÿí·™ÿ߀NÔA½…ÿß c…ÿ¹€ÿÿ€ö„ÿ€Eƒ“^ <é™ÿ§ ÷šÿÝ„{‡ÿ…ä„ÿÆ€ÿÿ„ÿ€cæÿö¨&€Ϙÿ]Jœÿß6‚Eü‡ÿór„ÿÓ€ÿÿÿý÷¤€ «…÷èE€Ü–÷ö€÷ÿ–÷óy Tñ‰÷y å÷ùÿá€ÿÿÿ··ÿ²7ÿã€ÿÿÿ··ÿ²7ÿÖ€ÿÿ€ù··ÿ²7ÿÉ€ÿÿ€ëº€Ž€“€ÿ«€>ÿ¼€ÿÿ€ÞÿæHýŽÿã1û‘ÿ¸ñ³ÿì …ÿ¯€ÿÿ€ÑÿÿØ'%ïÿ®€ˆ‘ÿr<µÿz0¯þÿ¢€ÿÿ€»€ÿðÝ’ÿRÚÿ,ƒµÿùþƒÿ€ÿÿ€”—ÿç@þŽÿæ€É½ÿj€ÿÿ€m˜ÿœ€›Žÿ¡ý½ÿC€ÿ€F™ÿAæÿ[U¾ÿÿ™ÿÜ RŒÿøœ½ÿõÿö™ÿŠ€­‹ÿ¦è½ÿЀÿ€Ç™ÿü2éŠÿAP¾ÿŸ€ÿ€†šÿÎP‰ÿܳ¾ÿ\€ÿ€D›ÿ}€ ˆÿyü¾ÿƒÿ ùšÿú1á†ÿüx¾ÿÖ€ƒÿ€Á›ÿÓBþ…ÿ±€Ú¾ÿ”€ƒÿ€€œÿ‰€‘„ÿý8>¿ÿQ€ƒÿ€1œÿý: ؃ÿ€§¾ÿõ …ÿ€ÔœÿÛ 3ïÿÝ C¿ÿ¤€…ÿ€vÿ”€ -äÿÿýB Þ¿ÿF€…ÿ€ýœÿþN€„´E€‘¿ÿæ‡ÿ€¼ÿú]…:ý¿ÿŒ€‡ÿ€Yžÿþxƒ>ê¿ÿþ+€ˆÿÜŸÿ¸p1*‹úÀÿ²€‰ÿ€e¢ÿ÷Ãÿ8€‰ÿ€ãçÿ¾€‹ÿ€nçÿD€‹ÿ€ çåÿÈ€ÿ€[äÿý5€ÿ¿ãÿ˜€ÿ€*úáÿë€ÿ€‰áÿa€‘ÿ€ àßÿ€’ÿ€8ûÝÿ쀓ÿuÜÿþK€•ÿ€µÛÿ‰–ÿ€äÙÿÅ€˜ÿ€7ô×ÿ䀙ÿHúÕÿî,€›ÿ[þÓÿö;œÿpÒÿûMžÿÐÿü^ ÿpþÍÿ÷P¢ÿYúËÿð>¤ÿEóÉÿç/¦ÿ6èÇÿÎ!¨ÿºÅÿ•ªÿyûÁÿñV‚¬ÿ‚:á¿ÿÎ$°ÿ Žû»ÿót²ÿ‚.Źÿ«‚´ÿ‚bëµÿÚF‚¸ÿ‚ qä±ÿÖ^‚»ÿ‚dÛ­ÿËQ‚¾ÿƒVºý§ÿø«E„Áÿ„uÓ¢ÿþÂe„Åÿ…1Äú›ÿô·t!„Ëÿ… IŒÏû“ÿöÂ=…Ïÿ‡ &Lr™¾Òßìùÿ ÷êÝй“lE‡ÔÿŽŽÛÿ›äÿÿÿ²ÿÿÿ³ÿçÿ™Ýÿ¡Öÿˆ±ÿ¬ÿõ€ÿÓ±ÿ­ÿ¬€Œÿ€S²ÿ­ÿþ+€‹ÿ€Î²ÿ®ÿ¤€Šÿ€J³ÿ®ÿü"€‰ÿ€Å³ÿ¯ÿ—€ˆÿ€@´ÿÿÿþÖ½ï©ÿø€‡ÿ€¨´ÿ¨N€#Yͧÿx€‡ÿ÷´ÿ‰\á¥ÿÖ€†ÿ€cµÿ…‚’¥ÿ4€…ÿ€Áµÿ‚(ŸÝûËŽfú£ÿ‘€„ÿ€ þµÿSò‚ÿ÷‡€?í¢ÿê„ÿ€sµÿ¨†ÿÞ+€2ò¢ÿD€ƒÿ€µ´ÿç‡ÿñJ€Aø¡ÿ‡€ƒÿò´ÿU‚ˆÿüR€Rü ÿÊ€‚ÿ€8´ÿß‚‰ÿùD€e ÿü‚ÿ€y´ÿtƒŠÿó6€z ÿP€ÿ€»³ÿõƒ‹ÿì*€Ÿÿ’€ÿ€ð³ÿ˜Œÿä «ÿÝÜï‹ÿÈ€ÿ´ÿ+[ÿÚ ʉÿù„$Vщÿï€ÿ>³ÿ¼€ÇŽÿÌ â‡ÿÞ4ƒ À‰ÿ€ÿ€e³ÿb4ÿÿ¬.ó…ÿä… »ˆÿ;€ÿ€Œ²ÿþÿÿ†€Kýƒÿü?€SÐê‹LJÿb€ÿÿ€³²ÿ΀Úÿ‘ÿ_€nƒÿ€~ÿ¤.û†ÿˆ€ÿÿ€Îˆÿó®b>:B”êŸÿ„$ÿÿ‘ÿù=€zÿÀJþ‚ÿ¡€†ÿŸ€ÿÿ€Û†ÿõ‚ ƒH¬ÿ:mÿÿ’ÿë#€}ÿÿëê„ÿK ä…ÿ¬€ÿÿ€è…ÿňgúšÿí·ÿÿ“ÿ߀NÔA½…ÿß c…ÿ¹€ÿÿ€ö„ÿ€Eƒ“^ <é™ÿ§ ÷ÿÿ”ÿÝ„{‡ÿ…ä„ÿÆ€ÿÿ„ÿ€cæÿö¨&€Ϙÿ]J€ÿ•ÿß6‚Eü‡ÿór„ÿÓ€ÿÿÿý÷¤€ «…÷èE€Ü–÷ö€÷–÷óy Tñ‰÷y å÷ùÿá€ÿÿÿ·ð7ÿã€ÿÿÿ·ð7ÿÖ€ÿÿ€ù·ð7ÿÉ€ÿÿ€ëº€Ž€“€«€>ÿ¼€ÿÿ€ÞÿæHýŽÿã1û‘ÿ¸ñÿ«ÿì …ÿ¯€ÿÿ€ÑÿÿØ'%ïÿ®€ˆ‘ÿr<‚ÿ¬ÿz0¯þÿ¢€ÿÿ€»€ÿðÝ’ÿRÚÿ,ƒ‚ÿ¬ÿùþƒÿ€ÿÿ€”—ÿç@þŽÿæ€É‚ÿ´ÿj€ÿÿ€m˜ÿœ€›Žÿ¡ý‚ÿ´ÿC€ÿ€F™ÿAæÿ[Uƒÿ´ÿÿ™ÿÜ RŒÿøœƒÿ³ÿõÿö™ÿŠ€­‹ÿ¦èƒÿ³ÿЀÿ€Ç™ÿü2éŠÿAP„ÿ³ÿŸ€ÿ€†šÿÎP‰ÿܳ„ÿ³ÿ\€ÿ€D›ÿ}€ ˆÿyü„ÿ³ÿƒÿ ùšÿú1á†ÿüx…ÿ²ÿÖ€ƒÿ€Á›ÿÓBþ…ÿ±€Ú…ÿ²ÿ”€ƒÿ€€œÿ‰€‘„ÿý8>†ÿ²ÿQ€ƒÿ€1œÿý: ؃ÿ€§†ÿ±ÿõ …ÿ€ÔœÿÛ 3ïÿÝ C‡ÿ±ÿ¤€…ÿ€vÿ”€ -äÿÿýB Þ‡ÿ±ÿF€…ÿ€ýœÿþN€„´E€‘ˆÿ°ÿæ‡ÿ€¼ÿú]…:ýˆÿ°ÿŒ€‡ÿ€Yžÿþxƒ>ê‰ÿ¯ÿþ+€ˆÿÜŸÿ¸p1*‹úŠÿ¯ÿ²€‰ÿ€e¢ÿ÷ÿ¯ÿ8€‰ÿ€ã²ÿ®ÿ¾€‹ÿ€n²ÿ®ÿD€‹ÿ€ ç±ÿ­ÿÈ€ÿ€[±ÿ¬ÿý5€ÿ¿°ÿ¬ÿ˜€ÿ€*ú¯ÿ«ÿë€ÿ€‰¯ÿ«ÿa€‘ÿ€ à®ÿªÿ€’ÿ€8û­ÿ©ÿ쀓ÿu­ÿ¨ÿþK€•ÿ€µ¬ÿ¨ÿ‰–ÿ€ä«ÿ§ÿÅ€˜ÿ€7ôªÿ¦ÿ䀙ÿHú©ÿ¥ÿî,€›ÿ[þ¨ÿ¤ÿö;œÿp¨ÿ£ÿûMžÿ§ÿ¢ÿü^ ÿpþ¥ÿ¡ÿ÷P¢ÿYú¤ÿ ÿð>¤ÿEó£ÿŸÿç/¦ÿ6è¢ÿžÿÎ!¨ÿº¡ÿÿ•ªÿyûŸÿ›ÿñV‚¬ÿ‚:ážÿšÿÎ$°ÿ Žûœÿ˜ÿót²ÿ‚.Å›ÿ—ÿ«‚´ÿ‚bë™ÿ•ÿÚF‚¸ÿ‚ qä—ÿ“ÿÖ^‚»ÿ‚dÛ•ÿ‘ÿËQ‚¾ÿƒVºý’ÿŽÿø«E„Áÿ„uÓ¢ÿþÂe„Åÿ…1Äú›ÿô·t!„Ëÿ… IŒÏû“ÿöÂ=…Ïÿ‡ &Lr™¾Òßìùÿ ÷êÝй“lE‡ÔÿŽŽÛÿ›äÿÿÿ²ÿÿÿ³ÿçÿ™Ýÿ¡Öÿˆ±ÿ¬ÿõ€ÿÓ±ÿ­ÿ¬€Œÿ€S²ÿ­ÿþ+€‹ÿ€Î²ÿ®ÿ¤€Šÿ€J³ÿ®ÿü"€‰ÿ€Å³ÿ¯ÿ—€ˆÿ€@´ÿÿÿþÖ½ï©ÿø€‡ÿ€¨´ÿ¨N€#Yͧÿx€‡ÿ÷´ÿ‰\á¥ÿÖ€†ÿ€cµÿ…‚’¥ÿ4€…ÿ€Áµÿ‚(ŸÝûËŽfú£ÿ‘€„ÿ€ þµÿSò‚ÿ÷‡€?í¢ÿê„ÿ€sµÿ¨†ÿÞ+€2ò¢ÿD€ƒÿ€µ´ÿç‡ÿñJ€Aø¡ÿ‡€ƒÿò´ÿU‚ˆÿüR€Rü ÿÊ€‚ÿ€8´ÿß‚‰ÿùD€e ÿü‚ÿ€y´ÿtƒŠÿó6€z ÿP€ÿ€»³ÿõƒ‹ÿì*€Ÿÿ’€ÿ€ð³ÿ˜Œÿä «ÿÝÜï‹ÿÈ€ÿ´ÿ+[ÿÚ ʉÿù„$Vщÿï€ÿ>³ÿ¼€ÇŽÿÌ â‡ÿÞ4ƒ À‰ÿ€ÿ€e³ÿb4ÿÿ¬.ó…ÿä… »ˆÿ;€ÿ€Œ²ÿþÿÿ†€Kýƒÿü?€SÐê‹LJÿb€ÿÿ€³²ÿ΀Úÿ‘ÿ_€nƒÿ€~ÿ¤.û†ÿˆ€ÿÿ€Îˆÿó®b>:B”êŸÿ„$ÿÿ‘ÿù=€zÿÀJþ‚ÿ¡€†ÿŸ€ÿÿ€Û†ÿõ‚ ƒH¬ÿ:mÿÿ’ÿë#€}ÿÿëê„ÿK ä…ÿ¬€ÿÿ€è…ÿňgúšÿí·ÿÿ“ÿ߀NÔA½…ÿß c…ÿ¹€ÿÿ€ö„ÿ€Eƒ“^ <é™ÿ§ ÷ÿÿ”ÿÝ„{‡ÿ…ä„ÿÆ€ÿÿ„ÿ€cæÿö¨&€Ϙÿ]J€ÿ•ÿß6‚Eü‡ÿór„ÿÓ€ÿÿƒÿ©€ ±…ÿïG€ã–ÿþ”€ÿ–ÿû} Wù‰ÿ} ìƒÿá€ÿÿ‚ÿÐ Ô‡ÿür€1õ•ÿπ݀ÿ˜ÿþãÆþŠÿë vƒÿã€ÿÿÿì ÍŠÿ}€Tþ”ÿ‰$ÿªÿt é‚ÿÖ€ÿÿ€ùÿÿüC€¦‹ÿþT€€”ÿCjÿªÿê q‚ÿÉ€ÿÿ€ëÿÿq€vÿõ2Í’ÿö°ÿ«ÿwæÿ¼€ÿÿ€ÞÿæHýŽÿã1û‘ÿ¸ñÿ«ÿì …ÿ¯€ÿÿ€ÑÿÿØ'%ïÿ®€ˆ‘ÿr<‚ÿ¬ÿz0¯þÿ¢€ÿÿ€»€ÿðÝ’ÿRÚÿ,ƒ‚ÿ¬ÿùþƒÿ€ÿÿ€”—ÿç@þŽÿæ€É‚ÿ´ÿj€ÿÿ€m˜ÿœ€›Žÿ¡ý‚ÿ´ÿC€ÿ€F™ÿAæÿ[Uƒÿ´ÿÿ™ÿÜ RŒÿøœƒÿ³ÿõÿö™ÿŠ€­‹ÿ¦èƒÿ³ÿЀÿ€Ç™ÿü2éŠÿAP„ÿ³ÿŸ€ÿ€†šÿÎP‰ÿܳ„ÿ³ÿ\€ÿ€D›ÿ}€ ˆÿyü„ÿ³ÿƒÿ ùšÿú1á†ÿüx…ÿ²ÿÖ€ƒÿ€Á›ÿÓBþ…ÿ±€Ú…ÿ²ÿ”€ƒÿ€€œÿ‰€‘„ÿý8>†ÿ²ÿQ€ƒÿ€1œÿý: ؃ÿ€§†ÿ±ÿõ …ÿ€ÔœÿÛ 3ïÿÝ C‡ÿ±ÿ¤€…ÿ€vÿ”€ -äÿÿýB Þ‡ÿ±ÿF€…ÿ€ýœÿþN€„´E€‘ˆÿ°ÿæ‡ÿ€¼ÿú]…:ýˆÿ°ÿŒ€‡ÿ€Yžÿþxƒ>ê‰ÿ¯ÿþ+€ˆÿÜŸÿ¸p1*‹úŠÿ¯ÿ²€‰ÿ€e¢ÿ÷ÿ¯ÿ8€‰ÿ€ã²ÿ®ÿ¾€‹ÿ€n²ÿ®ÿD€‹ÿ€ ç±ÿ­ÿÈ€ÿ€[±ÿ¬ÿý5€ÿ¿°ÿ¬ÿ˜€ÿ€*ú¯ÿ«ÿë€ÿ€‰¯ÿ«ÿa€‘ÿ€ à®ÿªÿ€’ÿ€8û­ÿ©ÿ쀓ÿu­ÿ¨ÿþK€•ÿ€µ¬ÿ¨ÿ‰–ÿ€ä«ÿ§ÿÅ€˜ÿ€7ôªÿ¦ÿ䀙ÿHú©ÿ¥ÿî,€›ÿ[þ¨ÿ¤ÿö;œÿp¨ÿ£ÿûMžÿ§ÿ¢ÿü^ ÿpþ¥ÿ¡ÿ÷P¢ÿYú¤ÿ ÿð>¤ÿEó£ÿŸÿç/¦ÿ6è¢ÿžÿÎ!¨ÿº¡ÿÿ•ªÿyûŸÿ›ÿñV‚¬ÿ‚:ážÿšÿÎ$°ÿ Žûœÿ˜ÿót²ÿ‚.Å›ÿ—ÿ«‚´ÿ‚bë™ÿ•ÿÚF‚¸ÿ‚ qä—ÿ“ÿÖ^‚»ÿ‚dÛ•ÿ‘ÿËQ‚¾ÿƒVºý’ÿŽÿø«E„Áÿ„uÓ¢ÿþÂe„Åÿ…1Äú›ÿô·t!„Ëÿ… IŒÏû“ÿöÂ=…Ïÿ‡ &Lr™¾Òßìùÿ ÷êÝй“lE‡ÔÿŽŽÛÿ›äÿÿÿ²ÿt8mk@9KXer~‹‰|ocVI3 T|¢ÈîÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿçÁštKO’ÕÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýʈE tÊüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø¾e Z¸üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷ªL*òÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéŒ1¬þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø— :µÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûŸ&ªÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü’tóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè\?ÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁ+”ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûp#Íÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯Uñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà7•ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúq ¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜Ìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ­ÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ+åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐ"çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÎÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ­¿ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿwaÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü=+õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿä Õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ· ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿxRÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿú( áÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ[(úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿè½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ”Qÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿý+Íÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤Jÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü"Åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜Aÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿø¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŒýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿíyÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿQÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯5ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿù’ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿjêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃ0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿû sÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿH¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŠóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿË;ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüzÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿK¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿvÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì=ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿcÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ8yÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJ†ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿX’ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿfŸÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿt¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‚¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ…¢ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿw•ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿiˆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ[{ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿMiÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ=DÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤¬ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ}„ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿUJÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ úÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ˜ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿV?ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔ§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿIÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ"çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿe0ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷Ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥[ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ.Ûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ7áÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼jÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿAØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶Dÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷"©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ}óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚsÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿEÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›êÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓ Fþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿô(…ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ]ÂÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½#èÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏ1ñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßBùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë&Qùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿí4Bòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿá)1èÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓ#ÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁÈÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøiMíÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚ0Çÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨ pòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåW¨ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüEÚÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇ0qäÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔZeÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊPYÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿E5’ëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿà„&N¬øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñ@ C„Æûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿö¼z9 I„­Ôùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóͦ|>#Km|Š˜¦µÂÀ²¤–ˆzhCic08¹ jP ‡ ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cÿOÿQ2ÿd#Creator: JasPer Version 1.900.1ÿR ÿ\@@HHPHHPHHPHHPHHPÿ]@@HHPHHPHHPHHPHHPÿ]@@HHPHHPHHPHHPHHPÿ]@@HHPHHPHHPHHPHHPÿ ·Ûÿ“ß‚8aÒâ¼é^b+ _Ì¢ZÚ/gµëí_®;³‘V§OM4alîFÂ݆‘góºÌ_v"ݫ֦Óí¬eÏ·1ôŠ8ùw( 5¿ß‚@aÊYå#rŽÚ‡ˆm–Z}[¦¢IÏŠûp3Q«EWrš÷m•h㊰3§r ¤QHr•Ê~üºŠl»‚¥ã‹¾©/ß‚0aÊYå ¯gáßüRp“7ø…*<[çu#›DíÍT¿ޮDvÈ uÒY&±ëF{>fËoÜ[ öϪD†;r.œ»ß‚(€§(ÑýÉWø+ò'QØÙôR™fð/ƒá0^ñÞ͆•ùÙ’2¨:*}-·û@/«bù®@~¯:vÞ´±ÂCÏÁ~óóND+ûÏÑz/Ê(4 )‘Þ&{·e‰:$å÷õÕ¨´1ŽõÛå&ø1€ÁŸhÄ4†ÆÌ™MàjpA2Þ¾%‚Ù["Ë–¤2ŸcƵ`Ôà_kݸÓh[jƒRyCi•iüªE>aVë|ˆ¼MXâÙú`b¿ŒnñsT«+ØÔrTrúû _‰/?ö^(¾÷¾lÞ_O1¢7Tœ?Oæ_E£Q 5ã±D~ "¿öMƒ…/ÿ/;³ÊŠ,´ž@ZY¸ÊuUÙ• }ª¿¼™Ï`iÏÁ~ÓóN Çì’_^¶kb$6ÑÄpxî×°iû]”Vâéêƒ1nÅ¥b·÷«C·‡£m†4Cl´Ò Ó `š„nÂP×wË–¤2ŸcƵ`ô*F¼èE›¤§Oc$¨ù»["üÓdµ> ø`…8G]îT) +Î0OoÐxZyõÿ‘¨c2Vžk/?ö^(¾÷¾lÞ_O1¢5!>IÄÀH<žó.üh‡oE’“¶] ™·“TÂ9!MØŒCØÍ9E¿OBI9­ãò”jœûôcÏÁ">Ô)ù§€ Çì’_^°%Ø"±j✋n½6û‹ê ‡¾ °…Û¨í¾MÂ=ÚW4õ:!zªhËÆP)¯(2 ;‰:ó¼ŽÁíhwŸá7Oƒüܹ¾y›û7$J¯’—Õ¼i+¨00&rJul ¥‹i 0¿ŒÝã^½­í´ÝNZÜ´™Ci*8ªÉ –Ò<<£©ZÅäh Òª=eðŇߙù˜Çàd7s¡}Ø#§4»F7ùiáü¡\¥W$h‡^§Ñ~bÃæÎɵFC(Êu¿H­G¾aÛEã³^°=&œ ó¾˜3¡?(·&Z=7[×Wvyq[¸­Eé×6ïß ÉݱòðW`ÑöÛÜtÚŸõû¶ 0!/y©uL¸o’¸*IÑ4BF¯™æ^—mß•~v”üíeyùr—TGìj—L^åèM˜J4ÂOE0Úh¦ÝÉS·2m‚Ø¥6®_Ñåml l6ÑqÚ—f¯(¯eäpÙ\Ï1­ìÒÐ"—MÍ3‹†@xPÙoK¸‘¼Òiu.ê¿-ž3,»ÐÞ\‡ll—–Ú\÷«§Õë»ý -j^ª·ÝCûÍ"ߕس*Ôq{’’¸°k r7/º·rhf è”óÜ´sC¯e)®ë×8sq¡·;L‹*à]NÀÖ4¨1ÚÏ%Zzé]-a)çʈõBÿ\ȉ¨Ún\Üédñ›1úÀ~ö×5¸&¿9t¸Ský×P4–èXO‘o±·tˆÓ4ç oÂ1Tªß,·V˸®/ä/‡Æ–’vè¥-æä¡À´iž2„Ÿ¢8ÝuÉô‚S ?. \·òŸI`ß^tÓ£×Û³ä®ÆCMÖ\•…2m÷ÏžÊH½Ó¬3éò ›•å„õ[×h‡²eøèwÈ1˜ë„úâí³»·ÖÞ‡¶Fmm‘éb;¾'·<â^OßäÑi¯ËIk ô~²ÀG¬£–jâ@0Óhý½o»Äl%¢Ѐҿ¤ëH°lÇþ<×ͺërõ&žø›7oR ‹-9ÜXóeôúÑÁꡌ’€5ðF.ûŸpÛüä®ÅÀ>Ħþtºy¢»1K¥t:¶×/ÌR†5зŠÐ¥­ÐZ&½•Î_©”pMùB”ââp¤;âUšö0#‹ŒƒC¢ í`B&–kE˜j‹_¼åEàTdŸG×ôXÖ; èÔü&`à'ºÿa݈櫋ß»~v¤üí@ey X¤Å˜íªP]|rûY¥ÑZf= …j†éY?/à-;_ä•MNtÌëHÿ!JªÝúr#ÕѡĤàòéè—¥ (¡!ž› Ç0ßbùnݲÑ!”ó(Œz9•ãY/nmSD:üïòLúïãîö12&”j3ÙDRx0OêÔ²2láÝÎ(ŒÆž «±es‚%¶Ä…/ Õ%xèâFg˻ΥèiR‡/ì“ÒåtòŸh…yñb¢2MTB­):&MÒ s sÎŒKvßáÀŸ§iFªC%Zzé]-a)çʈõBÿ^œÐ¨dVŽŸ¤pµºªÊüÁ‚ûšÀ¯»­Nì˜Ë éùê4f½ˆ›"îé²â§‰‚ —Ô‘“̹_2*Qø—ÿsûÕT¥¼Ä7 ½¡)wõ5fìQó %^2 E üàöòh6µ½ûy‰ÙÆË Ö!÷¶z¾‘N%oUƒÚæÖ–C8 ?ÜB¬ÝJ²3˜ª{ñ:úÿsºâxžïc7ñò¿¼ÄçWÞ¶w»¬›TzXŽSÿp[sÎ%ç©lE9¤ËIk ô~²ÀG¬£–jâ@0Óhý½o»Äl%¢Ѐҿ¤ëH°lÇþ<×ͺërõ&žø›7oR ‹-9ÜXóeôúÑÁꡌ‚ÛØ“v Íä\¢åf['ùh%o…à>ãà¸ð•A9½‰²{¥±AjÂìÜÍáÌy5×ý%A¹¬¥?/ôw ’SUœØØØ‰¥Hº@ð­Âlð…|Nó¥¾y8µ;à›élíZš}ôq¡C©’k 9bœÁg¸*íÓfE ÍŸž^Ÿ]N€uºU«RrƒNnGUlmÜ'·ÆMTÿ:Ÿ8•Ú‹ð4JìÀâ½U¸É’ße/—ñt\h’ÈD Ø©y!¡ã)°ÈÔ€'k?­1NKC8îRðrpð€<÷“0"pÁÐJ¦oü"Œ¿ÇUoé“ "M‡;G·ìÜmBÔuè8v…„½Cl"ò8ZðUí ¸²þ§/ºÇÍåô6MhvÌ&ÌìBð¾¾Þ¬:R^ÒÈwš3&SI=^m¾´ÁNp °˜`$„ïgø´¥Y mqF¢òŠÒÀß$ô*B“b~.ef`]ƒ Së³Èb—…ïQ&ñ…´[©”mcÏ»Õ2ä°ÊÍ6¸“!(|‘`b§´O|C¨¯ÁÌ™‚íú´¥Œ¾/kïri:Ì¥M gd_˜»u÷76 †±óæ Úo)˜™<°z =ðE c[ÿyÆà?aÏõ('…ÎVóì*¯”ƒµ r×Ëu5—›Ã§þ6-rÆ8tê5ÙÁÝÓ€.ŽÿS»¢/´î5¸ŠFײ L4éË÷Ñ”½Ä:·:Š¥ID­&é2L͉aþ:Å¡ÜnÈ©ÇYÝ‹.(=µvsm4OV;hèUóm‹ 8âø^ÒL\¥”5è¸jw^ÈŸÈç_ý«Ñ2¨ t3v´~ßKGðqñ„èQ—‡ùh‡3¨ ì,¸Ú,×j‹fø0 ‚@d¤ýù¨BþnÁݱû»Îï“ : Ê­ÃŽ »uÌoù¢áfÊíÄF5ô7<ìà.‚¨ð6U"œè«…\z-ÅoDý³D‡• —Ôkõ¦Æ±þ:‘}ÞCJÏ78™@ÒÉUÝBìµöë§b¶Æ½9§'ØpMmÐî e8dPÃv<Ä“†%úLÆ.24¡[U¿TïòKˆðDu” ¬W9doe±óÿù“:hÔmùòÏ¢V5÷°6T”VôD£‚$jwÃ!pÙ|!9Åñ‚TíÔ—‡µ²IÎ á,]c†;oŠãûËÃô­›ß45Ž«»Ü²8D@È_Ów]©úY>NÅXJ±Ê4Éj? zêèmHŽ®ß’Ú®>ïݹòiElY^ž$¸‰f:} ©“ÑìzE0ÈlL¤hªülpNóq¼ýžTP¸ª_z˜ÊÅÑÝîL!ƒtoÃÆmàdÂu^˜sYȵ‰f?Ž›ûijmZ´°câë°=uÿ>´ˆ{cÍѦGàÊûõ>ÛJ<ñÄC'‹CNè%å Ιþ›‘‰þ*ëõ8«S"ÈïÇ{Ûó[«dÖ¡‚HãožZm=Hb8ËVh0sxÙÇò]^(;Ò0„-9 %#ûSÇ'qYJfpDŒÁtîdFȤ ä7Οêå˜v…+imªÔ–"ÝgÔƯv“±–Öÿ Ï`¨µÉk=DògÌž¼Ž %·áìÍÈ×ü§ ·˜òžGäHÑfp$væ°r[5¶Çx‹î¶2š!sg¶g»‘ïý˾QPÞñ¦œu´ºÆz¯39‚&‰š•²+¢3'¦ÊSRƒ7,–„Žt&fqýo~'N5S”ˆÍ¾3.þ ¹¶Õvú¹šT•b`ä"Ö9ÿœùëcÞ—eL¥m祩OJ†æÉ3|bþ!¦¶S÷GµõÕšÙRÝ4Òsÿg{èO¬—ù´¡ý›) ½hsññE¸¹Òé©86- åÛìùŽgËJ=3bx‚i”›U™†ÐÑ5eKøb+µØ’Ï8¯bÅ! J;‚Çpת9ŠåœÞ;Ë"[Aî7OäØª-yæ'Ã螱톙p?¬E’̯VEc.ª`Æ„tÔò3ðŽ-3ÔK€¬T ÷â0*JÆÊ¾Ù§Bû"“Œckˆ Qï ʰø”TZ×±L ½6OÙ‘!ƒo_D_ߟF·çÑT~üÃ>Ìy68*‘´™æç}äÑ-@îË=ìaèV‹Š`‚[ߢÍ6|HGòU,e^s`§¸"\ç!̵<»«Îãi«øP]Ârý«Î)ŸBPÊ^ŽsoDQ6åõ¡¨v|"æS§¹@@Ø}Ä|ù-Ö覲Ñk +Ið0Âë«q®@ÖgŠÜ+¢ à 7ø#wÄÌr¦=ª©µ^G|¥3UâÏe©LéB :ÒË·‡‰{Á[(^Åܽy«ãÕú.¶*ðôB Ó¶®9綠ëôX½ÛÚû¸ƒ-ý©$zs]EÏ\g»Kh#^ o®ƒF+±Jr'Ùq9@€QÚY·úÒÍH¸Ïˆf™”Ð\++2meˆhaj“¢œ ÚêšaªÉ"˜ƒÅdÂ!{K!Þh̪ ‰ê Œ0Ù‡1šÜœäÄÛ€wâ8jUä±µ¥BÕŽØqÉzÔ6þŽ:[3t€Èá‘"Xß)ÿý|N0×KƒD›ÂÝ;TIáGçKËPW‰§]àQ£1ÞV£˜ˆ•ØÇf}ÛƒÚ²I7œË’›²_‚X‡ŠHÇ„+páÅAng] HŽÑGâÙoõÜ^¹ÿ5Š®bd<ðÁâxá¹½×- OW<øJ¬ ‘—²"½?z™†ý­'«0"}qnÌP¹Ð4>¾q (±9Î~øðôÿ0é ‰*FóJ%"tå‰ó’Â×8ÕQØVÍaòó\ÉÇÕiÏNð¶¹KÜC¾Ê›ÀµID­&é2L͉aþ:Å  n{ˆ¤¼íÝ;"jd¾“ÑeÊ·é.Ÿä†§¯^º1øžùH²uµ™kƹb2ð1¦Ôo,B¦P_SÓA²UV,fèKÇ>Jñª;\΀vã²QÇ”–4<ËÂïtiHz:{Tv™me?å%»Æ X»,y™÷w ~!¯¡¹çcÿºb£ÀÙT}å¶X4ø7Ûⳤ_”J¯X™ñ«’ÆÏåJ%×€³âÊmûà{ÌÞ<ëÃBùft{š%XòCÝbN©÷DJ@@ÆMÕè—ó†'i;\¶ç<(pâmDìpù-_ñêL>Ü|‚hœAõ]# ®Q©£{Å$ë3ˆ0*ßNøWyév‡{ xfPð%U{C9TC1/Q˸KxNwfó¸{Ë p8 JPÁ²·á¾dCÅüälŸ9 (Ákš Âs(FÃE4\&Û UóÅÑ¸Š®AÊ4Éj? zëF¸÷ëó”Å;éÆjÂÏ€¼‘ÏaLùH>šLæDñ¤¥‹èö=%`Ð2± «ÿóËÍÆóöyQBß½Ræ0f¤ï÷ ¦Á¸óã¤@—{îPëÞÃ\´»Éaz²X“BšÃÿpÉÚX1ñuŽØºIìe$Å6çªEE·•£RÓcÙSp5k¥ ;£ãŠ@Â8™þ›‘Þ.o1¯ç8«S"ÈïÇ{Ûó[«dÖ¡‚HãožZm=Hb8ËVh0sxÙÇò]^(;Ò0„-9 %#ûSÇ'qYJfpDŒÁtîdFȤ ä7Οêå—†£À@zYWPm óÜ–™Mß•tÚc²gÂÊ ¶ÊtÓÓ2Yõ#û>‘ú¿Ñáí˜ÊÃݾ÷Ͳ,¨ÅÔ4æ½VgGhÑ~aÊÿƒ’ØÃn½àèÆý¾Îæ°ãàd—¿B<>šKœ2´,O©* )Ì™ú.¢òuõµ }|6"©Ð䌭¡]™=0îRš”¹`t´$ròF›¼Þ4ôYKÑËÐÜξɩ^ƒueªSjxÔHg:Qˆ¤8 xªruri;ªœóäŠLÖÀ¶ˆú‹ŠÏ˜<»eâS _t`|ÄŽ+KK½qPš¸EºÒJ÷ÞWåJ:cK±Á^!›5ï7»i*¿,ij²?æ9Ÿ-(ô͈â#8àæ¦s¸ ¯n¬=U<‰mQkŠ.¥E™)h ¦¥Ãd>Á‚næRDË-1oe°|ŽáÿM«uBîÚóÌO‡Ñ=L;’¯ç¥ÈaâÒl=ž¨Ç²Â•XlþW¸¨O)þÄò ^T••Ž&j¨ü¼g~=‡X’@ËÊ®á[¨<µ¯b˜zlŸ³"CV©<5ߟG·ç¿qøo¸Ã>Ìy68*ŒoD x” ¤¤sSÍÌlW4n¾aÁ ò<þ;gEÕß°65áJÏlÜ‚ü¤$'ìȸXwÿƒí_>;k;Ñ´[çîgÙ“³ϲÊÌ´‹‰TϹŠ/FMŽûÏ—JÓW›”‘¯û‹ÕñŒÍ ÂWæ›![ çO9ðNDUvX½µ߂?Æ Á‘xXÝ0+þ#UTp²"uqÜùJø)[?}#üžù7«ÏªläâÖo·mß»dÆt 1ïVØlˆ~ÎM~à _Æ[ÜëAEÀÿ2Mko¤‘éÍE©«gÍÚhx³UåJ2!«W^]†\X¾¨D2ôB7©÷Áîn ¬ N%Z1 ]a¥]²Ì"+ÄÚú͆@½®©¦¬’.Ãh,™@y£U»På|ÕëÛžÛžûàûéÁ¦¥|i¯µÑ†m#kÑôgbù•C'Å•ï’ð=Åà`˜bn2$KûãdŒa¹Æ|ò¦…äîJ¡µ¯Öó1õå"—JTQ£1ÞV£½–T¬‰n.®ÆT˜¼½L¹YmöZR-+\ãb? ã:íDvŠ?ÈCìÄõÆzÐéÍí½ãZui 'š0¥z®3±„çÀŠU`0êqÓ6_ËPM˜]«‰V¢±¼ÿh‡_[¹êÉîs÷¨aÓý‡I?!~ÆåÉ1·x‰­½¿úk¢ÈѳåS3£ ¢zw…µÊd~z;ùùñID­&éOìOº±õM«ž¤o[[i ¢•°ïb ³TYH•‘«æš)Žf>FKbÖþ‡QXO_ÿ1Ô(³ï\¨V¨ñÍZ¿f„ß$=<Ä c<”ÿWóÄùþ\uÖòÆË@oÌæºÓOé)sÿfjõëùýÑŸ¸ ±þÜ/ÆàØSEçf}.^–]+sS÷ÆÙºúVƒ·VVˆXÝÔõ“‡ìî–l…¦`Z\§ç¯:: ÷ãºf·I ϼŒãňlœýtÕõ LPgjœó«ÒDzw6»-¶áPŒaFC_a{Ž/*„xŸÆ“÷¦è‹«œ¬÷Š(IÖf 5`T¼sŽ~§]ïÚ¥óÿeN@žaŒa½þ.lÿ1_ ,] }øWÚHqŸx QZÖ‘oK¿lã,xñ­:'ÎH 0Zæˆ0œØuûW¾AÁTÍ»'Ò"]Œ¡…œœ×ýGKçZ5Ǭ ñFœ·õÜ[ K4û†ëªKûßTS}p›54ÐÚ|‚+9$1#{ÿ2äúˆŽ:›lK2Qמb|>xÿÏu~Ü@žâ~Bª½2ü¿Jò:k2t ¨yÿ1$<¨•%ce`c‰šf(uJæÛ•äñãtä"æk²ñ˜ÿMÑ\–1œR!,<5ßž‰_ž†Çá¡ÌO ÞjŠuËÔvpÂB]nù »|î„`‰—€5øši°¿\œîô⎃c7Òp‡NDe—É$fôÿu}‹¹†gÙó—Á€PÃZ¸é:E°Çñ˜‹"Çt9î¨Ê¼PóàzŒ(<ÎP«½ {r`VXë> ã÷•].¿W\|í¢a¦DS2½>½CØ•¾3×ðíÛ;ššj뺣Ø#…7’Ʊ%“ûNÚ{ßdÚE}#5Ež+íÛ„I#Kòý{7=±éÿ'™7Eü0ý,jhôþXü÷#ܳâ¡)±wì¢÷°>®Çé'Ýêz,¯Y}Ǹ”"~ÍÚÏ>\^Ê%W1“öÎðôu%S"}Z÷‰hföökSaߟ¦ýùú‘Gáéí͕·œ=ƒ¿ŠØâb“蘋ÆàvIº ÌmÍÒlÇ EYgÒÛ’)’´•{ÊáfS Çbvˆ›ØWc¦„Š¡ì’ž8ó¥*Ë©ï‡'¡l¤_挕¡ªxBècïôEÎ#{©è䢢pL”g³¡ëNElF5c+±ÿ'ýççW*$F(q·U}×MÜÈi™ ?r–aÛ¤»AÔÁʇ~y¨n”u£¨ò_Ú#ÔãÒç´jýÛ•O(†W Ø+ŽJØqÀDw?ˆÒÙ ã¶õru ‰´YAÇ’˜åWÒ¶ë*Mü*1}4ôYTÎm©‘lÄw ò>ÿ`¦ŒnÑÔúšŠóátI7*wDÇ#É@hý÷¼¢rl²^r»vÃçÕ>BfËÈM>~ø”“òŽÐû-ýœ• q£p¤J¸¤Žmì¹&ï!8ŽD]qY¶š1@yøÉµ?2'ÍÎ ¨›™‰é6Ùó…ÈÐ’qŠË‘Ü÷¦AáX%±§Ø:_àp0ÆÒ¦õ®VQê.ªê10†Ú³E¢ˆíhs2ƒ]ËÇEß/Ü ZQÙË3Ï'‚Rç⮵ôäJïû¢r²‡Ûw½ïðZ€ˆUíXpõ6;¦š@)Z> !*½ï+*ª¹”3QÆ {<¯ÜÍ,Æø-pq§ KÅ‹¿”Õa!Ø ÄÖD@ôL¹*—íǰSŸˆc#8éà¨6IŠÇÊ ‰í»µ¯, @·h+{Œ–RºgMG,|ñ]Þœ”ÚÎõ–>•œ!ìn ˜vq ûÀØóí¶“y¥ÿM63)š¥¼ñ4°w”+¬Òç©¢Þ‘åpëVóŢﷀOà ݲšä=L±”Ö¹ÑåÍLgš§ýΆ6ÜO•n#ŒÔ€Gv8Q8.͵aTRþAÃi‚‚?ú]’H¡SŠŠu Ôf”ËÚª]§y˜!|–ã# lð*âúj |ýËDú—>ÅUÔµå½n®àåTºq€¡Ö}wø›äNlµcbTj!‰gZÛ»Ê+h=•tÕ zK¦Åš_´´Å zǨ^É’5Yw‘â@/Ђ*W`7GíºË›¹Ö2r7TÔ“1Y ÑßôÓBIhˆÜ,KpÅ ©žÉŸŠé³ yNˆˆ…Ú”!y˧m+µÙÏ Dº{ï9.ûj¬xQ5qÒtêpÇÕP«|“<" Ã+þ7s4‡7]¡‘_$5‹¯ìU”£âr5-‘yÛ×ÌûºñÌ(ÞÌÀŠj…ÅYI];/<ËÝ;s2üÞö‰Ä,4Øÿ3ÜÃGW¨•=HkpºùdYwLzáɤþý¿ðŠùþŒke›Bq¾ÉŒ ¼êPD³CÕ›€NÃÎÿ î“C&·È·"eÜ;Îoè:º¢-õYΈEÉÄnño»·Â#5Wv¼&ѯgРûj8÷4t#·``,/ܰe[p¿„r‹Œ qi(ËlZpIÒë¶\î_xƒÖ°fä ygb¿.ÓGdó[.:ðé1°Á’å™mToO !™š~\ôøÿ:ôK½B[–•ªzÁŒp¨Í§«%<—²2`o9&ËrwÌ.7e_7@ÂátÉØ ÊH=¼— u§24‘—ƒáÆf^ª÷ð4 %Z¥ü‰§’Ñà¢zÔŒñ‰ïyBGäÜ ?Ê\X×m;f‹/¢ÄXÙ€Á€[%;jxo•u­[C°Åê•çuí!¬††]2h ˜Ži|Mœ]ÂZÄÒû ñvPW¶f†  »/QMÓ‰Bn¾¶Tò]éhÉŸf95P¨#ÀŒÈ%a݉ïq§Y>Ã0’FÕ |Í[…¡DI‘˜ª8Õ{…Õ[÷3ª²‡°šZ8 2k@=ÆU•îØhÛìoίMÎ#Þ£ëˆV”ÖÝ&ï(¹EJ5úFê,Š0±û‚“7•ÈúŠ/4@qâ¼@>˜tHqÌHJÁ{T÷õ6h4epUÜÙüÚÇ •HŽöJóè<¦ 5zš¶zE\£<î@ܬEA8½ikCç2-Îö˜v­ãàÓ¨ðüqveúgüùË›~Ä‹DK¾™=äðˆ03ê—ë–‡ =£*ΕÉZÔÝø) ’:(á gŒn%ï“m벜µ ¸»WšèÃÀiØTã¶àM‘/Õzá=¬«6Aö>zò[´ 2ZB,Èkîxˆ¸}i²ŒºÆ?kÝõdüâmÅt6æáX)_ š˜¦{妱ç ðñÌ^ôŠ×ü=l~|f™Æ³Ä~ê!/»­¹1¼ù˜O¾¢ÝŒõÂ#ÍzM $‚‡lZ’~ŠQ¾*È®bþӾ®y« - 2ß÷Ñ‘lO¿`欨q× §¯Ø!îuRb§3s¢5{)ŒC‚ýØRpbl kš¿£„•¿h‡yA'àù„¸¡É¡í©J˜[±àù/<¼%úc¾ZYÃÉÞ–  ñ>PªÎ|aªç¯Ý"÷¸ûµVÿì8ÂÉÒ^§ Káʧ¿{ÐÕÇîr‰°âÍ€‡öÎrï°©›Ñ²bõ ûÏd•b ÞTÆQB¸ÝÓW9× ½ŸËÒ@º{ã›9±D½îúìQnêcJœh+®é,ŽÈ*‚=ëã-ß å¼ÇS˜ãpM]!¥›°Ç>°oI÷-™ûxͽº+©ã(øšä¸Ñ+ªBŠëx‡.ı›´[*ïÔ´5¥€j÷¼WÒ×.ñùõØYTÇ_–z:úWËnðpËBÿ 4T˜¤¸ð] OÊ´™89ù– ;Hˆ^žEÕJvÁ¿œ,Æ«ûèÒÑC»éT®³Eq¿Ù ú†q¼9¼]Ët~êZ€-TõRñ„¿÷Ûï9£#"-ÕªýŸ%cÀ*<8ú¨²Á7ú̲Ì÷Áê3Ij\]‘-.‹Æ…aݺrygMÁ^Fb¥†µ%EÆhð’›.¯oXsœÕ½Vß2±#dã¬Èç,ÆÙÖgrCy7‚¯“xXxp Í;_Š¡i–‚Æ$ÌŽóF4}}ƒÊ"ÿG±4.G,1Û~Ûíð7‰¯t¥iU=’RWsÐÛL­¦4@F¸iÁQ,»W1ÂñìtÀR%ˆÁh6â”[¾ˆ8Êž­ž×b]"sùçÖâîcH.G.-„²Ó0ë Ù¬òŸ¥OMzß\Oö²ÒlÑ6ˆµºÙ79‹Iä|È¡ÛøŒôCÇ«¾XpùÁ¨ƒ Š_¿”…;¸Ù‡‘¼¢µ ¬Å–húcÌóô$."n#½#Of±ƒ"½"µ‰´@¤¿‚îD“ScɘU{?ft pÛN¼qúCþ‹ÕCåÒ&7N°ÐZ+ÞVúçWSÂVëW¥=RP"žlÁ øæV‘æ9„6ÎÅÞlž¾KOU*¯…!d“*1½PQÅ< ¹ê|­kô:[¶HÜ¥¸Ó´ ê3aU÷_PãèäѼ~ì5ƒ.õ4¦ð‰F-§îÒÞ•×·¬!ü,’{0Ý>|´ UÚ€F?ÞÇ3-'¬ Àþ}õKÒ–S'3F£yÀ)³+ÌØª%pH—쬣eðíé':,=o Kù»ÛÿxKgt"³NÄSΕÈÇÛOq..x’عÀÛø}V½ó2üN,n»k´—ÄYZ}Ë6Ë 'õíôÉÖVÚV– :ëH>šÔ ÏêTì ÖÝPµ¡@È)›Å*Šß×C·LqÝÃuGK¹öãÂö§(þ£Ië¥ _v”à۪ßÅd Õ²fŒñE,— ¥Û£§¥›‹NÒt¡Ñù‰` U\R5á›åGŽv»,¶üž÷G 5x*=b'ß+ÎQÆAÔ¨ Âûü(ÙüÈT·>a™“Ôi/œºßò&ÓeMkz¥G¾ñ¤Ïf|lZ‹éá[îä7t,ùôæ&–÷^ªh·M>²ÊÆ:¡Á§ÌÖ„½ãU+*øåa”­{¬¥y{¡ƒœŸóô‡ÍFûôÿÂS'Ø˜ÄæßÈz‡#]ÿ"_ÍœT/‚ûZÇàÚ)JÈÃA/niÄgÿ}íGGiV#.ÅéØS¸d¨ûVNÚÑF)2P…ÞØ³¸))ž¯]"æw=tèõ·Ãˆ¤šEÛçª~~á·ŠÅD=XÁ³8Rï+¨ÍkÔË=ж 3Þw<&ó²c>»,w“,!ÚTº‰ëczl¶R^”ƒXŽGG|9ÄŸY¼ÞåÒŒ/¬e¬ [ä׊j’­Z¢]Ï9pØ@ÿ;µßìC½h`duÔJ±Š¾<ÝFøËC6Ͳäpˆð] ÊÒï¹B*H?KÑG’ÍÔX²õBˆ»ä é-ZÒ:1 P d´'J$ç=/!òÌËÞ²CÕ>¿cg¼5õ¶òÔ“[Ïiæ™Xƒof#8A(0Òô'–cêšÕ'žIÅkJ ^0ðýÀ% èIÐvëâB¤ ¢Ý&Wÿ]6-{%M}¸·pB~;J8ä+;b"‚]h<󯮿}*Q¯÷ª€u5jõê’˜Å;Ÿ­ÒÏ_H¿?€H¾w°ûI›ZÝQ½64ŒË5+ž‡ã$TÓöŒ~3Ó†(Õ’tßϽ‹€èʹuÀ.QTgiäÐ ¬±zð‘}‰|FÓd®ËŒj}‡„LPZSèìþGÞ·/¾rÝ„¦µ$õÝŽ’„ÎQáËý¼Óà ¡NDµ•Áj;ÎýШǩ‚kýõsäyú2+‰nõ—-…ÇÃÜUÿ]ªj(Œ¸ÿH¼›èŒP´-DŒ8!²ËâL?§ÜÜ™àýÄå ŒmÍ/äódgqñ‡Ø}h²?ߟ¬]ùú—ÇáéªðœÉ÷„{Ò³ð*ó}/ÒAR…0BÂÕõÅ„Õ&V{w`ußµÓÂ%F„s—gxÙIM¨^–$~û‹€Š+¸HÞZ#En‰W:I¸¡¼it9].0˜Ü]ÄeÏÖ‰XÌ¢#¦#[à÷…§­*‚#?Ôpy4Ø#¯àj“Ë*ºÐWV+m])P²åF÷îöÍõÌÙX̲MÞìOå^XçV²µ €Z–ÚH…¼5Šv ,÷¥ãÄŠª±7z÷„¹/yó9ÿxKsúÂrQ¦D | ‘ÈjfàÙ9ûp˜æ,‰ïÏÓ&JH‚å?%ûòJÌŸÑìŸrjûüØä,‹TÊfÎÚyùZ×>L„S°ZK ÐeCÀŽ4)zí Jù™•ã¡pO%å²fKbŒÈ'ŽQé‚Èk?¢vã·¾u/8ýú:.ý\u\Éc Úút÷ ûÊ'XF@c»ûžh)X>F©ë½àG!Ây"†iU0z-ùÒ™kF7Lë†õDüˆæçE•F$°£ %Í ûw§*~‚ö¥Ý€‘‘fŠm(èƒò+€&âGŠA°><¼~¿šgwvê¸nûÿwz"xžG±ûò„¬OA‚šea»ì@ŸÃàJèÌ‚i‡SË@>é>õ@ÑoŽVÏC‹ø&ž“GäúÍmä™é¯D\ÎÞ¸!ËÕd"1¸ïF˜GÁÑ@ˆM ˜J ¦CrÒö 6/ÞÐ9äeWÃÈèñž¿¿˜€WIíáêœñb‚›ò™ÊWÓMÒõÇö\MQVìZW ¶-€Á‡Ž_ßps Ï ¶ùÒé’.¡­27Í%®"Z£(+O„wl´‹¦gÜйIŠæFÂupëG°)îâQˆðãÉÄÈÚLXÝ"í=ˆr´ˆþ+ú§»ž«ßð4 %Z¥ü‰§’Ñà¢zÔŒñ‰ïg&ã¾!þN¼à9¾`ú*3€ý–‡òu‘įXØ ‚ÿ4«ÕʲD „‘°ÅP<ö8´Z‡t48‚¾nK¼`È€mC3ZC#•z»ÔÓqÈ—R`ß`®†Ñµdsë^QMÀ¼ÐJßa°5~}™úÄY½L –íˆ!ÙÓ(³2ËÊ$Æ}â>"*fg-²Ûõ¢[këE1ƒˆöžš‘\tÉ@ÇF‡ŽÙ·0çÃòU–TšîÀøJÍ0&¡üÚ¦„"þ{Uº6 Úùå ÝíKökô胂¸’ýFûÍ>9¶è2uTq¥^ÙöÛ†í6Aý!‚qu?;¿þìØÚ¸ýþÒŠÅ·4¦­ Ã(ÅT`G‚ÝÈ•ˆ¨ §­-hcüåXéˆXY»_2/ƒS³ó ­_Ý3JÑ/‰ZY`P/k4ía¤8ªÙFàDýBðT-¦÷—÷ÍùUÅ ¸‰žr‚®pm åù¢Rê­@ IéôæT›ªµ‹çt©­÷ɆJqħ1´û;õ¦Ñ RAA¼0þŠ0¥N¸ $'éŒ§Š€° pk³ “(ña³ß?¢Yð^ž,þ)á45J•—ïdï„ÍLS=òÓXóÐxxæ/zEkþƶ?>3LãYâPi9Üù}ÝmÉøkh2’Ûˆ«wkŽÑf6¹;Âwyaðå-ﵟøûÖŒµøùÓ'צØéô#¯RüšG½°@NÇVÆ+×ùȲ¥Õ¿FÂ@4©yK“aCøÒèíí˜Y’ökÄèê7ñ’V¶ýèuK·¾Í™ßs71YÅfB!‚‹^¾QC‹hžÜ#2Ÿ?¯Š²+˜°ï´ï«†ÞjèKBŒ·ýôdF[ïÁ9«*uÃ)ëöˆ{T˜©ÌÜè^Êcà¿vœ›Zæ°Ï”?Œ¿D{Û Ìt#GŠ—’Þªïœ _sçŽIì&ˆY„oùkôdG"zmæ:¼€ª¡~⣑ÿ:ÇJt½îßEõqÓÁó†ÐßT…ÛÎÃÈ—K§ëRU›K°jU[ELÞ“¨oØö{$«ò¦2ŠÀ~θH%ìþ^’ÓߨxAÍ‹‰Ýß]Š-ÝLiSƒÍuݰXÀEb×—_O(Ê7yާ1Æà2šºCJ 7aŽ}`Þ“î#ÂŽ5¾ÎÈwXÞÚ*’H Âè`,eÛ =·¶cÄ4ç7´ßr‰&Ž95ù^ŘŸ³×P’/è® •Ý?Aºo½'Áë00;F,à︓zW¥0ÁLaV›ty¤C*ÒdàçæX€í"!xByU)Ûþp³¯ï'¹VÑ^¥uš+þÈXˆÔ3áÈxÝÜ[sdkð‡RÔj§ª—ˆóø$%ÿRìT Ñ‘‘êÕ~Ï’±à}TY`›ýfYGæ{àõ¤µ..È–—ÅãB²ïAÓ˜ûË8º€F/¥ìë.–Ã@Ø0Eß}‹™H)ßõ‰“ƒûŽ3|üôpž¨È‰Ù°”­À!FÏq4ÂÃ×ã⩹î©HbL”Âj±£ä¨O¨p¢ý£°Ý’JõNãS2šGà-,ÕHê®Iö,Â)M_Glú²üÑXÂ?‚^Wv®Ê…â Øé€¤K‚:ÐmÅ(·}q•<[=®ÄºDçóÏ­ÅÜÆ\Ž\[ e¦4aÖ³Yå?Jžšõ¾¸Ÿ´1[q‰´E¨Aˆ§ò‹Iä|È¡ÛøŒôCÇ«¾XpùÁ¨ƒ Š_¿”…;¸Ù‡‘¼¢µ ¬Å–húcÌóô$."n#½#Of±ƒ"½"µ‰´@¤¿‚îD“ScɘU{?ft pÛN¼qúCþ‹ÕCåÒ&7N°ÐZ+ÞVúçWSÂVëW¥=RP"žlÁ øæV‘æ9„6ÎÅÞlž¾KOU*¯…!d“*1½PQÅ< ¹ê >“óo³›ÖRxÎy¿Z“š;Ô™à}ÚGëòE'Zû±¨ŠÚïø¸{3¨-LÖÔ*?ðHSú Ôâ2©­<;âðAÓò6¸ï¹d5¬€s"€€g dGÊ$¤ažbŠ-¯!XäŠ?™éôÏK %ó›¨Ë†ö$â""²TbX¨#©@u„y\ü·˜À“°‚µoÖT(бa ç€ÕùRÝÒ&$‚…$d8â,­>å›e…’iÝͦlÍ8 o_é×¹é‡i×nl¼ ¥…¾¼…„êÈ|‚Óà…¸´œ°@í¦°€ú3nE·àý¹˜ î2Sl!¯toaJ•8ïâÊóz¸K!Õ vô8^ÁU4YÊ‚XTréƒëaú>¯TïK'ò¶BÓDjðTzþÄO¾Wœ£Œƒ©P„÷øQ³ù©n|Â?'3'’ æ}“t;ûæTÖ·ªT{àLögÆÅ¢/Ë®Œ ¤~ÎÎuoÝáF:TèZ÷w= ¨Ôªu´ô¨èoWÙ²D>9Šsƒo윖‘9ü¤`ü÷Æ&•«ßV'MÛ˜¤l°d™±mõ©>ŒYuºJ^ñ”¤Ã|—ç‰\4öæ\Fñィèí*Äeؽ;êwL•jÉÛ@ú(Å&J»Ð;v¸MP#Õû¤\ÎãG®£–øqñ“H»|õS¯ÏÜH3—n1“Š>¸6%EøtÒTyÑ:O¿÷ýôÝŸlZ×] öIõšÚí#þOÈP¾Õ;¾!Q<ô|_š{´5ó¿–µçû;˜‡Ðdh׊— wê¹V¨«´[¶Sà?ÝÚïö!Þ´02 ŠBŸ”1Œ¾<ÝFøËC6Ͳäpˆð] ÊÒï¹B*HÀÍ<œŽK4OQbËÕ "XµkHèÄ€ @%’Ð(‰bx[-œü¡¶i¹dć㴧¹½#žfMkÄÇZШ£hFùº‹ÖN]Ä^Ü8LåºÄÒöã»^—4ùp£‚XÄ>®Ü*AÐÙ˜µu_Öhù±V ôìyÓ"]G†üvDÒ3,Ô¬‡Xº¶4ý£ì Æ—…r©WÜxû¼¤>û= EÇ)î v"˜4Bž;„ø’ª­µ$^ÈI>- B0rŠþ(-)ðpÎ8Ý9nÂSZ’zŒnÇIBg(ðåþÞiðБ)œ=¦*û¶Á Í*‘ô‹H¶ÚÑ.¬ý „×ZÌã¸Ã}áÐn,ÚO£×M }ÅÎV6²1B¯¨T‰pCe¡„¸O¹¹»‰ÊC·ÌwÎ=H›#;›\‰üó•¢?ߟ¬-ùúiÇáé‚ðœÉ÷„{Òµ®‘¯‡Ü˜$cßè2>~޲"‰„ zÆŸ™Ž™~éÇËP³tN¹J$$‰ÊJ„Ù@Ùö¤üòV>§çPº†wmÀ1›¡Õ14Aþ¨ˆt}èà±o/ Ö/2;Óñ]ñ§˜Ü.š*‹–¤ŸEÒ6¨ÐÞ|C·¸ÍO01ÚA`R"nËIô7àu—E; ÅèB´ * #¬vÒë~‘ÈR ¤8úŒ}娴­Jîî_J_«~­bVÈðdಟ=ªå‹ó|a¶™‘øñêq»ì¹ç‚"šÙÃ&I l±7®c\‹ÿIÜeD Wb;ìFÝLSõ0ež “¡_ý2ü9@¿’tÃmð§˜Á”­ãl·íT¿_Ÿþó3+Æ%BàžKËdÍoW.:;T­×Xœˆn$Û,8æM(¥ç"!îVÇdùViÏz ظ¹¸·¥Ø®äùÆ™î(\¡õHùο&ß áÔ忝„¾;è—;<á"Fú¸)Éøº»r¯ÇøIØ'[|Ñ_¥¾/·²™cßÎê½"7éýÄóÛ^)©VHÔ09 R§fŒ…£°¦²& ã“gþlŸnc[V47ñ:ˆ=­zÂ’@IþóïL¡=:í26ˆ|r¶z´_Á4ôš?'Öko ¸(ÜÏMxÇò6é*/l"ƒŸšé~AlY!…ÊE§-RbGþ¨Œ—Í'C¶^F9‹óç¿û`çNz\]¥}FOm_Dèóh!)hÖýc—ÿlsgBœ•¤VrýkTç·5%~!‹ˆ(?Cã%åz°†t]­Þp„âtyÌ¿ÔÏ’ÚúÅý5zBø¼?Mã¹~]+ö¹ÔwC®3YùÇè ùS«4x.„ÇXÀ-Já 9æ%ö–:·ÑQÜzzÄbÂR¨îë¾T¤j°4%3FoUrÜÍ)jAl~忳MÝìÅmãÌLÓ.K ¯®X,o†àÖHM¶ôì‚ÀUV±¥²¼ªI]t9 %|FúÌ€è!3W+Ü6£TßWp_ŒHÝphßL‘Ñz#Ëî™Ã?þ=BEo'±Ä’Zœ0©a°ç* ‘„×u ÷ÔÖhåSé +th„—0Ô%QËZå$ ý£Jú“d1Îo"m å«lèà“¼î))žQóT°žÐ”y$‡¤‚ÿx£ãa€Ì~W8b1ŸÆ­.«X×½°êò€ß²¥_Kã8 “.|×¢©+x~Ü`(ÊRU–ú—Îýß=V!Ån“»~Fpö*‹Á];s¼Ì|ì3Ÿó w½ÒÌã. D­!âPjh€'¿²BûÛC‡`×Pór†àbYeû¹m˜Ý7O³ýÅ—ªºhüt­c †æ}Ÿ†x*0¾› <5Ž=k§k¤"hzà/1¤NRäì4·îÓ#Úך÷)‘R“ÄÕ+wvÊ—DÀ7Cï8È&³§‹Í»ª[4É!„ÔÍ94Ìå¤Ù›£Q]ÌP»Ýªí%ã“éÞ´{žî!Ř~<œL€m¤ÅÒ.ÓØ‡+Hâ°Oª{¹ê½øp F¿Í¼¦)@%B›`1$˪z•B˜à݈{ì­/2…ÀßÀL.©ö‹E5T«—óÒ¾:fµŠAÈîR=ŽÚM•`RÏ¡ îaž=5=©ï&ì©0áÍÃQmМ›L<ÿOÝOXi á—Ú I$)èŒ÷ؑއb®NƹdëÌš) \u†?W…eX`Áø2š7áø&¡[d,l( s•ü\°Ù~b²UÀ_¨1¨þØ;‰5ù™ý3°l̹®´ç±ÍÜ*›”:O)ŽäfzÓŽ=†ûKû JÜl÷L,=~>*›žê”€F$ÉL&«>J€„ñЇ /Ú; Ù$¯Tî53)¤~ÒÍTŽªäŸbÒº’’ŸS*SÑà_ºª¦é„# ©;^ç"’,B"ØéÞ?DûÜÄ͸¶ËLhì3f³Ê~”!=5ë}q?hc:¶ãh‹P‚%N(5æ‹Iä|È¡ÛøŒôCÇ«¾XpùÁ¨ƒ Š_¿”…;¸Ù‡‘¼¢µ ¬Å–húcÌäYb>Â|®4E«˜\ìÍ0Õ=öô!Gà3€uvf†°Ÿ=© œ,‹½ Z!vîÆ…ÑßÍ¡SÉÁ “yeº 1»§–|ø<%¹Ö’¥vÿ9v-ÇÂë0–²ÂÅÆ®Rl8RåˆÞ¨xjÆÉºH>y,mçÙKçZ²ÇSÁ¡/щ¸@~H#ÈÙª 0ÞB CÂcƒÛ‡ÈÒBÉDL ß&<`‡XRWðñÇ‹šœKˆÑú‚P™Jdp¦9ºà ¥A¸¼C„™ƒÓ–Äì .›ƒI£B¬EšNsŒ™ð´šLË.'ŽÞç;8F'´ª³ŽÖRìùMe’Á²0>ׂ'.ŸßZ7o±=1:Žg‘A}ó4D.#ÿIÅj!Çei÷,Û,,ƒNîiÄþd “ ÙqH™ùgu*vÔâ*]AQ9S¥Æ… ct×ì¿#˜Ÿ³áÂVt ÒIÛÃCƒeÁYîuÎt>~0F‰Ô}y!EÄ鶤¢ÛÜ¥ 9³³"Ã$®;“s-Èì—îÒÊ a×Ë‘N‡¥l…¦ˆÕà¨õýˆŸ|¯9GR 7ïð£góœo&¨ãF#ÞÁ\H7çBòÎú¸Ó룇‹ ™ñ¬œEùuє݅DÞ­ÿl“ì/óºîødŒI «[À+6 ⦡ »} Ç9+4Ðèž©°ÔMIèÖ:^ÇpZuhîáu`\ˆó3 b˜-ðn_œ%pÐKÛšAqÿcß{QÑÚUˆË±zvÔî™*>Õ”<‰6mJhP¾ÿd¸IñÏ¢ìdõµñ…½fÚ.Ú:!b3N‚¤=‡8Û–Pòè´Ê ÓånÔ=ª!x@{.f!ãK&-þõƾ…[wÈ Ã-^žìm½YýZtèPWôÙŽWp%Ì÷ï£è4*iÎY˱àæÈumÅ⢥Ð9l‚BùÓ–×lx&ÍóJòŸ”1Œ¾<ÝFøËC6ÅQžwÃŒ’¬èdh%òÆÇ¦ô¼O™ˆñ40æûë9¥:Òq$ {Ïh¶ŸY_5 €•h”ˆÖ EÔ>Y™Ë4ÜG~˜©ÍÀØ}à¯qfQR0ø§ûÉ– 9†Ïìž¡;¸ŠUG{=þ‘DéOµásO— 8%ŒCêá ¤ ™‹WUýf€?›`ŸNÇ2%ÔxoÇcÆÿîÅMä$ œÖ¬…EŒvhù›·ïæ)»³ènJ*'C;_ƒ6‡A.ù—Æ— 9öq¶uÃÂLMßÞ¡§‘4ŒË5+ã”wOöÆŸ´`½”Òïz÷ûmƒòik -ÛÞ¢öÝÈ…ÅÚý¤âÀ¸Ä JàZ}XÑ ŽÉþMf›ÍiÔlÍPZSàáp.=º"rÝ„¦µ$õÝŽ’„ÎQáËý¼Óà ¡"S8{LU÷m‚šU#é‘wmlϤ/£qÈ »×ƒ¡ËÄÛõŸ¨ðfT"÷9XÚÈÅ ¾¡R$aÁ –†áý>æä~î')ß1ß8õ flŒî>mr'óÎVˆßŸA—çÐŒ~ðòRG…»¦&K6lã)ã(Gžÿ1¿«D©ââÃyIIØáË 2\<¢«,/#T‘ì6º *!Rf–•Q9Uv¦«4Ø'ŸåKu¥¬tˆ#â%çcúé0%Ùùˆ®Ñùûv²Dùˆ¼ûA*#¤@O+ˆˆÓÅePÝR +˜¸#4Üò(îÖÍëFÒ]>˜åRu»ýy‘áM”zyî08L8 jÿ_‘Þ2©áÍP]ü:aHÏ|‹…-Rý@›ÖŠÅÊòÀKÉ:ÓæÎ’ì/“Ôæiza¶u”ýT¸çM¿|Îpå佈2î˜?uy³‡Õ®¥QŽè?²5ƒ¬ÜÄŸÎf"`‰ é%;‡òùÖ£¦÷@Ú'O«³D ß}r/hí·æU{Û Céôï¾»nØyJF³NJ€G¶Á7æ&þDßñ’™dªz[îÄÆ%bݯWâT3II…Â"š^|JmÖœ·—8‚æd“£l<Á?¥ƒ"î™LòFøH̺é¶åã”zÛ\²‰0"Å=^ò& 1‹—`YÍ­zA*Ö]G”‹½r„ HÇnÒ”$[“ßíÏ»…·)áøS©Þ±÷îþò&“iVÅÿHUÐ1º†¶Ã1Œ1ZH¥<'"wh’a<šŸÃR†> %÷A2”bbb€€ ÉDßÏ¥˜…j,Ýøq²¹ÿTr«?›ƒeFVÍj 6ñ©ÌLGiÁÂì‰øäè¾ÿÿs8ÚB]˜;»:\ÝTWˆãÁ|g·)p¶Ë^_³ M=ôó°Ó0á`A)túÿO‹±1¢÷1 ³Ëj€êc}%q´¢v„ûÕ~pýÄé¤U<*)%–¼žAR·¼1Á`ÎóÿXë’ê½ 3sI¸oâ¾¶¢.Su[¹_ÈʆÙ7½žõöŠ`{dî-ao ¢Ú¶è0œRëèo¨Ü͵ô`•jEWA NaQ8²ç¤äVΤ†tE¢ã*§,dÒ„e‰~ C¥;Ú³Rª·¹ú]YŠ®1üÙ‘e,B£w{HcŠF÷‹Éƒúh Å)²igTl¼7w£µNª5»¦ÿt€u«°G+±O&()£ ñ_=l‹J‰)-Òòe•ǽÈïGÜ¥€A‹{å"5ÖIÀì»Ý;â¸ùm؇5úÂ: †)MŠšÏ`Q¯}ecqST ˆ ¿8ŽÞQNˆFþ‰np’#¼æ!g`_NyšÙwfžÃé?ê>BùC[±ÿLæ"許la‰] §¿³H¦ÜË>¹ôq­ßs!ï8é ÓÉ”ð&jÃ…¬Øº˜ÀIVµ1k¥ÎqÆ›•ªe¢ÙÎv1ïp°*¯–‰öCw ò¨_»z,e§ðŠFµ·ìœeû”5A ÒkåæX¸ê·ïßë°Ûª{"‘ H2æ&Ñø’TpÆg¬†¦ö¼N:ÀÀñY3Ñ9ÕpŽèýÙ¶höîküJœxà„hSN![ÁxZªÌ•7Åž7‹ªl-íö¾¾0˜øâ’Òp"Ò›Ûª¤i1àDæ¬5šœñée#YrÀh ””ÙOâ¨UéÞ­,ËÙ×8†&D|÷K†h F ÌÌÇÆ5´P_O9žíß›9µÓדK†cIšªq›^+‘dïc»7Ï/è¯*qåŸ #®yAº×üÑ|d·\dÌ,ùEÓŒ.Æ$JQýJãz!ð¾ÞÔKýji œ’xÞgã`¸]x¤ù½€¡;‡\ŽÃs’:ñåhÈ%6–ì/A®í`Ô£8®)¤2{8§^ŒÏE/"³…Q}ȼçôÂð›²xΕZž˜d·Ñp‰Üõ = CsÄà"†Œ!„òœÌK¨Â@±9×Î]« bY×ÃÌPsò…7”!«|î!ŒBM¾}⪤9;~Òà,ò_]χiCkœëZ4Љ6Úf@s݂݂ÉúD‡°wÏœÍ?X9oÉ}5LojHW&!L²Ö.Åýe a^õÃ@âÂ_S¨ówäÚ#D#§çðé3øuµü:Çþ›ŸÃ¦áØwðëønÞ?†ÿ?‡P?Ã¥á¯@ìבJb%vX£~\¹5ÜD£¶S®¶o¶_'³.玼XlkºUòÞ’]yÇ=­·›MnÎÈë˜e¥q/#R_}éuEUŠFF^~xŸéÞÞdI%„ëk¹Mˆ„Dt [0<èÕÔŽ¿þù쯑TâÍ ¼cÒmì©ñáåláÀã0m£W»FWÒî- û›HHnï}Gß|¶Ôâ=Š‚ KÉŽ8s—‘Î?¶Ëõ¨l)ª9}XÉçï9K|Î]½kÞi·i¯¨èß"Cørû™¹MË{¡ûÄ–>CiRÔˆ¤)t*X¾æ)¾WYg†t¿ýìý}÷ râ®¶±ûª"¸#Nõàuû†°o»ˆÒü>úvÝ&}ÔNîb4Ø÷ç%½¬Í{ìº{ÙhÌ –4¼Y—iwøo?¤ó~@E;”s1¿iÂS>Ës”X­¼ïÀ'’ÓUÀ›(šñZ îjƒjC4îj¸6_º|·Ó.^vÕžƒ©±^Ò×”Ž#³˜Í„ ¨p¶ÿí#@\´&{-)Q¤•ù.…Õ‚†4ÇÎ-]Mº €Ê&‰%„¹PíG4Tý­ òO8pxêÃáu¨„.ªê»© „˜JpÙ 9µ.G»†7gVf„›x¦ §ë˜- Ì4˜ÅúÝ6¸¸PæZgKUc’~èçÁï-x¹Ø>ãñ›åfhÝç¶ßÒû‘Âêö Z‹Îgæ—R*8tÿXðø d™‘ÚŒãï!ã~{™¿1 M‘fv["…Ɖ0ÞàTÚ+ôàÕ°5‡Î_£›Xlau?,“ì„l|'¿® TÿÛnP¾ÊnñîÜ^—êÊ6àNó`N?U?°­áöÒVääTµ‰åQÑ×\–O/ê»G@˾BC4¸‚Hf,Àsã%0.W‚NbáåÈ©*Ì7˜LyAV=ÉÏ0¸ãVÔÂ8VÄ«@énfœ@Œ<¦AUo'r%Ÿ‰ºNíÄô’«€Z0%­OÀnêò¬~jc¤L™©îô0/qÅi¼kïû€ææ8?åU%Ö¥©½ÔxræŒÔ‘#˧VT*äûÇYMö5nãïR÷$­Ï|W§LUˆ2qšÓ!Q|ë­^«ƒü0ÛróS{È10È2·¸(ñ ì—mžÃ"wåׯ0#ø%ʰ9- ½bˆ#QœÒÚ‚I .?b윴Ô󫜻µH÷¦³{Ð4cŸåÊÑÉþÓÆG£í¥åM€é ×XÞD·é§_Ã#?-Ä›³D-ïDHhŒ\¥OXAßHH¨\7™¸"ÿ.{–ÿ|4bO·æ È '\‹ i|a GÞ/-YÌÌ"$2r#X…t2nú ¼bc-‹Åž£`.à™ñµå«TNÛÍP°¡_J°¦<@“µ>6¨<×çˆÇ ¸~uÀÅÜ4k*xïc×þR:ÊOéFO£P½?ÕDsH‡\·=¼L8ÞLÍ í_osÌ?J+ æŠÇà<Í«1VŸgÊ‘Mü#±Q¾X±”üåéôe$vŽTYÇ‘ñÉÏXµ(ì+íŸÈÑ®ÄOöû‚ÚDÀ– °o«æÏ0ãí@°Ñ™qs2/¹*˜ D+ý~£òæèãM), ç6]\lüÔÙ¨\(Æi¯é}ÊAßàˆô9ó)ádˆû-þ³VšÓ7é]W/ xH w ÈLíAžŸB<²X2,"î£àÎ¥¡¨|áÕXºvIPI¥o¥Áë BïÌe‘Žÿœû±ùbÛq¯G#îñ4Ä ¶ÌZhĸä-Ú'óJy¹âç5uÒƒ»ºÛÀÎy´¥º£n_V”¨ˆ«rD¢´\Å·1kSåÇc¸î©=oâñÙ1½—ëIÄZö4ÁM Gü%¢[œÇeûížù¾«3+ñ&ÀèºTI­ŠR’‚Áö¾§÷E6%™¼|—Ý ÷}èšN P/"{ÏèIƒøÅ6¤Ê77 J§"È[yeþäW{š¶é‘9Ù²¸¢ÿ È à7`cìé7—ïîÆ¸çJïÈùa'ïö^ê‰\³ùc}%]hßÍαÇ–¤çmâÄ”ÎV“yâ*@ow¶'Í ÝnG3Ò-¸*ZúSKjÜ× ¹žãúb゘]‡*Ó0dø\Òmdc_ÎÕëÁñÙ…6$f©ºž]¯OÎêïr„ö¤¢­Üô!û嫺O ߯gÐ<»‚‰ÑÝx “öËÆò¸/¦4tu ¶&šAŠÙìŽp<ƒSµ»5¶Nß[œôÆTß®4VZWUý$ßÄ ³t!£>‰â=æa½ÇÛ­ïhõM¹ój“ï°†øI·ÂSwìiM;cÐq¬Sr°`8üI9–'Ì+pƒ^ÍÂeËzˆ(~Év¨ÖÝÚϦ4í¦Èk0¼Ý± qZeÕï§Ý®ÂVJé£ùÕ‰1ÅäÚ{|˜Ð|ÖÌþÔ%àZÔù+ßL4çÃ$•- ¸Z–klöSnÖ«küàdš6¶dÜå5@ØBob–(§Ë¥8™i®›…Ø´Â]›jº7 6°Z¥k†‡ WÀÞñ›ûæOi•¹^I Žë@ï°ÈÇôkw6CÍ ÿ ŵ“ÁòàPbó"¤’(0è¡Ú·æ<ÜÃ2ÍVòûÌnÂ#r=9aŸ{ÂnAõ ½àßÍÀì0޶†¯ö}ˆfÛEûøë‚Q[ÿm“èË,J,l8$ $Ôq;-Ìèh<ò•(¿j‘;`Ö3]W³í2’Vô¹Òñ†Ì’Ÿ-huÁ!CHgÞ¤–+°WÕ*/)ÖûU h¢æoŽjÙ30l{ ð[Ó}¢}3Tíò²U_l}tí£Ð+O©Ê8ÂaÎ&×ÅÀ#ŽP’çÏ%Z㾎6[ޱJ͈ Ï'¡»Íú9¼tq 0¶IΨ§§Ry H^iÕ;)m’Õ6s(v‘Xr£¥1mò÷òcp¤GÅä­?ùA³©j·K¤òÑó7Iî]ê…½ÇåA*Z+§Âϵ|˜v»¶îBSbpbŠër'ÇlØÙ)ŒL{ ÕâÛŒ¥ÔŠ[+b4§y0‰ öÌDÊÒ‹ux_=-O²ª'sz 0¦ÁVÏ×c÷ˆ;hdË™9ߢ&ÍôØ h§ì„§ÿ:ý$Ž/›„^ïúl7%A"|êvŽ¥<{XJŸqéÙGFZDÉt 4çRj2¿ÿFZëJ݆5òÚzÌ©@n¡¹]bü§Û~Ð9Æi|Éå0ôTÙ¤ÞUÒíâ¬l°a~c?Sü‰‘uŽµÈ³ÑØá=­?ÉãDl…¯ç™>©ÞÅÔUž¶#“; “¤*ž.õnC&øRȧrk ÀVüºéÿ#Qc¸†~_ªDΑ\뿜ü‚ ë„Bh#”ŒÃfq>_ªo¿^ó´R€ò)±æ¯›!øúÀJ¬©Vëë<Ë¡‚H*F}yW+‹Dw <Ò~Æ û%OŒ} •÷}Ða¢ Z¬å—¶uð¦l­š²Ù®V¢£Udî”öN2úRˆe|\oUŽSèËÆÜúÎÈëãšÌðÌÓiøÜEðÀéäµèüUöþ) å-îõn¯£é¹Hj7§«Ò@ê‰| ÇW+å¨.ÈŽ|R_¬½„ $Ââq›o"û ¦#K!³"Šö~´¤ КÛò¹N3¬"ñÀ+°r—›ÞšXlt5úÆ Ÿ©Òl’J1Ho+‘Ûîèhýy'Ö› `N:/b…î{ õo%ŒM5‰èqÔ?å1Þ?㎾PÇ$%vå%ÆIpÀé%Í{Ž2sÆ×ë¦Ë!f¯9Àc ûmðt;æsÚ€IÓÕE›²ÓâU… '…Bµ¿‘óÃj?ùPŠgb¥ µz!¥/ƒÁì ±íÅE£Zöà Fü›?êýPyÄÃ"HW¼Ó¿7Ót:NnZB«6'ëý3æ³/·4ãH«tÉwø<´¯ìþCÈœÍÌpyNHzGBh<Û°Õ h†?°#%q} Mâ@gÇ ï3Ozgà™NzÓ*+ Ü0—l2ºöÝ_ã<÷…Ád2î3åÔÈ|òê¶C=9m¾T,+»µÐìIk®Ê¯1aÚ‰¯ÿDŒ”&Þ$Ís1 zÿX)ÂÚg»¥„GNÞ‰G¤‡úH±ËX×:NW¯Ê Aš`¡ðPÓKl£×(Õ’Í¥ÕamN-Ò[]¡wãº_ þ$¼£šHo~z ÆÜ·ÏÌLÒRð·Fÿzå}þÎþæÆíô>¿:¹%’á~|£É,DŽz¦~f²Æ<Еqú4MMyãgqìŸôÈ[̽ÕMaB~N Æ;ÑÅ~d33̽ÂT¨:°å¦ïÆÓ«¸S³QÍ©~xÒŠ·cÅ•}©Çv›H°MÇÏÿQôÈÖ5¼¹í÷ º¥M Z P†r·MyžÃÙKùA g°ÓivrýFLuƒ¨Ûþ™ Yôd Èã,\¿ƒÕëÛf`jÚO9*‡]èlûó®&è…Ȉ5Õ, 5B­ó×g,x-aÌî廂2¡÷Éêþ “Šy{H<ÞœÌdUh…î´_8žUe»Þ#-Ä"ì(ÍN‚5ŵ¦ñS¦´žÄ-õØËÌ®?«©)ßê²ï,4‰j+«·ÏÌBÄlh|U²†âò÷¶&t7’¾á㯓 ±ƒ:t0à×$FÿsŠAi¿þèŸN}Ú5ú)ŸSæÑ¹§ž‚˜ÑÏò¹.Í~‚x)’Û2oò'¢ógl!;Ü)¹Ò¯Ça‡þ•µÝE^ûZLá_¸iQËGGß½EQyÒ:е½­)££Ýõð¬-Zl¥ ÷[╲¦ïw2ä ÷“²üVSxe…Œó„¯:Ž<Æ¥W½xþÏTDŽŽ,v'lç´$ ¥5°¿­œâwJ>ìˆp§[‰ûGšT ?鸃\‹•tó2¡¹8ÎB¶Ñ ð[öVºIU÷Å­Â’6:òþ¶ d%¾¹yQB>x ác>7:ªK%¾íaÍçtDWY69¥½ˆDß@õpð¶3£l[á¿LîY£é«TkŸûãàdÀÖ†ÄÐú±?î†}/z%È~x× çíå”K;ºBeµ‘¶”‡¿²}7ÒBO•é%{ðp~[úß5Z;0„#ˆûìo¢cïH8ô¦Õ~žK-}Ç¿‡—°/Bó~Á™ª^TÚ(Ыûʺؠ9ÇFdY”ýø—t¥mµ ÐW4g"7d¶® Ѿ°8`ìûÑ®¾2TÂôû¥öÿD2Ò¶ôg.H®r[Ë;ê5~ž ¥l0þ— P%HƒV‚),ˆMÇÐέՠÇÖEêX$d5| ³×Oê&¸ªáUµÎû#’{MpØOV \iWoï& §ƒp(¾åcýáO&y à’î¤E”èâæȌ˜p.?YP9F˾/Îïð4Â<ÄÜ@"$±PX2F$Ž“¹õNC&ZÁ øÙx¾x1¯õ*Y?õßj ˜ªU昆î4.g[HÐQnŸϵ6Vþ„îWxÌ·¥· !ŒÀz]TÃ’·Q½ù¡°:5~ŸÚ©îO­!‰&3䎘8_ɽZ½¯;œ¸”ò@mÄϨÚâþ„îP¹ŠA&Ü`×dFžÜAA¶…k*OV¸¥¬ŸÇ Á.YBöQQÁ:4V(é— 2¤º8=2 \DpŘ ~ÎÅ«ÕM§(Îà3ï˜ì#è\(˜I½Ã6vMs'7À¦`µ­¿FFü݃.;Ù‚™_¬œUçæÉ£±ÃÅÞɶ`k*HëTÖ”Áñ2©Ý÷Fj¥†õ+PD`_ncÆ1 ‡{1†žàMÞFBôÆÿ :Lý˜ ßw›ÿPšâ–i:tSOì°ÆNR 5§Ë-ªñDÊÆg?^›¾ó·+-凉Ü,áä` ê¼$#—#3¸j¬€Ûñ) ™½~8xxñÕ|ƳvCĆT&úi‚Uµ5C:%TÇ4uÍ{3» ÍÝ — w7÷ä0ÈîÄag´;-} jŸW¡#/§=Á—¥•(³QÀ@¢1<ÕÒ@w´k«^=Ï¢à÷<sÆ£|Žž/ë÷²‡Z£Å’Ô0nÓlÑHªŽ}”˜*4ˆ4Nä°xÐ}„çjMq @eѳgIƒ"ªìT_“§±€ ¿œûLˆŒ+X<ìcm :ÞÇ«¡ Ë ‘6"¾ WˆóNbÔ­A¯ (SÙvÏÌ NÊöòsêz­/q}~£)tœôí@&9»[æ<ž.q97ßnóòö½hñº@­ñײ‘íødiäЪ{HUåw™ÀÎ%Ó£öH‹?­(êÛ%TqŠÍ#Å?s´i£´Ú½–ÚúQ>Y¥ðÉp6&¿£Vû†2µ&)º’¥k…ÁÍÖôÿ9ºÇû +é%š{Œœmº_™†`?w±9ÇÚïÀ†;+MCÉP@J@÷Žƒöp|ªi…²e¾m 0ð<†·rk…3é\wî9Ï·lH‡\»â{f‚óÀi{/žôõg¶–X˜Yã¨WýX Ë;ƒiÉk`„[`ú>¿PŠ@8õh_¸mÔËÚõÍ‚6ÄØ—.®*: Iê·p-E£ø%1§¼ošÂj˶ ±ý  M?DdöB »ÇL¯—güNwYˆÈªÖ$OÖôÕñ~fÎ={‡á—o'àYq_w C· ëü.ïó‘»Î/ÔUìü׬-ÙoU‡µó(Ìls(”-nfÖî(tÈ÷é[°ëGÒºr’:@‚·%ýÀ‹Bâ‹Úåzþ?…¥[±ï˜ŽŸÖ6Ä„· Uÿ!ã†ØAÓ2¨ýZ’“0ÌÃ×´à==œ_¡„q|HjÓã fŸ£Ýu–&´ðo¾V“ôûd\ Åv?zûå$õL}F?Ê=h$Zœo™ÇtûµkùÉwGãH>§…œ?íÉ0MÍJ˜ñ’áÎeÜÙF^y¶ÌÝÅßÁ·î55aÅ,ØPÀ¾ÈÑ_QÑ ß7ôw=(¶±ïrCËs¶ßÜ¢Ý7®†ôËh+ç@ÿZÒÀ4L=ü“3/ˆ-ñDãiÑ[Ì»÷xO.v6öÏ=£Ý?×ÝëÓbAò#ud&F›UŸÃýÄ/`•Q\G½ÑpÖ§'å½ÙÞ<˜ €˜ÈÖ XA¡™ÚózÆH•L@Z„ÛåvÈvŒ¶8,´/!Ã÷— å û:8Ò Ë4É“ú:²ýki¾éš• ÊØÿ$³ÊyµûŽVF&»/”:Rñ{© °‹°1—äžBâ:ßSùb¬ëƒŽbž_ELîiEÉÌÌ;ˆ÷ÀqERƒPR'´R*”3e*¿½ãƒá?~ájŒ%exHÛü“6Õ ¶\÷.…„OEfsA¦À·d_ÒòL!w Yòš*Ám_—s£‘,]™îÖ^³‡S u£DA¹¤ŠSfd¾ŠòÓ) 8™Å„îðÞ-ã–!"šó{TØ\—ßÄ͉JÇhÞºîÝ’×ØþøÜ€+!P³Á¾› ¡Õ^-El%«ÓøkÛ±Y:$‘I‡, a4¿þoüéÃ?) ±=<;ÌŒ7 Zª…x¯ƒýnLkÏ'>äw+©²‡ ÌŠÖ…¸w™D‡ÙMSu–g[”v0jÃ^SꂱÁÍþ¡#^þó8êêuè‰"É¥¿÷LFŸë?]8@æX6úHc»¡.k6lÚ°‰}£U›@X+ã‹·Ëé-ñh#7xUj ƒo³ÚºY­Rz¨Ìâúœ¨c¨»ü®û@Æûh4N¬¬­Õ ¬õkDËdåÜ)µ‚”^£Ãª¥OŠ—Hq=»µÛ2áâÜQûnªŸC¦ñ =”c|<ø”1â_Q¢ÝÀÎá­/öÊ""”f‘’ß|§ÄÔ}a Êöj>8Œ$<™^á1,ϸ>_Š aUꋨGPM¶³¶‡n0¾"+hKM‡‚à>†5ßo¤^KûÏ7„O\×D¥æiÿL ñ®> cX5Àܳ§°ÄBÔVþŽö["šZ¤M/MʳGWõ˜ÝÄAôú®Ãí(½•(Cg ¤bš¡8—NÖà´;†L×/á}gþG\K¬‹H4ìÌs]ñì°ÅûØù&•Ä›D{{` å£Â°õHQÒ££8æ‚H)"´ø@šsz©Ø‰W}Ô¿¾x?ΜŠR é|Q\Ÿƒ[G~‚ú×äÇû«´¶?§×Ë®ºý‚aަºŸÌ³›ÿÂÀ›'§ì{æ›fð½šìœQÍzµs­­Ÿ#Ц¢áÓ„}äUFé¿>#?9âk[™Âÿ/ Z*òÂv‚2Tåõh A;3ß…Ü@ï—pÕ÷¼[ðxÉu¶>fwè ŒR~/¡G§’BV),pGöÆBÉC¡ïxÏx³3ùƒÈÙÏxFµ#ƒ@ùïx Ww2â5 Ø€©„+ãON£TÕyâ÷z¬ú6jË®MP°ÓuÆ›x·khcÕV4»DAî]ׯޞùIƒajYãlž|å·)f—O´²ÊØ`bçð雸v7ü:éþçð鋸v+ü:ÈþÇá¿ÿaÔ'ðéGøkðÝhÆ{/‰! HQzè¬Òãp2»ñLÂ1’i᩟¿B¹Àž”»g†_»Ç ¯ƒQ%>xºê%ösMüŒàåo”Xræåj-ÂfO ‚¤GV±2ÖHÄbœG LL9Iåôû#zÔ9W893'Ù[ßåá!¤ÕÆ| ó:(µ–b¼ûÚYª%Ç…¦4?xoëžëzœ¦sÎûõf#…líF»bƒÉ”3Fòï%³è¬šOÄ€$‘^_ÎÃä>§m¼кÓ|Rù*‹+¶a’™*Q>ªËXmtÐ8£t/}”œ8†ù²,`Z2 t@%©[»&wL><#mz'¼« .‰ß™‘ m˜›bèC é¢Ëõ´‚aÉ{$HfRTÿj«ð^~(n̽ ŽV™[u±"Ç61Z¤èš¿ 0Úv2¿æ¡n{ÛÇæøÇàûˆê«í^Qî èí -2eضhˆÎ™ˆ‡gÒHÐÈÎFO ¹•ïw5A­>ÙøR)# >úT,,Æ•©,U7¼ÚE²c\¬0ܸ&°0Ë740+Ëí@ð*Öã èCZYw:¯ïã ÉDÿè3‚ÎyˆËýW2#ËK¯6^¥˜ÄB'@{i‹ £ü/~ÁFEnô¹²&×#Uø_ðr>m©(Ã0ýOªŒ¦Mc„ƒeCÙ[à rîu$M9L?Ötn~r¸’þÍÏ•~p«_Ãwl!ÁλŒÔƈ£“›UÎåʽCDBÏ•^;‚Z¦S #ãUwÝŒ$Ýqš.)¼”P2õ‹Q'Ïï!ã~{™¿1 I‰ÌXOböÃjl˜[ §çØqÒSùâ†l.ðjæñ²¨Ï͈»½OG«ï3^ì|¿í ÁCùµŒ(Õëáà1 X—B1QÛ{´HYnÁëw“²@Ò G‘‘)¸E.ø~­¯-M+hYº$ZPÒ6Ý‘ CöšµшáU¡^B†|¢+¤Ré­%ÇEddVƒš01ô’Q3#ãÕÝÓȼ!(Ýbß…äÞìÄjM|öb@±\´ÞðõtÙSÆ›¼ð3U›¨ŠjýÁ’Çt‘F+þ>"¸¾G"á?²ÌMHvÑ[#Ïööd ÅþÏ¥gŸ’j¬.´a8’š~o L~Cv€ÖV~‰½9øtæØX ÷Ÿ+æˆ'» ¡W‹^êÌ%ä£-^¯‚(Ü1™5ŒÍ8À^>Š4eŽ"˼˜™† ¾têg´½À¦8Ü’B¹J˜a¾x¸ƒ;§ #…Ý7F2 lì­ÿD£ lOùþ%æÔ[Y‹|¶æ`ù·· •à0<Ñut/¤}T}-ߺs·S[Ûš¿[éÕëßPÈ{•L„˜w@±k1¿fþ õ/Þ<ôn„y&m¨%b½4É÷¶Ï/Ð ¡óÇ~{‚íç½?Ôý±³JÉRÊ™]™rˆ˜4ÛÒ–¾VêüùF~Ùt¿A 2_yñP;«ó™·im´°(òImðË^`k=mÇÝ/4¹?è¨Ñ¼£´dŠyÒ²æ ‹ðœX^ê¹acStlÞ«° Øw0Ówÿ/ö̬¢yÝàñYÊ]töUÂÂÐe·Dœæ}j,E¬1—±˜?“£z[ª&ºÍSH®=A—•Í©ßàˆô9pAÝÆÎBOçtVc*¨deu\¾ä>çÛÊPL€°b¯-5#Ž÷µü‰çEÿYŒ©"ˆfáf¶e•fçãš´9¢:Ë‹”#Óò«gn¤¡=7ø‰çiG{ÆÛJ€û|Zj²‹ü0á;ÿqrÛ4iˆEèc1ûÜÙh@’š/žj,vC¸¨žO$y@!ÁÖò¾ÐT>TÍÔ¹¸á ‡ðŽs™Ð¤¤ˆ‚ßZ&ÜL¡Áå~Ÿ§X ÿ€ƒvJ)¾ô–{·"°îtÏ'Ÿ¢e=Gõ2GÜbêžÇõñç•âô€€ç õ‰hŒïÑe.Dh\o¼ ‰Šd#H(çïÕÏ‹Bs!&1N Þý|´ «ÈjÛκ÷ï¡“èx¼õ’Y4ùÛÛ˜œº…±çãÙ³oØ/ôo6ÍècöyÀË–ìn;šxH‰*e¦¡_öþFq×&¿k:»ž»ÀRÄEä_ ¯Ÿ€^4!£Ü÷J×ݰR¿b[>M¥ 'Êžþ’a³©Ÿ\§óc°¡ÚWa˜²ܦ-¯b]¼u“‘ªÉ21{ÒŸïSĨí,˜1¹›8û8‡.d£ú#‘C(x‡fp»6¯’6æwò Ÿê´U7˜b žgЄ¤{E˜.Åïf Æ Òk ‚„ƒbTTÑ=qÕ—¥‰8°¬ ×J9—EÍâèÄãg„ÕÛEà¾SÎͰPŽ—ž½ œJ"PÕ‚¨7#ÿ¿EK£í¿ïÐ èE|  "àNÍQÖÄTI¹Æ—šÄóÇuõ—¦U€"f?™GZü…JÇ$sÐ1xtFP©i1;T°2‚Kml÷ÿjﵨáÝW¯‹ØŽ#Èr˜UXѼl10в8&k¨Ï«àªô€DÕW%F,©é8Ð?)ÈŒoÌ=ìô½e–”¹P^¹kêÞÑùÀýH ÷$Ç´ˆ”Ž×ìk1ýúd ô§°ç¦@™éßÈTí¥tÒå83ø+df±¶DŽt&›˜!âL5èD™Ç¦ª!±$×C³Òfç“áz94û©Ñ€Â$:¼¥naaha)÷4AA€J:¶•׳ö¹iØíÕŠö…)økr¿ÅWã¡7q„úš›:øiƼçY°wW"WaIhóÞnÉ?›½Ìå¾iA¾ôÛ´JÂH1`œMµÚ§éÎIÃîѺÞŽ©Ý%µ’Ó· y ^¬¼òø uDtù›þíDàl}e¦¦ÌzЖ§3”òpXÑ¿Ç hÇ8i„DOÉÐCs 7ìi»€k˜9[ú¤ Ÿ/ª%²DNg”6qLļÎüªþ¡?ô1?ÅÕ;îˆ _=¥S“«¼f_QK÷'ü$«‰*Ü«/ñ˜'ê$ð+.öÅšbm›ÝOöß™øÃÎû;I¥7Ï´|ÎŒKyúù›X,#™7 ûœÏ|â¼C(Œ³Ý0ª‡²Gq¯-r|HÍh^pšäH¥H·5‚ôfNuBo)©FàîÉ«§DÝw©0¹/‘/D[iïÿRë½Q¿oÕG)8”göÝîåšzÌ©@n¡¹]bü§Û~Ð9Æi|Éå0ôTÙ¤ÞUÒíâ¬l°a~c?Sü‰‘uŽµÈ³ÑØá=­?ÉãDl…¯ç™>©ÞÅÔUž¶#“; “¤*ž.õnC&øRȧrk ÀVüºéÿ#Qc¸†~_ªDΑ\뿜ü‚ ë„Bh#”ŒÃfq>_ªo¿^ó´R€ò)±æ¯›!øúÀJ¬©Vëë<Ë¡‚H*F}yW+‹Dw <Ò~Æ û%OŒ} •÷}Ða¢ Z¬å—¶uð¦l­š²Ù®V¢£Udî”öN2úRˆe|\oUŽSèËÆÜúÎÈëãšÌðÌÓiøÜEðÀéäµèüUöþ) å-îõn¯£é¹Hj7§«Ò@ê‰| ÇW+å¨.ÈŽ|R_¬½„ $Ââq›o"û ¦#K!³"Šö~´¤ КÛò¹N3¬"ñÀ+°r—›ÞšXlt5úÆ Ÿ©Òl’J1Ho+‘Ûîèhýy'Ö› `N:/b…î{ õo%ŒM5‰èqÔ?å1Þ>AîÏâ‰$³r c±¬übˆà'™â\4 ˜6²ê»ü˜ÿ:£ ûmðt;æ|ÈÀ$éÆê‰¢ÍÙiñ*†“Â!Zß‚Èùáµü¨E3±R…Z‡½Ò‰áAàöÇØöâ€"£Zöà Fü›?êýPyÄÃ"HW¼Ó¿7Ót:NnZB«6'ëý3æ³/·4ãH«tÉwø<´¯ìþCÈœÍÌpyNHzGBh<Û°Õ h†?°#%q} Mâ@gÇ ï3Ozgà™NzÓ*+ Ü0—l2ºöÝ_ã<÷…Ád2î3åÔÈ|òê¶C=9m¾T,+»µÐìIk®Ê¯1aÚ‰¯ÿDŒ”&Þ$Ís1 zÿX)ÂÚg»¥„GNÞ‰G¤‡úH±ËX×:NW¯Ê Aš`¡ðPÓKl£×(Õ’Í¥ÕamN-Ò[]¡wãº_ þ$¼£šHo~z ÆÜ·ÏÌLÒRð·Fÿzå}þÎþæÆíô>¿:¹%’á~|£É,DŽz¦~f²Æ<Еqú4MMyãgqìŸôÈ[̽ÕD9Y$ªpš"©Æryè¾)½™@$7¡þ+u¬ÊÖʉæEN~ªpB»¢ƒ¬¦œ5Ìû]ÿ€n"n>~pªÂc[Ëžßr ªTÒ Åg+tÐç™ì=”±ï”À0 &{ 0f—g ÔdÇX Š/yÇ€sŠdÿ:vÜølŠXÑU¦{ ´[‚i}U ÖÃ"$UxpoM1saL¾6r0r¸\ÌðTyx±à´±K<ÉE1 ƒÆ¨}òz…ÊÿI2ôPñ©´Óˆ”Àë•©y¢ø™Äò«-Þñn!`ÉFjt®0ÌuF­dP¼Ä±Ø$Üðp2k3ú-šE:ä¿â‘¨Â-“Ü¿M@îJ†C9(£r^ÜÕÆ¨Þl Öy0Ë3§C rDoþqH-7ÿn€ ñ4çÑí£_¢‘éõ>i ˜Úyè)ÿÈpÆkôÁH„–Ù“‘=›;a ØáQŒÌÓ[5Et›]¼ÆuóR!?Õ 6› p6À‡ƒ&¦Ü¤u¡E†(.Î ñPITæ(2­6 R‘€®¸üÙRw¹Ù2S, ´²üVSxe…Œó„¯:Ž<Æ¥W½xþÏTDŽŽ,v'lç´$ ¥5°ϭœâwJ>ìˆp§[‰ûGšT ?鸃\‹•tó2¡¹8ÎB¶Ñ ð[öVºIU÷Å­Â’6:òþ¶ d%¾¹yQB>x ác>7:ªK%¾íaÍçtDWY69¥½ˆDß@õpð¶3£l[á¿LîY£é«TkŸûãàdÀÖ†ÄÐú±?î†}/z%È~x× çíå”K;ºBeµ‘¶”‡¿²}7ÒBO•é%{ðp~[úß5Z;0„#ˆûìo¢cïH8ô¦Õ~žK-}Ç¿‡—°/Bó~Á™ª^TÚ(Ыûʺؠ9ÇFdY”ýø—t¥mµ ÐW4g"7d¶® Ѿ°8`ìûÑ®¾2TÂôû¥öÿD2Ò¶ôg.H®r[Ë;ê5~ž ¥l0þ— P%HƒV‚),ˆMÇÐέՠÇÖEêX$d5| ³×Oê&¸ªáUµÎû#’{MpØOV \iWoï& §ƒp(¾à“Rôœ9Y¹ ¤‡o8&&}2ä?¬ýkd€#àñPÕ,Rªór>ý¯jÄ8¶y±zJµùà0$tϪr2ÖWÆËÅóÁ¨)RÉÿTW}¨6b¨AWšb¸Ð¹ž=m'QrÝ>Ÿj4mË¡ãÍiŒ$*Êø%L¸Š»HÛïx¨TÇ1; "¸g¤e£ÏHÇ{ÑÏ9ÑçfrƒÔ-s§`s—žH ¸™õ\_ÐÊ1H$ÀÛŒñ¬ˆÓÛˆ(6ЭeIñêÁ×µ“ãøá8%Ë(C`™kÞ Ñ¢±@ïLÀvyu·Í ·5í:Êß¶Õ<çcÊ7ØóÒïÑßßÚñ íœt±“r…èÅ ¶œ+qÉ[”Tb5Lý¨±—ìÁ ̯ÖN*óódÑØáâod‰Û°µˆ•¤uŽ *kJaÈ‹Tîû£5?¥†õ+PD`_ncÆ1 ‡{1†žàMÞFBôÆÿ :Lý˜ ßw›ÿPšâ–i:tSOì°ÆNR 5§Ë-ªïáüuLÄî#6ï¾Ý ªJÇBø¼FeÄH#ŒOO×Tœ„‚÷AŸôF„µéŠÞ.ÍíÍP}›²$2Q`·þœ ¼³È¨'˜Sìg*gÓ""¦ ”H~—/àóh }¹¨…ÏÐíŸ]Ñd#µ7<{Š’h”D{/ü(FŒEO5t#Ýíç¥Y¬ ?"ìOFjcÈúiŽŠòúÐ-¬s캛×+QºDºúÍJ—ê ׳â­¡a¦s4#3 Wû•ïÛÆÍ†P+± Ò3¤Á‘Uv*/pEö8¥þ'&gG\Vh¾»ýhî‹¥xë ”ø¾DØŠø,e^#Í9‹Rµ¾€¡OeÛ<070Ú¾Or<êÒð‘mèÖóo$MJ×àßÇBü! ­s”,Bro¾ÝçåízÑãt[â/¯e#ÛðÈÓÉ¡Tó%œ©Á/ Ù´ÉËÃGì‘apˆ 1½µµïiY¼åWD„FŸœl¢iµ{-µô¢|³Ká’àlMF­÷ ej LSu%J× Û—ÍÃuÊÜÝcý…•ô’š{Œœmº_™†`?w±9ÇÚïÀ†;+MCÉP@J@÷Žƒöp|ªi…²e¾m 0ð<†·rk…3é\wî9Ï·lH‡\»â{f‚óÀi{/žôõg¶–X˜Yã¨WýX Ë;ƒiÉk`„[`ú>¿PŠ@8õh_¸mÔËÚõÍ‚6ÄØ—.®*: Iê·p-E£ø%1§¼ošÂj˶ ±ý  M?DdöB »ÇL¯—güNwYˆÈªÖ$OÖôÕñ~fÎ={‡á—o'àYq_w C· ëü.ïó‘»Î/ÔUìü׬-ÙoU‡µó(Ìls(”-nfÖî(tÈ÷é[°ëGÒºr’:@‚·%ýÀ‹Bâ‹Úåzþ?…¥[±ï˜Ž€­Ü]>ᢅ).JÂ~ð# JÂ(ÓÔiew(l°ÿ{Äüô]vY`Xq‰>wyŒýÎÝ«‘{è·þÏåÇ$()¾½e¡¾¾]IŒŒ6wsï"磠•=ú„ÏQÒ}N…&D±V‰™.@³HÅn´úÞ%Wý6Â&™•GêÔ”™†f½§yía@šÒuÂ+Ì[—åßùË/ؽ>dÐ7Ç!y”!ÀùZOÓí‘pƒØýè?Õ1õÿzÐHµ8Þ 3Žè)÷kkùÉwGãH>§…œ?íÉ0MÍJ˜ñ’áÎeÜÙF^y¶ÌÝÅßÁ·î55aÅ,ØPÀ¾ÈÑ_QÑ ß7ôw=(¶±ïrCËs¶ßÜ¢Ý7®†ôËh+ç@ÿZÒÀ4L=ü“3/ˆ-ñDãiÑ[Ì»÷xO.v6öÏ=£Ý?×ÝëÓbAò#ud&F›UŸÃýÄ/`•Q\G½ÑpÖ§'å½ÙÞ<˜ €˜ÈÖ XA¡™ÚózÆH•L@Z„ÛåvÈvŒ¶8,´/!Ã÷— å û:8Ò Ë4É“ú:²ýki¾éš• ÊØÿ$³ÊyµûŽVF&»/”:Rñ{© °‹°1—äžBâ:ßSùb¬ëƒŽbž_ELîiEÉÌÌ;ˆ÷ÀqERƒPR'´R*”3e*¿½ãƒá?~ájŒ%exHÛü“6Õ ¶\÷.…„OEfsA¦À·d_ÒòL!w Yòš*Ám_—s£‘,]™îÖZwĆy=@ÿ jþŒþ¾å‘0†!Y ÀJΘEk›£Ü6f³”Ÿ…ŠkÍìUSar_6%+£zèàù|N(@h²²ëÕVìÖ‹føôeÅ?Ñ6a+èõYâÞFætM°¬þüóqhDõÍwôJ^fŸùb^5ÇÁŒk¸‚oôöˆ@ºŠßÑÞËdSKT‰¥é¹Y¡Øêþ¯?ÝÄAôú®Ãí(½•(Cg ¤bš¡8—NÖà´;†L×/á}gþG\K¬‹H4ìÌs]ñì°ÅûØù&•Ä›D{{` å£Â°õHQÒ££8æ‚H)"´ø@šsz©Ø‰W}Ô¿¾x?ΜŠR é|Q\Ÿƒ[G~‚ú×äÇû«´¶?•uQpô¿ÚWÆ:¬ì"è–ð)Ïýù |göw†«kŠ9¯V®u U³äqP«Î3Oý¿8ËÁÁ8•D÷ˆw|kK5‘›¾þàÛæ¶» À-ˆ's¦{ð»ˆòîî¿b߃â@ÐwXò@é?)zô­÷i-"Ú"±ÁÛ %‡½ã=âÌpÍÇN±æ ñZO_»2°³ˆX˜‹»Ã)C:Oèó;Ä ¯O|iéøcÒ/>gu÷ÅEšéomü£a¤Þñòóßu3vÒ ×ó÷„>ѧÈÔY$r …©—²yó–ܨ)¤¿g¥°ÃÏìçð雸v5ü;þ gðé øuÏü:Óþ£á¿çÿpêølhÝhÆ{/‰! HQzè¬Òãp2»ñLÂ1’i᩟¿B¹Àž”»g†_»Ç ¯ƒQ%>xºê%ösMüŒàåo”Xræåj-ÂfO ‚¤GV±2ÖHÄbœG LL9Iåôû#zÔ9W893'Ù[ßåá!¤ÕÆ| ó:(µ–b¼ûÚYª%Ç…¦4?xoëžëzœ¦sÎûõf#…líF»bƒÉ”3Fòï%³è•J&AÌI15ì'´g®Éå¯Ck óŒÔârxí[jÚŽ›[&PùÙ9îxº&O@ÙIÃXo›"ÆU ƒ §DZ‘e±»²gtÅ”)0^p¿«¿¸{2ìqÀ€t!MгÜd…†N’€ÂÛ ¥h 1¯¼@™¡,‰^öö¬`·JemÖĈØÅj“¢jü$ÃiØÈ>ÿMBËâ» 4P " ·º̘¿ˆ*tÓÖ½‘‚2êÉåéhÍ NòâšW¢ù6H@WKQ—óÿ9D©??”Ú§ä‰Ww:¨ÄVŸsÌy´‹b,ƹNa¹m’Pt˜y*2R’8 ùÝ¿£ˆ^ƒ€s®¶ËgDQÊMª€º§J½C@BÏ“ã[‘ʦ«ÓÆkñ¸´2‡´ÝqkפÀÖIÞž/®ï!ã~{™¿1 I‰ÌXObúT\'ÖnqòÙe¾¿xIM¢ÊUcÀgHoY’I:*“`Z°%Ùð?­Á.2ôELRÖËR=mü6Áë×ùœÚ\I–(cU]µþvêkÎôÎóY•°á"#„Ǿx*=ÿJœ9ºº1¾ J'öCèÓ`Õ¼/³IxiѨàíâ2E[úvÖjÂØ¨ädVƒš01ô’Q3#ãÕÝÏ1{€béO6M‡¹›—ñžz&­‡d_ n·ùÿ«lbÑØŠàwåËïð¦Ây-Â}ñCyrפ_ʰÓ¦ÒЦ›Öé³ÛÞ}‡“2…wßUÑD"ëªfQÍ !Æé® Z?äÜ·Ò!Œ¹ ·©s:%EŒÿ&©ï…%£–3‘~wšV9¸üû39âDSa*éñLîL×$é §t›-G²æY®#Gõ‚Î9ÀºGJÜ®¨õ£/ÐËÖÚ¿”öxÆö{OjRƒv€ÖV~‰½9øtæØX ÷Ÿ+æˆ'» ¡W‹^êÌ%ä£-^¯‚(Ü1{õñ¶ú´É¥åÍea@qÀ³^p8a},òŒF Ä? RV±¾6Bä²Él‰‚¾Fv“¯ÜËÆ;¥áƒ‰ç<Žâ\:mEµ˜·ËnfÿM½¸h䝿‹«¡}$ ê£énøÓºœèêÞÜÕúßN¯^ú†Cܪd$ÃχÅfp‡Ð÷ë€ÚkJ–±8¨Íƒ°še¡G¨Í[$™ˆêßb¿F´×²“TÕûøÐðñôÿ)ûcf•’¤•2»2å0i·¥-|­Ô/ùòŒý²é~‚d¾óâ   wVç3nÒÛi`Qä’Úà–¼ÀÖzÛŽ%º^iœW±ËL”Dëš²xhÎÜQò´ÙÓþ¢ÿ*mäî¤Gi£gt;ª²‰ÒÌ«é¢yÝàñY©Ö {*¿áah2Û¢N]ú¥bΆv$lÉѽ­Òa:MSH®=A—•Í©ßàˆô9pAÝÆÎBOçtVbe£¯”˜Ø<ŸpöY G»÷œ@2 òkÂA,u ¡o#Å'ýD[”¿³.øfrŽ_ÚEòs0@ÖÈÀXGÈhÃXã„æ 5e#؛ĥõ"L¤wP«ádAyò4_:ÕLDPd õ0Æf˜Š À''‚€vÞÛìÆµØÒ¢™R|3]‘‡#ŠÄ³Tb‹Ñ{…ôù'ˆEQ›ñ¬Œ m?ÂäÇ¿‚Ú*qw”îÄ€ÁzCMîM¦”RÏ-«/‘%DqÊ¥}ž}Ç ½/­9Ó‘óˆìV‹jäWÃ×cNʘ8_;ðß –.*t6œ  Ñ&;oífÁFma­Ï¥€Á²™ü}Ã0öÌœ1.ø7C"²ègK@šïí«O¦ld|i}¼s¹|Wj¡rͼ71©ìâÝò¡|^%äÓ Ï'Ÿ¢e=Gõ2GÜbêžÇõñç•âô€€çK¥1ÖAÎ3üÏó ¹ÕBwÐ —Ô?9kV¦vµp´ëÂ7“ê§ìy¶_þÓèF¬Nƒ;v8îJ.'¬Vj;dÓäOon`jrêÇŸfͼ{`¿Ñ¼Û6C¡Ùì*Y/™Õý‚ï{aëZF¡ÓÎóãU/Òháöÿz‚‡eˆ—bMGŒbTí¬‰­K¹PUÕBS®È¾±šMÌU®™ Ð{J’áLúå?›…Ò» ÅŽå1m{í㬜VI‘‹Ünôÿ=O£´9æC|M5UXžÅþéBÓ9iu7¬ŠèŒ+­s§:ÜŒ¬8! Z =ÖL˜Àñ"V ù§2“×}µZ‰™—à9ŸHÅa"2ôšè ¡ Ø•4O\ud%ÅibN,+õÒŽeÑsxº1øÙá5vÑx/”ó…sl#…Ä%ç¯h'ˆuìA³æ_2rÓcf1¾HÆÖµë<Íéô j鉳Š6Çá`Vk:¶Ë`Á Ü ¿¼Ë˜Ê°LÇó(ë_ )BxäŽz/ˆÊ-&'j–PIb­žÿ}]öµ¼;ªõñ{ѤyS «7æ&GÍu«àªô€DÕW%F,©é8Ð?)ÈŒoÌ=ìô½eÐ+÷"iq9ð['Íû²†*%çkÅB¸ ³ØETgF%¼ý|Í‚¬Ì›}ÎgŒ¾ ñ^!‹:j&Ë¡×.E-CÛOïA^é4ß[ˆý ØŸ“6HóZÕÐY*7t v®uÞ¤Âä¾D¼¯Ó1Šžßð*]wª7íú6HÇå&]Õ gi¯–šzÌ©@n¡¹]bü§Û~Ð9úqa2@äÔùÎ ¤œéëËáX¬|—ÛaD^äšà¡?_Q ØÄUÐÁöN7Y‹XÏ¥ºôúî5¿+b¨ï“gÎY}}Fg°e2× eþú{¼aˆ s ËØ¼$üµMàBDIÂüe/š½à•NQ·tßðáL# fG½q’oýxiñæ¦h#+è ‘neó¬¯,š {eîÞDê´G^*[Áuš·\‘d´šõ"¨ 0Á!›ØW—+T‚[, æ7° µ”b¥”:ŽyÛ£J|ì1» ®Veðe*lñý9OHºµ¥±[Õð¡¸êå|µÙ±ÏŠKàu—°˜A¤˜BüN"#3mÄî;š ®4ÀˆERÞz¦NQ|PËàl:kÎ>½¸Š4«E¥ÿ+ýã(C}8>S¤Ù$”Þ2#'Üc”Òu'yÊMÂ7áÉ«1 À*”0ÕVf” ×ÉQ¡Ã*ö¬¤Ÿ%Î\çŠlÈÜMsiÝ}ñ)‡©ò¤=ˆ#õI–âD~Ú·®G‹ÜÈÀ©wch¶&d]œnèîxQä+[Øø·6+¬Öxt¸l¡V¡ïD4‹,áX•½ã?¨Æ£Zöà Fü›?êýPyÄÃ"HÛpï99¨Ý§ íN ‹áCÑk£}Z“@I/ø–â­É³vz“°¬iÝ•L"ŒñAˆ!óbÌ0L5cê{5-¡!QóbTÂ3»8ÈKL1¬UÊ—aX½,¼<9;&"ÜPÍ6Þ¹p|Òò0žó¯Ì VêLËa-²uyì‘ ìÒ m>^¿ìá í3Ýöµ¬ž'¯*³NÆaÈ äºÀãß`Ek†8™èø/?Å ’AÙ÷k ¼$ÊZ«ÐAlÅŠ…«˜Qìþ_¦¥ÔÚ ­žBSƒJÍöÕÇG›1#Ò‹€î2Eo.z~@5@­†L¶@½í<,á»QÜçà ­ÚšóÆÎãÙ?èî/ÈT[D’ÌXϾÏEÈ‘1Ó-BxÃbbàÚ«ó+Û§¸ŒoÉYʳïÖpÕÖF¦ßµz•?ø›¾õ ŸcËžßr ªTÒ Åg+tÐç™ì=”±ï”À0 &{ 0fšæ¹1›DYÊ„æ®Í%!AI¸Ý3«hV´6²!kšö;ïR[M73–B‘v^Ÿ_èõyQ+Š•ƒþeðü¦KkN«–)g™(¦$x•¾OP¹_òL½üŽ´(œÇ©àÜà‘ß•Nbƒ*Ó`¥) ëÍ•'{“%2ÀÛK/Åe7†Q8XÉ8Jó¨ãÁjU{чìõDHàHâÁbvŃGäxtÌ™*wîù¢,<¬ú± p¶ÿB |Šùâ¾àúÉ:ÀˆÌØÄ¤1béDù4ò0¸‹êÌDÉ“VIÚæY™€ýë8+v¾ÕtÚõ¬Çq)óág~ÈWæ-ÙßNþÈ C.56#þåêü_¢|ò'Sâ1·#²[#>7JpmJ603¶ŽG’ø%Oï¾u¨ÀÇ2ÒUeU³Ÿäk/ùŸæ´žÓB £õÌ:HS¥äÅ<‰Ôô–¯ó«ÔÌé8à TDºCÓádÜèXè$C‹ß®â/VŸ“aŒ_Z+ZótjÉ s=î·ôóÒðhêÊõ~ìà§3Í?¾‡ÝÚÖ²•w …íüðc_ê T²ê+¾Ô1T «Í1 Üh\϶‹H‘nŸϵ7†3Uu×ø úÖÕ°TÝ*^—ëlŽhÑž@ä’çfT ðJÏÌò§˜‹yþã¾ÓŠÕ Öž²2$\®¹•–Œ3vÕ ÕŽ£ì³‘²Dc«+ÚÚhíôcm ÖTŸ¬qKY>0ÿG Á.YBË^ðNŠzeø'mXW†ÛLõbK&¹VroOè94ú“íõQ7®‘ÝpÖNpS‘å¡1OÔ;ÇÄ‘ÌÁk[~Œø0!»\BT:M·`ªˆÚ—XTDÔÐ^‰ŸTÔ}”˜ÁÑ¥B£Lá’¹†Ðõò{‘çV—„‹oAåí™#07:ÓÝ•H.WÛpUJ©|ßX{Cª#ÏÛð?Pû‰S9FR=¿ <šO2YÊœð½›Lœ¼4~É"œ\Q.*í¡P3¨tºPæo¢ûAò7žõR©\#á’àlMF­÷ ej LSu%J× Û—ÍÃuÊÜÝcý…•ô’š{Œœmº_™†`?w±9ÇÚïÀ†;+MCÉP@J@÷Žƒöp|ªi…²e¾m 0ð<†·rk…3é\wî9Ï·lH‡\»â{f‚óÀi{/žôõg¶–X˜Yã¨Wù´÷¼Ô˜ÿE2Œ Òý‚qÂD^V1;§’©Ô‡T\ã#}5Ë«ŠŽ‚Òz­Ç³ûCÞ8'º5Yaíe+6VØí|#ü€¯öRŒ¿#ÛJŸ›çÞâLSëé+ª&ëq^ˆ§)Ö¦_ú‡ »y?ËŠû¸j»Mö?Šœƒöw…Ð1g­†ì7STïÂhÍ5'SÇN1;ƒÏÀv(›±Sæsnyb~²b¶œxI•Zp`uqÅír¼¿À‹Zï;Äê°ªÀA)µÿO'<` +{ ° OŽ)*¬u≦M¡|<ekQ…Ø}qfĦ/¸¹å‚¼"UÃÄšò¼FV@jÇè*o(œ®µNÓ€:µ×4_py¸§¼7²X>lhŒKÒ„’™:â­2\f‘ŠÝiô%¼J¯ú8m„M3*Õ©)3f”\ö¦GÇ.ÅÞq}³¼³…nšif<«ôÅgpì ñ…¨Cò´Ÿ§Û"á+±ûÐß)'ªcê1þQëA"Ôãx,ΆJ4=ÍjŽŸkùÉwGãH>§…œ?íÉ0MÍJ˜ñ’áÎeÜÙF^y¶ÌÝÅßÁ·î55aÅ,ØPÀ¾ÈÑ_QÑ ß7ôw=(¶±ïrCËs¶ßÜ¢Ý7®†ôËh+ç@ÿZÒÀ4L=ü“3/ˆ-ñDãiÑ[Ì»÷xO.v6öÏ=£Ý?×ÝëÓbAò#ud&F›UŸÃýÄ/`•Q\G½ÑpÖ§'å½ÙÞ<˜ €˜ÈÕÇfVѨíy½c$F‡JŠ& -B íŒò¸¨ºÄƒ5nK7õ…ac¶Á*"ݳvl¨r[†„ó2´Ò¡oE¥œÌw$ý¿:hg4:n­ïRq¶øÐ«ÌÑÆ 8Ü¡G[êb_,UpqÌSËè©Í(·“ìcóMþï:tOvqú8@ú$ã|Í3:?jnáÒúe]ŠªKPC©,zc%E˜žÅJ6•“RA± À1¯º!{Ge”6¥g±lß9¼5þtr%Ø8ï½ùôÔ¹ûRýý€DšÄPtÅq8Þ€.Ú­£.>QS¬fËÂÝÒZµEÀSכت¦Âä¾þ&lJV;FõÐxÇvì–¾Ç÷ÆäY …˜Ž ôØM¤ÀÛc“#(—1µM•IE·Ø<ÎH©Md lB £(BPyÊ>ze‚‰EU ñ_úܘמN}ÈîWSe™¬) pï2‰²0š¦ë,η(ì`Õ‡E¬‡Þˆ©ÿRÝÀ£ ™µådŒlŠlЪAðAìÌÃ)®@æW6úH^Ÿ¡.k6c ª°‡RUGB“ÓM?Xå¾_IoˆÛA»B«P-Ži°o‘ öêÌâúœ¨c¨»ü®û@Æûh4N¬¬­Õ ¬õkDËdåÜ)µ‚”^£Ãª¥OŠ—Hq=»µÛ2áâÛƒß {TÛ˜yÓ¢`°Ê§¤É+A휚?T"GN›m¤!<'pa멇‘|à‡üçÕêJçåóí-AøQB~ÒqÜKý¹ù@ÉU\WqnÇ•Æ\bgoƒìZácÚ>|\‚“²vÜÿ:eÎÊòÃ'³q>x®ÈÚLSu¸ñYJûÀCÍNØ1–·¥`ôS/9aħæÙŸ,¼sDçsÔ#3?aô"¿¶ßFÆQ­ÒnÓK#5Òã¸/ç“@a¡Î„Œ±Ó'ßp±ª+PçN¾Ëáù*ä²¹Íq ¶¿lW ×H$ j8¾áª¤lã -,ˆlƒw¯ü·úÔ….§‹÷?ÊÍi¨'?/d¤ÅXðóÉ2(CF´HÐVô~+31Ë–‘ï‹î»S·u‡i.ÐKò|Ô¡q6ŽjL”a`b—ØŒô»]²€Ö·´óàSk¹‚ŠLp>ÿð\Šq´C˜‚Ä®Beãþ“ àºäžm†±@MÌÑø¦?x/ŠÀ„’tò0ÏüdME?»VXþ•˜Ù©$ÞdJÃÌØÝfÑ— …Ê—½ÚÍ8”(ÅBŒ­â…Yáƒ?x°¶üÌ3NïÎ÷7Íd>‰¹ðòe{„ij>àù|N(@h²²ëÕ—€ËèUX´m³·ùÇå{EG„òÚ<^5Á\ œ’*„=Xà³ø¡DÚ»®‰}b'þ`X—±DcÁ®ÍþžÃQ[ú;ÙlŠij‘4½7+4;_ÕoÝÄAôú®Ãí(½•(Cg ¤bš¡8—NÖà´;†L×/á}gþG\K¬‹H4ìÌs]ñì°³– 2ÙK)ogýcŽ—-ÁV*ÇW b¹mÿAém»ªQ\Š9©Ÿ I'šø"^ÙfhóŠã§”†x27’ýÊgA/Š «“ðt°ø±Å<@„ëÙŠ$üü§dupMwüŸ: !>ª7xàê³aرa”T¬EÔƒ9X¾IøH8ôªÙò8¨Uç”~å„Àªñt¡‰Þ –P®uåºåçï¯q¨ï„ɶî=ÇŽº¯ä‚È„·Ë¸Gº÷‹}—¹[öó#Ø4š¤*b]¬È4U<éQãZ‰{_—FÿZBÉC¡ïxÏx³3qÓ¬yƒ|VWnxÁ[  éH^ÿ3k—Õ3D|!_zuú¦«Ï»Õgѵ4§ƒÄ*¬@} …±‹GfbÃylkME)ãꘆ½~ô÷ȲHä RÏdóç-¹NI~ÏKa~“ãöÜ¿¶èý·í¹qûn/Ûp~ÛwöÜX~Û/öÙ¶Áý¶HèæôÒÈð±_Ctæ.Ý"SC]hœî¸(.ÔæÞ! ùiÀWR±?G5‡·`]s$þFFøu—>Å!ƒ¼"ø'õ4tocUp©6+¨']Ã0è¨,“ÛÔZßûW/ÁÕñ¡Ñ{b«mÔ0›“ú~k[¤o7X“ú¢M½g=Aü‡Œñû÷öú­aþšôì¼þ•â"µ7aŸ¢v4æ)#¨Ù"D¨V®7Ï*§åV ímsÑxóNªë‰ð$U8<õw).Ÿ°|¥lœ¶õ®wŸÿ_ÈZ|Ÿ½ØJÁ°S¶ŸêÕ¹‹#j¨.o<¤µaŒ¯è¡èÒB5mCx“m™t°–À(…W¸eR#ÓªLW·öÈ]és‘ô µ =ºáí*ºwÿ6.ð×aÀxÐ>7>" Y¡»Ý¥^IjÉEdøßB0UIPµðÚø^ÑsXªþËbu;ÅLgV~Óà÷ωp¯5ê‹ò¶~Gd¾ú³§á>>6E㽚OÕ7àœ )›ÔmÒ ÅP5èGØ­Ë-ø–"1Ìe/?䕵 )¶Ê(úT›9¦íXøEžŸÂôjBB¹›k^µ8:=Ô§Çiô.BYË&™–׺‘ôë‚qC$±~Úf{ I09¹Ô­ãž«7A‹5!24=Ææ|µÏéî\»²vK°¯´&¿‚x„†\X‡Äm¦¹±ÙÎÒXÈ­T–wMY¡%‰ÖöïÏ”JyË;Ž•U$üí룩EºM¨ëÿ:7ÈgvÓïñBàL“ÓTÙ|±m±Z?é‹·ÜÑ4Dñ…á3?¶éT{⟬5“hò%è+ìS7R_âí„´_âúÁ׿õs#”2:œàf•úéÖÃZ:ªëšŠ Þü 7zñÛεå':9 ©­õöÉ ³@?¤N´ÕF›÷Ñ9ölû´úå¤zSaB«@™GtÁ=Ä›÷þê¡n!¦m$|adÇ>êÅ%‰CžĪ·E©’q}ºFa6¹^Œz:­ÕÁ‰~ÒÇii¹!˜©9>dêÚ&XÊSÊi£Ý/vÊO Cè¾MkmÌ?¾}©;Æ¿\ûb/™{Y†!…ÚÍÁ§ídU*{›uËEÈܺjüÇ`ÖD 'œÇ•\ô4ùz`â:WPÈÔÚ7G™j÷Š{ Áþè øé5«‘„H:³Ôv0åKžâ ¦üª1ÚbÂ×XZ(;ÎðÁ@Ý Çéuh°‚ûÍwßÑ0òܺm.·uª¦~ÿQš÷¡2e,äá½µÒ?è‹:”[‡¹àŽ˜jÈk»A”.VPMš]ìž~–Ïow+.¢6EN©už4ªStD"…0Å w2Ö‹PKW¨ÿ]ÇŸá#ÕsNìlç& ‚íU©œKø@õ;&ƒ8ª¹Ð§¯3Bo{ü9sꘂÊÕœR‰XIÙÙ|ÌçTðw×ÂSÈ4Úèìú¾R0ð}D!(~EoV™Y£9™%ɳ¥JŸÐÃ;ÙäOŠÉ±* ࢰQv‹‡â«=\øEÔ×ÏÀ8!Ó`zöTþF[ƳW«€¶û®Ágè0dï‘oÊÖ-ß1ºùÚZÄÚXy^“Ô"Ã9ÕF’çÀDJ¿¯æ¤5Q:·•Ãë“;j8Žh;/£Q¼+>~:òÌ¥ór y*QX‹(æñûùœ¤ã EŠ( ö3Nu`¼6±œÃŽ6d°ç#bŸýàS·¤ ¹ ˆ>?bÕ3Öÿ(ÃE‡!à¶ãÒŒÉÇ àð‚.×qÜvh»1è¨ÐSë„ÔkèÃ~ +j±ä Pb#.#¼p µÀMäŠÊ Ñ€]+fÀçlD ùƒú`Õø¶îɱpJÿ_]ö9€ šºu ’Ì.ó-bho®ÇÓªöl˜€SŸ²Ù_L×£”œûÖ´v Uf{Ø™Œ >5j"™É-×°ØÖîëH«„ÐPŸ¾ñëËÔÑM!:Kbíj_õ[çÌ¿qé T>GÊ|#ãÉT9>dJìÀBÝJº St˜‚7ÊÔÑ5ÕŽÃr€½CØ}êÓ^ލŒh–‚ÔÊ>¯3‡k¸5Yƪ €ƒ·€‡±8\ßÿ%‚”%r¯ªjG¡†ÌÕF»2û‚4´/¡Ø¢b«¦BåY|lbeÀÞÔÙ«¤ÃX„“2³Q§bžZå v²^ce–Ž0JöZ7£«ˆ=®6÷õ,ëïûLÒqu '"wbÝŠµK´‡ÛŒz¢œ‚8hìŒT¨Ùovq½£Õ ÄuÃÇ ë­L²$¹Ô{?ž'cÊNIÄuóoµ àÊêñígxˆ©Õái\–_Ç1fycÎov²/´W†SÓšøi'âì'Hçìg'kq3¬s­ŸL¦IÄÂG¾9ÑO,¤f­u²›šô;mpªæRz MÞ«iÃ~èÿE\ @Š‚¬XI`©%p̺îQJǦ#KèD¥s¬ù€‹DçÖoD[3øÒÿ/Ú-Ñw›z2ñcÃEP™Bð*h­XãKqpီ\Žvkh O[Â_s[VÝ º¬…Oø1Šæ]üÌä>¹NóÄç’[,?ƒpŠo÷—îa­²• {Œ=¶ÄÃæÕYçÍë¢UÁ7¸2óûØm¨¬cŒë“§Xwy‡ m*£²­§Õ†Vó–n›½™„àã‡k€´>°É‹‰ÂVùj3ék “áƒü§œç#pÛÞ} g¼6L¦ºâé§žW%Öqü×-éC‘xÄ¢˜ªÈœŠFcŸj£Âúžæ®GµßÜ¢nvŸð8ÈÕ¶ È©mÆ.þ™oéþsu¬òºNÙ´3s^¼;üŸzû—lþ…L94`@? ù|P»Ù"Îáf;½ýí–Ynt½Uaßë“çIrS¥Ð“z [äç!Y»#'‚ý Õæ߆Š:ÛAÔsüÖƒÂ:žáˆ\„%ð7 Lš½’Mc»õ…ýqµlú0!‡Ö³¨Æ!41Ÿtñ­…n®³ø^¨˜ÐG©ÐA,Ua+ kŽ¥LN %Þ€/^d Ö~jñw ƒ…ðòÍŸ}H“Ìt»Ü¹pò¥ÉÖBµg½Åý½1Ptþ°Fl­à*¬)Ös!¹ Ä æ`Ú@ÐM@$a8ÏÁ}ö—£@¨_ðóßßGÛ•"Óö@+©†’Äçº;Bz„É/’²“ ·×MÀ§'åçÁ½^ã% —%Fò­é¸î—ÿb„:#~vvw‘Ò‹æd;½ÊR)‡,6Àën{iÊþ´~d—pœŠü›†-ð í©þ? e"Àž¸ß†‡:ÛAÔsüÖ<¤ÎÂ&ù¡/‘¸~>ñ.ÂÀ%!(¸ÏDO/¤ò¸ÔnVK»“tåÐjSC½°m–ËJÑþ†ð/ƒÌÒ}D™RÆ;€^¼È¬ÓªvèSýŠÚŠ¡"~‰5¸r|<©ru­c}-‚ =pqÔHµäcVoORcÁÀæ`ÕRÀÍ@‡à¬ GYŒ|'µ¹„«¯ÊÙ×J0§²:Y‘]L4–'=Ãî’od¥dÚV ë²—$oœ‡šëÞ9Ø„hÉQ¼«zn=àÖq =Çç‹ý-që ànn­5 sÑP [sÛNWõ›Ɉ[Ê©?5ÚžL~-=qß…|Ng¸'2éÐòÿZ¯4… ßÚ6Ú ´zþ¤S-r¡»¯åŸìk«D=Kû%SëT†Ì½|žâIdôS›ÌjefÞA†ÛÞL©¥Ê,ñÿi‚ój!‹´‡S<8lEXÈ><$Üé$=¬Ç,Øãªê3½æ6€s¶V§ëÿpÛ^l«èMQ·ë+9‹ß@6‹CŠMɲ]JKù!iƒ~hdŸS~WHƒ|b-éD8ª×Š¢Ãß™~v´üìðeyùrŸÈÿ† •eG¦ÿS†‚…2éƒ<1¼éÏ\h‘;@;ùãÀÂF˜Ñfaj!46Q áA1Èqb¸ámCšuEªâ¬‚T?ñ¨PqÒÔÙ»[É‘`âðÜ”†ºU9/*vö@™û-ƒö›òºìuàWë~o×^ÀVDì&R1%7Ȳ¨èÞq”÷Ù¾"|š%vÈÖ#Tˆ©¦&¿Û8|'†Æœ ¦>RÀ§µ¨!¼¶tàðX,¾8ZøƒóX†Nn,™%ZxQ ØÜ)dfìñŽè¤½ü•3«‡€ÿ>#PÎ~M0è¨ 3«'•ÀdFÿÕæ×ÅØ³aÔ£Ž³A9ä?Ä$Yÿ3^ Î/$,e@(^Gž¸Aè"¿Äm¥äŽÈÐ ”M_:-Õágˆ[î•¶úõPí–é&¡Ýf´˜•æRNéÏÊr!ü=âÏ46ÖT+Z ¬ ÓÌ Ü7kZôfå|Ñ6T¸®+©NH¹•=t6Ý{ú¼89C3!jùݘÂOB*À¾´!U±øÓjËIk ô~³‰âé!QáÕÓÚÇ8¸C*ÞÍ¤Ðæƒ ò¾¤è#5Æp>€ó÷Qâ¦û!K#(°6E©'Ò|< AѲh—¥óë¦)îa“wdb¢-“Ï5u›O®'%ŒÅÛ^U¼à†µP:€ó÷Qâ¦û!K#(°6E©'Ò3eÄ}nJß°ŒŸ]1O97ù®¨ØZài5]é…aÌȶ)Šÿc ôôиG² V‚êG=w–­GXÒñè#µÚ²ÃáU“g^ÜnZàºø½ñäóFt„ºJŸÐ§‰ ýpR!Œ‚òÇ~´³ž³ }óEº7œÑ¡!YÓ?(={­l7ë>´Ba]Ã]w'EM¿ÄßÉ~v\üí0ey X×aßSþ Z?~¯ÆŸÃ¤­›à䪛ʕ8ͶãCZ…2IJG8ª; ñÝŠQáúwù«Ýjzjïå¬ò9.”š㉺Ër¤ ë·bÝ‹HIÛÃýlfªB nÒ(mºá7æ¾”Á)øúc½ˆÈ†éJƒE20¢ø…¶ï g¡8–ƒàòl6ï¼…d4ý¡£]”˜±5DEð$ËKðéË ÔÔ‹ÊàJÈVªR€F[˰¢Ñlt'²eU̽:”àZU´|³ü,¹ÝX-Q¥!íl…’¿%Zn1w™`£’GO eœ=? ܾ ++Yô\^ÁóïºÛÿ_ëá*®X ‡G¿J+ñÔ:QøqôµƒÜ±²“Êǰ‡#õ UyÀGÅPPôKhO‡²½¦+ßeýjÔ÷1ÝôD-~ƒ|ËpVË€#úý5JmÖü´LôBNA·%4n½—¶™Tùt0+˜ðÅqö§øHz^xaqf¢ÆÕý.0l”«»÷YPÝÞÏ#pÈŒ#EYd¢½[Õð î P gËEC^R®×ä}_Âi ì ½!I¤³÷éˆ(4ú®¬;+Ù“-ªâ$©ŒÜðeL (šøb<³Pƪ€­!IGø#†µÓÅ€gA%E„=¸¦tØ{Ò_­ÁO6-þÄÎuÆ–©08ƒcAx0éˆrô)¦å·m€P~Óú5x¸ˇ~ÛÕ¶=ïÕXLÝÿA⣠D Ñr&¸rÎîŦã/¶¾ú5¼X¦;@ŒÃ+ 骡ÂC ïgXÅdnJIEC3¶‡%÷È´ß›µù»ÇàäŠèÖ8‹¸®Eª¹TE(_·Hõ|á4d ³úÖuÖŸt’R©Œá°¶K¸T™³wZ5eeç\Qƒï½“µÀ;KZPƒo‚  g1ä–JR~vŸ6µ@8ëÛR”EÌ›™Þñw±Ÿ%o±N§-b8ú˜±³¢éõ3 Î/)sß±Õ@÷FȈx/IRè«àòXz±UÈ-ÜFå·™´}âúñ%M£ úˆÑʸ4O¿áÃBÂ6#‹G‚ò˜r˜cÞ—rSøú3Ûª¾[söúë‘åm¢9÷¤˜¼²e£Î`Ÿ7°I ‹v©¼ßæúð@ÊŸÕVð¨?¿:KCŽfÖ-»º£üÉøYž3ç™Q?®Ö‹M½ n#àZ€»²-øW\—»›,€V¡ÐHƒ½â‹cJfɦÞåUGör½64 M”¬dåø˜µúD˜Ã ¯ŽA„Ë…¬F¢¥ßŸ@7çÐìü÷ðÂë÷—V1öÕ¼Ó·Ìœ /VŸüÄ&23uŒ)úWks›Ô‰Â¬¸>l¸ÂXÖÈ<Ù c‘ÛûÅ…9}Ûé±í¸ÀHµT÷¸¹ôàeÉqQ¡K/óÔðNÃý0Ï&·~‘Âxp]ú_Zôlô„ÿŒ¶‰D)ËsÏÅSèb=ÏC«u {¯ÈbLýJ¢€ãU ŸV2‚3‰û9š”ë!( ä±Ï¦Ð|=Þ@S£´ÉVy§ém°™".£@D6*a„¯u|VûTИ³¸¤‹¿¨z_«‚§<422B9HëÅ{4 Q&ÿD¨ü]¼¥ý¬j0ïd+9K*|Eô^‰~”š@ݰ¸ÚÕªÂP çÅP#6§~ÛN^íâr²ñaSCs;òs¿²ôS‹ l¢p=ëîyÙbn—í`P܈Èÿ1]“)¦|Á/}5ʪXÿA‘\N-:‹éw8çñëØ˜n²S1æ/¸=“{}u›rvØ‚ ihÓ¶“Õë»sT «_ÞýÛR9y2Ul³›žÓ[¶úÃÉJáªÂˆ^J³tý£¶ {`öÁR† ãKñ&¯øšL™SéHÏÉl“T)¡O%å"†‡=Ù©Á_=]Ví]fn-Š¿(k.¨´ôvÜ ¥;aõx!z4@'TlP³z-¢ Pf׬ÊH‚Q‘u?o.W ™ä÷cÕÒÁ+ “{?°Ka†„åôaã馨"Ü—ü[-1µžˆ”ç=уØåµHBÒ‹ï`Å哘…> _¤3úLýj}ž²{ùàmU6Gbžù¬r sŸEwMÈ õ|6’š=Ö€¹ÈLMÂ\éAÈç{)Ÿ•TZ½TšG±÷fþà^&²7㚫ɢÚÖÄyf7×ÛÛ–ôÏöXL¾=>Am!Κ^«û_Ä4Ÿå"t&'tż%JGÊ›u«ìÍh P;Jˆi«MÝDLaÿ€Ç9óœ1&¥Bú˜EÒ¤3Ô¿.ø‘Ü«ÞÖM†k~ƒg‹Æ›ßÃE¥‚?`@Ç$‡ÇäÐV¬w"ÿmz•.¸z^(kÌ x¯^#ò²§]P¤ukDnªJá8/Ú1Ò”4Iº»W¿!~Q»š¤×1oŽÙµ* Ù¬p›´à?=/CÊ>kLwD#ª§M–va*·Í¼ävÿ C¾Kt÷«.ä‘ kP3M•’­8$mX©Îà•=êèEBèP¯Û^æ (’¡-P ‘ܦjÒ’€¾KúlÊ仕zu-¯²Koð =©JHMU4EÐêí»m8*³þI:’bT]Yãf§µ%µJå-’[n¹HOm*•& ðuÚ;|Åj6¥Æ4ÀR£ŽDƒS_)Œ¦*VFßµ™U’2°ö![!ùFc™KbÚTµ‚œ§ˆqãÅø-ð+Ñ¥ž\þóõDQò …‡œd€èó# ½()È‹1*ù³2T|½º(¾v*œö‰xůFýsŠ“v:í¢2äà‘´p×Laã馨"Übb!—ÞF5f¬QSÜiVé£MŸx}ÖÉÍ¥:»L‡“ç6)–Â{Æs° «}Ë’ ùÖ ú\9›ƒèª2!Š[u•Ì´T_ÐJU—™™ P¬†!zNJ…Ž×§·½51!WÝ?Ý/´¨{Šm­Ó»ºàßv`šÏu2(§%lÞ˃یÆÈ%E¿¤,ÿ&™ T±›;“|o*+^ì ï´Ý5ždTTÒ9MÎÄDVa¶rT\ÉÊïY¿~sB7¹¹lsÁù>rÀõ€¡ ²´3Ž!F<´ƒ“G(g­­]â’õýàÅØCÇJø¿‘y@Ó˜¯*ñ,D_ïU²&"Ѩš~!RƺgŽiÚ~IèSx©ÁiØiѤÏ3Ø)àMõVæiØüœ&|K¹è¹«RBbÚ!~†ÞÔjZ&'Ñ¥ð`ÍA@Fî]VÕ{ÉOÖC\¡lï|† ûííH“1i¯ÇÌâfÙk\“ â èiDOª,¶ùÊ«M'æ±;êæË·NQjnVšó‹Ìû›>ü0 \9ÿA ƒþœ)v2¥­JÚœ Ž¢ÕòÚqkx¯½¢‰w¶Ïv‹ëëÖèyx`k4#š(°ÉÆô–CÑÖŒZ«¡I†3=Ÿõ è kÎ\á¡2÷ÄH½Þì=I?ÚóoaBÏÍå\r’MVL|A³X9ºUG BqžŒ{IŽ,BnS0§Ë&‰@}»C*Ö*ÖÀK[n(ì |˜em—j¶—eÑÅe4X°ÁcÎkc™û±ýZj'f3zÑë„<;dƶHöP§ÎDôzüÏ Ì oV•£5ÌÁDâ]3ò*îZŠ€¤EQ‰_]IHµ°kWQKâ1ÿ (7…ÕÝÖX³A©l¡â‹MÌ×Ú*‚yñ<ñv^Ãë ¥êÙ$MAz—5á·ZÜ“#·'^WVn²Y}/ðL5ÑgE«[TL+c2`Ó¿ߟH—ç¾óóßÀÂë÷—‹§Ç+uÑ9é/ÉÙùw˜˜D1oý¼2¶¶‹$æþÕ™ù¨Z )ã̉¿î(1c ãÆ]õ¬‘*±”Z#fUäƒì2ô8NŽHŽÈZ#ù-›PrúEêìº1x@ssìMØUFš?kS0{4Âd§~Õ%ä솅GãƒF9§Rå¯û´¡QvÆ#9(3à'U¶hª.D.8å(\ ,’Sñ’$ÑWp<›Nªáf,Á&x¥Sý›³ÂsŠıÜýÊÃ+L´ƒQãDe¬ÿ%]Îi[O”mŠ• &t’E#}™ ÑJh¥ÕfÅ0qõ°E¹~ã.zRXt¯Å ²rèuC”L/±€¥o W™–×C¨LsEª‚vk&í$8Ï@Kßv¶\ HP²L+ºáìXË: ±ÅÃt=÷u]‡öòµRÑE¡ ´&oµ<÷zâRSœÿIú9½çWB*B…~Ú÷0iD• lVù^ó?¼Sc8ÆïLdÑ3qŸ§Í½Èû>nÏgy-¹‘Žßkàìþ XÏ€H¿M2¤¤3í‚t˜þÐÂãžImºå!=´ªT˜ƒÀMÔ[hî+c•ŒíE0GŸÕøùF*L³ŠÚÃgãn#™™U’Z²Á{)Ø›gVVB¬ª›9WL»FGB«šÝRªèÊ¿0æDÛÔOg*«àdé¹jœðµ\=6‡ü'¹“ŒÄ>.šiÊþñ΃]ØÿO åV§J‚£O9K*|Eô׿Yí^fáCîÉy©ÝÂ:rÁQ3{ Qì?]2îb,•Nlʪ‡æQ¼b`iÇ:¤i£Æñ:qIÓÊŽb;»àULd^´Díþ £¨ÒB’6i~„êJιªq®Œ-©÷$}½¢·§vh·´R 0ªJë·ËáïƒúÁ桞‘6_ÅH?ÅÈðDµ~ë;UxœE —×ÉšŸRxÝš4½ñøùf™çi‹~óh3¹ÝUõu+ÞÌlj-VÃ>{Ù±—éÔÕaV~·9T¾mvZᎅÏ,ú¹Çö@Ño>¯/$èŸ!Ø ZŽ8*޽ï¥5‘êñ!ˆ\¥šsž5®J‚N•AãÑn \ÞwJIhþ~E9¢cM”3\\ÖÉ>ð…áòvZQ”Ëa=ã9ØU>åÉïéy·&h3Wè3ó!þ$B²#h%VÌx¨lA¶èøÛ;²Ì¯žnCºmeÏá>xI&õ·LÑmr:è*[›§wuÁÉì‹4«:z~\ômüUi>ô¹ôŽU ©\hø—0âŠ×»;í÷M“vO¦±V\…'ÝÒê¹Fd¨¹“•Þ²~üæ„osvÐ'ǃ¯Aeòsc¥S‹Oí‰Û#8ÜlïÎî«ì¶Ñ5³£å?@Z‘y@Ó˜¯*ñ,DIþGq?ýY>þüžg>Ž0`2JPóä œÚמ(…}d´R*øœ­•Àq§¾Ld&Öe82\¥•²¬±h¢@±WñSF š®èøq¥^´M ´z6^õá»FZX ¯g({sZ¥Å úЃO€^£<[÷•#õŽÇ|²ä”¤î\IãÁ…«iÚÁal9ÆJ²ZMK~nC™›D‚VS 9מU Žëè× Ø´h®žÂ^9/w&± ©@»x-§‡ÅõõësVàeR­uOóí@ccÞ}˜–°>µsz3~ýºÜ^fÔÿA7ÖHÿr‘AoϡFŸ¥´ÿJÏÉ4Ïä+ß<ú™s‚÷Ž’¢<§ᔞihX^õ“ígX;1)xOi¡áë|ÖpDâó·ù2Ã).Ê£ŠÊh±a‚Æ.­ÐFËïÈKõCE9LúþÆÿyL‡[÷‚îüò{U¾ïÔ†õŠ’4ïñÓi’çl/mįŸÄUçt&TïNÍ•îg”°}Ä Ñtà¿#Ÿ“(7…Ѭ9²PÒˆ²…×qsiˆ}ÝS«“WžŠü—Rèj7°æY™$‰¨/RìŒ7—\ `ð Ý9éhîÿ¹{ WGÒSÍ ó©c2`co¾Úßžˆßž‡Gá €Ì`y Ö­ûòŸ.2oÊ^È„…1x/#¨8ï3³_”[d¶µÕ¦Ÿd˜óq÷9Ø!ßfâ4¬[Ò¡ÂH%z¤PC“Q½! H‹RŠOIï…ÿdÎ<cÕ×P”ʱàöøÎàˆªA7°¨#Tï@Z%‰IjÝÕ±ˆçZ©{»®åÄO ½Žâ_Mw#ñè¨?é- Æÿ|yÏêœÞôoø÷¯"qýþÊŽ¬-Iwvjý†i†!Sæ\f™œº÷#Wÿ Od*°‹3î ùK­(¼ìºïQ‘ßÓèøPz5ð(1Á+±êíE]ö+ó˜[íóuèÎŽ»ø¿ªmJ½ï¨·N|pâSofi’<ÊG•í ËŒ¤â Û…‰[¹óU¼ªçŠExÝ–Yç©«D¼ohX«–‹¢Þ…Ñž½"5¨½qðΛË!q¼'QåëõÕ‡ç¼tŽc{PŠ:–!9©ðÈ%À_.‘e—Ä"<ð©³nÆ2'•讨‚̈–Ñö·÷,~Ûv§—çÔÞÙ~¨MI¬œ|ïÆåš–»¶aÓŽM¸ëâ÷EIBÕîÇ£Ï[Fç ž–³ZgtòØ!‰MÌzh«U¿ÌÐÁ Óýw3–Ä6í7D»‰Ó]0ÊUØØúf{ëÁyÌ%^à8B¿xo%5mdÔÖ@DÚ.‚Q½¸HÆaËÚF±KYsJ}o7U¢ïû§¾™jg-C-Á\ßNzG2R\‡qÀ3eXؾ2Ý<Þse|xŠ;ü¥ p©þ’Сx¥ß”€ør©Æ#‘˜-Yñ‹¬&ÕÔ¨€’½øi¢/`N îymò>ÜëqN;íHÒÓ OýŒjèLß9’#†½pRzüV–,/‹b­D¨®³u»#*»5iî¡JâWªYÒÄLSòb*Œ7ž‘=:œO ü075€ø2üÐŽ5Íäx³ë |¸eö½‹- ,»¤/Ÿæ’Íר[¿¸b„–á©Ø‘ù™ýåˆv‹BƒV¬Éø÷¡l’ù:š°ý"o1¸ ߟ§=ùú¤OÏÓ¤í:ÜË×Sö‹ˆ*PðÀÕ¾2Ñô)ÂD.´HÚÆ›|¡Íuovˆ1ôý÷ìY'ZÅ\¾èMCÆ…ø5´u`žâZM ð¢õŸ HóaŸäö.Œ KPÛ`è‰ÝícÀDþºüÐ)°Ø­ºÈ:.:k0áAÄVH…¬‘ŒdÌý\ÄÏÊq»þ=R‚ú÷/ðPÉl|à )H‡÷ÛFH’¥ª{¸R?–®ú(‘'†þØMOŸª»'w$먾šÐï˜÷ÅaåÐ  Ò»ólh´p|dzc˜zÁÅfw¥Ôºq­œvA˜R[aXÎfÙUš´—W†ÿB\’gAÙ"ˆ*}×1ÈvH…³öá7»IÕtlª^)?†ŒºjC-lL鯴¶‰b±ÑÞBª¢´„Ÿ¨°eSÄWO<7<‡EÔB’<‹ÑÔûˆi'Z°QÎF||ÅhRU¦cÉ”&vüön¦0×!\¥¢ˆ% Ú%ƒæíÝiàŠíõÌr}'¾­Lfp/6I¾dj”ù&½¾«øjeÎJîþºiuY*…øå†È?›F¢è!jmXÂ2´-ÿO´iOÛÛˆ0œ1¢§îñÍeÊiRi&gpa†ãp,`7Âð–Ø¢ÏÌô¼)CnÍâÐu¢š³4ZÀe¿5Ñ#OÞó‚(å6®±û«t\ô•øË#ôS¶ ¢&òE¿7Œ1+HÔŒ>kʪ‰b°î–¤Œ‰puR•iu ±î#>-6šºS¶J‚©£¾iU x“‡aÏÌÅíkŒÈuÃCmÌ¡IYÌţÚ=éûaoááJg;ÿ@βh;hMh&ŽšD‰U4¹X&±Ùæ1nÂ}Z¯ÁUÇTØüsê¤NîÈcþ÷Ö¿­En ü/]™G"å/Á¿t°%; |S¢Ñ&׋H_GâÃc‚T™³}]“ûþÒ©çWäY0Õgç¡n,KÒÝ–]"GKˆ [gGàpé†jZ¨™PÐ?G “¤;e¢_øÿ@³úüC’/óôÆú8Ègn(EííØ]i/©ùÿ\•¢ÉðÑÉ•`t£¡*½µ¢æ´|ºlÿOØ5®ófÕÀFë$×ß„õ}ÇñEûA¸2ÓßÞpÙ¬  "£Õ¢õ Ì銛^‹ÎÚËÜeÛË+E8X7›Z_ðFÔÔÀ¨uåŠ5ÌVÓ”Žî0}Œõ©÷Ýû0¢9½3Âãr.ª­½ù<‰@CÍßãl•^ ÄÈDÍrŠ×ïÇT[j’;â{Ö¨zÝ!íÀOÒ'AZ«Œ\Fü¯ì—±„t›v3¢}7œwVLY³NOVжìî}GO–O&ƒO¾«‚À–Oög ’Í67p ôĬg˯¹t|÷þ˜u䦌íÙ%ñ*µ¢¾ÈóDú³¸3h(?¾f¿.¸/šæÌ²ÁzEŒ‡^½RX ƒÒ}O —R£­#É”ˆD)š§Rj›Xî6À Ð8t³Ç 1©&“+$àÐÝ ú$wpšhŠz,¹sÔ8Ðû,Îz”<}Ü?fe¦¾°Àœc‘O¹lüÐé{Ñ]C‡5J{±`|H‡½¸R¾¼¶ÕÉÿ:èš QW#ÊNÃö™äÑy:xÛ\îÚÀ°pQŒ½¾[Nbú¤}iôSKê)¾ ˆšY󱂨püËRwïòiÖz56«HûZt׫®F¤é4>àä†QH"݆YË%<à۽ǒ)3 ëÏ@‘Fš^H‡‰ /yUæ1E:.¡vÍ;÷¯>xßœÑ ŸCùP2Ÿ80ïléô§ŒËÐs }|b— ˜Q¿tšk÷•ÝUZkQ t|±dHF íôøÇîÈî·º_9ž—F!Çé%œŠ·ÞÖ›®‹«Aˆ<±¨t>s—¨ð¬Ëªnc…LNÕÈ3¬Âd&_ È”ûÓÝîÛÝÛ«¯-R¯Ö5³°˜^Ãì_¥FCpi¿¼ƒáÐ}/¾GªKK1è p1¶¾ÍÛŠH>ÊiÀ :bÂ@î~ÜŒ0{åI´ò4'ÕzpŽDºüÚâÌÀ ‘É0¿¶’§fJ;f%Z=Êœ>6áÌa°–¹¤Ûrs+lêÊþØÃåû×1膌ql¦Óe@2™ ×̘Œ=,ìI+ž½óþï=ÊeR÷EÒ²-5Úç‰(t{&5WÌËÊSPyt2LPú+À‹C81å,“¶ú0í½»!ï¢tùBü1ÆÆ»þªÜ‘OüøCÙ_¼¿nËáÉì ´S+NôàœfgJ¦/á!â±ò€jïÞ>¦LÀ¸K‚:YWÊ-EçÊq bîl¾h”=L8ãY1¬ÓGûÛ ü…ŒX]¹ÿ ìÃX—‡­²a~JÏ?›Îm0šmÎ=¿‰Í¡}¦óõ'9â0Ø'»û]#:áㄦÎbqÄ}G¥ðÛXë†(Y-ŒÚ~½˜IôèÝFÆe×›Íz„4té°€ó¶ýô9cpà4 ×ä4|Þñ©_m³Œß]e¤„sÂW T™:æ¬6~( ĸ“°+1µ2?mg„Ša©Ì2j ߨ#5ñæQ‡ã`ò¢^-8°0`ˆŠõ ü'Õ ›U­#.e§p¨ö'¾‘œì¡_¹ÈN湈’´^¢ðÐ¥—ÃM°LqDfR§ûvÁÛÙÁ=à[iªgª"Ú^öVãħ/é]¥p®'¤L)¯õñój§Z; ÀFgL þWdÚsG›†ÀÑ’ËK>väÜŸCº}·Oz %ñ Ù³ƒ†ÝD·Ëu*¬ùýä®wSþŽT2è.wi‘²™î5ñu`m/¼U¹ºaÕ(‰Þ.ßڨȉLßLçØuE ʺÔàSt¡åõTzÂþËòiß@ ™ºì@Ñ´µ¡ñZ²)Š Jñ9”k~""rFÁ«ÝŸ+žÈ ÏR:N\uPÊöYH¹Ñƒ­Ã]11Ù¾Œbç»v Ô¸„»{ÅôjÑQi—m·z5­Å¨,Ž!ÉU,õŸ*îÝVëoÚ†‰ðE+†õ-€6iÝ©Qw?S€{™¿øo"áA´YZçÞ&htLï\ʃ¬‚¨Žêߎéò eÛøJRDMSý<—ôb xè8±[À¾ïîÕi±Ò—üo?»BÔŒ¢`¥ \êwxO—ES¥¥tFá1[ýNÝï‰+%B°£•B,-±iŠõß?`‘‘;DM.#È}\I96ƒ­þŒè̬™{ol§×jŒX¶µÀyo^Í®î˜hãIO~ë$ÕZ­³ý­d†>®/¯¦²VU9KÐ4]œìL K¾ÇA¼äPO.Ч± .†4z4Q‚v¹ßzÃVÑùÓa_i䥚Ñ2A}Ä5×3N¾Exe–‚©§ \Èu^Ÿ^Õ/8¾^×)ï77âà'QvZçg« šAÓ”5ù©tÝnåêמ5?¸ŽÍg©v©¢ \U"¥’Z»&>âOxfËý…͆C5øM£=˜R=GI-C™Þ7KàÃJÝÜà}i‚’A õž{“f½ÞY=j-ão-’“%$Zu@µ¤ ‡a_U‡ŠŽ÷rFÔNŸ8%/óB‘ûùp=úêÄ~î²þöׄ¢´új„ã LÐ?yR™ˆ¾rt¸IÚ˜–Â]Zöñ‚ò!vdchõ<^ÁžL²ˆÕ’σÇVÀ¾ôaŧ®Dɇ³7ÄL³ ŽœQlj_U)wÐm!R?àõ*‡vò%C>Äßì]#PIü¾Ýu‘3ùcèÔj-¾Sh}C‹lüDIègªƒÍƒÚ³7ƒ¬x,¿m¾„4ˆ»â éƒîÆäMûhY²'óÛöƒªˆÒ$BñäL®HÐ>î4 ¥GbÙ°mËÀ9‘…Œ˜t; ó1Âu .£~úÍlpÊú¢œDãj {›f§WP!ƒ½êW‘ÿ9ÆBUîu¯8}~YùÒ0rkÐ>*ÁOIZ»ÿ-Vv?ÒÇ”U™~qÉ—OÝDñþ·!iÛ#ÍQ¹WúÁ©'<=ù.FFzEÎ`óÙGžã•×®6ÖÍ}˜-ç‚y·æÄ’& †ŠÛ¦bCÜÜñW‹ޝÃ..Ì=ZÿM_³CÂÇGZq‘Y(PQ¥z0sâSÕúØz’|p»ç™Û‡+dèˆnñCÙ²ÝdÜò 9íH×{™3Þ)-Ç¡<³¦ã@-q¶Õ­ËÿJ­çñ|1îäŽåÞÂÙŸåðÊGÍ9–˜ XÕþ޶ðp«PÔÜzzpî“aÔÆM€’wßó¦è~ V lüi~BÈÄãE+#‹t!bÈn)me7¦®+Ñ~£ qY!½Æ‚Eö¹sáè PÅt‹*NrKFRë¶[µÙWY ø“,NrX&4[„kÅGhA78‚W)YTžjP—yÖa=ÞÛŒw>ª%öÌïŒ6ž9«Ø·9ߟ¬-ùú­OÏÓìðœÉôzìÒ S yzNˆ gÒ6¡&ÞulHò˜…1fúh„7ÕeR@x;²h¨üSØ›h¸ìÄ*ÐqW£=UšÊd+l#ø865:Ê…m”—Œö‘—%cŽXÒ8û+´}h`D.ÑëãÅhè#üƒ€€Ý¤mT$O›ýöPúvZgH”*#†°ø@UM¶T†¢h¬q£^÷'–Îç~Ý)co†Â2þR…f·ÖúÎñ©…òŠða.xŽß=e•0Ämnpfø4?±óY ¼ÌôÕ”[áñ ‹F~Œ¥æz,ºíi÷î¼»ˆ&7°†žVy²naUö M±|>¯¼'ýÊwpuÊ€l›Ú[‚o߆†}n&ÓS3â£$ºM«©IúêùsŽHµgEV/á•(*û.âÚXÝtˆyæ´˜ca#W<°¶~uüú ìÀìqg« 5\ÍP¾0Þ¡Àä$K¯Ê°ØldI?|þß/:Я4gÁÙIaŒÎÅ` œðÖÅôÞ8‰¶çþ;2œE¤DŸ&ãë   ú?õÜ2ùë"¾ÑÐ¥‹'"ÑDö¡Å´ÙB°ý4ªa_H&âKJ ÎI/ž—w6¢²œÕÍA4qǸž!÷é'^j/;*Åj§›;šÄDÉýAñΩtÉÞm_¤ì^uÞH0a'¤”2ç`ù®Ña,Éqù ièâi•w ÛðÿÌÜÿfŸQاN·@l¡›Ål÷Cí9Ô¥‚©³{r’¾Oójk‘c`)ôƉYcLì)· ÖŸ#5—Ú}ÀüP@” ƒâ2÷“Ä$ˆ¹C~«žÎK~?•ïaE„c  ‹º¨Üº*2´Ð‡hÜÇà]\få²;·'o¡˜»XQ1šÀª÷)MG&s窌 ÒÜÑíË·€®lh.bpë´WFÄT(MsÞT.Ó­ÚõÍ\Š6ðž‚ùLJ±œ3û*ã†?ÞlüaCK_Ä‹–΃„ÿ 1gÜ—6"<ÏOC@{kÖ¿ëWøT½k+M¯G DVZÜ:ÿG}-SÇ_Y,¦çXd•!½ióõ–m䨨_8¡%Ó=Œ€ ù8ŽÔô³ŒLŒ”éžt[¶©>·ŸvõzõöNf»]¼i)|z9SüíE±¢÷fdÎYÉPÃð©-ïO Ÿ¡Ðšã‡ÎòøRñˆEÃ…±€ß©³èÎÅ3,{æ@^0à°eÙÆãö¬› SÃüJ4c>’—%Ùì%’„a´è“ýK} ßÖ…pofšš/`P¥«U`Jn3¶üìˆ=vb3€uó g­Ÿxs¤8ëRç®Ò͹ʖO%_éõÊ~ ¿ìå䇬Rß¼G¿–£sƕт¢ßËŠþ ñuò¢*R,E'¢a¥õÞÕ,¾nÐaÓ5™ö´4 Ku“@™™3Í6¦K8V–눵O©l<_èfa»>ßÍ%#Q=WLD¥Ù_5"…3~ÅÍ·ÀÞƒð½Æ"é¾gd „ÛÂ&ÝoI†¡êv‚«T«vúD›ZË#}AŽ1_¾³Ë`YË@xBœÂœ¸Þ?ŒÄHšnŽÉÕÛÚâ«Üªëb Œ0zâƒO‰iŒÐ?G ç*ÄîÍBJã‰üîÕÀð[±:G"ìÂ\™Ô„%.Zõ³­%ìÏMY ±²>™(>52ƒÊ8 òíà‚„MÇÓˆQ`˜:„íã£<oõ0c÷–º-cÝÂÊ‹Ã-¡¶Ñ‚XYA­PÌYõÏß÷^|²JFi 6i'…AÃÒ¬µ´ © tb4z9ÂD3w ÏðFÔÔÀ¨uåŠ5ÌVÓ”Žî0}ŒÂ={ò–‹°®+ÒÞÛøð“¼ß Áª,¹9ù€-?4–®o·yÅ)V¬pÓ‚ÃJÿ0î[Ø›®ðgï‚ÿýcüE)>d²u(ýÙ.ÝÍ)šc×,°.cïRJå+¨ˆ×´úµËO-÷(Êf¶2ù` Wœªy§^N/œ°fùc…?¦ÙïA´¯†â¦#¯òÞ”¦ÜNä?YÁý~Òqà7ê‡n¬ øëFÓ4t´O†êw*¡Ëµ¯æ‹§ôLâ…3©JÜ4…S ARRgø[‘sRNÕ\ûB‚¹"] 0ÃÀ¾ÒЦì–S£­ÙÊJJltW?íñSòb:@Æþkâc3nL“C¥îý UD¶"{±`|H‡½¸R¾¼¶ÕÉÿ:ëQW#ÊNÄ,†# )jãE°„¿{„0Uo¾eÆ|âqr±•·ÏÊþ¢àvÍÂS™×jÁEºÄƒ°hJDe–æë¦7ÝΧ) ˆ@HÓ‘ˆ<¯úÀûmê>VIlÈ^"VbÛÉxøÝs4”^%'Ýu.ÉD)ê2‰aDC!~Ž|ö¯3X,&p‚H³~b0ï ð\Šy‰ mV±t ˆENjaFýÒi¯ÞWuUi­FÑòÅ‘!.w·ÐOã»#ºÞé|æ0A=ˆqúIÏTRùÒ$#&ãçõ‡—ûÌÙ[;rZp E,_éþPÝ]†3Ó4üú2eâ­ 4˽˜D$óÛKÙâ¥(´ùZ[¿Ÿ{£l‚Ê H4Íó(ר°ÏuD7è¬é? =”h/Ÿ š#xþ󜥘`Îl_1Œ‰¿“ÁkÐ1ø+pkVì×y¯Dˆ°ÔJžHmoï”Avý…\’?HýG6»º`a c%>Aû¬“Uj·÷}’ízÊC¸ fB]3¨ .΃v¥‰µ1Ùá~Cð»}n1n üjëý ÓÚt†ê<”õªú΋LÐÞ¹’]| S9sx‡dÕo ø¬&vL›ÕÊéˆhP›ŸÔ—©f,ì‚A2Exa¤Rœl±ÂìŸy”‚üóÝ{@äŽ=w”vë8môFuàÞÔ65Ô»TÇÑP.*‘RÉ-?Ý“q'¼3e¤ÂæÃ!šü&¤žÌ)£¤–¡Ìï¥ða¥nîp>ƒ4ÁI ÐzÒ²ø01z+++Ä@¡óJæÅ GdÝÖÕýïv‡÷¢ANÿtá'·qW&.ñyS1ß@£0ùc¹ä¶„BÒ‘ûÆ…ŒÌãMÂv(ª¢¸·Aàœg( †¿O05¶4Ù^¡¤Þyá— ÓxÁ#¹ëQË´Š›¾‚Ç=þA>uijàj_ûva8<õÈ™"Pöfø‰–a‘Â“Š Xáñ+ê¥.ú ¤*Gü¥PîÞCD¨gØ›ý‹¤©~iýÊ÷äÍvTÏIÛÐÕ³Ãå:ö ð©œe¹ó?–àqå9püЈ¤Îg".#™6ÿJÇ —l¬¢%¶¡É ¯¤w²OXŽ›ì‰}|Jjå¸=_÷ÀI²p€L~}†ƒù˜á:…—Q¿}f¶8e}QN"qµ½Í³S«¨ÁÞõ+È€Œÿ\ã!*ˆw:ל>¿,üé95‡h`§¤­]ÿE™S±þ–<ž­Rü¹ú0C<@/\.µ •&Íúll8Œ9Gvy¤^y²u-«F¹öqP¼S·ª°ñï­lÔxmç‚y·æÄ’& †ŠÛ¦bCÜÜñW‹ŒbÝ’Ê aš¶ì+CÇz›`i³øñ\i³œ¶Ýf‡þü2˜|J‰ «ÈÔ¾Êùö?sŠÙ:"A¼Pöl·Y7<‚Î@;R5ÞæcÌ÷ŠFËEÄÄ1èЉʠ4× E®¶´9m*´²ñƒâÒiž)¡ce&‰ÎsDГÙ@‚kJµÇ÷¸¦4í jÁûÕü4pš"R ä‘ÆDŒülvtÝйm¡êÁ­Ÿ‘í1 ]œl³m°åÚ)É'3sל°Q…8¬ÞãA"û\¹ñþj¡ŠéTœä–Œ¥×l·¦- ø“,NrX&4[„kÅGhA78‚W)YTžjP—yÖa=ÞÛŒwÝM‰Åñ†Ô¹R»£Ìçߟ¬ùúoOÏÓŒðœÉôzìÒ S yzNˆ gÒ6¡&ÞulHò˜…1fúh„7ÕeR@x;²h¨üSØ›h¸ìÄ*ÐqW£?³+5F²NmCf©qY­±xúÀ×dq˜²gªì,—¡óš—’½ŒÄâN¤uèý‘2¼F?()ÆýÂì^ƒŠïÂe{+åŽcçt{¢€êQr‰­­¡ë˜—?€Mä~u.±6 Î¥ âÞÆ«IiWµ¶¿ÔÈÄèÕÝ9R—„ðsžÑÓo€YlEŠbð‹iµm;dýŸêdz¢AÍ·í$×&nÖRìù¤ó›ÈØ]q-|°/ÇCo! ÏU–w «õ qø.Ï\›½ÁC:õо‚ã=f,³—™¶»3Òè-§Æ=ŸÛPÍ(áÄ<ÿ{¬ÅD’ƒ>#Õ_nèv}ëQýÈ ì­cìÀìqgžú¶3úÔ_ºv¼lÓ$G¾Œvìħ^v”8ÆÁJÅdÒOå'§±ïÒâ¹2“ò¾ó7ÀV3æœÊA"€ Ç÷déVÊ»™ä^©œTÍ­½[™y„W€*E<"‚±¸¯wÈ©-85ä'‚„±paý¼ç™e?BB;‰Ô¡!Ü<½]ÿJö¥½:]}¯3/Cr¨“Éo?Ûes Em£‰Ç,ƒMìæÐõŠjàd¯u»×L¨"›ºñÛöÖªj¼µ®RtÞØÔU¬ßÙVÜúŽÁeÞiå¦\È‹¼ÄÚ' oøµosÁ±¹€ƒ—mƒ¹Å”¦8–m‹‡ãÖ‰Ùvíô쾇bý¡ø`ˆJ&l0¯"2oû<= û¾DÖ=N1=XU>ôYžù¸¹uq›–ÈìÜt¾„~bíaDÆk«Ü¥4E@™Ïžª2ƒKsG·-Ádƒ½Ù²Nápæ¶ö U¯òŠEY >]ÞZ3ô×p TŠÀ.¨šc†¾ž±–æ)Ù¢t꟎ÿ<ÙøÂ†–¿‰1Ýÿ:¾½!úì¿Ò’LgHµQŒ$鼊“!ãÊÆe{±#¨ß¶à·Ã)Žo¦t7\x7¤N™šÏøûŒ+³.I¨9hKÜsó1ÈíAŸK8ÄÈÉNœ[çE¾éûkj“ëy÷oW¡__dæa{±µÜ![Æ’‘×Ç£•?ÎÔ[/qè4áÈ^)6\wbÕë"å¢ì­h3d¶a”¬f~O*^"/I]¶ê€†K"›VW>Âë0Œ8(Eüá ãØƒ:r:±±›NNDÐ ]ÊB/ÆjQHD ξ}¹2ŸT‹TAŠ"à¼Î+†SUc–;¤?¨8‡q¬JЂ®q¯¶º©¾·­®ø€Ë³.ìÚ9RwÇ͇šo]uk¸opå䇬Rß¼G¿–£sƕт¢ßËŠþ ñuò¢*R,E'¢a¥õÞÕ,¾nÐaÓ5™ö´4 EgBBÁ˜Ôµi­.ßí›î¼ä ßšèù4Qɰ‰"Rr#Q=WLD¥õ{aHB˜«·1þ:ðw Àü.¸¤î ™¶®À€ e±õAÆÛç*h½gßEŽp…fz4ÅÜÄt²µ>^#?BJì¿ zè¼}±JX:ÌÙ3éÕ‘C¸ó¾1‘ÇÁˆ¦ÔÁ®W!q89ø–˜À ôp¾r¬NìÑ”)Ô®8ŸÀîí\å±K¤r.Ì!ÉHBRá¯[:Ò^ÌñäÕ›#é’ƒàq¶Ík†®g¹…?‚ù±‹“¨ç»~ØÓ*¹ûâ¾ëÃ/–IHÍ$Í$à0¢!È8zU–¶u!.ŒFG8H†nâcYøpŸÃ Í`Ž\ß·¬¦`›nü…ÚªÄɦÕ7§-‹;|»Ì¬øD¶®t£âg±Ì«ÒŸ#d\=nk8Ë\n`†+uív|ª|ØYCÌá€]Š_¸Ý†M‘z7K…$‘Ãèož¦ÌÙã™·fNÃ)mHIYìî±7<Ž\÷µÅñNÂ9oÓ¸ã‰Ã‰*4= 4çÿdÈg÷·@¬/¯C#ù(ƒØ¦¢ÑÔîÿ”!Øw[Ê‹v`®Ï7|K›‡½#÷–ðP(ÝÛì#Íâ¬àmp´%Xį>«MŠgïú¶ Éòý³5ÆWc1ÙRÝßrš:H ¦¨.N©Žq«Ý‹ãô áà}xª!­Âbm¹Ùp ñ_- æž´áî·…j<É!k¼{þ^OùÜ´Ü"RW–]ò‹ME-Ý[þÞŒi –Ž[ö¾ ¹¹‰ÙjÞ6&4Ô{†ŸÎ“Áu•ð¼Bq ÿ"~W·¹àj׉ñÝ®!óô"åñÐ/ëF²ä€ /‰úÁ—ãUQ9?h“ìòY¹Ñõ÷y{ù?q­"žbC[U¬]bSš˜Q¿~­ÎN›¨¤˜åœŽEzŠ*¸šê tãVŒqÒV·—ΈJü›³hÞ8Zmäpf)GB£¥¦£î-’nÕ¹ãdm¾oÉO¬÷ŒgÂú3aÜ;«¢€Ùxê[s–˜CØ%›g`µà® Ç>"&´=iCl‹P©é{å!£ú—S-º’@z¯/›»$édl"-x¨y Ãr%>ô÷{¶÷vêëÁ T«õŒ×–"®w?ŽÞÛÿTýw\iœ¤vx§Ö¬vlh4?ù©FŽM±ÿ]i¢¶Ãjÿ-éH0Á±M&?ãe@™Ûäü‰ óÛ¡ƒîCÄÎ ´  ì¸¥©{±T˜™CØ™N¡ÍØãºõv•0ðöЖZwËSÓ€Vaá'&f}ÈòC”«Ù؃ùp÷º6È,¡ÄƒLß2z‹ ÷Pãǩʉ½/UÓÚž#>q}Ó­oAÉ=œbL E~©àÃn!¿3¯7¢5A’(¦Kz€›û7ÀÈP¨d?zpN33¥SðñXùKmW~ñð¥2lÈ+“yéd_4{»'ˆ-…3ìÖgh˜<÷­ö«=£ã¹a”T™TQÿw«=’f‰÷ÚôåÌǸ<³wI½€•.†S-pá (Ž-ì†ÜE×ÉBù-7˜*¤CjGøŒ6 îþ×Iп ø!)Ã|ÁžÆ¼’6“ë wM…¤#Ù„ŸNÔj 2ús‰3ë5BÒHAÔiÕÁ«¡–kÌ6'&hëÉt©Æ¾Ý°DãööT?*À–ÚŸœzî°4enAû¬“Uj¶ú’R6幄Š_ÎîY—LÀꋳžôر7€ìÉa e~¶;@™îH±+¦ zЦ¶xêi¹”+7FäÛ[ }îƒfÆñ |ÎaôP씢£a§ãˆŒ’`ÀDa±Ê9”’š¨Qé*æà·ŒØMÏK¾‚÷*–¾_‘®ˆŸÜGf³Ô»TÇÑP.*‘RÉ-?Ý“q'¼3b´›Ú›pcÎa"!V)áF5FqÇý¿¨Lö†¡œà}i‚’A õ¥eð`bômMŒØO‡!È­´MG‘É2êÍCÛºò¦5ð…™æúýɨ´`×<›ÍÍv­jÐíRíDajtPþŒ÷+[BfxhÖãä¹Mxgå?hí•cÙqÍ1ÇŒ0ûžµÌ»H©»à(,sßäç\K>¡5ñ·f1þmÌš‹°›±ÓÒßR”îQ€•j7 h‘Z?ÍÔcÝè„–é"!CU\vv.’«÷ö¯îhïʉ•à‡M¶¹ž”íýWT- 4?¡|ÿ K¸òrì ¥™ëËÖª!°hbºÍ$µwÐw÷€ãòBkéÝì“Ö#¦û"_D_„Äš¹nWýðlœ `Ÿa þf8N¡eÀT^­áS® G”B±¶´ˆäfg÷ïÀ—÷°Gn•Íàžz>|G¾q¼òX9d5¦²®ÁOIZ»ÿ 2§cý,y=Z¥;ù˜$‘°o´8]Z‚z¨-HÂLôz³æ¬‘vø m¸zŽ|@’G@=RéYíkf¤{Ão<Í¿6$‘0l4VÝ3æçмXìcì–Pk Õ°waZ;ÔÛL ŸÇŠá£Ã,æ ±†í~è;ÎÓ”w6±÷"Ëf¸2ú†øQjë3™±“…’™­˜ýÙBñ²Ñn±±ùTÆ€<“>¢( ç'+¸„A4Y1Ü´Eß]MPÝï@( ÁˆW dc1•†ŽðÓe2ã‘UçEÖOOL«sóÒ½`\[„±z¥c¾ÿN›¡ú?.4=X5³ò=¥ù #ò«VÛQMIqœ’s<êâS– 0§’ÖÃ&-TØÃÂ;±®–.¶/™Å1I}e‚§iJy2hìÌ-Â5⣴ Œ›œ?Á+”¬ªO5(K¼ë0žïmÆ;‰î¦Äâ€ÎøÃj\©]ÑæsߟFçÑ,~ €ñ0ÔòÜU|£b“Ô*ô’qTV÷ÊÆjH¡á,•R„¿¡æˆqмƒ­ëÞ°)³^ÚÎ7ýÄE}Ÿ.7DŒÚ£ñŒ¤údÀh'ÉX©Ä”LŸ)';]»ªµhË¢õM¬çÓ@Þ8R&,ã_°<•°û½Üᛣǫntã$ùRxìØ’ÍkÑo‡Ó”D™÷ä*üp:s ¤–>gÄÛéžßé,mŒ6ý´æyîFèHCZFžÆƒæïåk½cC]ÉT\p3`ßçGŽ|äl$ð.ƒÓhÇKÕ_Ô˜ƒš_I¯ÞV™ÒÞ‚é§® Zäaÿ?õu…n¨QV9h¯Ø{~þk…À`öQÌNÑî»°Äcg¾‰µ˜0yeƒQëÚ<¦—Ä‹d>°,{º“s Ø/F _nçI'4cà ïZCð €â]óp£^\&Íפ•4—^ ÛîS“naÖ ¹l÷©ýƒoå:»Ö{þM=›ÃÕI!„Uv,ÜüÖ‘þ²Ö¨¤*ô|aøj\„%ÑU#÷~¤ÍV10-ÕÕï’UCâøêzEÿþvè|òbÒp»Ó‡P;Á£{ â_ƒÌž‚½L`E+Œz(¯‰Â7ÈÏÊþø Nˆ2ÓèÀIa¿°¨¹²ÐŠé¼_›çu;^@Äýåâ'½Æ.…ž,œÉ[c ºî1›jvþž *“¶o*<\tØ‘ê;‡ñ?–ËÀJ™ÎÕ+Ÿ`ʱâßøq²œ¦÷.¿’GgÀ¿¤ó35×ÖhTHó]î*Þ–[Ù=y^¦O7e:ظ…I xƒ'ÿ&©Àz'ù=ˆÔþá„x{c>$4¬i4Fv!oS´ñÐ)S;yÐp·$2ý+ï!M Ñ„#œ[ýŒH—óN†=(-}îEAä8nüåã±pòŸÍLJƒªþQ«t>XÌÈñÀA_vžë¥^Ô›—^˜ˆQí»óŽÏ ˤ4!Í¿ªþ‚Iœ×¨ÁV’¾…`N©rñäY£ž }›IËû ³ NJñowˆÎBkÑ=Ô¡_‰Ì .¡¾íãø›»Ú"%÷ÌÃḂ (qMÓ©Ðô=¾D†µIGìÊu‚ƒÝw(0?³°¶‰®Ù?®¼&·¾¹Ež£'[-Ηð_½5ÂÙ›ŽÍ¾2 Æ]%™ìÖè‹ð>r‡à/½yê¶rˆ\ý ¢Pãâ_”õ¾ÕSQàxö½`G›3¦€ñHÝʺ<•É:[îR3:Ÿ``ódOèça ›´hgùvßC9Y $’ý}^Kx^G¢ÔÞÊÀ-~³tºŠ ¶üCz½`?#Sà±lwðÀ îž›¥CICÞ6‚¯Œä Ø›yòHaVydÈ«Éf3zߢÚc#…ïȇrp©€Ð8©tm pC¤—¢øû°÷ðµö7K·ŒnôU=}Û»ý¨ â<Ö[à}ÏicÚÃ<Šú›Ì~¨ `×ÙÀq‰¥-0ã}/•Œ?JAwÊ>‘!É×£ŧ|ð…Ûqëû:£ž ¿Yéq›¡3´•¯#0XüZ† 0‡–®ä›¶ö—UÇkïËÁ PÖáùf°:²œ½´&ÐWØð}mŽÏ,ŽnÿûQk!‡}b'¥¿L˜=¸µ]?»«6üé(ê'3U?ü„¯½v§üVà#uïcÎå$j´Ä ¬;'°œ—öªP¸ˆÎ\¿tÃG¹¸j„dwY„ýÑ”‹ óÚÓ»-ÍCeþ‹ÕfÐû–^á“ÿWZ/!±ÞýäÆã½ÚÍlfŠ‚2ÒƒŠpe‚ár? ŽäŠÛ9Ô>D£¶w¨ÖÈÚ6¦áíOh÷©š—\–°4¹q jáµaÂ5;o‰ø,ó0­Q®˜Üì?»[ÞEð°{[² ¡ 6*Mž\õ³u¦ú§¬jœÅj;zŸS©¢ÆW Rë/ªî°Õ¦OtՆ〄Ìê-µBÁ)?Û|óÉ” òÒÝ%ÚÌWqgáMT =! hÊ{3'ô+ÖPw×*òH fìŠP¤Î>+£’X½”#ù`‰Îeù ­S¥|cQ+Þ`?;iØ#ÏæU‰ T“#/©=i9ÖTkˆ–b\Œ{0ËØ",¿à:Þ•7çðêßøvßü;Wþ'ïçÖ‡óîvü;¿Ÿ±ü:³þ·ÿh_âàèÜøÍg $¬lM‘¡„š”®³0KÏ™-P¯õû/ îeኧ”E"æíÖ}uÂWæÈ"vürd-/Ô?>Y…È,í,P@'3QQ–‰ótÃCíè’ˆ;µú²PL‘¢²€w2nŸŒ*l0àûª¶Åtl@ %H†‚Û’;ô¢ y‰Œ'˜‘·ÿ-ã¥Ï1w9dÇá˜àž0®T‰2¯Û¡_ûAÝ¿ò`ÂPÜÄmöY¼Êç:J@*¯‰»CäL"—àF ßNÚ±º..—Ã^Œbu(m˜øõZ«ˆ{«3LïRiê³”*…éÛ 0òƒL™ö/ˆZŸ¦3¥] ¼ä¡ƒŒý\#Ê¡Wº°ÕÇÀß÷Û/úüãÈMzYö.JŸR´Œ·5 š£šÙŸ_êÙõÞÞ’©Q=ï½ÜIi?wÙ!›àn}ùïM§¹qÛ¨Æ{:‚wÙ§Ö®8Q¶†a\¯?øÿf—Nµf¬ít7¤°NFö¬Ç¡Ù´—(©}ì¿!ÁЇØÖT™]!:³øÃÃn Šºæ)n¨Ý®e:³lDS"ô!Ôਪš‡-Ý„Ôê-£³´‰æX/uC>ºÞìL?wlÌuÚÅÌÃÀTxG_v"Ä#°ØRflѽ}[RÓ7™Zm ¼ñpn9qÊn J@£ã§£<–Ë-˜¦Xë§ëÏ5=vUÛdÁÕ°Çßħ9ĘbÛ}æÎ:ë'}F–ü?T±4q‘þhê$µäUQ˜²pÓ¡ÍSmçÐ÷Fœþk ìôÝÈÀF5…lnÃ'V¥'.ïPf’“mZ®²lÄLŠ÷cÎí%=˜´âà›:M¤Œ Z]D+û­Ô„,Ròä òJeCvë"?c¡g݇rÃ` *#’È_ÁSªôÌùÈ£5×m„>ÆŽiÙ893âhhî%93f ˆ'tß<ň›6æ@$$ú€æô_x´R-zŒ«TòŒÆáÞ†{AT¢]__íR¨xÞ¦]´;7†ŸÆS¨2œôjû$ÞQDæ<ÞbÒgZgï©‹4ªD×× »Ì×¢ƒ1£NCbd˜9¹à¤‚0Ÿï.|;Cþ™G11ÕPñÒ ™²0z6/Êf& ¿N¢bZõ Žvú/ãÿ^ý§. òܹ·‹é«ä]ÿk IhÌ›r-W3—ÝzØâ^tê‹’á1¶+Y— “@UðysiÓ:.Ý,ž(«R°¼iPr))Ä¿ÜÔeŸöBÉê¯xeahëÐÓ¾ˆ†í k6úg½¢Y t·±6öËìŒtZ·8Û€°š1N‰¬–TQÎVŸGçmÙõdL´Ÿþx‘·JÒ v!Ö0 /CÔ1àã ç8œw‡z…´ü±”ñ¢5!"Yç¡ôN#ù³›‰Qa94ÜöçÉÍô‹IÜØÎ)Ùk8Æí–Ì}ÓÏ@-]ÓÖ:Y8Uè"@ÁNµ_ácš³@æÕ‘i1ãI­­¸¨s >Q/æ R:‘Œ&"CUæ—ÿl:Ð+¾9;þ`è+® cj^‘çz]æ®x+ö¼Yœßx$U#–Àã`7?Ù6Kq6ÀfHϬéI];}F’½øáL–GóNÃõtÉW£0$ÚÖ¶#¾ y€/«A¸ërÊ»‰tI"Öâÿp]ÒM¤™ØQÊÙiÌ<Äa4”WÄŸûäÇl»\Ãl3¬  .,ll îp«»Ê‹9†Š‡Åˆ¹¦ðõÉsÞQb@CJL¦íŽ{—n*þd´ÇÆuß(ä‘)µJ9pW©¾\™I-¸ßY5C S,9(43ï8²…Õ6´™ì"Oˆ¦úÞÙʲR8ÓsóÛ¸÷cÍ»ø ˆ“=vã3ÔíåaIá€u²®q…l. Ò&r¨&W„ïo¶ü[ìÞ*ƒŒ{TtL;©‹!Ä_)- ÅPƒ}ÀÕ#rÏŒÐM&+†2áçî (’敘÷Øf3P¹i@Ôóús˜³S*Ž©•CMÓÕ.K‡{â»”•¬G 2÷ƒøæ©4\-"F,Ìcw[Ý$5 å°þU.Ô¬Îæ¯yâ8ÄðJ’Vó h²íÓhÜN£ÿ?¶ }¬|’ú«¬¯M¡ó$¯¬³‚ETpHçPR¹º¾”­”X8Ò+E ¿>R–<¯oOÀ#fÍÞÙQ›»Åü^nëýÁ”½Í:dä ªÚ„-`DÖ>ìXþ¿Õ¼U䓦ÇOÀ®Ïs`S¬Y~‡ìgÝR<£Ï1¿÷Õ\YH}b%ÁŸ‚£•=¨Æ¦s ÄËÌE=ɧ†_‘¼˜"¨­–‡ìŠR4Z~åþJíDšYyÛw[w¢ã×Q®í n1D€koG^ÎÝšnŽâGt¬ö…Ϭn![V6¯…JÄ{> ëµ­ÒÐj%ÛþêCí»\¯ŽÃ(2gµMôJ‹ßã¤èã.c/ýLñ¾fÓ+‘Qî9|µš**³ÕÏæÚFÇãjÙ;BQ-n€ªë]>í4ŽŽÂ„Û´x;¶gRÅŦœ—‚X›6Žò<ÔWË[xðÒ¯C‚n(úžÄøì´×L»—^…ËM€L©¥Ö:÷ÞÉA°¯™y)ÑE={±HÙ1‡ ¶1,é rp÷h0ù6Kàæ„ê‡!d(ÝR–æÊCzGíDyÛÀi»=ë×_ÆÆCW­yGêÓ¼Ó¹ºñƒà…˜/Bz,×–z€ß(q÷C¡Ïy·Ý'r׊ ˆXgvÌ•æ €—Ù¥}2ú’‰U’Åîm×=ÎU&ˆ}¼¥>mȇ%KÝAø=¤ê– ú3^ˆ:Ãàv³]n)#™íä,ÒçŸãõº^ÙìŠeè%Ûìèj5¬ L|>Gæ<Òú]ò’ÃtÁ]@:sÜñˆ y—“þãâÆÊäb—]f½Ì¯±B‹w¾_Å·GÀ!„"7Û¤‰£šÞaˆÍ{ò¦rn‹TÛ¶Å‹ùøÓØ¥é ñŒV¯©õuiðŒ1Gµ7|Àý?Òý®5]’Óä•%CÚÄÞåϸ)w–ÞuM <ü8 Ūß-ˆ’©CàOuʇQ’ˆ³T˜È·Ú»ê‰=õòKÈYÜÅYDÆn‰S)7IÊ’75dýJ‰ÁMÚÕ"¹°æ¾ÄuçJŒ QÞ›.",ˆ-jmtä €‡¥þ±ì²/Z‹H#ïZóì>£:¶W¥wã[â‹…D&ÁÊä·h4%ÿ½'Úp¦Œ”`ªwUÙÀÃ¥&:ä$9khsôÂ-¿€Ÿv*Ræh/Ñ[cÏÎ_fƃóÎÌBá$ô « ü|C4asµÎ!êñH:Ô«¤9nêWhžs›_ãŽëòó$SïdÞ9ƒ®Ã.Ðq»OR¿Ý´.ÔCΪᰥ9j68ç|qš6èÛâÛœr‹ŒJš,@±Ë@»È}Ò~pÐ .Æ•ØöCíµiK9qé›ÞT¾ªuÁAÜ7Ï•–­uÐ÷1ÈôŸµùp­úœ²@²¹ÐisL÷t}ÿV?#Rªý—˜ef]-™‡a<%wÜ ÛJ½8ò e]Ä&N°õ˜×ÑŸÞ|Åm£ª\j Û;ÛÆ?ÜÛÓò¥5ïâ[+(ù÷ \Ò¦yêÓ·ÙÀ¯™²ºÙ¹ì®9×D¾\×u”ü§£ÏÐ;¨DÕïÇkÃc±©¿ 6Ó¦€,S”ô“ þðÄéøâŸ¶O =Yº› {V‘ååO}é¨ÈWc¡i‚W®l#zVf‹ÒS ‰I¨ë”1i^²Y 9J¼†ÉŽëi…6§‚Ó‰È ³¥sˆ_ïY?ó©e¼VCï˜ç&Ôø¼N{-›Æ<š XM_øm,.ŒÏ%FÛ%‘R!¹ã½ ¡™ÍœcÄÈÂèÛv9Ð1Lmpƒ`§=Ý¥¯Î`|¦ŸæÃ¯õÑApÔÆÚ»îŸôœ¥=Ç—Lçºp'¾ãø[¢¸9ò„^£´5¦¼ÍÊYç×Ùˆw¶/ &¸2ôù8¿—¹¢H¥¸Züû!~!ÈY¾ÎÀ’ G<¤kXt 8¿Ç\± +É'õŠÓg“~˜dÑáƒa5 ‰àdˆCz\!HàˆÃ7_ìMÚ‚ïyxˆ"¡:Âgï£be–—r4žaÅi˜^™û€OË.ð$*MsCÔ£ÿuÛæuºéû93\6îh.5Q\•ww|d­‹ñ@êY˜–d}lX·exxc5$ù-’”?—™Ù ™µ¯›ßÈ­>2ûãc½»œØerœ«I Eïvî5Ûk%.Æ?ëá9 Ì ˆr(y‰\NmC…S¸Fö*m!´ "ö¨eMÞ±Õ|šT¡€%*¢óäÜZ{i½~ÔÁãÑlýå¯9ÁQŒ®'½&‚ ¸¥»bpš9Ð W5À;ê` ÑÝÁK“ûõp'Ïü !ä`ñøL.ÉO*“)2ÿ+CòK3êHRLI†úíÇÇ,|;™¬X´màkàߘø6}ÙC4Îðs½¯ƒ.²Ã eÛSdŸ™'#¸ô²ŽºÜ7ROPJbð~âNtžvòŽYh>V©m(¦ª•@½eé¾½âoü…ø¥ú%œsáÁ·s‡«ÿ1$ R CÃL¹Jç ÔÏýîϸg§ÿ-ÆÎ˜uû¼„m«mx&[,€¾DQé°üÙîʬ,©û™â€é' ù3¯tìDp‹Xû”ìZ2ïü{‡d ©Ù.ÒÑ1w&Âó5˜–ù']¨4ݯ½\Ô§”ƒŠo#ÑCÆü@sÞH€°UaŒGÑI´Hw‚[T§DË;ÂQ ª°‰$ód/Ùäµ·ò^³Î?“ŠPDÕ0¾z-¯'õkÓƒ»¾p£¬Ò€l•²*-ôÕªc°z 9ÛÀuJS+¨xúYáu:{#;¾¢(íU)ôôŸ‚n ¥6Þ÷°" êH3`U‘•¹:‡åŸ—! FÉGŽ)ŠBúÛþV›>”PÞü“‘@ ÉäÒ´M,!F¼MöÓ|‡w˜øs6ß:aÅj9Z0nUaÕ_Í{-‹åZ;®mã Îú§!„É"o­,õd1Ì*f†§'I®ƒR&esÏ*TÎçÚFl˜²´’4*Å]ÿÂÏ”„"(69¾Šö¸Ø'Ù5Hé `ImcðÇ55Èó4,ŠÔ>z,O«ê畾V>§ å9c­ÜUf*CvÂ{ÙpV¤]bbu¡¤ »žï蕺¤f+Ë~Oul„Ÿãs–¬‰­‹©߯ÇOÇòNŽ«À2!²šÁ yÂ×ÃʯnJšëŠ R(- áŸ[ 9â ~ë䨵~ceÅïTЩ¢,ޱK‡8܇@3ŽèÁfÑþW g¾y ¯å—7]Ò-4»«”2·3ÅF·e¥ç)x‹[ŽJŽVîMrZ`)¯ïAéù¿. ‚y ÆXšÙG[%N¿=Áq¶éYÚjx¡¨K\¤Å‚‡fh±Yµö‹Õ§4œ>S]W!ÕD£pâ~zûKLOŽÈ@«Å©àG£Ž^röÙƒŒkÛd8Gh½{º¦Hú%Z<Ò‘™©+ÞÝ-»$üD±”l§)“k'0ëWˆâcœÄƒ1wø{K×`ö+=Ð<¥ «'DÃKÀ¸aë‘Wb£½†®—;±£:b`²:å @p{»V¬ìÏQÛŒ'€õXà @⚥’‹¢Êé 5Ê ,Ãåæ'$#+oÔåfÆÇ>ºû¨¬w3ÕÿB‰6®~9u€éèRû«áÛÛƒœ6ÜB'^Ôøqµz¤ô‚|”dn `"Ó…œt+ ,ˆÖNÄ*¶¦` ãñsè=ßÿM„R`mnt1W”=–v)1Å·{wˆÍ (þRÒS£%*zVÁú;Q#z.BûOâFƒ¶¨a~yÃl<,ÄòE¼@˜¦Ò»9¨;3åSi*³k±µñŦ¬×eâ•éo9ÖPù^¹WÒlÚ#VÊÿ.ÿW»ôÕ­–㳓ñ—ćB£©tÈù•“q趯5cÄ…9¨Ÿê9êèbd­¦Õ>M—)FkIïNV½j³\ºÓ_H÷@uèlYÇžgÖ<œËÂÆ2¾½¢ÉÜ#¯|¡­¶%×9²ú¤Šðóe`¢øùÊÅ <îbÀ@ñum™¥o“«Ü'ƒ¼mi"6N/‘tÇ ÑÎG¿jó‚d¯+mHx_}{ƒ;…gÈd#có‚¶’…f¤…ØÉâd äþ5a}ßí8Ñ7 T ìënèf»ô±Ø´!C"ñÈš2 Q*èz‹ý‹ÿ"·`7]è±}Ž. ±±@½ý}.FÃÿ,iàM\óCÍ+È´'-´û7ùËE4JÝ(º6ñ70A©ÌTµ²ÙïHx1vå£:A– ³åíæ`žï^K¶‘S–à ¬yLjD†ŽìÉyÞ<[Ûyd4:KáœCe¹iѪi4{ BHŠWåÉþsNÑ ld„%É€;(Òp1-ÞÅÓ#‹˜Ynì¬kôd´dNô¾½[Hn)úùYƶþeË3Î걓Ee¬c¨U†0ÛÞˆtÙ&b]³óªAS8¤9Íø°ü½~§«+@ 2×[i£7× 2Ù•!’Ÿhãž;=¤ßP @HçlHúîÌðeiáÐãŒ5–oÓ™¯1¾9_Y€¶&Ý¡“±,oy·ÑÎØg]Üj®]  Qf‘0\Ó/A( Á|!¼éØ‹Q­ð+üö3ùù»=ÝKG\‚ô3)‚«÷ ”|—ðžÚñn$sqU{8Í(ª;ù‚w^OÔÈÞüC”ÚµGŠ+úHErì]ç*Î[×¹AØ´H·_ÖI¦Øµ¶µ7JävåUÜ ¨Cm ¨•ÝŸíúJ£…pR_ÿj5ÉñqíZî䶺v5ªUÚЉtšÛ+Ô±@ž¹áó}”QéÚr—Þ•v¼æEɰêeJÌÃ’ÚM(oõ$FŽ Åì“ÂSCüdŒ>€Õ鉓”þž6žãØ$R5R6dÕ¥p™ c&'ÖÝyýh®º«Ì}\¾kéîÌ)*oÑ'òÀÙ,oî/Ãn2Neð©µβÄ3>}:BSÄX³ýW.Â5‰-ʵŧjnOÔ |~½/ÌA‘:S« ï!ˆ}¡³“ZçÒ—Ëà‘ÇÐõ5¾ƒgÙt€þ¡!e«{(\°¯seƒi磶Ko÷ßí`&°†tùtî¹…Œ­i«Lz0°Ø‹¯¾Ø‰`# ’…\§‰‡gÅ/ß$QÔ8­Ku)Ñkü}}C’ò°Ü-ÛŒö8]. š9We7r´è‘hºR3¬,ŒÔ™½¶t­A@o% †\1²£Ø{íx<”ÃffÉ}¤N¿#³òS׊jÙQbDv¡Íð=¹?*a•ÛÚ÷ôp@àæŽa 92h)Ó@­ˆBoÉØ¿/‹\.0¶M2%Œö†ÙìZvå'Œª§5gun¾8"¸ûš‘3»hA ³îêr‡…âé3TQÉwÛWü< 2‚ëoŸ4}R–‰iLmF—µ×§8†æËžÁû@‰H¢ÉsQ LI,%äØšh_¹ñù#üZ&ýö¤æ¿?úEA‡U„4•¢v’‚0[Ú!ük›ÁÆ!ršó'ê4ë ]§‡ cŸU…}E!„m-V9tPÀ«ÿp·ØòÝâp^&Øé6ßùu±·ÿÔâ(¥Éô[cÊ3,öáÊ.¿Ž|…B½€4 U»Ãž“‚N¹–MÚ}¦` £Àù)Ê™0\H„-cÿd;t€3î~\ÉãÛ0ë´28M ”B`ÎæMæ6nZ`:BïTÏ“':Dy³†æŒ†j ß‹›ðœÈmóºü DBžìÝRytcõB2qá4M‰_ Çtš!ñ&ˆðÞArxßfƒíŽWE/TMg‘h‡åâ«ÇCÚ+J×ä^÷­’îqˆ³Ò>ýþ-y¤@4$ûœÐ‹YMÍŽAÊÇ’éȶZ-1?ÔQßÎõ¨!W)µî)ÙF?B´D?²élm¹ºÑTî¢=4W¿q#ÖsßÒ è¬¹ÿ>F+Å€˜r/×Y"«ë°‹ŽC¡Í2lÿGÈ·zVä¥8 S&Sl\Û_VÁZ˜f¯[a…7ÍÌ÷žÍ$4Ÿ‹½˜›x3¬¶WÜ£TÏ‹tP«*°g`v_,<©zžø]y–ç,Ÿ¹|ozåhÿM‹ðû â$°«TÔ:™Fa—™ÎAWŒÓ^_d ôÓ+Û_Ò°˜8‹î³´Áy¾§Ñ;N~{¹ DˆÒ5ú̹°E©ÕGÀ`r¼üG'áDtŠàn¤½èxŒþ×D³9µ$ |^åË\§¢R2¿_Ò]YZÉBƒø’ŒµÍ!wðæx ‚Øe³ŸÀyØ ’—ð¦{¼Æ¤BݾœOIíì#¤,×ñÒmD¿íHpB‹—G¥5"Œ•k½®ëÍRø6£]jUÎk‚³&Ùª3 Å£àÓPOá†JNø;:øëò‰ŒTsœÇDOs¸¿JÈo2IÒ%Gz†¹®ß‰«jd,Í²Ž²¼¬Ÿ{G>>JhÌñJ÷-ÀZü9¡zWùÏdä¾!àÌôBVrƓƞßx‚dØ,Ù1Ë©ÆtE5º³P¦<(Ì1ŠI\ÛÀ~À;ÀƒäÍ|ï©kûÇBª>Ž%xÀ è…÷FÑò >]‡Á—…ˆ¼º.¬¿çìÞ¹­`¢õ·6r&Õ% èvDN -Rùð+Ðk©—lyg^^$Oé[–‘j2´ò2Õ[qÉ¥pÄöã«9@³ÏXo¦¦âkåÍ„š¾{TfWð((å'”綊Ⱦì}‡Þkx›d‡¾Ò`}ì U,l3¬d®w¯é$–“ë9Tpj_ .æÚ?êÁ=i ¨£5sÁYu˜ãmIŠP¼J¯iù.£“>#n¢i­!ºî*™¥Jýö5ÓŒ/:| òX”[*f{¡äu\hôÍ‘;t^BÅJkð¹ýødå«p2c<»—ÐûU0õ68µ©©z ®Œ£h´BÓ^þw_ Oz>qH‹šnÃ~~†ðaïEaئm\‹ôèVÇ‚~Š¢I­ÐU],¬¡CÌß&-¨QÆÛ©÷ ÝÄ‹1o:¯h¿ 7¼MnÙU1ÏG†C`•Ø×´"p¡$s àIú‚Ö<Óõ0rç@hT–W=Wèÿ}ÂÏ$F¶ÃyUI\ÚEz*Ÿ÷âl„É8Ùf&'ïEË»»_ è•U”bDç:lõ¸9X{¶[ÄzßI{¶.ýŸ©pŽt7ç›ÙœÕ_š“_Ò—üÀž,ÇÁåËû×?½Ýãq–Ž`–*ö£L÷¬«+ÁÁ¶¼#‡’"雹——ÒÜü wêOtH—ÿ®F2e8GƒKdôPö,©Á`“‰s»ü7×­ÐúøIÃ2“às¼…c>'k ²t£ ¯ó„Þõ4Ó‘5Ï«8çfž$Žï±I«Ø<‘v{·R"K€ë†Ù2 ù)lÀH´(xNý/Ám¸¯¤¼|Dd¸îÊ¿Æô±ˆBôQñ¶zs¬9r,Ò‚k;Ãàææ"Ä€²Ôͯ|iÊÉ´¾V0º˜3êÃ|´Wlîl£ÁÜ÷[±ß‹hª¶¨q’C³xióÓJnîu¨ÅVh@‰õ’ËÓR<û ê…Öð~N*qˆü¶U¾f¶Q $$Ù¶üQ´VÔ´v¸¦ï¦fP¯æ‡Í§òs±‰~%Ê×dªK‚eÝà‡tì­Ë<Õ²gˆ§ÀM<1¢á^ºÈ«YŽNS;ºk&ÐŽvïºU¸‚ÑGi†bz4À)ÃÜj‰‡å™†«“#·¸pÃ6Ëã [›'–·¯OâUÓÇëë±ÎDcöK‘JøÕªôòVì[Ó› ñ1õiÏRV´d/¸rm _D°ŸÉaK\:¾ÓïÈÂoƒÅE0`à «O“—·“#¨ûß²òOíO°A‰­Ï.ºÃŽv¯ªbˆéÿFãøÏeëúµÇä¢Ù:ôXbŸH^oN­\×'Ø+àÅ6,\ûg%=môÍ¿ëE¦¡J;äÚCBNS}b"Q ‹0„PXi?¹±ŒË¶ÎU}¦=÷5š+<ãaÕ¯Ö¥™Ü³5Ö™Ñuö;›D'í;%}xS—z ì4[’2FóehLB‘2®ß׸…Ñ"(®ãàzò?aÆ®Lc—’]WÓªS ½£çxœL'ÔõNµ`Z´{`Á``Ø‘€ÆyxPæ&p+¥=QÜ4~’„ËÐ[Âm̼ҠPSí?˜¨Ob!ã¤å¢IÞÆ"_ÁÐ¥Iµd¼;hKÙü–^™ªÂ;°v6мÃã»ÏXn‹šBG&¤Ìfÿ–,@ þ›=ž™TíKl#K&€¯®leɤá2.5tuÝ¿†ZÍd¾´AýŠQ_Fð½8ZŒd8Ä›» ü¤lsîHÓ–’¢Ob= ~±z³<òæ²p𱓔ýÔø”î/ËÕ ä"*œvÄBø*°û&ôÅú¯…òÎlK\ÖùÌ!¾-Ëû¯(íŒU+%YF¬Þ_BàBtæãs[èiQ°7=‹?¬®°ï"4ßCï9±çô-áájxs)áx[óáïçÖåøw·~Æß‡X;ùõ£üûª¿äoèÜ®¿‡oô_áѸøHäAÂÓöáÊ9ÇATG_zÿ/ÆÒ –iy"U<Ú¨”âp7&–ÃvjÌ–$lsCÃY–_Ö§¦~I*ÀO±ý­°ï{”(TA‘\û'κ¼˜rôû ʈ‚FSËÈÝÎÄ]¶Z§˜‰rŽD)äÎü>d5²<ø6¯X²‰“‰eop¨9i…ÛÿS…XšM7¿‘†ž° }qÀ¤¿PR2‡%Å®`/ãý'ŠR)Ô«ïHŸ^Ùl¿¢ØÓrÚ(ßÀª†©½m¸c?8ÔFûß‚ƒÛ>¡ ²–®½Äs:¤ƒ‚ãʈŎÐ)–Ãàä‹ÃŸ@+‡à+¨Ñ“tM±.¿{øÄy K{ÿATÄ*¥jcj5EÈ`©, bY¶MQÖT]îŠÖæ+t$Gµ×lá¡•^úúø/îÍ[G¸vQ?‹qÃ’H…·0bCqŸ†<_ÚEv-@¬”‡e ø¹i,iTÀ‡xr·–7)œrÄ£'xÎD…T½qÌ‹¡UP&ü_šÓ! ”—À!Ù寽©8‰6ôhÇ¢Iß4IUì6SðTúî cC7¿vÇg–^(WÒB ~{ÈHÅnÎØV| Nâæ¥áL•l:N¼eºüMú~ ìFñô–e.ƼéZÞBgw¾¯½¼7™œb øt§zÓŒñ¼5Ü –542]üp”*Nxºk.!¤o²=¾í Ÿ?ó¢†#lpñYHʹœM°&KÍ]… ɳHhAKÓ¥L&€¡_-(X€•Í“3]ÈÛêÚJ³)òƒo%¦E(‚tõ×qüœt¥þÂZØ/0³¦Ìøu%õ@q"öú³û;Žï*TUóLùݼêeµ™¬¨ÉW†àêέ¬¸¿ið^Fy_)À2×°úr¾dš¶œœÑÆÎ«m1„\îEõA÷ QÝÈÀÉÕ©IË{Ís«X ’>#"îœKZ´ÓÑòfî‘í® Ahݤø[¬„<Ùœ…¸ý„baD¢Í¶‘„=kF˜¦]™5ŒPáx j‚ª›8 “ÆVóÛ®D ái±ÍmŒ!±<ïïË\â2 BÓ»z-7ÊoÂGasÚèÐó‚Öt¬ Mtvú~b6»{މ=Ó¾‘‰¤ykÝYâû:øßV^B,ÙBñ Äåªóœ¹IS¬ÏíÍïÇÏepêÐÈM©–Ù} ¦4 »7°âÝ¢-_ú-´&¹¤°þÃt®|^n; ­ ØåycOÏSÐ×Wá­&¤\F°Æ~ö†òë^Gjð@DÀñT7ƒËKý>g!|P¬5µ* Y„!zË èDozÉ>vš3É[ÓrN…† )R½Ö8U6(©âØuëk¤–RX±ÓQUe¿XúNtE( <Ÿ N!Þ&à'òÜ´{‹ŒÑ•ÑiGú TkîÞ{%½ÿSp‡ÃïFMƒ©ÏVOéÙô a€¬¢lC›.è.?@× 9Ó6(Sþ²UkVRî`¿à(óõˆ¿8Kñ¶Y°x*ÅÿOÓ©3“g“Põ]t¿Ì´z\Áu¨§3؉ë˜/(ЧyÃJ½–…ÞëÑRg}±·º¯2‹nx;“pä·‡±¬5ëuŒ.p³rƒ0‡zÍǰ»ëF?‹pì‚(NQžM¿”Ç^Þ÷e˜A›0r1 Þéšžì#7 î$ä ýfní‡Ì Å¸¹“u±DE$”Ê­œu߃õC[ƒ¾·ÎD»³2¿å å×qFj°Rxû•=hãdb1Kla`wùñ0!ú*„AnYG½ ¼H\QÖjwÿ6¯ôÇÆfÂGQ‚›¯ÙÚ“f‡gU0Š1ì9 >¢‚¨¶Âì7¡€àÑ=õ¿o¸ÖaÒ¥âÖe“öcìŸB´õ`¼ ÞD(IQµß!ÌÚâ‹ÝÔïCÜ‘ËÉìØè›£ññꎟà8¤\î¦{o%*ª]¥KŽÈÛ¯ŸèÁm„ËÖžý¡ãô#sV»\·mÜtЖxC+½°¤#ñþõG²‚ö'ñzUyž:y áÿ‰Krtɼp}ð]âêá×k+ê3V¹²à¨^<À ŽE£ ¥Ô¤îܼ3xmãOòmLÆj¨zoÁ«Ò.åÿSªgÛìf·`@=Õ Óg¡ð:vþP†¼QšûÆ¡Öǧ ‰Oòü/H™Î#äFœ0íöß‹}›ÅOe grRåž}zí?)6|ðüùå÷vâ’¼\cÝD§d1O¡ÖŸ@/ Áä;§ÍG|ÐÖ©À·Kðm2*‹ÜÜv^ø Ë—•=˜ÿI«¸„íµZ¢DØ¢«¤@NÍtæ,7¸tµkt”ªBÐ[)šwA|4ü±#:ûÓ^/˜4]õÕ¢|ؼW|#Œú·íd™Õ%ptÑ<',ðWÄÓêïÖÄœ?KöaUMÿ@\3ñûààæØ‡H7侞6ª ¸‘%8wÔ;qH¼ª{»ùüì«+Ê‹Èýο*jèRE§1ÃÛ–­ý—¢È×ëÇBŸ¨æsù4‰^ÙOø‰™ ì…ÿu\¡k¥Ô›ñŸq9!Ï%à¢\vä~Py¶¶]º|%nÙ§ýùà!êän`=´Äòu] ÊLÛÌEÐÂFâ!§È6 ac:Mž&àB¶´êÝÑ€­¸üÏ?³EšžpÍPMˆaJddü®»ì’ë¿K,Šô»6fßjø 3´Õ™:»L\LÚ)fòˆÔݽ“gZLÒMi¡71/\®¹úHwqµÙ«ºfÛ0¯¼áw;qêõlÏ’'½!Ð>hªÄ‡©ÅÔ¥´¯yhò.`_½Ô’íøü:o 7åSÅØ@ÙÃ÷—ú#æãM7¼ï(½§Á ‰NŠÔú@÷þrw;æN½NV¤6AŠ›†ýç8÷ä:(þ©Œ‹±ÜϼèCT=§_˜gYíÄÓ²®´smkÏxÈì KOŠ­õ£°äB®ú‘xç9j8²q²±c]´Q;w8ãC2¡ðÇ÷, ziJ°/Pû™«±c¾†ˆ0ŪŸ¬ˆNeU®T)k\sµ¢ºxØ…‰}ÈœJl@‡Ófæ+Þ,ÞÕ[ÓÍÓ?Ò„iÛJ„bHß×$«Oi̳–Ûx€¹JÉY¾à”S[¬»¾Í¸-[ Á¼{i­ñNsâ^”ÜÄéÚäÝ?l|m¼z"6p¨¬S°úó òb â'ùú ” ^/¾9 rô“ÌËÏŸ¡oPôEÁØ£–ûÌoÁ)Ÿ$Ùvï—ïÙ’D=þ–/¦Ð5tû;› |Ù¹ŒtZ×›ý³›GŠ9y8Š—¤(\cÂS<§ò¤Ïwnð.D9͹₺a_mº$ +N7…¬ àve¤%Ù%õíòï®+Bè/-+/§+5ãRx9RT!Í£z\·£ã4‘ôDdjÕ÷¥òȸÑSñ¥z¿J1kË)I9g0.êä²½é’zºZÝWå²9Ö?ç|±Ô)fçæ>>7¡Ø“™æ|à×\épƒÃ à`;jw¤nÊþávtF¿»ÌU¢µ]à:ÿ>ª'*^AÄ”•ƒÕ'U…§HP_á~&F¬7PêNQĨ“å’BŠsWö„[âHÀâÞtZ}V¡LáÿX&Mˆ7ŠÏÙb :êî-õ1T iIö×S©ÉQŸêËO惶(±Œý-…|G5†¶ª#ë ½g-aŠªáÞ)ðqO81«z‹²‡ºQ|úlXV;kHYÌݦDï«saaÝ¿Sùä!-drV9s-…®”º°^¼›nE…¡èqØËcvª\ŸjÖ&ß"WÏÜgs¬¸:Ϊ¹1ÎU¿]ì¤Á*¶5c\8 9–ÿøÐ¶‡µk»\TWöÙ=ôhøÓ]sK$<b|ÐõÃÛëââC9‡óv8ìÈ#JYÑkÆÛ݈¦œ ºÓô;O¬.•)C׌æÛ™Ôø]f[´C+8K“lWV³ ·V.*€»•z‡EPOÎ0ð^Cìl#ÀäØGIN=rƒƒÞ­Ú5xPÅŸ¯àˆ¿n¿,Fðë5ÄȬ]®0Tõi¹^¹QnÛ€=b!y5ªÒ*?’ò æ®(ˆèkKÅVÒÛpBÎ[}˜’¶÷@ì¯ò•¦Úf#ÇôSáÖÉáaGo›Ï/‘½›îq-cÔÞ/ømH>4¥¾óÿbu.‚%º¬ÄQñðˆåV÷oøˆÜN$ç¬ó—µ]`Lß< êžçs{É;g¨Õ®´F$uÀà$· móïªxèAÔÿ ©R¯Êb®þNY©¹µ‰¡ö[7Œx+4°šÃøm,.ŒÏ%FÛ%‘R!¹ã½ ¡™ÍœcÄÈÂèÛv9Ð1Lmpƒ`§=Ý¥¯Î`|¦ŸæÃ¯õÑApÔÆÚ»îŸôœ¥=Ç—Lçºp'¾ãø[¢¸9ò„^£´5¦¼ÍÊYç×Ùˆw¶/ &¸2ôù8¿—¹¢H¥¸Züû!~!ÈY¾ÎÀ’ G<¤kXt 8¿Ç\± +É'õŠÓg“~˜dÑáƒa5 ‰àdˆCz\!HàˆÃ7_ìMÚ‚ïyxˆ"¡:Âgï£be–—r4žaÅi˜^™û€OË.ð$*MsCÔ£ÿuÛæuºéû93\6îh.5Q\~FáYE¾àrQhïyBÇL¼ŒÈµB+Ž ‚š-¯Âi /zS÷,þÞ~ÆùùEÛwMŒ‰¥Š§{öä{šÁ`e}C·€Rq^6> ø;Š9 ž¢W›PáT›HmÏ4Ðb¶ ;ÌïeŸ¡á³r_—YñîäÏ;SÇI+|»ªHç2Gõ÷å§/VÄH@O©"§Á– ñôAà1íKÉrŒAݱ8Mœè+šŽÜ(ðèîà¥Éýú¸çþò0xáŠÜ&d§•I”™›+Cò‘Hv$÷l£ùãV’1…“U*€Do˹ù‘Ú_+üÔz*ûY"s9ö‡þËôٸ51e·]ÏÈÛYŸÅ·Þ·ÁlµJžj~ðwÎacŸ®¦)¡T:¨Fø9n¦ë,äx y}‚”˼š¯73h\Gë¶Äx¿$Š.pœ5Y:ã‹Cv!òdQÄó8ÜUR‘…óCCëk*%J„]£ëöM(•3.ÿcÜ; ]NÉv–‰‹¹6™¬Ä·ÈÁ:í@¡¦í}êæ ¥<¤PŸ¸042kXN.”- »GÅQÝŽ™¾NÈéwÈÓ–ùø4:¬lÛƒ¥€£…›qí†(xïi8DŒÎ¡&;búþ¬*˜_=IM=«[þœÀ–.2߆ñrN·»‹¡ª-TÇ`õ@s¶€ê”¦WPñô³ÂêtöFw}DQÚªSéè)?ÜAJm½ï`DÔfÀª1#+ruË?.B’ t•Ș.öUÜtG#ÀÐõÕZO,E#UbpTåÞf—­u±’2â"•ìÜ2&¬Ð%ÜÅhÀYœ×(r& בˆ©{.8ƒ8KêœD†$ˆ¾´³ÕÇ0D©šœ&º H™•Ï<©S8kœi²cð›“8jªQ;üþ|¤!A±ÍôWµÆÁ>ɪG?*îÊ¢ÇáŽj*k‘ß4,ŠÔ>z,O«ê畾V>§ å9c­ÜUf*CvÂ{ÙpV¤]bbu¡¤ »žï蕺¤f+Ë~Oul„Ÿãs–¬‰­‹©߯ÇOÇòNŽ«À2!²šÁ yÂ×ÃʯnJšëŠ R(- áŸ[ 9â ~ë䨵~ceÅïTЩ¢,ޱK‡8܇@3ŽèÁfÑþW g¾y ¯å—7]Ò-4»«”2·3ÄZÙµ#-(G9KÄZÜrTr·rk“úÒÿ€¦¿¼!k¦æý2 ãQæ2ÄÐ8¶Ê:Ù*uùî ·JÏSÅ][E&,;3EŠÍ¯´Š©óIÇðCvè깪J3 Ðpèׯ±$´Äøá|„ ¼Zžqj8åç/iݘ0(ƽ¶Ac„v‹×¸ ‡ "GÑ*Ðæ“¤«A½¢Q23Üa")'ˆÓ{ DÑåÆŽ×ÀèßVU'1n|y”8F.*KçØ«ÞÎ[.Ú—~ z½ù+ E”^DäG¿”3Û¯ó™'O tŒeCyVœjèÙjïÕiD„޲>¦<˜Qõ•?†”уH1ôE;E&0Ñ¡nçÅ2mdæbÝjñB]¾ci5ÿx{K×`#¿rB‡~Ä_µ™’úa*… Jéc»§>„ˆ„–v‹õλ›"/ ö- zˆ ^;eŸ]®hh¦ŒOê±À€!Å5K% E”3Òj5”Y‡ËÌ8NHFVß©ÊÍŽ}u÷QXîg«ÿl \2ür,ëÓÐ¥ö#W÷¶58.m¸„NâÝØ)ô–b4‚|”dn0ODfQÍ€–˜zë—òÉ’ùy)æ6LËåaÆrU5ðÖ%¤§FJTô ­ƒôw¢Fô\„öŸÄŒ?mPÂüó†ØxY‰ä‹x1M¥vrPvgʦÒUf'×ckã‹MY®ËÅ%ƒ 3Såù^¹WÒlÚ#VË?.ÿW»ôÕ­–㳓ñ’4·à¾CJ¨÷[÷‰á@!Ó%˜4Ž·K°‡Ç}äh PIÔ6”Xãp6ßCNâbékcÿ#BçοDÔ’ Þ厭Pgã4h1ÝNÎ!UIߘøÊ€ð|DœXQçÄ…ÇIØX#͗к®·:Ç>ì&(&ˆÅ\Nˆø+øR†hjt$¡´ÈïO•¼^,ˆTX°¥7H¼9 |ỂA[Q5ÂX÷ÚèGCúè ÷Všz·ÙôLI’Pƒ…=ÿ+c'‰’˪ˆ$u¦ä.®sèID¶+@ ¾ªCY.Ð¥›¾S±pXÈ]ÿj&iÑöq‡•'Ì×BîX‰¢M¸~®„Š´` ¶!¯GMÏî/t„HAâD¤þã¸ýèb-ÇSô¢€î²žsZ‘ŒÅK[-÷sÃ\³nZ3¤`›>^×jöo5ë×®ƒß:ÕïêNãˆueîëP˜ô¶¬š-<ÓuÚ"ì0„‰|‡Ÿ€ŸÎiÚ ¡mŒƒD¹#peN%»Øºdqs #k˜6õÖ²æ@ FDïKëÕ´´EšQ$uÚ7\>0CÊwçæî“YnüLÅoJb–… 5ký*Cªµ"XÀþ^€?SÕ• k­´Ñ›ë„™l‚JÉO´qÏžÒo¨P $s¶$}x÷Ë4A•yþ¸u¯(uFwéÌט¨à£YúvE@Ö [õ ¦¤ ·iqå5Cc®$²’Qf‘0\Ó/A( Á|!¼éØ‹Q­ð+üö3ùù»=ÝKG\‚ô3)‚«÷ ”|™¿®EÆCñ‹3 Í‘¶øR©‚w^OÔÈÞüC”ÚµGŠ+úHErì]ç*Î[×¹AØ´H·_ÖI¦Øµ¶µ7JävåUÜ ¨Cm ¨•ÝŸíúJ£…pR_ÿj5É9¢ŽêLJ­¼÷ÜæunÓ«K:tz„ö}Of\ïeWÞãv‹plÏt´Êokû¾È)? 6°•„t'ÑTJ°I¹ ,Ò›G!ê𼉇V|üNÞ ‘HÕHØm“V•Æd)bYç’€¿ßµU¸|#Ëþ³ˆ®‘$øsðµVÐÑ×í•AÙMîÅ^mß– b¦ç‘P~pš.­¸â4ñ­¦Ê’Íyhä—,f¾?^—æ ȩՅwÄ>ÐÙÉŽOIóãÌ€è‡úoñ¯v°Â@¸žÔ53½¬eÄö~˜&º@¸ä_-é§xÑžj\’Þ94ªOvƒK—ã/‰Å/ž£yëïµÚ€ÄJa"rP«”ñ0ìø¥àûäŠ:‡©n¥:.ß_P伬7 #¢]ו~¡-6èPåjU¬>Ù?ä Ú³Õp¹j»8F艵ȩ”Gºqü',$‡~Z.øèÊ*ªÈÉO¾(pÈÎã;êü)›à{r~TÃ+·¶-æàýû"ÒŽ¢a]v[Þi‚ñÙk(Bú¯åjUˆyö.ÅŠÏŽøäϳŽ\”òžbù̯6÷}\õ†Qˆÿ8|Ѱ 9íž-ÒGï-cÅÆ½Zëî5.»jü7§d-ŒÚì`°ócr)!½^×\^œà:ªœ 'ps8GÕ¸aa´F€ëw=ñjšäššÛS¡L§g™bòÈ ´”‚ÞÑã\fŒBäçisõuá.ÓÃÐ1Ϫ¾¢Â ¶–À«º(`Uÿx[òô?&ëÄÛ#&Ûÿ[€Ôâ(¥Éô[cÊ3,öáÊ.¿Ž|…B½€4 U»Ãž“‚N¹–MÚ}¦` £Àù)Ê™0\H„-cÿd;t€3î~\ÉãÛ0ë´28M ”B`ÎæMæ6nZ`:BïTÏ“':Dy³†æŒ†j ß‹›ðœÈmóºü DBžçÙ=lr}mÒW/zä‘õÕÔ.I^üd)OŒ °üéBØÊOžž 8R¡8. ^­†•.WX‰&äaJ’TöŽSNúHÉ–F͵“(ïH¿]Tô8>­¯õ{™8ñ¯2<@Z¡ N‘,‹e¢Ó“ýGCýÞµD+Þ(< vǾÌýžï|åÜÒX“b ãi·Ñž2îÔ|øzÎA`³ø„=„¹ÿâQdv|3°CV%7æ?…foqV,),1ÉJp¦L¦Ø¹¶¾­‚µ0Í^¶Ã 2o›™ï=šHi?z…ˆÇëòÏ]·¸Ç:ûÃèc‚Eܽ<ãlï¿Ð;?–ö“3ëëUb1‰OŒ%ºFSñÙõŒÄ¡`»ŠÀí'ÎõÏšÙ}4Êö×ô¬&"û¬í0^o©ôNÓŸžîH"4~³.lEêuQð¯?ÉøQ¢·BtÛµï­"Ò%ƒìAú_pÚ]ÎÊ´ã.€„û%é®6 }Î4òLnà„qÑi$QÀ†T ÷ÐQMëÆÇ tˆ[·Ó‰ð)=½„t…šþ:M¨—ý©Q`òèô¦¤Q’­wµÝy£Ê_Ôk­J¹Í`£ÐVdÃ{5Fax´| 4ÃN9Sd5Jy6ßH«Ž²?ÿZæ¯Qcˆ £räÞÂ"Óžµæ#¨mê(ë"‡ÑI¥IНixšÛŸ±þ(šyÅñ^¿+üé2si“©pfz&â X´ÇªöP<<²\l˜åÔã:"šÝY¨SfÅ$È.mà?`‹íCùßÕgÀy#øÉ'JuN CµjÈGР’\Öþâˆûãø©¸‘¿u„ʆNS,ÅC„æÀpüŒ?úÛ›WÕ‘JB€†ô;"'–©|øè5Ô„K¶<³¯/'‹t­ËHµZ yj­Ž8äÒÆ= '@³ÏXo¦¦âkåÍ„š¾{TfWð((ä×{‰¶ŠÈ¾ì}‡Þkx›d‡¾Ò`}ì U,l3¬d®w¯é$–“ë9Tpj_ .æÚ?êÁ=i ¨£5sÁYu˜ãmIŠP¼J¯iù.£“>#n¢i­!ºî*™¥Jýö5ÓŒ/:| òX”[*f{¡äu\hôÍ‘;t\r×´•ЉU×KmßÃZÁrúj¦¦Ç´Õ/A•Q”möxZk»_Óéд°xK2ïh°n8ZÒÝ;;ÁN¼*¨ÎœÍ²ÊÂàOÑTI5º «¥•”(y›äŹźϿ:²S:Cëd`TŒ%€o. €6l×ï±LùÊëoP :WgŒ]6èK-mÕ•I£ºe~Kϱ'ÿ-\‹öˆÉ±ÖLö* V 2ˆUš¤UåCýJ¶Z‡î÷~©ud€°d{¥aÎ¥ +î/j¿¦¸²ûý¤0 V$ÿVŸýPû÷7k„9Ù¾êô|qšÔ‘ ì;s-²@ÿvœëw²´Š«!õÝ3ÃŽ»“¾.™ûˆfå{À·~¤÷D‰ðµÈÑæL§ðbélžŠÅ•8,q.w†úýs3(n`©âDÆöö[b‘>ª¯Õ;S4n@9³V%'EDLY¤Ü"BpÎùL­S\wÅp¦Õu™ûùé*…É$QøŽø°)‘ k×þ7ì[n+é/#Ñ. {²¯ñ½,b½|mžœë\‹4 šßÁNðø9¹ˆ± ¿÷¸Æ9Y6˜aFl2W! Bîy‹ò®'ÿäŒÔrkÿ(ŠŒßÜ¥"þø¢'ëÈG“µ—xГáõA¤²Ä4Ô>ÅBº¡u¼“Šœb?-Uo™­”BÉ 6m¿m£u-®)»ÁD)™”+ùŸáóiüœé›ei[*´gwoÑüÕ‚DЍÆñ¾ôžÄOÆ7¥¸3­ÕÙplÅ1ðVަ|ºÎ܃µ£ VwЦÁ`_Ö†…*W0ël÷¢yf`©äÈìÓ€ã°mÙŒ_«s`òÖõéâ|:8ý}v9ÈŒ~Ãir)_µ^ž@*Ý€Ëzsd&>­9êÚ£†@2û‡)7<>€¿ÉaK\:¾ÓïÈÂoƒÅE0`à «O“—·“#¨ûß²òOíO°A‰­Ï.ºÃŽv¯ªbˆéÿFãøÏeëúµÇä¢Ù:ôXóõ/îêÉV®9éÔ¹ õã\¥Ä<2#e÷"Võ%§¦ò¨éiêÖǸ§9©× űÒsc–õšŠ~ïþvˆƒ‚Òè°ÁÝOQF\­^Û{›Þ˜?]yd8e U“] ¤b”ÀY¥´R¤G*ïÜD)*àmýpk@8]šÞ•ÜVfè¸ $˜Ç/lTú¤ãŒqoª´üš~ža_þÓÊK¾`°™áÖ< YÜÃ5¤š8PÁª<⬈Áòfˆ|”&^‚Þn`µà´UÑ ìo´þb¡Nî- \t|=$c~Âó(’Óyø‹ 0à;IbOÇBÎй‡Þ")¼^)2÷mÇmD…Îë ÑsHHäÑô€Yƒ,ßä%‹(?¦Ïg¦U;=?'AR/gf‘„9wvJ]Ñac}çY¦ûJàÆÍú¼ ½}Pçödüxó#ЙÖtÿ)DÏ…j)MLITš@^ÿ³<òæ²p𱓔ýÙD7·ç4ÉyЧ±¾ϱßáUÝlKžCOÌÞW8ƇË3»(Ó)?Šê}B‘iÌ‚ª¥oä«(Õ›Ëè\NœÀc¼nk} #Š6ç±gà••ÖäEʶ*ÎNl©ïý¸xZžÊx^é#ïçÖåøw­~Øß‡XYü:´þ½ÿlÿaÑî?‡VŸÃ·?áÛ—ðèÌøHäAÂÓöáÊ9ÇATG_zÿ/ÆÒ –iy"U<Ú¨”âp7&–ÃvjÌ–$lsCÃY˜Ûú ZGä…«áÝE? ù(¶DÏ,à2.àEå0h;‘‰£°Éæ­õ_ÕPïM¨KÛŽ9þNMÉp\þxü óIž4cU§b’Ö|Ùçp/§~§ÓÆ·KÏXÎûâ¥b§²‰}‘ñÍvÃOZé—°ÓÎЖÿÖw1ÉZcÂ²ÑøLOïPüH3H{sЉ§ÕnB³A†NUŸôµ}%›B„ÄþhȬ‹¯ðƒyß" Ë·7îCj° "–fpÒFÑ iBóà+¨Ñ“t¦_Ä#ç#ð½XØC¨O*2-·(¹Û%¦q\lœ~ö¹1ÐìðV@Ñlßm!EGU|qô"Ã_ìv ¢ƒ5-…Äê3ž(äÝí¥!š0BÛ˜1!¸Ïà /í"»‡ VJNò„ü\‚4‡@–4ª`C¼:Mž;£(pþyÙÞu:ÞpsbÝØ&fÖÀÑK­<ó4ú¨­J±µ6«úêBQÚûLÜ™eK”˜Ý8þ±¡›ß»cÈ3‰K/+é!?ˆ=ä$b·gl+>§?ñsRð¦J¶'^2Ý~F¦ýDû¬Î5 ïì…qð9¡ çÌý‹Ù+ ³[O.7wäÀ"¶>ÀáÍñs?büÿ6œí[ÂÆ¯~+½;N Ô±ué>½ÝVgi+ pýñ¬Pó¼I†-¶3"UÅØ*àÜí·¦ëk.;pky)GÛžó»ˆJ œôž»›1ÛσÝÑœA/³Óvw"ú û7H9)@H@—YÍs«X ’>#"îœKZ´ÓÑòfî‘í® Ahݤø[¬„<Ùœ…¸ý„baD¢Í¶‘„=kF˜¦]™5ŒPáx j‚ª›8 “ÆVóÛ®D ái±ÍmŒ!±<ïïË\â2 BÓ»z-7ÊoÂGasÚèÐó‚Öt¬ Mtvú~b6»{މ=Ó¾‘‰¤ykÝYâû:øßV^B,ÙBñ Äåªóœ¹IS¬ÏíÍð8·ÿUUIîU—d¸CÈÜPÇCÆ~³<_cª¡µW(¸«0ìås°˜&(­¹Nõ„:²†€žuÜP®y_šÞhò‚ù¾ÛC‰$õD$†Y¸GE¼ ÃµùâöÓjÇûSAìWׯšæBé,¯á`±M×Ta^²ÂGºÞ²O¦ŒòVÅ4Ü€¡a¨ T¯usBn *¶ë3ÇŠáŽë9xÉE‘£llcKTS¤ )¼1…»î2è°a•v™E¡Á Ë Ç'¦±Ã¿¬?-è¯e0ÒÞÆ¤NR  ZÀó=U¬+ÕIIò2iTK 9…x´Ø”´©µa^Tªbøw²¬0U…´°\ìmÖl ±çéԙɳɨz®º_æZ=.`ºÔS™ìDõÌ@i€|mÄ:ÀyäìÜÊ*xbdzµÿy=ÿtaì~ŸèÞÞªx•6³A Y‡PoÚ0ŠÀYDM‘×Âkot/nËîê´²Ÿ7…Ôliˆ„Šùç»±v{™9ÿ,Íݰù” ÷ Òn¶(ˆ¤’™U£óŽ»ð~¨kpwÖùÈ—vfC÷ü¡¼ºî(ÍV Or§­lŒF)mŒ2 ÿߢ¨Då”R¹mó%Až·Ž·sÿ%Äi©ñIáç ÂqP!‡À£ð(˜n¬qO`}B1žz©Ž<Œ#ï'÷^bEãþÓŠø¥ÿi¼! ŸÀ;¬:×°)b´õ`¼ ÞD(IQµß!ÌÚâ‹ÝÔïCÜ‘ËÉìØè›£ññꎟà8¤\î¦{o%*ª]¥KŽÈÛ¯ŸèÁm„ËÖžý¡ãô#sj› Éw¢¸ó ÊŽÁ¤Ã7¢aØ(çñ«Å4ª‡XÐC Ÿp9¢a~oȾ֮{÷n®RäÞ!¶±ß‚bšô.´3®¦œñ^‘=7/ ÞÛxÔ›Syš©Øê À°cêô‹„¹éÕ ³íö3[‚°Æ ‹j†i‰3Ðø»¨C^(ÍýãPëcÓÐD§ù þ¤Lçò#NNöûožÍâ§²Ýçñã$®îÃÑÍ_)%Ä Ò$ÐY\J®‡GI8ì?!À†Ø†A$Tè#ʱùXY …blzS½Ù¯ƒ! ž½¾u`1§Ñ?¯ö^-rà :±ñ{-6¥ÄCÖêc·ñ\lä|`ȧ’óÞÑpCõ0Y^|3«|à·þï•Р%j < ë•![^8¸0W•þ(‚zdÞ}3äv 1ìõ¼àZ½ ȳ6B)j:ªñJ6hŒä8³9©Lûh`ŸÊK¶Í§§÷ûü¤¥©¾ÄÊðy­jGkGðÛgn)•Ow"¿•w6c „‹'ÆëuñmóÎÊ)NvÈ¡f¼ë¤ æêF\óÜSùãúŸP¼Bõš%Bë Ïecãö«ú¢ œÐ•»õØÐ¨ÓEyÓÒ°g‡Z0z(ð„Z4Iœøü ¯éëC¶—¦’0WÝGÿi st0‘¸ˆiÀò ƒX Ê~û®að˜åèË_Þ 8þ·¨a¬ ¿­Xä­-NÅÙ ùlÐìÇOåaxÕ”®ç£ßA5ÿ º°¦t9`.a,[C†0m:ì«ÀýÞ¸jÇ‚-*j ®6WàJ~ðœ%J‚—ˆþ@\ÐeS¸ÿny5p7LÛf÷€¼.çn=^­™òA÷¤:ÍXõ8º}²¤²¿õ:õmú‰òt —gÙcâ\—š{±·Xï¨@B:°%hpË‹rXµ‡ÌT̺b ʨˆËÏ©y|“g3ÓU“šcx’½î‡t͹Kè#š¤žÔÉ#ÄyØ8™'ÏñJÕ4Tmp[vc®5á-t/ƒÕ¤VP%'ÅVúÑØr!W}H¼sœ³Z[i©§O­NÀ¤Ç"àé¿°[S[”PEG4¬©4ˆ¥î;Ì¢e×|ŒC¿ýâwò™y8‡5“_Ë#üú-ŠŽè[;WSŠíQåU^Wpø|™3€O7Qÿ%Ùû6•ÄÕ£×$ûoª#¤À,˜Ídª7ðU5nT] È_f[Ö£¸ÌÐïÚk|Sœø—¥71:v¹7OÛ %-ˆûZ]Ú]Ùƒú®ºvΫ«”8&"7 =Ï ½H™}ÿ<©ó'ù¸ZX@óù1K«5{·wpZ÷ó)µ»B¦ÜW41ü†¤¶+&]döt 8<Å/ææMÈì:JíÇòq/HP¸Ç„¦yOåIžîÝà\ˆs›sÅt¾Ût$H"8Vœo XÀìËHK²KëÛåß\V…Ð^Z"V_!nˆ‰¬Ê½LP|ZJyšã¶×šËX|–Wá¯_f ŶC¥ÑNºp "‡0*?LµÜÂ>° {Ò.ùßĹV¾úUŸzÜYûš€™¿H«FH¿pO¹Xi†p='KûKi¤=d…2º‘}( ÷%ª×øä…EsŠm‡e®Mš’£]5 èB CTaÅ÷KÎ0=wîÌá³$‰m¢ŠÔœ;y˜[&,eeHçŽaÏf{tïÿ%O ~ÚÆ·¸ O*ùÐ%"è©Öú/ÌÕNe˜¥óÇ?§Ú}1ñáËéT¢E ¶ÍsÌž[ ø£rçB¶d<©±±:ûvÉ’Èj.A@ÑtÄ ë딦gk`¬ÎÖX©a°†:`’ÂræO³7h¦$Þ² ÆK) ¾:GmðÅ%Q¿Xºî@Ï£ iẆþ´ø;Ã}ÐeÝ¿Ÿç]ÕW&9Ê·ë½”˜%VÂÀ=^ÀzkCŸÿ~‘´ kÕ²-¯ð+>V…GòQ¹ÿXJ¯çšn—ŽÃõ}ïh:~±çŸÞ÷¥Á2pã¹/NâÕ™9vªàã^i!öËO¬.•)C׌æÛ™Ôø]f[´C+8K“lWV³ ·V.*€»•z‡EPOÎ0úgB ì×ôÿd0ÚacÕü9¡Uä(3>½ >D%Žo|}6mtMïå‡×Y"üñƒßþŸ‚ÎýqsÚƒU ÀÜZ¤½p”·,Dt5¥àbsa¿´!Êò÷Ìî‰ÙaÕ.M³ïmS]ùú(%w!ÁƒšÛ¹ù Gcs»tÖIJ÷ÏQ!îF^É«¡3Rðn^$‘lùo—eMV’ž³Î^õu‚‹€ðƒù¥Ë›ÞHáÛ=@~­pÍ¢1#®ÿ„’Ü)´GϾ©ã¡SüUKú•~SwòrÌ MͨðM²Ù¼cÁY Õ„Õ›‹L¨ùdŒ\:¼ì’¤Þª^âe…ÓŒOKƒ1©|2RL§ÝÚð¨ûXW78´Úµ”ΙŒ@Ò®S6³á"˜8så~ý[ñØýôš»Ò–ŽkŽ2=(a×z¶'u§Ÿ·Ä®É?×Ç\± +Æÿ`éb c„ œ4SÏ¢WÝ\KÛ¡¼ŸI0{¥Å“‰^(@—kÙË*äð§ù×;\–P&ìjcÂŽ°ë#FiÐ/ 80ä¿Ô\(êßzØA¬…Ú¤{ÀN¹µaw ‚nãHÇ{`\ÉÔÅÐ_Q>f©¸Jy3ðããkE.̤ŽÙcñá{À î¾þ3’Ë ßswsÌŽ¡±¨PêcÆ$£V¾&‰eïa¿çJà¦ì+ºUbW›PáT›Hm«·Pl½(Ì[B;ön¢ÚÅH³Me¸ Q#È Ò?0y»ç§ÝW¤ÂÜ‘ç‘ÍÆ"—iàù%yXGFªÈï´ù5~âdÒ-ùû…²’§ù¼ò~®ùÿBF1[„Âì”ò©2“/óeh†p®TØA`OÅD¾^ä÷ÐÃC[æyÿ0`TB¢“†XÝèç5+ä¯gó*¡±V<ïs=Iè+f‚ï~t$¨_õŸŠ q{”]ìAÆ,fj[ž2˜gG†/ß× SÝ߉†2?;ôj¾ø(X˜nNʱͱGe—™Î¥dZ‡jÈ>eá|Ɔï!T™Ñ‹:|ƒ¿yÌÖ&Hªc ËïívRG°§E/ÐxÐpù,ã_Uâ.%nçWþÄH5 2å+œƒP{?÷»<@àUžŸýn6tïÝä#m[kÁ2Ùdð""Rñ»‡(ï[ÆÊo tiª×=MÜÞ¦œÃ­o$¿æ¤ ù“{{L©›I®ÉÌÛ° Âm+þji½¯ãÝúT²Þ¬ÚÈ‹½Ì[žûE€ô§;¤2û Ýà ¿Cú:sÒFZ#H¹çå-¯ûNϬ@§Þ•Ð=v®PÑqŸTkkýŠ5•Cxs!^YJ‚Œ~pUCåö'­?M- Ö~vá<ü)ãÓm ˆ^iVœ\—T”*ýX('ÅÕ°XWô°†¨Ýœq²ÀT;ÙyüêTÙ»k?‘”ùªÚç?1›«ØÞí¼bÀe¹‹/è#Œ¯‡Ü¿õ“ tëï… =ì=ë¤ÛC󴌎/ˆò¥»S‰îØ»OX#¸«1«Ó°•ÛÃË»ÊÁÞ*ŪÔ|Vùò$Të¿Ëš7kiÈ]¸…Sˆ@•£@N9½—ë\šù¥ …™—‡²¤xŒÐN’~ÁCrÀ|"·|)×x>$v—ÊÅÿE_k$BÎg>Ðÿl¼;M›ƒS\›Ü‘Ñ«ø2 ?‹ø¯Ÿ¿ ­·©@¼ÈdX\´Cš¬Làô®ÍŽÕHÉœªãH•a™Ù Ж"ý!®~i(MÂË¥®8´7bß)FEO3ÅU!y_44>¶²¡²T¨EÚ>¿dÒ‰S2ïü{‡d ©Ù.ÒÑ1w&Âó5˜–ù']¨A‘FÑçcœ6–PÕ8Þè¥yYJr}q÷7?§l›¹ÅDÙy$8²B1Þdh3ÑcC;!GŸõ€aI ó˃H˜;–5¢RÜ ‹¬të±çHwÕ­ÿ'0%…KŒ€wá¼\“­îâèj‹U1Ø=Pí€`:¥)•Ô<},ðº=‘ßQ”vª”úz OÁ7R›o{Øõ$°*ŒHå0T‰â‡|•>2’k¹€JüÕ¨T“ÇÊ µ ®ΞfÚÒrX%íJÏ„ŒÈG}„f‚T{t²Íí+â†oY®P:8äL®0?#Rö\qp—Õ8‰ &I3}ig«!Ž`‰S459:Mt‘3+žx1R¦p×86Ò3dÇá7&pÕT¢wùü,ùHB"ƒc›è¯k‚}“TŽ”¯gçñs›Ú¦?µÖ×”Œ«•LPàOL ¬[ë4¾ü5/>e*%w‰‚$Ãh±©2~¼pÿÜ{Ý–R¦L“gRo::•WQ©6üSû­ÖÑâÏÛrÐ5ð+÷Ö}¤4£ÀÙ¦AÓžòÔ®ª.Pr³C8/÷ïýýìñ‚–{ ÈIDé”"ªñ,^T‚!9æQØ'©j}s¥Ãü•—¯\ J¼iO÷âÖu´|Mu«…6vï6N͸c߯ž!ß:ÑF¿~¢·Yw|pÍîS—©ˆû8pÌ2óW{ £›1è«Sð:OÚeÇâ¾ø;wv ü™ÇsóDÄõ/“•›âÿ¡zk2^"•x‚c-:ºWHÖöÚиiPG^øþ~,yÌÞ^Q¢rH-Jüèb)[øÒŠ˜£¹rä˜ÃÓÏð>U»Ó™=ûJSxNBŸ,¿Æ=¤¸r +QÿEæ‡ò¾›Þí1æSF& ~”Á”Îy·LÌK‡ZÒ…·9À ÑÍÞ5yãnÄ´(ƽ¶Ac„v‹×¸ ‡ "GÑ*Ðæ—CÞÒ Nâ'pàmã*7^Í%“Â@e+$Z¾÷[ÔÀÈã*ãZ]’»†Ev7$¬ÐÝITVŸëy›ôè€d{UN´¥&ûâ­6EÊ;ÈÅ{Õr’2¯´ÀHÜôI”øñ®év&Ç­C§!à¾y§–aòó’•·êr³ccŸ]}ÔV;™êÿaD›W ¿‹:Àtô)}ˆÕðííAÎ ›n!“¸·v }%˜ „_%Œs¥ªèÕà µj::òÅY«~*3æ²zàƒzvˆ^K¤ûÅÖã)[ZEgdy°¹;õ­ðû¿Ñ•kgïÞ™W½\•÷¶³Iëª § Ul£¸õ7¢ä ´þ$aø0ëj†çœ6ÃÂÌO$[Ä Šm+³ ƒ³>U0†’«18ðv»_ZjÍv^),!šŸ/Êõʾ“fÑ·s_Ž ‹È Ž#ªÞêDÚzql UW:ÐŽ§GWx nBš ²3}+°¬AÍJÃZµ[O’ÍM_zžÎõ‘ÚòÒ#,å2’­?XnúxΫ€yëHž‘ôû¨­ÌŽ[–Kõêb¬Ôï(/ÉrëÑ™ô»¦2ÜÊÎUÿJœ’Q%±~!ørÔYœ[ksO©ñ†‡$¿Lú)¾ØaÙ2;DÅhòó8ö+ä,ù;ùèOH&MI‰f¾¤ÓozŠK¾·à`íÔé§&Þ3>Û“ó¦® ;ô`¯˜hò Ä$ í¡ÜO‘T°4ïÿx\¯ËÏøÂ£Â=Q\æå>PeQã?ØBìž°H.JØsµjÃ`úî~<†s{“[e¯‹së1vå£:A– ³åôjla8S~xïöRN•í–ÒÛ›JdüâÇdô)òænrü±Ø8`„n+wŸQ”ÆÍdGV×¥¨÷ò=Y*8¹…‘µÌzë Ys £"w¥õêÚZ‰ëeKÉR˜3LL"²¥Ïb  %¾å—l6ésà¶”"Ó$OlŠœþ—䟽þH±ž_UÊáÑÇh‚ 6(éÅÞ£¢óMÔ#f$ì,L·TÕ®c&OVsö{¸µÔKþAú#µm#ºw~Ì”g¥G·€Å™‡Èzú Ô¾Š£¾‡ÔÈÞüC”ÚµGŠ+úHErì]ç*Î[×¹AØ´CHè°d¬äòf´C*Ò„Är¯PÇ{§+˜ÂˆHÀ9ÛʶæZ„'²^“íJXZƒ‰ÀÙþC–ZVÚB/ù1^-XîÞxõ¢zß<=‡ßñÔyù„æÄàdâ˜Ñ ¯ivà¢wÙ^ßðøÓ³Ðs_…Á#Û7¾ï⮲Ès¿¯“`(6ñŠFªFÃlš´®2v:Y ƒc÷þ€‹pw‘«l|ͦéÒY°ÈÛîúD÷‹¨¡ß%êþÖÀÏáÊ þÅU ¨XÙbô¬…Û5X/²Éž"?,Âk×¥ùˆ2'Cªua]ä1´6rcx[n4C-îÝOâ~üõÀ—Ï Ïw©{ÞN ëÞ\òÑ.Vù[NWÓ´µ»'Ö¯YïšáM{^d.jÏF,¤lcb¢V ï÷ºûív 1˜Hœ”*å)x>ù"Ž¡Åj[©N‹_ãëêbÓ‘|ôqÃhÁ5h#Ú!.R ݘ+œQ5ëñŽñ‰’M;: èÒ•]1™Ù\Ðñ'³ÃI½Fç4a³3e4teUd ä§ß8Nägqˆõ~Íð=¹?*a•ÛÛóp~ýs]ö®¼qÙž!©Œ {Àn´A¦Hf㥰áè!…‘åöø\ ŽgvËÊñ\·¬2ŒGû‡Í“žÙâÝ$~òÖ<\kÕ®¾ãR붯ÃzvBØÁq]®Æë67"’Ð0{º†Š±?݃àæG¶»‚dÉ >u3D¯ÖÒÉ\À¤baËàb\}‰&{ÿ0·g^e ±æí™–“(®î. z¤AUßpøÄ.Nv—?Q§^í<=ú¬+ê) 0»hl ±Ë¢†_ÿ¿/Cñ’`þ¼MËšbê ?ÇÞÔâ(¥Éô[cÊ3,öáÊ.¿Ž|…B½€4 U»Ãž“‚N¹–MÚ}¦` £Àù)Ê™0\H„-cÿd;t€3î~\ÉãÛ0ë´28M ”B`ÎæMæ6nZ`:BïTÏ“':Dy³†æŒ†j ß‹›ðœÈmóºü DBžçÙ=lr}mÒW/zä‘õÕÔ.I^üd)OŒ&Ãøª¸Ê’ˆª‚ÞydÜÁfQé·Ì<ˆŒW!ËDF“Ð2dkÄ¥à7ÿNÊÈ/Pã|xÄm’àoá§°‡îBͪéȶZ-1?Ôt?ÝëP4B®]í€HS˜¨ [Lr ô¤x|ʶýšŒÛ#‹ í&-ûŽY•<ô’ðÁ2ž%F¼åç-cÖ:3ºøD‹+¢Èu`QIìÿ{RP¤°Ç%)ÀR˜0 z›bæÚú¶ ÔÃ5zÛ (ɾng¼öi!¤óu¹p¦¸ç9 W<ÀZn[qyø„H2Õ`¯xEqÊõö¸öp’Z¨ºA™–_æ©ãð$à´”’ ;7½…oçÚÿ]´±:'äÌóªdÁÀk·•¾ C;skú6Uf.Û›ˆ¬tú=¯Ÿ8ú•ØuwœÒìón×Zÿ)DºÛä²j}ÕùwOGÛòVÍ.$¤fÆá¦´ W7[aàGè¾™•±Îm3¿#4`Áœ‰¼?²)1Pu^®`´#ð.¯sÖºó!Köúq>'·°Ž³_ÇIµÿZà….JjE*×{]ך<¥ðmFºÔ«œÖ =fL7´P46XÛ¨2 ƒŠì7õ¯ DË  m hh†²h¦æ)¸µùmb7™{@ò¯ž÷Yk)ÔoÕî@<ÓUŽêµÀ~<ûÔ‰¨"=}²·P t‡—9àø ¬8è ÜÙ½Z? ¶xž4öûÄ&ÁfÉŽ]y4")­Õš…1áFaŒRL‚æÞ¯LDŠÜÌújÅÈNïQh ãnƒjqH+í,›tÖÖ=‡ Ðà÷ÓhØ0Æ{*çOakN€;x'¸^µ_kþ¶æÕõdR ¡½ȉåª_>z u!í,ëËĉâÝ+rÒ-FV‚ÞFZ«cŽ94†1h ÆP,óÖ'[Äi©¸šùsa&¦Y•h©•rGàuEÿ7´Î.bòµyíÑñïªÏ´Çµ¸ãSgßѳ"3,Nâµ#!"*4,UxX_>7SAg{@®'(^ÿ º4P¯q¿=9 OÛÒ^$Û‹ðM ^ ‚Ѿ6·Sýò£6 ¼4õ©ÃI*°õt˽×ÐMIGpÍ âo_˜Ù;mÜyw-’k"3´ìª K0ÛØ‚Ô{E·}ë™íª}TÜ¡S©¶XTŸ•~¹Æ—îd“Q»¨ì'ÄãP½ñœ7æ[\÷{Ïۑҙܸ2¸4D-w»ðK«$ƒ ÃØí+ ~u(IW]èUgo2!`Ú4Wö`üûg>ŠÝˆþžÃó'Ü2¯a!ë¬å”$Ù3S@E3³U¦Blö Ûi"–÷—w ¯G׋Oc9¤¬K@–µŸ™1|¾·,OkÚÆªƒ „@Ñ G‘$CÁ‹¥²z({Tà°IĹÝþëõÌÌ\ÔÓüD÷8D´ÇIòúØÚ?W>™ï3õ—Ó´'T²aÍaƒü(¿m 9>w–jã·TQ$×.ëYªaïñ“[à²3’æÊ›ä·7±ŽNò|oí`6Äãn·¥ŒB¢³ÓaË‘f”[ø)Þ71$þ÷Ó§+(J  ª¤ÈŒN…ØgÚü"]4¨¤Åý H ¨]ï&2U<›ýû2ÏFˆ‘—k'Ž@.’,l}µ %ê^“ØØ€Á0}òØVùšÙD,“fÛñFÑZ7RÑÚ⛼B™™B¿™þ6ŸÉΙ¶V•²«ZBÝt]¦¢¯†B°Ï¦i±IÆ zw*0Ž ò¸4+ËX´¿Êxw^®|‚˜ŒCJ[ÿ{×EÐÄNd#4I1â»lIá. Øë9È;†m—Æ·6O-o^ž'Ä«§××cœˆÇì6—"•ñ«Uéä­Ø ·§6AâcêÓž­ª8d/¸r“sÃçùóÉaK\:¾ÓïÈÂoƒÅE0`à «O“—·“#¨ûßsR6’8±ˆB÷h`vE”ûŽÚèþmndƒ®0Η:O°$r‘ä瘓þK¾R{ì5¢ÀJ¥‰®LÙÏRŒñ¼ ôL’Ý›$퀶4ò(Ô”"Û ál§®ç !U7 E•‰LþæÆ3-®Ú‹eµÉt÷ £\–ÌQœå–˜F'Â^]^l+L_{#Á†È9]/¥pvKk ’k.Go’ÂK˜°:é¾ÍÖëH.þ¸5À .‰M oJî'®î$L0úVÞ7+¹òJÓ”KB¹“õE…¬¼;”Áwõ…'«GÔ!óâÛWâƒÚMÊr*+2Înª‹@¼&ÜÁkÁh«¢AØßiüÍGO›öT9´°™¢C»<Û³;IééS©)ªâ0£E¿VÓQDGç‰×t Ó­ZƒZ£B‚Á›Àê¸H.P2ÍþBX±ƒúlözeS´•ô´¥"öviC—weÉ“RÜĶæ8Ï9’b_ty¼.,Â&û¶€s±ˆYR Dc@Ø~u8yã~õ.Ñ2ûèKõ‹Ð™àÇ—5“€¬ ÕŒœ§îÊ ©½¿9¦KÈDU8툅ðQdö9k.šk¨Ó =¶Þ6òºÃ—‹‚‰¶áÅq–V€`Õ›Ëè\NœÀdo«{Í&]·C0ؽ]òYØztTg9+ÂÉÍ•=ÿ[‡…©á̧…â]çðÑ_á¢?ÃDÿCFóøhwðÑ/á¢?ÃD±ü4øhð¿†ð?_ó3aÑ)jº…ºahä‘&@K45Ïú5-¦XfÚåŠ(G‹`UDL*X;FÍôKûžuÕ=—…PÓxž¬µà ºŸ¹Af.(t˜}! eq#Ù;xÚ©šÀç3á©M4ÉmØÙXû{SwV¤Gg²éÃÌ;Ð-nE‹·ƒWM^l«Ž£ùc@EæHÙÍ®Ñ!jê¹ì0Çð?L)baú/ÝÃÕþDS_{gK¤p‰±öi;rR,ÊÂáð–DÅ:nUº­*{褷0PœŽ»£¢Øù6‚/à³ÑyÃMj€ kʼn7—Ü'‘Œ®Õ?¡XÝŸAc[]]A ¢ÙˆÃmøØt3ƒ ßb•„ùò'Ig/~)‰˜ë{Ku(õžúÔ²ÂÛ$UJ‹¬)“ë^c™jW…4öSµò¢ñ[TñFr󎽯oB·(q‡Û?iž[F5xnߘÉ> â>P`²ÿ!¸ûLnS`Æ `kõM0»ØÃЩ\YoöiˆÔzO|÷Ú“áòÏS^ÉÉ#3Ø–†À.#7¢Ä„Bmô©ÒÕ¸95ikI®¨Bûë0ÿ8s¬Užaß!è†Ü/ x¼ì;YSðRͅЖ9Wä8HXƪF¹Úö:>Wé‘®­‡',P}á Qš}òæŠ^ia)`KmÖy4Z’< Ó:÷îIO£¦Ά´­y“K¹ÝQï{+êó›ؤµõý/\—+ãyi2BgPø€`é–×|fŽWA-õZb­q“[ßåÇÁ3tm´ÛLh&d*$‰ê:âGÀ¡e#ÔD³ùm³Ÿ¼X"½aA1á®÷¾hjà¯[Rè9}âeJ›ö ƒŒνë2i éÍÒ†0‹^߯CWQòùÝ»aÂifŠ)D(^žœ+ÂVÐR2K‚øB¿ .¥Ž‚Œ8ºI~ð‘Jà;ø\0sö>”É¢¯:ˆoÄ®ô ,ƒ!c\Ðh1àâWÃþL’RÍ+\GœRØPêÏIšŒË÷¼p…˜é¨‹+¬+3IºøÃ ¶q]×"æSÌõ·„Ör;DöHÄô:E¿Ì ÅhnÉØXIJ¯`.Ë,€+¿ª—˜›\b;c¥S^6¶ú*ê-˜)÷eXÜÈÝ1wÌYu‹ak,¥¸ Ë|ø¨7Ž ‚Ôß5Oh;ÁXâ-š «s9ŽÍzuiû::.,wy@gÖ‰e„1luFl)=Ÿ è¬pœÈ Ú1ôv °ÜÍ $dØþ:ѯ‘°1`‚Fø eÅ ‚K{nWêlh6½;€Œp£ÜŸ+Ïö÷^]Ž?òchëžü!ò ÿøœ>õ Ëëg{˜fªëøA9Ž;Q[8|5È D`|¤«Öðf_åÒκvYkD>•¼-†ZOu8,$1=‰þÅÛƤ~y$yN¯2yÑ’³TÀ¤î›uËù£’ï¦Öts>¯BŸÿ "õóIÄh¹@õ“ÀüJÀÏ&¯1øQ…¡ 0t.9¨Ïop•ï)-Õd¸lŽÜ×* âú£€Ä{uÒ&‹ñÉ|ego3›”Ñ+zëV‡’KÖÿGPükz­vTeÚ³3³šf‚wå½Un@㈰HIGÃÊ—¨ à[EpZ0!° CYØÈ<+ §ÉôŠ3#GUukY˜6àÛ·F¹$3.2-½õÎ÷gUé/¿¡õâ«›5Ï3vGÈ7ÃgÏã8‡ ×;?¤Egp5Š!C8¶Žl,Ë’Žã! öγà:5øÀY|mîÀ0‡¬òN£ê fÁ›áb“ãå09ÞÃÉ=¨Ëˆ¢öˆgUqB^mw’<Ó1„gO¬Ær×`x‰§§½?飌¾7˺EÅÌ gHôïXy¹1[=¸Ý2aÐu…ÈÿZ´—2¨4F·ýº-5çmËVRñ?Äý¹©t=þ6šß¹*PVxxŽñZiÐÕ€¸†êDgÀizå`ž(¢Ø]>m§n¹Ê€Õ8 IÛC%®´z¨4™‚!¹Út€§Ñ¸ìÕ<ÑzÖáÄïÿúÄ\Ö €Õ˜¥¶ñ «Q¼IøX®Ø0Ê%ÏÒÌj Ù›Jו‰^8ªšÁÂn.øf‚¤I?y[”@Ï×ðÏ,©¦¶ŸŽVœ¼7_ËT÷júoc1Sjr¡‹$¾_ļS‹Dƒ&äz×G†×¬µ*޽dhö冘jür(ÚÔc½@x™1M6ŸáÌ…®vÁ• ÎØ'•äÇâÈ0¿¼„uoþÑVRJ—Cw†ªº"ížX™G ÒÎ[ïÇ*{v:­Èùe)¼@¨âSÉf?©`'¥ÇóiëÕpÌ‚ááümAÕß)ðô´˜À™ÎÝúhçÔ ¤›ù=Òì@¢õð™çIuÖS×0iÕ_&îY]Ç=ÏHù0.,Ÿ ¤‡w;fU0¦™iäú´§#m¹¨lᜎÂ\¤Î““‹H«SâCP0M|’ ‚Õ ,ø‰ý¾ ôd½¯ÛEëÕ\2öc¶µÊ¼+~Œ<†óÖò4ï÷MÂEÁ̾½Ì|ú][Æ/Uœj<…5 gááo%6Úë¢ø‚0 Q%¿f?ï»A"šÀ?\q»zÿ"b&.€û²£`SÈ£Uˆ²Ê‚b»T¿²m\`,ßÞ] Æ·0¥î‰ƒåyE8ž]§]Ñ2¯åÓµ‚ÚRxº…Ê# “«Y)ìòã_Â…ñ·)9úc½¹7/¹€bÒŽ8QŸ½XÚeª6cÙ‚øt›'Kö­ŸÓ„ŸAtJ àˆ}"B0%Lg©^š¬aìµt?S€AÉFEBX£6ЩǛq ·°>)ß×[ ‘uëý÷úœXR¦}1¯„±¥kÕ üå£<ªA¸ö¯„‚Z¼†"HQ·ÅAÆJ”ºx‹!·Zý–1 ZȲ,a®¦Š£V7#Û˜‚¼Ç S°¯Ø9ÛHä‡ÉÿdÖékÝ‚}€H){’‡P.R4ÿGÑ » )Ú G¢ù€ë=õ,(kLŽªDƒ‹2Ú—MBµ~>ãÈÕf›Y„¯Ñ/)x€»ãb¶fP¾#7ô<âÙ§Û°þÜVRF›9§Ô"þº¶B`ºc;lvuÇY¸#§ÅξXã§`% q&+M3ôT¶ç°X³ßÝpáÙö°$o Ûl×ÉEμ„eñþÑ„Ž%!8×Ì€—gìf]VÁý¡¿üÕ‰‡/÷w¥’j0\t/¿'IÇx ÈÇ]0{€ùIK’É^\‡®õ"Ј‚ñŒ›k&Ð%";òô޲¯8Þ8½ÉþÿЇ‡y-ú®þE&<¯]}tÝCÓ--"7D×Ç dÎ÷mÂ4ÛFyí {wñÓ ó:DäAs±«¦ÆÌ겇¦K3ô k àZ‹³°MàúÀ·‚žÁX_ò+N­0¸«ZŠÔÓ,1Ξnìö7öOzóÂUZ«#Ë¢h°3<è«QT$ˆèÿWÉ‹6ž?‹þm ‚´<ä¦ç¬Í^ñnþÚ8¨€#C^†ïبC´yk†xÖ@Xlü$‹ÄLñaS…ØgÑíß;?Éò57’+á¶÷b] 2 $H]7ëÿ2pGu1ˆG¯¬ˆèÉç¢ëÅ]oÚ‰buI¹-qNRd«½çH@¼€(ª7~– ”7ÊI·Ø©K±“0]UÆÑyE^.7÷Kψ’_‡Œ iiÁìr«tkœ¾¹ÇÝÈÀ>O܈7Q^ž4 ¾šLv=Ô3Þ•:©g‹­åDø'ÜNÀôïú©—4šTƒÅ7rt¡Ö­k`|$,ƒTþÞ•)k"w ÛYkϰIµ£nÉç³ÎS²9ƒ¤ˆ›ì òªhOsäûúØÒbÿ7-§ù"PPý‰G=IÝBWu s6î> zS$U÷ºWõ /æ8£÷ç¬ù#[-°§6¤DÚ¶>ª¹ö躄Ͷ%$ךÖ·ªœi¦¦+ë¨K}Î(—+p::rÝ–qtø ÈLBKysÇÇÙ$ÚÑ5¹¾A÷¬*¹AަX?w{õÅÆ‚ì`"ç¦G7f%zÀ€]ÜòMŸÐ©½ýdcBtý(òÕ°t»õW-–pgä¸âÔ0àæ=¨h/#pº8oJÕ_€(ç?¹­yøžwsÀj1Ö8ư-¢Úþ.¸ÿ;=GµÞýµ,¸ß(Ö]ÎHðtK¦ô“ÄÃ!ÿýsÆ~HsŽCÞ˜> Ç¢ê/ˆÉæ1à:†år ÿŠjð½ñ"–4 j)õØ«7ÂmfT¬^Û ¢¸ÆÖråUV}‘¼®b\SªV:š/¼Ëz0KNîÝ>S×—9zÜ'Ê$ZÊ ïRTQBCp'…%ËÕš«Z­ ÜÚ¶Ò[Û¨¬dt¾nØW)=œ‘ŠÅî¶ä^-#ÁὈkJ‹Å” â[ì ½Éµˆã"V¥f/Þû”÷ÂF…€åè?“›«žAÔݞݯó\PèÕAùÝbJ6 ºï´ˆ„ÕU{ÑÄ™¡K4]TïªíLâA6ƒÅôÊ ‘»x•§Š½•f×~êÇ=pCÀ©i' p"‹lµ‡%ñ³Â©`p@ iø%Õ0¿ñtwR¤¿7mñwü«&¿!ž‡ÄXß~À…#]€ôÎ 5õ#«_‘‰›4R8-%W+7ËbÞ!ù`~ã?+~¬ißZ)éÌ8ý+çŸõ©\柸:±ÏX¡%kê~ù\å!r­SÏþÍÑ›„h¯:-ÛØËŸR€Œ¥A•´_wGTGK„/Æp-Žuûú·.þìod6®êzÆ.= ŸËŸG8(ÒÒ¾.„ª0¬9!¦hèo jÇs~'Ä.9‰=Mð·:pÎñ=W(ŒQ°˜ß”9ŠVQàåEHæ Ê–ûJ¢ye·‰¦5!x,ê¯Êì¹qÝ“:ÂV}7YQ¶Oÿ'â$îs/»(ÚrtKeÍ4_ÇͨYPOÀâCtôVã¼VL¤×ˆêưo‰²Éœ; 4 P Ѱ¹ïXImáô\î×’˜M»®Å#¬BQ÷¼Þ.wG™<è}+Âù??ÖZ…0)&÷Ó¦":eÖj­Ù It£À/!൳˜RµfQ«¸uáßwêvsW} L+&Öwu¬uÜáJ†õd}̽)¨¯µNM«)¿ÊâáĂƩ²&ÉÞªÁFþ&Z[Ûe†\Õó*ÛùJ¦nj>{ |ˆ—!I0¶BV6¶/rƒŽL~úÌ*LóX³$"Ó…è¥ þN}X’ªþP&ÕcòzÒÛàÔÓçØ|ÓÛc|€³_ôü?_ymÓTã©Á–$åIr°‚á¹[±©ÿWS/íDƒÞ„,>‘t¸æz<rø%‚û OílÔ| ¶6oKðÊØÉá~é çZp+Í Ê¹xÒšfLY0¼ÿ {}OûÁ–6 XNáý4;69.‘œÝOÃ"É&ˆ#9ÝPZ°']ðXØï!ÝùàÚŽeW&4´<À›&2ÌîÔ6 Ÿ5oô?#"BºnY¡4¥Œ¬°hÇE ªbSŒÈtþåš(K&Vèåþœ•IéFå¦PG,W  J$©„xnAÖRoñ.(ñeßâ:&µÚ2MÛñõµ+x;—鮵$n–D êsÚµF|H˜¶Ô2Äü;³,0»+ý™ËF2KæK¶®sàV0óËê5ÉÐê0¿-…xSý#ýgÍ+ÎŒR­a /åŸ%c D·-MAâ%Ìx¶í·{í&œ86ÕÊkH´ý”ÕZd"Z$ÀP´á¨h¿®] 5?˜­½t*F׌ý;QGßè:—GhwêJnyv¤;JÌÓ9{žÏ`-Äñf[ŒLOâšÙñ¾µÇw„=H¸CõêqqŸï†LÉ|áS·6m†~G £ßÓÊYù»#¹…õ̶SU—S£ÕýM'ø ú¦ôu"EƒRgU'$P罌ñÕ““`÷Ü!G`]9OúW×55+—ö¯YÉlñ«‰rññ師ò Z@eÃŽ!*ãÌ¢¶È4a«÷£õ›ê#³÷³ã—c+ áÆ/óìF" ™´cüa!ð ‰4“ŸøZo ù€ŠÒ SfrÍ¡\`úžØ~žÚUÙiâÎ6Õ³ŒX¥8hÁ´FkF\ .½L0ÖêÜ<ÙÀø>ÏÁòϳásSpmpGÑõ¹3FÇjÞÄÌ«½ ¡ò Ë,SÝÒÖ½à‡ys-¨`‹6AÕ7@|çÏزÙÿKIgù#.Ë%1LQssÜD°º£Ö28y˜Ð³WeJ ¶‘î0|¡1!‚k=wPTé¡ùÓ„‰ÛèÎ+»ÈíYϬÆ0«g[ó%ö‘T*Y‡SoMOòß%HŒ'³ëð•âHî_Û4¯ªƒµ÷³¸ú¹"PÇU×OBj¶gžÕgagfbIn{“"}–@IصѽٙY×Ó¼¹m‚ï²øqÚ°ü¹­>TÉòÝ’7ªÁÛ <£d=åÛŸpð3µ] }O;sèþ°A1l¥‡5È¡Ym‘wÓ±&Xût­?-››¥„ß§‘ó&0*ÿ¨Åûw£˜‹Ž–Sùá‡2€Õ ’M—h˜†Ôg]ý˜ZÇH´ˆõÙ¾äó)#8û$b“?£Ú\0 øŽCêŽé’Iûi÷ä³IŒn6Ýwæ~.âË2Š6«†maÝJ"°›Œ¬a–Ú+ 4Ú$%³ Itæy›ï—žBôœu9ð¨ÀZÄÃ(D5íQcO_â‘ÁÇÕ(¾3búåm3á"EæDÓö©%¥84G‹j*ÛPCH;PüÌ‹I† •Ì$Z:|yHuË£¬Í¨'½ó¡¦ÖÎñZçEyâ@u8‹šÊãLb<®jÃŽn¢I¡çàükÉý¾ký…>ØùÃ'Y14w»¥hœC`æðÓ~'dÚ‚×°ÉÖ\4LA¢CyS|¹HõWöJx霹'‚%nRõ™JççPˆ+¶Ô¦²?®Ë¤y¨ÜÙƒU 9pèwxŽå*¿YÑІJ_®Ó/«kƒñÑÌhY_,¢ D‹§„}[bp÷"E6ôbê82‚¥h Õ¶z`t©!¤<ÊÑ“vZniEÞJçí2ÓÖŸœ}ˆÉ>a5èáy‡Á3¥…ì²G9†¤,úÜð²ý¡þ7•|uÊ)`²â´–õ4iôlrWÚ§W,meâé Ž[Qž2yÉ”Ð&©¤GܱˆºíûÍåÕÑÜ s)<è&¢‚áËôð¥{åÔdF¿[MÎ'/å°˜×Åh‰ø,aB¶iÚ'mUMðKÂSñ¬´e¨ÊQ€‘Kâcׂ֒‚Câ ¯©{±FºÅ”¹nd}ÅÈá¨oI.é[8d5cÐJ *ÁbNd‘ü¯,sJáÎô¡Þâ`¼Ì£ù q=ÕVŸ¬0–~R²‹æS¥žvÜÎñ…éÂÀ#Ó ²½„C}hù_nÜpÒqõ,„Ö%ºYz#^‰+8³_á˨ž±Ç†eSÍÏ QŸö3:ýªÍì¬×&Ú'Š#AÃÑ'‰Š[DïÖ2šŸZ:Þ¢.d‘FاPŸG‹“Jˆ™Ncjú63 5J/£'6§óJ–ã{w¡©E¿]$ Ž)j«y‹vc0Å™VÃÜ9 KŒ»&Í1Ç Ÿù ãqÜïµ]…û‘ËêRÛO–ûK—ˆÄžçH4¯EàM?êçõ¨ ËÞñâgf€<·Ÿ±Â"ÿ YàŒº«„‚ ¦v!¡[Fq\î8º=‡Âè`[δ”=tL¡€ÄÌ-$Îw%2 ¬Þ…Ú9%N„C!Äd9"ú×sý)”Ìÿ| þ¼APõ*^¤àø?z³(‰šÐH¤÷‚þ¯Ä¡Õ~ØÅ°ÈQŸÁ†+…Áe{¾Û¡7)ªÚœÖtS½2 v~ÔÕëí8üëʤÔq‡s¼"7 {õOÚ!9ùßìéº'ÝY {èH—\Bð¯ÍI+!ëbèç®õÁ‰–#-yç|ꌋ2c]ܱnœ†”wI@ˆ©ºt:Ïv&ç™zj ùÈ”rZ~v˜ë# LY7 Ÿ(œ^G_œ<ý‡¬¬‹¥(Ð%tÛ2’ºNx”˜ñ•ô WÔ@€§[Ìj9f?ßQ˜ÖOQ¯T­º ÐÈ×Ã"HàH–‰ݳÎrx’ÑŽ¢"qû8° Lk»þƒa5ªÎú©.b ¿äÍ?&RAx”füÆ“žE<Æ«´¶û1àiWu‘­Û=…(“ç)íaÍVF@I³•ûÀvÃÔùcë­Í¢ÏáWUeÏA°Ôæñ­¨€|œOáù´aÛ–»Uz´Z¬‚ê`}YOVy^ÌÔ WI†|J:âxP?_=Ì5a‹ýæßë}©øÏ9Þ®P7xð~´÷žÖ©L£güBÏÚ(6„ŠX@üÇm ÷·è9¿QªZ»ÑÙìðdûVчç<á§ËÑW>sÅ”C“’œ:OÜôL´%›š_¸EOÀ=’ÈØ š0(«Ü“/¼Àéè–À*vH™]Àš)(¯ýr)‘’— äPa/c~{pª”Èr"kŸ»·“[š‚ÒÜêi[Ô+_°w­Æd¸]AãüDÈ‘+ t+—\6ì½`­6äÕ£A/Æ]C7’6U8¶»Ò8‚¨ur¡¬uÐLÿjEÀFÐ7"œTUÞₘ§Ö5y¯&SÝ„ÓÛMªù¸#Ÿ4DÌ>³€¬# ¿‹:&K› ~äËV¦Á„$.hÿ€Vï™iirL¤¡íP3|)KeíU«"|*Là«IñdˆuŒ«ØÜûÀÒ5  çpz¡|•L{½NÜÑî~™ |pR„ˆ ™TŽvMÜjAÕ-Õõ CÖºò¥l†Ê–\,D²ñK^gÏé»—^bfRBÍ8£ÓmförO5Éý÷ür¢óÌèAú¦ë$\pMì÷©>J'žu|h*›ŽcÊc˜q¹â•Ù½Ì÷êä Y²âz·î™·GåµíË}e’ù1ÖžÝîÕÚ—’Ž‘‘l!Vê™~}% Boy¦ÏÜqORË”š+J×¢ ð&º˜åYUÛ~î}‘"³pùûCLb{ßYOð4iVKO¶ÿ"ï¥åp}üûÕŠß( w8Ù.VæD¶ëëùº(…Œí©ŽHägÆ—‹ìÄ}¾þ…mnÏ HVÏ/êEn®pHEóJ?Ë­®ßÞm *QÛjp Ô–7d×$nNÃ@ –Ìýk qS0—xþ1eŸø‚‹v3ñˆ‚%õI:ε4ôÄm·!^»ö v÷¦Ô¼b¬‘€_ á«®±Ýã»x£pdq~ÜÐÍ(îL‡c¯c^çŽ] OE†>äñD/ì=ðî§Ûw¡ƒ‡b饠% œß%úrmG ~Ä@¤+ Z³§°Vñ±€–á=L´¹¬ÕJñ Wº4 ÉZ}Ü&¦#Ñ@Ú†L¿ÃÐÎm£ÜU«Áëv> ­JŒ†K*Ú,Jfž,„¼!çÄcÛ¯mº¬îîôõÔU×:xLÙí·ZL›cv®ú—šE\_%h‡Æ—ôáp¨Ñ{×Ôvž’%ŠÈ‹:ú`p$S‚åsÔ4 -À—Ö¸:R¼ÊpðT6[Þ´•0ˆ(GlVÖW<0z]'›‚o\ôÇåêæ$û þ[WpàÓ™EEôÅpª•ÛLäŽH‹8+4¬©£(Ø7MwÑ”ð*¢òÚô T“7ìÀ° žX²¼ €>­2àÅ·^’<úÎÝr´}¦#>ëg¤»ÌC]2ÆÍ¶ŸœÉü‡å‚°1Ë4i9x³S\¡OYpUB‡r¬^Ø„ôŸWËà­EÇó²€Lt-IŒèâ;G1C§Bú5ñ„ÍÌp@³]u-ËY(´%°u«PæöÄúú{þ±+7ƒ“”õ-?¡ÿxÏÍ8•5ú 4ÞäI²jBÚ×:MŠ7Ãsâ£íòqiMõ’%˜’7G®õ¦*y«AYkŽŽàc¥<»Q8XA3M»æ‡ýˆ’Ø{²úáÚG«t¤¶WGµqèÅV–3ÎïÄöŽ×‰>`Åw¨ØÌ7Wè”±Ø7f¿±Ì4šçXïÆ·àcàÆ8Ï©p*Rê·®Ö®>Òî»9>Ñ5{v€¡WÉ&o7ƃTëÐ Îm>ìDJ:$¡€èŠ2×< kŠ¿ÑªßÊŽé€â2.§xßCUk«$Gå…·#–ƒU‰ 3ßt›£‰·GQ‰Ÿ½h=OŠ~ü›fuµt]%ÁÉöб“–G‹üEŠë½úeà’ÃSÏ6¼3ð3 œ¿HuJ*½MMÚk·>â±l#Í€öÑÜ‘ìÆyÖÚp¥ø’,}$/¼ Í=íz9qZóø¶ÛcÈW2 áXQ£¾d~¸¦ £í’°àТÂAÍÉÅ.3ŠRg )NZ/ÿlÒ°¿¨­¡èçŸëòrF74£ê¢,b¥â€†m7ÙYèX8剓Uß5ÿu_¾ ®bYשåƒCCÅv20hË{qôik:A¯¶üžƒ •U³¨ÎG£ 6^“µi"2Fø–ÆÏõ:y¾7”ú‹9Î=±ø<¦#)”˜6-Æ%\“øñŽÂ'A%¸ý²å¦bëQ‘ýúo>Vκ,ã/Þ¬‚¤0„¸Ö’* ÚàšA Uà?DîÓ}X:‹=QMq`äøÿD78moÜ÷ ³`—«¾F?õçJU;S@_OMþµ¤ª‹`…ŒïL<8ÐÄ$YœÈVí_R˜U[A‰‹Ž‡²æ1ÞþRA@ &º«¨9ôrÂÅá»ÛîзDd~¶ïóƒ"ê1:aØ*È{â=HI½¶8È›³iéô×l—^øWz-åhâô‚òoÈóË6–¼B R>K×û“3æL#¨`{÷¢ñù«ù‰LUC8‰Ã!°+4p4Ó…À<ßòm—€ë¯ø*$)õ‡*üb#¢ ·=ûã(èT”œò·²ÆXv9 Ùµe øÇhIʀȔ©þ.›Ô¥½’«ýÆ·2„3Z:ÙªÛ¢pôÉ“ÿb®ûC0ˆí¼&DÑ7—©•6ããZ Eïï£è™øèÄ3ÿBÂ]¿p¡?ºŠ±LËýLVŽØ5é€jlNs‰S{o+¢+Ö„ˆóŽÛ² §ýö}aé”á2NÄìÞ…d+¬xBÍÙq0‚ÖàF¤µzmëbà!k3ÌTáã¢øáþ,Àî!Ì<ð{ÖÆ±$3ò ׈þk£1_ôtb„Ä2¶Ãÿmt\,­OäÓðs…býn¹ûÒªùBvâĽV;pý-ÏAzA4&Ù`im¦Ú öœþ=ª](ÌRݴˬ ¿š‰š±X² KÓË2&½“¥ÔtÒ§m³Ç$1Frž"8ÀMÑ*ß™âÛú %M€“«) ›e+A%˜Pa ÛÅ€Ïu¬n÷êdCn°§YDAé8ð;+dާVr¾k$ 'o1Ëš¥SÉ/Ï/П!±)”ª £m=xÅ…À²Š¡'l"Âà,më€MævvÃü8¹”c€ûÉ­¢Çý£Ò$¢×äðó3ÓÆT1—Ã`ÕëâÒ<çØwöÎ,Ñ2e¾äGˆn-x@;Ê!ع1ôà Š'„ʘuKÖ²‡,sY 3~bô²pèaP¡Ø ;í Wæ7\þÇ—\fr}±'+-ÁÚðßµ$èE0ÿPžz)ùk¥ˆ0â÷ÇŽ¢÷À*eÎȪK‡xn³²­bí B"»c»¨Ò€'6Ï@Î’+ ‡7†K`¹BOôÖo”U­G}ÙŽ¿Z›S——º†„aîZ›‹wBÞ …òÌEòÔ¯(ÒÌ‚é¯ÈM¢ê IØýð£%ÀaÙ›YZQ²ImÕ©ôœDc.óK&1Z ù Â&‰êXAŽO#9WûCßÖÐMý³ª­èõHü³Ó`“}Y€*ë¶£ÍYûi™Àþá§•·NÚ%ÀðÊš0’EácÚA½Iz[þ8µ*Óó’OÁ³f}¹¼"^êL´‡•vêÖªñJIAdŸ9,Ÿ'­N¢È‘å¸ô#q?áÀ:6Ê;^4± ¹‚VÓ-4­ tìhkîņ»ÔgèòI­[‹ÜM¬-z7¨‚z•ž0ìT·YùÌø9»î™†O²àª:›9 UYÄ-çæ÷-v†„äô÷âR}=7ÇZ„§eû7wLú³ìRaáÅü8ÉD)”ëKÂÛ:zýI Qe'®U,„îÉÿgf±Lƒ+¸½C¯ÑŒ]»='b¶ùSºwÌÖë‡iÒJ{%pÍù[‹í‹Tª2î§#‘¸A£Šž# ˜=ðþ÷ކ%u_v¡kÒ_R®Ä8‰Uˆ›#ír{zR ßÈã6ì¨ÛøDEDÒݾÀƒZ$™"Yom©b ¦êy¦är1h·¸ðMyýÚë = C•G›¸äh“DF:F‹]~G‘Z¬[¾"0á ïÄ& ܆—Q¾q¢Ý¨­(§Žü‹'Æë³+ƒÊY¼ÌÑÍàŠl¢ÎM¹7—VÝòƲ͌op±•S Ö²ÔÕ8X<1¬¢!²ó¥í•j#÷„p;‚cݾÙ^ƒªàΕ>‹RDi û˜„·]ÚD–ÇñHýâ ù©70ómÏ?í0nîIP ÏÔЀO»_ãB¸>Ž‹méfÜé~hÙg¯7^y¼[~ãÑ7œ"Pöq{x©³ùq èSýf]y$(fA®;›ÌCdêþ´Þ'fÀRÝÄ©þï·"ªMÁÂWÔ—®— ¨a!õËTEzµ*£®žª)‚65Z¸´CZjs^i°„ûLŒeIÜÕáô…°£.è«ìº tű5É€/{¡1U2 ]騡€tÖtBêÓLàx–ùpÝfÕüÈmÅïïêVKcþ©Ë³ëà!ß3¾Ž“=##t|–[àZ+.v„§Ùа3í€vÈ:ú÷tGÚY xfòî}C îgv~`®›†ÄŠp=%S4?/”$DŸ lÒÍD×s *T†iü|z1,[Š Ídaóؽm£c½þ(¢ê‘+@4xAIÀOpBÔ7Öàçáä°Ò-äË•¶[*þjt­å“>ˆ›LÄ/…ÐoÓÞjOò?5ãPh8…[A2òåâòÞ8ß:*oü="x;Cîðª0™Wrj‚Ü{„¨8ÿ½ÂDz mdiwÜûâH-Yµ9™QkÅŸnþ¯F¾ç?ÜRòÎ©å€ ùvû ” §  'ŠL·szŽs–QäÁá ='k'ºÛ*LêÔ8Šÿbw<äÉpe‹ ZŠCøÙúñ«»«‰'¡‘ ܪüw4„¼Þ¥`Ì1ýiûÎäC1£·êÔŸ£õ’Šø´Œm &¤¼SZyþv7^>’E4òD¿ Uq¿AÁPŽ¥¬@„ÛMI—‚'l܆7•®ÀO=Ø4çnàKò E]Ä;]=(É¥þ¾²©ŠÃmO6jð<ÚÎ~/a:é? Q¿J¡ÂÂHRõ³ò_æì]³„¤ ’Ѹ¬Vâ!a„:‰– ÿH“zg»ßô£: ‡W<ÆžûŸ _?&‰¥µ÷,ÉÎ<ÉÆónÃra)KY…kܱÜ&'CV2¢÷v`xKë(o3}é>Çd'Ý)¾¢ÐŠ 1¹Û¥šË&ýVå@–3Ö½`ò~ÏRùf–…$¾š¾´pP‚;9²¨~^òu(¯×‰oDìÔ„Õ™Ó²=,ÍÕcþ2#±YûcõBnz]*Cì5m8³D㿾Á†Š¾Çð&µq ádÙ_ìý ›§îõ›G£ ÑÅ"³€ÀG# #|µƒë{¸ß1ì+„±äªIO†8¦Âó‹š¡*Ç@gÚû4Àk³ŠR—g™æ¶œPt*óŸUp,ZÞ{€ c´í ÿQø0:ÑIãœæ ô—õ¨ ËÃ>²rš}:¶!L~ÉDDe0æ¿Ï\C±Ád·H‰Hí̹Q¸[MXhå€}ÆÒ¾œjÝ‘8Å@[ÝN•ZÛ¸–rá?KÎãÙÆá~AÞ$º¹¹h&i÷ ÁÍ1M8¡7Rµ ùÿ<<ªysŠ4~ºM…2]»0IË›€²ý„¬]dÙ3\Å@!YÄÑËa·é*{OÆ­¸¡?W VaY8Z¨uÑÈ4}ëëÁ€ó&”ðàKÓÿF4æ¨é•^öÎÌÊhý ¿eÀ”qŠV§Ý@–ßÅF]1CŽà!r0^Y.Æbt}Ãq« ¡@~ùÃs© å럞»öµ˜BÎxÈ/å\r·š£öŸíÁÉ,û땇‰¨ÇrÚ>ŸS¢i'$W¹òÆ øø³Sý—ç·IåÒLtë}qV–×úæ+§"cÂiOÓ–'ê § üzÔîä8@…^m?X8úÂìN„x`Aơӑ*q›I[Öo ÙÑÙ­¯*åŽÙ)ì«5Ô©Gn£Üã0m š{&!ß3>õM < wÜÖfEª“ îJ¢—êÚ=|w'¼­m-¥±$Ò ^_rBTÚXŽøO†~LZØ@žŸéãÎjîþYG„#ù½±ä‰ɽØœí‰ùª½h´.^ç–Ô=is64gøVš³8áUÆ\ä ©ï!Þ½“±¦Óý :2õãšÙWtÆÚéÎ+[ e×—^ž']\>ë\¯nµ«áauäÄwxwP«Üh1Ü…l›Ž´J,)û©°{ åo-BE¬IxaZv}*Ŭ@Àšè»³UÉ]÷ö¥‚ڢäW´ÂÝÉ”ˆˆJ˜©ØdæB¹ÊWxš±xH‡ÂuÑLúé6Ò9¶“ÝœÞÄPg ß› º*Qc38jä_´›\_Ökž¶}PˆfÓÇ©ìÁ¿ñ&¦ïUú¯@†»+DÃ7å™aöÉ>i§Ð¦È¥À3k'šÃ÷ƒ¬mìX̨ÁIouG“ÛÓOÉ)øÙ‘ƒð¿uà‚cŽ1ÖÛõ´«{sáüM0{L­)Î<Ÿt>Å|HëmBüdƒHIš% K™J×;[v^–3¦ŽÇæÜú‰¹ä%Q$Ö¿Í„RïÑ?.½:êìyì­¹ýÈÔZˆØÂŒŸnòÔtH¸sùW4E²sÌï,dðWž‚d»õí›SÏfhøcÁõ,ÊâèëÒ ¦Õ(Q<Å †®Pt)¥#EbãHÚòhó]ë<^ýR élŸ¢ÇŠ'3¹HÈkahø,¬4õìQøf3¹ÚŠÔW–h¹ï!®@ m춺ä÷O³!Çãàd?ô`A‚ž7<µ@ŠwË¢õÜ…öF}(äøn8~bû’9n| hïr!FçÙˆªü,”>ư b˜K,¦(OÏÛ[Õc÷I %@]Tvæ›yÂVì*bOóOþFk‚—~E{”*@VqL„¢äçùÕ)Ù¯–ä‘!5ü±ùrÔ+ÈÅ€S¡³Î+“šiØdƒ bB~:¤ý`åUºýÒªjaÄñ¾”äoÚR ~• ³çó€CÕÞ.GºNó§Ô tè‡_ÂúuŽ,˜hšPZò æ;×Á6÷…ý5‹Mi‚zŸÿzBNWÙwùùâ]‹¶=—˜QZê/µÒe¾m²^XpÕ¶}= M Ÿ²Íu#>áp¿·dzPðx½Û/–óQN/||˜^OkJCÔ4CÎçÄ¿l|³V °6êVý.˲õ«‚ÙÄã£Áçð£ÑjSf7–ê·Öƒ…rûÕêr‹Ø‡7¨ŠòH‘€÷Z‰{…‰¬ € r‡Š?N/ñ¤7o Ö²ÚíB@Üçy¡´äÞI‘¤âü ›ŠÊ–ªðNM?¹ž»ÖÌV+»ðÞKmqxVhêRÍåÙyÚÏR×<·<Ö«åœUKÁ9Ÿª˜ô(Å«jÞh©𛝓Á±bsHÅ~;¸*ppÐwc½ñoT±ˆúÝù†ɾuÎ’¯†ØˆáiŠcŠ=QÆeµô ˆþ3AèR 8*v›>&‡ë‡æYfËà1žPê ß6Oöè^\RLâ5åÉÑ LRŸì+ã™8öªTëñðíòW³ÔòaãñÕ›n³Rùâ^Ÿ¦Õø¯Œ±ÉÀ7ÀSº²_„SsàØˆï_Ñ`0£—.RGø7íÅÎTäÎÓø*¶þ¢0uÈm¹†h:Ï)åÖ "x£ª¤{4vj&&´øþK¥ŒÞ1îJ1j;}DWéVA´DO ¬5uŸ¥+)~Ý•ò1ÒËQ\°g6k»Ý¹ï"mÞÓ^üÁ Á—k7hÝü]ê÷ÇÆÊD*ļ¯v`zX۔Ǘ¨4€–kÙǸ쮳í Áb‹õ…%‚›,5 CžÛ½ ù(SÙ.- gBŠæï %£}~ŠOñ+UÞÊÊʪ()+"½丌[uŽ™ža:Y[·m5‡í„†?YÁ¢ú·ñÊ;}#ˆ/`(‹@Ètš+Pª/¼9¡˜h QÖWØûâД‘äïÕ~+É®tŸ­Ž¼F×J»«ÁÆT#zm‡5 €ÞÑçg•Zš]Ì"üÜÍ‹è†K eüØ´×9_òo£+-6¿Ÿ² ògZ&¿ÒkTmœ8‰–µ'ZäJ:¾°ïX~Ö ?Þ`;A…¢‘±vG¡Ãýž-YRÐ7s°FÅvÈ×A™§¦Ål¹“ü…ÙÎŽ~tæ…y¶- ßãVô6šƒÃð@=툤¼›UgI(ßÎͲc"Õ#»¨ŒýÎ}3…‚ÀX]Ï1®°ñ*bòýhµ5÷(?÷r5êÚ¦¬®Ý¾^‘ήÅxy³-(W¶$=ñ\¹¤Úâ­ÁÕÀyêï®÷»Tw^± tx¹ \Ô¾,\.Òý½Qt¥óY9bÜôéþõc±wwPø¢o¼§u˜ à Á'b,C Ÿ‰\€‹ï÷f!øñ,•î̾E7™‰9ÁC³IÍ ñ>2/ª£;õÞ‹Ü¥Éß ­"@,wb]üíey±Ûp“»EqÝÒ4:wíÑ`1¬¦ì‹tfçmh6AkÊÖ‚Ÿ¾ë4øNh.7H®ý_ÝéÂÊ÷ØÕÙ/õfà€Pox69>܆EÞe=‘´hDžݳÐC@mƒÆä%#†LÀB#Ë­gú‘—W€,šƒ¨ð<Û$·r§v;Õu³±.BœÜ~š€ðe*÷? 2v4a â9Icá@⇉ÐÁsxJ{ µrmïÁ¤¡¦‹dhËãZ¬@·ZøÏÂ%7Ùcâ…㪥Egÿth ®íâÖ<)1b©'åö²J+$žô¯ÆŒÖÞ!ÇäPcò@åÒ"Ú’9ó¬Z€}Ý'0ˆû4•ŒiÙ‚…ÐÇôC ü ¨œxAUUô¦ff‹«WjÂûÔÊ·—=›£)üªDH¹çDÕrñÎb{31kw¢}¸‘_gmÂ6"¬.™=7êü“.3pP¬R¤²N÷xâa}¶qãr‘À:WÞ½ƒ4ÊŸÍø8éæXdSg4³ëw”€elÊ9Ü….0c*PxîÃ_t†#KGW¶ZÔ1b—ÅÅÿ2Ãâ¯Pj¬Ÿ©ý¶Œ½‰vHVJ¥•8 AŽ*ÍŒ.<étëª×w`#»ô(œ 0Õu5Qìê»È ì`„R¾¨ ‰¹X¬#—¦ ’õg[çpõ¤Êv ¥nüÏ#„IÕ’•{|“$ü÷ŠvýMµã• O.ö»Çx s£'ô–ÓÎ|@_ߎªòæ=f¸•s¢F@9šºJ­±ó8ÃýtÀ˜@ô¯ú¾q¬Î’ª'J~ {®Üõh¶7ý|cåô#–èµõéOˆ±«"cß²ýºÌ5¼_]^¶ ,dê‡âŽœÅ5GWä.À1¾¾¯ØIûîê‚Cã\@ðx§áÖãÏŒ¤•_ŒóOP®Üîœ Ž•Tœ5ŠÆÜ—(–£;^ѪÈÀò­¾ïÊÒûîGX÷_þ|&ìÖEJæ”î4Ûh÷S«¦^ŒC©Zh£«‘ ]Ÿñ„ƒC² z²êàEŽmFW“Í”DµÚ†²e&FJÓêÅÕ1Õ=ÌƾÛÜð¹1;vbÑãV½K§è3Ó4 ôÃW÷¬n¾³r,qaòµOw{ÿ/Û?]&ü‘i’æ>Ö´€A M»nkÖ’³m•oÅ#aFcÐ. #Qn À=äØxKHÍuòâä‚éÉmŠvˤB Uòˆ[®iÌY¥;çG®UÀð£¤ö 2Žœ8ÙT)%êþ÷•RȨòÅbȨÙuʵnóü4·øhGü4SøiðÜïá_ —þÿa¯—ÛÐ}£ÿa«ÃK†„ÿ† .çøiðÒøigðÒOá·ß«þ5ü:ï·Mo·y{í¾Ý%þQü4wøiðÒ~?ÃF?…©ÿ·ü4#øköЗ۩ßÃq?á ÷Û´|ú…÷ü47ø[ÂÕþôgê0ÀCä¡y‘(øÃLÿ'ǵ¿ÊïC ­ckYåþñZhÐìnûmmF¢#RŠK2üËA–?WÑ{äÔ‚ rò¹?êr÷³«»|ý&Ï•Æ*¹Àâ3…îhOsäûúØÒbÿ7-§ù"PPý‰G=IÝBWu s6î> zS$U÷ºWõ /æ8£÷ç¬ù#[-°§6¤DÚ¶>ª¹ö躄Ͷ%$ךÖ·ªœi¦¦+ë¨K}Î(—+p::rÝ–qtø ÈLBKysÇÇÙ$ÚÑ5¹¾A÷¬*¹AަX?w{õÅÆ‚ì`"ç¦G7f%zÀ€]ÜòMç¶åçèAþ3|±?¶sÞûçª 4ƒ?@þ‚ÿyÀ~ÖþÂz‚ü·Ĭ´éEfØ® 6·šrm¼G¹‚Ô ÔP}ªªÒ2\—Èï|z’¬Ñ1šµÖI@~ÂëÄ#ôÿVõ7Íj/Ûì"Æ®=…¨GϸÊT •Ú\"¦‚a ú^°æQ²ËZJ×W ÿã+ôe0+ËgdÛõ€Âº¥Ä¨&sͧå'ñe JbÒ¸c|é`4§3nBÏ…Qc|X›ÆeH%2ÙÎð·!ŽÕ¡œÃl¸ ›·éˆ+!eyžlâºÃ ¦FÊÏX+ñLöë#CÁµÂòãæ • òB‰0´ä¶AIvA‚ëî¼·óݶæÔw R=æl(&5±™‡F]1Xªèõ"ÞK|yÜ/ŠÜÏÞè6´E#í°”’7ÊþÄhš§í¤ÛE[ðYœ"éñ' ìßëð??χM¹c­¹Æ•óz»ëcÁðµ˜e,’¬\zÅ¡×X-˜ÎÀ©«¼š¶‘åÒî>o{Žþ¢&¹%eÕ;lr“[ u®Æ{ |ˆ—!I0¶BV6¶/rƒŽL~úÌ*LóX³$"Ó…è¥ þN}X’ªþP&ÕcòzÒÛàÔÓçØ|ÓÛc|€³_ôü?_ymÓTã©Á–$åIr°‚á¹[±©ÿWS/íDƒÞ„,>‘t¸æz<rø%‚û OílÔ| ¶6oKðÊØÉá~é çZp+Í Ê¹xÒšfLY0¼ÿ {}OûÁ–6 XNáý4;69.‘œÝOÃ"É&ˆ#9ÝPZ°']ðXØï!ÝùàÚŽeW&4´<À›&2ÌîÔ6 Ÿ5oô?#"BºnY¡4¥Œ¬°hÇE ªbSŒÈtþåš(K&Vèåþœ•IéFå¦PG,W  J$©„xnAÖRoð …ôF°@:Iýúÿ=—ó@ÝH“$\M[«ŸlG.†uؾa•ÁéÍ'ý­´ñþ'º«‰¯h^‡BIñK„y{Ÿæâ߀ËúL¾®0ïë„ñ+qû©@=5{ü$‹RI’µ„¢sÀÄLžÿRºÒî `kQºªmŽ‹Ì"êºdÀ Þµô³âúU4Ì]k÷KJÓçù»µÍµ‘‚­0* ”¶{cåö&),f½t÷Šäúêí8,Zu²T çóøXGîùŸ´¯Läí›úŒí°9”V­ø ë2A„@Š\kTéºï ½¢rkÌR%iþðÃÚ׿úCÃX²2ë1/ª×¥lâ¾ÀM àÄz­2¥\42Ï»±5û–Õ:åòã¤üjEÁCˆÉ¶0¢åI±ƒ½*]%ŽÅ¶ ãÒKH CމôÕ|ÿk/.7)Œ$<}Pë>?ÇÇÄÞøm×õD€Û\qŽq‡"†PRÛ}ÞúTÓDbWwœKdvÁ¾÷7ѱvbôN'fÎFV½ÚB+qQãêsþßDü¹‘" ¨›©ÈÐ…¯™¾Lr³î2°*X:—–&þ消à<[4+„–N‘¥7ŠSÖyœÄo"d ï„ÆY¯q˜üPpcLCå­¬J]s=£í–£Wþ ÕZåd•¬£ÿ6}=ƒª ÝÈÛ·qŸåñ˜±6(á»tËÝDÅ„y¥¹L”Ó5a÷š„ßO׎Q8n†%@ü×û\–üöÖW=8I¹GP¦t‹÷Ï6ö2s™‰23äÂUì9K-¸xÅbrȽîþjÆBð•m êå°vètÍõr­dùdãNc¯H‚³öÉrâcÌý¡K>«ò Z@eÃŽ!*ãÌ¢¶È4a«÷£õ›ê#³÷³ã—c+ áÆ/óìF" ™´cüa!ð ‰4“ŸøZo ù€ŠÒ SfrÍ¡\`úžØ~žÚUÙiâÎ6Õ³ŒX¥8hÁ´FkF\ .½L0ÖêÜ<ÙÀø>ÏÁòϳásSpmpGÑõ¹3FÇjÞÄÌ«½ ¡ò Ë,SÝÒÖ½à‡ys-¨`‹6AÕ7@|çÏزÙÿKIgù#.Ë%1LQssÜD°º£Ö28y˜Ð³WeJ ¶‘î0|¡1!‚k=wPTé¡ùÓ„‰ÛèÎ+»ÈíYϬÆ0«g[ó%ö‘T*Y‡SoMOòß%HŒ'³ëð•âHî_Û4¯ªƒµ÷³¸ú¹"PÇU×OBj¶gžÕgagfbIn{“"}–@IصѽٙY×Ó¼¹m‚ï²øqÚ°ü¹­>TÉòÝ’7ªÁÛ <£d=åÛŸpð3µ] }O;sèþ°A1l¥‡5È¡Ym‘wÓ±&Xût­?-››¥„ß§‘ó&0*ÿ¨Åûw£˜‹Ž–Sùá‡2€Õ ’M—h˜†Ôg]ý˜ZÇH´ˆõÙ¾äó)#8û$}p.§-vú †Ð çoáú]i'1vTP«!M­§6.uµƒŽûêðè©…§ N„¬¹Åã³$ÄÞgÄÔ¿C2+ØÜNMˆ= à óHt0J¾‡í›UõÕLB9sÈªÛèâîu¹Ïÿfú(ÕX›ï%h—&x)‹«ùõÂB×L·뾳θk$ûHXÛ z5™kÃT{^q¤ñÞPz¾²R,_ʔˊ>-Bÿ x†)’i@'©¬‘3}^0ö—öÆäâ<(¹œê"³ß>d ž‘ÏcHþj¤½ÕqíЬº8¢Ü˜:ìè`S]tŸ›ìbQñ½ Zß³P—ÍìØ ¿ïùž€sÄ÷ê{OÛ^X=ݬ¿‹a¬a×ÒXŒTtšÏªQF”cBÑ ®vB£U:#xVŒº5ZgÏ;æ¿IF™9UKáê±;Š2 LøX³ãü[lÄÜÛ°wÚ3¢-¤G xâæ›Ê¬çmº£S˜+¿kŸî˜¾õì:.!¢RkeÚ3ÒžµLÃ΄«`š.Þá7‘¼c%*‡!HGч>•ò«PýØä·7uÌ+Q|—LX2T¥«ú@JÑWˆ¨>b“?£Ú\0 øŽCêŽé’Iûi÷ä³IŒn6Ýwæ~.âË2Š6«†maÝJ"°›Œ¬a–Ú+ 4Ú$%³ Itæy›ï—žBôœu9ð¨ÀZÄÃ(D5íQcO_â‘ÁÇÕ(¾3búåm3á"EæDÓö©%¥84G‹j*ÛPCH;PüÌ‹I† •Ì$Z:|yHuË£¬Í¨'½ó¡¦ÖÎñZçEyâ@u8‹šÊãLb<®jÃŽn¢I¡çàükÉý¾ký…>ØùÃ'Y14w»¥hœC`æðÓ~'dÚ‚×°ÉÖ\4LA¢CyS|¹HõWöJx霹'‚%nRõ™JççPˆ+¶Ô¦²?®Ë¤y¨ÜÙƒU 9pèwxŽå*¿YÑІJ_®Ó/«kƒñÑÌhY_,¢ D‹§„}[bp÷"E6ôbê82‚¥h Õ¶z`t©!¤<ÊÑ“vZniEÞJçí2ÓÖŸœ}ˆÉ>a5èáy‡Á3¥…ì²G9†¤,úÜð²ý¡þ7•|uÊ)`²â´–õ4iôlrWÚ§W,meâé Ž[Qž2yÉ”Ð&©¤GܱˆºíûÍåÕÑÜ s)<è&¢‚áËôð¥{åÔdF¿[MÎ'/å°˜×Åh‰ø,aB¶iÚ'mUMðKÂSñ¬´e¨ÊQ€‘Kâcׂ֒‚Câ ¯©{±FºÅ”¹nd}ÅÈá¨oI.é[8d5cÐJ *ÁbNd‘ü¯,sJáÎõ¿–íxÒ´íIõçõ¯;nªýÆÍX)vÖNïhSí|ð&]°)#Y£H‚Bð,Þ ~¨ÆdòÄ@Ó‹—Ég?1¥u$dЖÝýè´±OòÂÕq±î:<:†ÓqV’8:‡4I^Åtþùÿ¤™¶lºXýs–ÒjËÙ,†Áú ¸ÔžH“8gg<ï²×ܱÃÙ7(E]¿„€Ì«zZI½5%ÙÚ°tÂÔëg“ðŒúl6Eìb!Ï€UTooQ$ Á¼Å0Å™•7°ÚPtlöÞÜäöc/œŸïŒ‡(xŽÇ,äÏ™¯Pû/wa Cñý%©¹ÇR }ËVŽñgmô¿¯OßvNßñþi§N¯t.+ÃaåµPbñ(0 V><¹»X×ÃBó‰é©6 ˆf«TjL>A>”k·«PsÅ”C“’œ:OÜôL´%›š_¸EOÀ=’ÈØ š0(«Ü“/¼Àéè–À*vH™]Àš)(¯ýr)‘’— äPa/c~{pª”Èr"kŸ»·“[š‚ÒÜêi[Ô+_°w­Æd¸]AãüDÈ‘+ t+—\6ì½`­6äÕ£A/Æ]C7’6U8¶»Ò8‚¨ur¡¬uÐLÿjEÀFÐ7"œTUÞₘ§Ö5y¯&SÝ„ÓÛMªù¸#Ÿ4DÌ>³€¬# ¿‹:&K› ~äËV¦Á„$.hÿ€Vï™iirL¤¡íP3|)KeíU«"|*Là«IñdˆuŒ«ØÜûÀÒ5  çpz¡|•L{½NÜÑî~™ |pR„ˆ ™TŽvMÜjAÕ-Õõ CÖºò¥l†Ê–\,D²ñK^gÏé»—^bfRBÍ8£ÓmförO5Éý÷ür¢óÌèAú¦ë$\pMì÷©>J'žu|h*›ŽcÊc˜q¹â•Ù½Ì÷êä Y²â[nãžÑßJ•-Ë}e’ù1ÖžÝîÕÚ—’޾ª¶«uL¿dñ M>ÌKÙýôqORË”š+J×¢ ð&º˜äú†æÏ»ŸdH¶­ò¨I'sŒ¾¥”øF•d´ñ‹oô]ôµ²ç¯çÞ¬Vÿ( w8Ù.VæD¶ëëùº(…Œí©ŽHägÆ—‹ìÄ}¾þ…mnÏ HVÏ/êEn®pHEóJ?ÁŒ3˜ŠõypÖêb&Þ<Æ…’ˆltµÖüaÊERXç³ó>aäü&Û¶1FÔL8(·a“?ˆ"Wʦ(NKjBÈx}fj7 Ùƒ@ÉËúi#Žf1jq=ÀRðâ±ù{tXµCJO¸i1_"þƽÏ»@ž‹ }ÉE)¦ä„’»{OièTgwÎXsÿbV‰Ã¬ò_§&Ñdr þ£ó>YÈä­ ëõ¬§¤lƒ’uô]¥Íf¨WˆXº½Ñ O‡]È iÂ=·Ô0Èl@òŠ @Z®¤£ÜU«Áëv> ­JŒ†"žyr–%3OB^çÄcÛ¯mº¬îîôõÔU×:xLÙí·ZL›cv®ú—šE\_%h‡Æ—ôáp¨Ñ{×Ôvž’%ŠÈ‹:ú`p$S‚åsÔ4 -À—Ö¸:R¼ÊpðT6[Þ´•0ˆ(GlVÖW<0z]'›‚o\ôÇåêæ$û þ[WpàÓ™EEôÅpª•ÛLäŽH‹8+4¬©£(Ø7MwÑ”ð*¢òÚô T“7ìÀ° žX²¼ €>­2àÅ·^’<úÎÝr´}¦#>ëg¤»ÌC]2ÆÍ¶ŸœÉü‡å‚°1Ë4i9x³S\¡OYpUB‡r¬^Ø„ôŸWËà­EÇó²€Lt-IŒèâ;G1C§Bú5ñ„ÍÌp@³]u-ËY(´%°u«PæöÄúú{þ±+7ƒ“”õ-?¡ÿxÏÍ8•5ú 4ÞäI²jBÚ×:MŠ7Ãsâ£íòqiMõ’%˜’7G®õ¦*y«AYkŽŽàc¥<»Q8XA3M»æ‡ýˆ’Ø{²úáÚG«t¤¶WGµqèÅV–3ÎïÄöŽ×‰>`Åw¨ØÌ7Wè”±Ø7f¿±Ì4šçXïÆ·àcàÆ8Ï©p*Rê·®Ö®>Òî»9>Ñ5{v€¡WÉ&o7ƃTëÐ Îm>ìDJ:$¡€èŠ2×< kŠ¿ÑªßÊŽé€â2.§xßCUk«$Gå…·#–ƒU‰ 3ßt›£‰·GQ‰Ÿ½h=OŠ~ü›fuµt]%ÁÉöб“–G‹üEŠë½úeà’ÃSÏ6¼3ð3 œ¿HuJ*½MMÚk·>â±l#Í€öÑÜ‘ìÆyÖÚp¥ø’,}$/¼ Í=íz9qZóø¶ÛcÈW2 áXQ£¾d~¸¦ £í’°àТÂAÍÉÅ.3ŠRg )NZ/ÿlÒ°¿¨­¡èçŸëòrF74£ê¢,b¥â€†m7ÙYèX8剓Uß5ÿu_¾ ®bYשåƒCCÅv20hË{qôik:A¯¶üžƒ •U³¨ÎG£ 6^“µi"2Fø–ÆÏõ:y¾7”ú‹9Î=±ø<¦#)”˜6-Æ%\“øñŽÂ'A%¸ý²å¦bëQ‘ýúo>Vκ,ã/Þ¬‚¤0„¸Ö’* ÚàšA Uà?DîÓ}X:‹=QMq`äøÿD78moÜ÷ ³`—«¾F?õçJU;S@_OMþµ¤ª‹`…ŒïL<8ÐÄ$YœÈVí_R˜U[A‰‹Ž‡²æ1ÞþRA@ &º«¨9ôrÂÅá»ÛîзDd~¶ïóƒ"ê1:aØ*È{â=HI½¶8È›³iéô×l—^øWz-åhâô‚òoÈóË6–¼B R>K×û“3æL#¨`{÷¢ñù«ù‰LUC8‰Ã!°+4p4Ó…À<ßòm—€ë¯ø*$)õ‡*üb#¢ ·=ûã(èT”œò·²ÆXv9 Ùµe øÇhIʀȔ©þ.›Ô¥½’«ýÆ·2„3Z:ÙªÛ¢pôÉ“ÿb®ûC0ˆí¼&DÑ7—©•6ããZ Eïï£è™øèÄ3ÿBÂ]¿p¡?ºŠ±LËýLVŽØ5é€jlNs‰S{o+¢+Ö„ˆóŽÛ² §ýö}aé”á2NÄìÞ…d+¬xBÍÙq0‚ÖàF¤µzmëbà!k3ÌTáã¢øáþ,Àî!Ì<ð{ÖÆ±$3ò ׈þk£1_ôtb„Ä2¶Ãÿmt\,­OäÓðs…býn¹ûÒªùBvâĽV;pý-ÏAzA4&Ù`im¦Ú öœþ=ª](ÌRݴˬ ¿š‰š±X² KÓË2&½“¥ÔtÒ§m³Ç$1Frž"8ÀMÑ*ß™âÛú %M€“«) ›e+A%˜Pa ÛÅ€Ïu¬n÷êdCn°§YDAé8ð;+dާVr¾k$ 'o1Ëš¥SÉ/Ï/П!±)”ª £m=xÅ…À²Š¡'l"Âà,më€MævvÃü8¹”c€ûÉ­¢Çý£Ò$¢×äðó3ÓÆT1—Ã`ÕëâÒ<çØwöÎ,Ñ2e¾äGˆn-x@;Ê!ع1ôà Š'„ʘuKÖ²‡,sY 3~bô²pèaP¡Ø ;í Wæ7\þÇ—\fr}±'+-ÁÚðßµ$èE0ÿPžz)ùk¥ˆ0â÷ÇŽ¢÷À*eÎȪK‡xn³²­bí B"»c»¨Ò€'6Ï@Î’+ ‡7†K`¹BOôÖo”U­G}ÙŽ¿Z›S——º†„aîZ›‹wBÞ …òÌEòÔ¯(ÒÌ‚é¯ÈM¢ê IØýð£%ÀaÙ›YZQ²ImÕ©ôœDc.óK&1Z ù Â&‰êXAŽO#9WûCßÖÐMý³ª­èõHü³Ó`“}Y€*ë¶£ÍYûi™Àþá§•·NÚ%ÀðÊš0’EácÚA½Iz[þ8µ*Óó’OÁ³f}¹¼"^êL´‡•vêÖªñJIAdŸ9,Ÿ'­N¢È‘å¸ô#q?áÀ:6Ê;^4± ¹‚VÓ-4­ tìhkîņ»ÔgèòI­[‹ÜM¬-z7¨‚z•ž0ìT·YùÌø9»î™†O²àª:›9 UYÄ-çæ÷-v†„äô÷âR}=7ÇZ„§eû7wLú³ìRaáÅü8ÉD)”ëKÂÛ:zýI Qe'®U,„îÉÿgf±Lƒ+¸½C¯ÑŒ]»='b¶ùSºwÌÖë‡iÒJ{%pÍù[‹í‹Tª2î§#‘¸A£Šž# ˜=ðþ÷ކ%u_v¡kÒ_R®Ä8‰Uˆ›#ír{zR ßÈã6ì¨ÛøDEDÒݾÀƒZ$™"Yom©b ¦êy¦är1h·¸ðMyýÚë = C•G›¸äh“DF:F‹]~G‘Z¬[¾"0á ïÄ& ܆—Q¾q¢Ý¨­(§Žü‹'Æë³+ƒÊY¼ÌÑÍàŠl¢ÎM¹7—VÝòƲ͌op±•S Ö²ÔÕ8X<1¬¢!²ó¥í•j#÷„p;‚cݾÙ^ƒªàΕ>‹RDi û˜„·]ÚD–ÇñHýâ ù©70ómÏ?í0nîIP ÏÔЀO»_ãB¸>Ž‹méfÜé~hÙg¯7^y¼[~ãÑ7œ"Pöq{x©³ùq èSýf]y$(fA®;›ÌCdêþ´Þ'fÀRÝÄ©þï·"ªMÁÂWÔ—®— ¨a!õËTEzµ*£®žª)‚65Z¸´CZjs^i°„ûLŒeIÜÕáô…°£.è«ìº tű5É€/{¡1U2 ]騡€tÖtBêÓLàx–ùpÝfÕüÈmÅïïêVKcþ©Ë³ëà!ß3¾Ž“=##t|–[àZ+.v„§Ùа3í€vÈ:ú÷tGÚY xfòî}C îgv~`®›†ÄŠp=%S4?/”$DŸ lÒÍD×s *T†iü|z1,[Š Ídaóؽm£c½þ(¢ê‘+@4xAIÀOpBÔ7Öàçáä°Ò-äË•¶[*þjt­å“>ˆ›LÄ/…ÐoÓÞjOò?5ãPh8…[A2òåâòÞ8ß:*oü="x;Cîðª0™Wrj‚Ü{„¨8ÿ½ÂDz mdiwÜûâH-Yµ9™QkÅŸnþ¯F¾ç?ÜRòÎ©å€ ùvû ” §  'ŠL·szŽs–QäÁá ='k'ºÛ*LêÔ8Šÿbw<äÉpe‹ ZŠCøÙúñ«»«‰'¡‘ ܪüw4„¼Þ¥`Ì1ýiûÎäC1£·êÔŸ£õ’Šø´Œm &¤¼SZyþv7^>’E4òD¿ Uq¿AÁPŽ¥¬@„ÛMI—‚'l܆7•®ÀO=Ø4çnàKò E]Ä;]=(É¥þ¾²©ŠÃmO6jð<ÚÎ~/a:é? Q¿J¡ÂÂHRõ³ò_æì]³„¤ ’Ѹ¬Vâ!a„:‰– ÿH“zg»ßô£: ‡W<ÆžûŸ _?&‰¥µ÷,ÉÎ<ÉÆónÃra)KY…kܱÜ&'CV2¢÷v`xKë(o3}é>Çd'Ý)¾¢ÐŠ 1¹Û¥šË&ýVå@–3Ö½`ò~ÏRùf–…$¾š¾´pP‚;9²¨~^òu(¯×‰oDìÔ„Õ™Ó²=,ÍÕcþ2#±YûcõBnz]*Cì5m8³D㿾Á†Š¾Çð&µ8›ÂɲN4¿²› óËG§B¨hâY‚À`#‘†¾ZÁõ½áæçb;¥Ê`ù)°ÇùåtÙ&:8–×Ù¦]œz•;=!—~Â/­þ@äZª¦uí«#ÑÉ@ÇiÚÝ>ƒ§'ÎOç0O¤¿õ¨ ËÃ>²rš}:¶!L~ÉDDe0æ¿Ï\C±Ád·H‰Hí̹Q¸[MXhå€}ÆËž²|Hb0°ÐÚšeÊŒ^ûÇÀíµÞÿ.yoç´RÔˆJ9I]ËÍ&0ù÷Uy>—øá#é~ûª™¡5¸ÜÍ”¥Ñ]1Gz»PTÌ™¢Áð_°ƒ•‹¬›&k˜£Êëi¿½êÆ€`Q[̵9ñ+n(OÕ•˜_ÖNª‚÷ÿ<"}Vy)Z‰E?Í´æ¨ç/XöÎÌÊhý ¿eŲµ)óÓá‡P6$Q†·ðiDžij1±‡­¢o=’?Ï¡z9|_`Ù% /U_¤DµPD9¨ùúHŒ²{úf,vÖΗ…; Ç­<µ§"f-xú5ö£†ÚJ.t­¬®LTiÇcÙqí‘®Ó¾?\d3ŽÒnuÆ¢YIÊqÀb\[gVI[:ó½ágÐyÕ15u{nñ¬öHéʾÆú~a(âjÔaÞio‚«ÇEÌ {¥ ©±©1÷è{’ "'ì³éÿi ٦ݞ>ßÅF]1CŽà!r0^Y.Æbt}Ãq« ¡@~ùÃs© å럞»öµ˜BÎxÈ/å\r·š£öŸíÁÉ,û땇‰¨ÇrÚ>ŸS¢i'$W¹òÆ øø³Sý—ç·IåÒLtë}qV–×úæ+§"cÂiOÓ–'ê § üzÔîä8@…^m?X8úÂìN„x`Aơӑ*q›I[Öo ÙÑÙ­¯*åŽÙ)ì«5Ô©Gn£Üã0m š{&!ß3>õM < wÜÖfEª“ îJ¢—êÚ=|w'¼­m-¥±$Ò ^_rBTÚXŽøO†~LZØ@žŸéãÎjîþYG„#ù½±ä‰ɽØœí‰ùª½h´.^ç–Ô=is64gøVš³8áUÆ\ä ©ï!Þ½“±¦Óý :2õãšÙWtÆÚéÎ+[ e×—^ž']\>ë\¯nµ«áauäÄwxwP«Üh1Ü…l›Ž´J,)û©°{ åoØdæB¹ÊWxš±xH‡ÂuÑLúé6Ò9¶“ÝœÞÄPg ß› º*Qc38jä_´›\_Ökž¶}PˆfÓÇ©ìÁ¿ñ&¦ïUú¯@†»+DÃ7å™aöÉ>i§Ð¦È¥À3k'šÃ÷ƒ¬mìX̨ÁIouG“ÛÓOÉ)øÙ‘ƒð¿uà‚cŽ1ÖÛõ´«{sáüM0{L­)Î<Ÿt>Å|HëmBüdƒHIš% K™J×;[v^–3¦ŽÇæÜú‰¹ä%Q$Ö¿Í„RïÑ?.½:êìyì­¹ýÈÔZˆØÂŒŸnòÔtH¸sùW4E²sÌï,dðWž‚d»õí›SÏfhøcÁõ,ÊâèëÒ ¦Õ(Q<Å †®Pt)¥#EbãHÚòhó]ë<^ýR élŸ¢ÇŠ'3¹HÈkahø,¬4õìQøf3¹ÚŠÔW–h¹ï!®@ m춺ä÷O³!Çãàd?ô`A‚ž7<µ@ŠwË¢õÜ…öF}(äøn8~bû’9n| hïr!FçÙˆªü,”>ư b˜K,¦(OÏÛ[Õc÷I %@]Tvæ›yÂVì*bOóOþFk‚—~E{”*@VqL„¢äçùÕ)Ù¯–ä‘!5ü±ùrÔ+ÈÅ€S¡³Î+“šiØdƒ bB~:¤ý`åUºýÒªjaÄñ¾”äoÚR ~• ³çó€CÕÞ.GºNó§Ô tè‡_ÂúuŽ,˜hšPZò æ;×Á6÷…ý5‹Mi‚zŸÿzBNWÙwùùâ]‹¶=—˜QZê/µÒe¾m²^XpÕ¶}= M Ÿ²Íu#>áp¿·dzPðx½Û/–óQN/||˜^OkJCÔ4CÎçÄ¿l|³V °6êVý.˲õ«‚ÙÄã£Áçð£ÑjSf7–ê·Öƒ…rûÕêr‹Ø‡7¨ŠòH‘€÷Z‰{…‰¬ € r‡Š?N/ñ¤7o Ö²ÚíB@Üçy¡´äÞI‘¤âü ›ŠÊ–ªðNM?¹ž»ÖÌV+»ðÞKmqxVhêRÍåÙyÚÏR×<·<Ö«åœUKÁ9Ÿª˜ô(Å«jÞh©𛝓Á±bsHÅ~;¸*ppÐwc½ñoT±ˆúÝù†ɾuÎ’¯†ØˆáiŠcŠ=QÆeµô ˆþ3AèR 8*v›>&‡ë‡æYfËà1žPê ß6Oöè^\RLâ5åÉÑ LRŸì+ã™8öªTëñðíòW³ÔòaãñÕ›n³Rùâ^Ÿ¦Õø¯Œ±ÉÀ7ÀSº²_„SsàØˆï_Ñ`0£—.RGø7íÅÎTäÎÓø*¶þ¢0uÈm¹†h:Ï)åÖ "x£ª¤{4vj&&´øþK¥ŒÞ1îJ1j;}DWéVA´DO ¬5uŸ¥+)~Ý•ò1ÒËQ\°g6k»Ý¹ï"mÞÓ^üÁ Á—k7hÝü]ê÷ÇÆÊD*ļ¯v`zX۔Ǘ¨4€–kÙǸ쮳í Áb‹õ…%‚›,5 CžÛ½ ù(SÙ.- gBŠæï %£}~ŠOñ+UÞÊÊʪ()+"½丌[uŽ™ža:Y[·m5‡í„†?YÁ¢ú·ñÊ;}#ˆ/`(‹@Ètš+Pª/¼9¡˜h QÖWØûâД‘äïÕ~+É®tŸ­Ž¼F×J»«ÁÆT#zm‡5 €ÞÑçg•Zš]Ì"üÜÍ‹è†K eüØ´×9_òo£+-6¿Ÿ² ògZ&¿ÒkTmœ8‰–µ'ZäJ:¾°ïX~Ö ?Þ`;A…¢‘±vG¡Ãýž-YRÐ7s°FÅvÈ×A™§¦Ål¹“ü…ÙÎŽ~tæ…y¶- ßãVô6šƒÃð@=툤¼›UgI(ßÎͲc"Õ#»¨ŒýÎ}3…‚ÀX]Ï1®°ñ*bòýhµ5÷(?÷r5êÚ¦¬®Ý¾^‘ήÅxy³-(W¶$=ñ\¹¤Úâ­ÁÕÀyêï®÷»Tw^± tx¹ \Ô¾,\.Òý½Qt¥óY9bÜôéþõc±wwPø¢o¼§u˜ à Á'b,C Ÿ‰\€‹ï÷f!øñ,•î̾E7™‰9ÁC³IÍ ñ>2/ª£;õÞ‹Ü¥Éß ­"@,wb]üíey±Ûp“»EqÝÒ4:wíÑ`1¬¦ì‹tfçmh6AkÊÖ‚Ÿ¾ë4øNh.7H®ý_ÝéÂÊ÷ØÕÙ/õfà€Pox69>܆EÞe=‘´hDžݳÐC@mƒÆä%#†LÀB#Ë­gú‘—W€,šƒ¨ð<Û$·r§v;Õu³±.BœÜ~š€ðe*÷? 2v4a â9Icá@⇉ÐÁsxJ{ µrmïÁ¤¡¦‹dhËãZ¬@·ZøÏÂ%7Ùcâ…㪥Egÿth ®íâÖ<)1b©'åö²J+$žô¯ÆŒÖÞ!ÇäPcò@åÒ"Ú’9ó¬Z€}Ý'0ˆû4•ŒiÙ‚…ÐÇôC ü ¨œxAUUô¦ff‹«WjÂûÔÊ·—=›£)üªDH¹çDÕrñÎb{31kw¢}¸‘_gmÂ6"¬.™=7êü“.3pP¬R¤°LZé1Ü\¿Û•çÅÔ»«åŒ=ÝõËëøNûÈ`¹ü)´GÏÙг&Òf¨ÕAÛZ 0hA®–;ð Œý¡ÀµÃ¿DbW1XwUøÅê¶NiœÏõ†ÌÈ–]’œ2GÄY¾ùmгc Žýè‡j uÝØçCÚ$­/0¼¤#ìÙÊ„‹ónŸ#ÀTMÊŵ½0T—«:Øw:Ë?õ¤Êv ¥nüÏ#„IÕ’•{|“$ü÷ŠvýMµã• O.ö»Çx s£'ô–ÓÎ|@_ߎªòæ=f¸”Êï]äæFÆïEØòjÑÛßW]‡÷©ÏaÒÈÕŽREÎB ñ3îÎbÏs0g_ŠD©—¼WÀ;‘ŠQ4ì ¹Qxß$e n˜S•·ë¡$S1òuCñGNbœ§É6ÄáßaDýu ݇ƸàñOÄ:Ú†ÄFm½4õ$T…ÓˆëéAHÌ vGÿ]¢?–£;^ѪÈÀò­¾ïÊÒûîGX÷_þ|&ìÖEJæ”î4Ûh÷S«¦^ŒC©Zh£«‘ ]Ÿñ„ƒC² z²êàEŽmFW“Í”DµÚ†²e&FJÓêÅÕ1Õ=ÌƾÛÜð¹1;vbÑãV½K§è3Ó4 ôÃW÷¬n¾³r,qaòµOw{ÿ/Û?]&ü‘i’æ>Ö´€A M»nkÖ’³m•oÅ#aFcÐ. #Qn À=äØxKHÍuòâä‚éÉmŠvˤB Uòˆ[®iÌY¥;çG®UÀð£¤ö 2Žœ8ÙT)%êþ÷•RȨòÅbȨÙuʵnóü4·øhGü4SøiðÝá^ßnËŠ?á·÷ÛÑ×}£¿Ã[†–ÿ„ÿ† .çøiðÒøigðÒKíÚ(ùô öë¯ðÞ®ûuÎûws‡ÈøiðÒ᣿ÃH¿†“ñþ1ü-Oø[ÃB?†¸ßm}º•ü7þ©}»uÃä ü4søhoð¶ÿBÕþôgê0ÀCä¡y‘(øÃLÿ'ǵ¿ÊïC ­ckYåþñZhÐìnûmmF¢#RŠK2üËA–?WÑ{äÔ‚ rò¹?êr÷³«»|ý&Ï•Æ*¹Àâ3…îhOsäûúØÒbÿ7-§ù"PPý‰G=IÝBWu s6î> zS$U÷ºWõ /æ8£÷ç¬ù#[-°§6¤DÚ¶>ª¹ö躄Ͷ%$ךÖ·ªœi¦¦+ë¨K}Î(—+p::rÝ–qtø ÈLBKysÇÇÙ$ÚÑ5¹¾A÷¬*¹AަX?w{õÅÆ‚ì`"ç¦G7f%zÀ€]ÜòMç¶åçèAþ3|±?¶sÞûçª 4ƒ?@þ‚ÿyÀ~ÖþÂz‚ü·Ĭ´éEfØ® 6·šrm¼G¹‚Ô ÔP}ªªÒ2\—Èï|z’¬Ñ1šµÖI@~ÂëÄ#ôÿVõ7Íj/Ûì"Æ®=…¨GϸÊT •Ú\"¦‚a ú^°æQ²ËZJ×W ÿã+ôe0+ËgdÛõ€Âº¥Ä¨&sͧå'ñe JbÒ¸c|é`4§3nBÏ…Qc|X›ÆeH%2ÙÎð·!ŽÕ¡œÃl¸ ›·éˆ+!eyžlâºÃ ¦FÊÏX+ñLöë#CÁµÂòãæ • òB‰0´ä¶AIvA‚ëî¼·óݶæÔw R=æl(&5±™‡F]1Xªèõ"ÞK|yÜ/ŠÜÏÞè6´E#í°”’7ÊþÄhš§í¤ÛE[ðYœ"éñ' ìßëð??χM¹c­¹Æ•óz»ëcÁðµ˜e,’¬\zÅ¡×X-˜ÎÀ©«¼š¶‘åÒî>o{Žþ¢&¹%eÕ;lr“[ u®Æ#ÁODb¼œqˆŸŸ’ÂnF4ÃN~2Xô,šUl…¬ml^ä)˜ýô#˜T˜2).„ £gžˆú(õ¨ËO¬¨Jø“*àc°¼7³‡gé°Èˆšr1)‹ÙNÿiø~¾òÛ¦©ÇSƒ,Iʈ‚ †Ñ?'Ì‹e.Õܬ¥`ATOU½³`Ž;À£VZf”N¹q¬¸”þÖÍGÀ»cfô¿ ¡íŒžîšu§È8»™É™!ñ¦s˜Nx»wY¹½£wPÓ {Ùö³î6À$¤(\áíüý:xË$š ŒçtAjÀwÁcc¼‡wæƒj8Û#ƒÀ†ÈÃX°3c›Ö8½Kô€M³Suô•þçû_«G óÎ×5Ñh*˜”ã2?¹fŠÉ•º9§¥REºQ€9i”ËèF‰à™Fáà(Õð …ôxùø :jý'„£ºekö47"ùnPá—ó¢ú ÞK4“¨Áí§KçD™ œñk©5asmJå˜õÞ03ýF f[ؤôµoºAøuyóæ2f6ÐÄë…ïúWZBýÁ¢¬ Õ¬?3>þ¶GVÒó¡1$G²û9D»®‚©øõC¾JêA)}¤ ýsmeàŸ´ ¨$¯æÙ1ŠÊÈó£Ù±¡\ÀæPGŒ¥ÂÛ‹DoÒÍ5ò³µ´q“CP^FgÙÀæàªñ¿±“Ò²ª¬k]óÿ Ëü·›Cke ¨èÀ–wXÃ(“sœ·=‹±úÌ“§ 7õXŒfä÷!±ýú®ò¦ü”¹#»–øÊ/Õ¨zè Œ$qê0â2mŒ¨¹Rl`Ä/M&I|о·EÀ•²êx 6ÜOÀ9ýeå­‹kÁT‰GàYpƲèëU½²£±°ú‰¶¸ããE  ¥¶û½õŠ= ñU"#6_È[¯Ì$´/‡Ìóñõ³5æàe‘û#qj¦É¹š ¯YêÒÞD<ˆ*¢n§#B¼ fú=1ÊϸÊÀ©`ê^X˜†ñFÅuáŒÄ~ÒÐk›ôG‰9´ZÚÄ¥×3Ú>Ùj5à¡1GýU®VIZÊ?öϧ°aÕD"-or$ðßÚÈ/ârª‰ãŸv–H§øoŒÆl(>$îFo§ëÇ(œ7C ~ký®K~{k+žÈ$‚Ü£¨S:Eûç›H{Ï+™‰23äÂUì9K-¸xÅbrȽîþjÆBð•m êå°vètÍõr­dùdãNc¯H‚³öÉrâcÌý¡K>«ò Z@eÃŽ!*ãÌ¢¶È4a«÷£õ›ê#³÷³ã—c+ áÆ/óìF" ™´cüa!ð ‰4“ ) ÕP/bp3—üæ‰}rø¥H¡õ=°ùìÎJ7JuaÑɹ0êc %ÑÐU²OGlôC¼\@Fhþ{é=YKž’bÐãó£)CÖÉå”ö… ³FÇjÞÄÌ«½ ¡ò Ë,SÝÒÖ½à‡ysD£±^Þœ“`Ó½ éëj8˜óHª…´?ïqæáès<׬±p,Œ5x3/§»<¼Ëvò#>O¢#øéa|=xI#Ÿœhœ$H"Üø‹×©~]?<Ç„Iï—2[à½ÎëÿI±ýáTý^°qaÜ 5%¦}y¸ú¹" WU×OBj¶gžÕgagfbIn{“fµŒ í3ëŽ=¾7Pxk³sáÿuÌE¨"•—ÏR†i1úí æ³„Ñ¿l¶ÑD( °³Àê6CÞ]¹÷;UЗÔñàS·>à`;æÊXt»ÂVˆ£Ôœç¢'YP矌Þ×¹–,I[kւظ«ü–F/Û½Ä_$ºœ *ªT,I6]¢bQwöak"Ò#×fû“̤`Œãìñ_à.Ì7ÍN`‚@¿÷"‚¿ô|ûÏ^¨Éï•xäug[Kßša¿L¿5ì…aè(ˆ™q;a鉘&ë|Ίr› uë‘lG{ €úÐ; —Vi†×o†6 É„ìíP´$¼ŽÐ9¦÷‡ˆûº¦0F˜ †¤„-vnwƒ>ú´ 4ðp‘º~Œ’{=‚£òʹO³žâÛò’Þ¨ÏwG¾ÁRw}fÂE«ÛÄMº¢4È“²I§Fž„"rŠ6Q‹g‰½ñ®Œvùá7åà;±,4»±ˆ½ç£[,??†Äi™Ø¡Ë»²Þ³‰º²3œ™ó?ˆÊ.ï¸*˜c®5¤&)Ñrß/~)+ÜÓe„J[ÕÞ5Xøzá|©S)Ü«š¡ädØ¡c«%xŠÉüAWÛO¸Œk"ôn¬'ªskv‹ïùè-%±dï]ö#+6{”H È㟊Ã÷ žßc•_Ìo( °ÃTØ·s# ‰o„n;ÓgÅ8ƒÕX3*óí5Íë-Ò–’@8A‰Êùß’&ì<®2s¹ÐŸ“q"‚Á‘¬Ö´,…´š}ðäV0Z£&õTéØMtÿ|Õ«Äî&x=ߦ;8Þ/o øúQáRz’Û3àÔ_pçH®ÛÅÐOˆÞ·!øƒX⣸ È‚Èè/7Ù³$• “Ѱ„vcxvGH&k4H®ŒT-fDln;[8–®?çI[÷ âØF|NÛ° ¢F´×õq¤ùfܽ\Uއ@®ßŠOYÿAFPÁŒ¶¼¾Ô¿ÙÝGD¤»^¡•EvTP«!M­§6.uµ°ïÙÃ4ºV4¹ùd«ÙIþß*E3ë Ëp±rzÛå‰+³kð”|‡¼å†ôãÏì»íT—˜÷êœîúz¯®ªbÈÓ˜¾G¥ö€Ýlq–bÇ'îwÖCr`òU@ãžGñ­ggƒËb -G<ÐæÏ+(¤8b?QûY'Ö:ÆÌÙ}Xe¯ QýíyÄr“ÇyAêúÉH±›BEÅÑýuçù…9f9_:“›^G¢"L…Eôæ%ªØ¦¬ey ¨\(a\O¸Dnc•Dæu縦»#>¦ê¸ÀöèV]?œÑnLvt0)®ºOÍö1(þeáè…C¡‚”Ȩ¡´DƒD/ùÂjž†_É/1C"Á˜åM¥É]£b‚ÔëÁ×"w3;=Z²[¼p¢‡4ÄVn.-ÐPf$‹:KfnæWˆ±VeL X'6„ˆÝCv® ’¢Ü秨ÑÌá–‰’„Y.Ü[LxÂVù3+LiÑÒ#b“?£Ú[Û ÚQÕþàl¼:ZA´O>‹™â%߆†EüÑ^H´‚ëØ»­dÅðùeÜpà)ÎÅE—öÌ>.O¨½"•ØV¢U¢0á3Þ­ÓÈ@ìß|¼ò¤ã©ÒÝŒ8M&Lø°ÅÔ×êLmàâ¥1ëËYÀõ¥JiC¬¿´à=˺£ç»VæoIWL!°"øš}n,êèUŸÉÕˆ¿ì˜©:ÔDðÄKýØM¨'½ó¡¦ÖÎò:ŒŒo„ ‚ïVdˆÕíÓ”>·ð§Q‰­ò¡êÿo§S‰‡ö>y0ÙÛ&óífÀ*È/u†áùÂ.]_n¾ù©ªÂÍ-@©Ð¼½P¼WÇ4LU¢^C¼_vd\½HõWöIåm7Ð>·æÑn~´1rš‚©*À¹Õx©,o»í¥*Oã2é½:ŸjVNráÐwxŽå*¿YÑІJ_®Ó/«kƒñÑÌhY_,¢ D‹§„}[bp÷"E6ôbê82‚¥h Õ¶z`t©!¤<ÊÑ“vZniEÞJçí2ÓÖŸœ}ˆÉ>a5èáy‡Á3¥…ì²G9†¤,úÜð²ý¡þ7•|uÊ)`²â´–õ4iôlrWÚ§W,meâé Ž[Qž2yÉ”Ð&©¤GܱˆºíûÍåÕÑÜ s)<è&¢‚áËôð¥{åÔdF¿[MÎ'/å°˜×Åh‰ø,aB¶iÚ'mUMðKÂSñ¬´e¨ÊQ€‘Kâcׂ֒‚Câ ¯©{±FºÅ”¹nd}ÅÈá¨oI.é[8d5cÐJ *ÁbNd‘ü¯,sJáÎõ¿–íxÒ´íIõçõ¯;nªýÆÍX)vÖNïhSí|ð&]°)#Y£H‚Bð,Þ ~¨ÆdòÄ@Ó‹—Ég?1¥u$dЖÝýè´±OòÂÕq±î:<:†ÓqV’8:‡4I^Åtþùÿ¤™¶lºXýs–ÒjËÙ,†Áú ¸ÔžH“8gg<ï²×ܱÃÙ7(E]¿„€Ì«zZI½5%ÙÚ°tÂÔëg“ðŒúl6Eìb!Ï€UTooQ$ Á¼Å0Å™•7°ÚPtlöÞÜäöc/œŸïŒ‡(xŽÇ,äÏ™¯Pû/wa Cñý%©¹ÇR }ËVŽñgmô¿¯OßvNßñþi§N¯t.+ÃaåµPbñ(0 V><¹»X×ÃBó‰é©6 ˆf«TjL>A>”k·«PsÅ”C“’œ:OÜôL´%›š_¸EOÀ=’ÈØ š0(«Ü“/¼Àéè–À*vH™]Àš)(¯ýr)‘’— äPa/c~{pª”Èr"kŸ»·“[š‚ÒÜêi[Ô+_°w­Æd¸]AãüDÈ‘+ t+—\6ì½`­6äÕ£A/Æ]C7’6U8¶»Ò8‚¨ur¡¬uÐLÿjEÀFÐ7"œTUÞₘ§Ö5y¯&SÝ„ÓÛMªù¸#Ÿ4DÌ>³€¬# ¿‹:&K› ~äËV¦Á„$.hÿ€Vï™iirL¤¡íP3|)KeíU«"|*Là«IñdˆuŒ«ØÜûÀÒ5  çpz¡|•L{½NÜÑî~™ |pR„ˆ ™TŽvMÜjAÕ-Õõ CÖºò¥l†Ê–\,D²ñK^gÏé»—^bfRBÍ8£ÓmförO5Éý÷ür¢óÌèAú¦ë$\pMì÷©>J'žu|h*›ŽcÊc˜q¹â•Ù½Ì÷êä Y²â[nãžÑßJ•-Ë}e’ù1ÖžÝîÕÚ—’޾ª¶«uL¿dñ M>ÌKÙýôqORË”š+J×¢ ð&º˜äú†æÏ»ŸdH¶­ò¨I'sŒ¾¥”øF•d´ñ‹oô]ôµ²ç¯çÞ¬Vÿ( w8Ù.VæD¶ëëùº(…Œí©ŽHägÆ—‹ìÄ}¾þ…mnÏ HVÏ/êEn®pHEóJ?ÁŒ3˜ŠõypÖêb&Þ<Æ…’ˆltµÖüaÊERXç³ó>aäü&Û¶1FÔL8(·a“?ˆ"Wʦ(NKjBÈx}fj7 Ùƒ@ÉËúi#Žf1jq=ÀRðâ±ù{tXµCJO¸i1_"þƽÏ»@ž‹ }ÉE)¦ä„’»{OièTgwÎXsÿbV‰Ã¬ò_§&Ñdr þ£ó>YÈä­ ëõ¬§¤lƒ’uô]¥Íf¨WˆXº½Ñ O‡]È iÂ=·Ô0Èl@òŠ @Z®¤£ÜU«Áëv> ­JŒ†"žyr–%3OB^çÄcÛ¯mº¬îîôõÔU×:xLÙí·ZL›cv®ú—šE\_%h‡Æ—ôáp¨Ñ{×Ôvž’%ŠÈ‹:ú`p$S‚åsÔ4 -À—Ö¸:R¼ÊpðT6[Þ´•0ˆ(GlVÖW<0z]'›‚o\ôÇåêæ$û þ[WpàÓ™EEôÅpª•ÛLäŽH‹8+4¬©£(Ø7MwÑ”ð*¢òÚô T“7ìÀ° žX²¼ €>­2àÅ·^’<úÎÝr´}¦#>ëg¤»ÌC]2ÆÍ¶ŸœÉü‡å‚°1Ë4i9x³S\¡OYpUB‡r¬^Ø„ôŸWËà­EÇó²€Lt-IŒèâ;G1C§Bú5ñ„ÍÌp@³]u-sJoHŠñò—€hq'Rÿ˜&ieC¬îÃÏ&eÖõ¥º†n@q‰ºýt÷,SŠªZ'«YÔ3kåki–˸]XcP‡Gbâ(jM†BÊïöågÖî¢ t™9õ~ùaCÿG´J™tF¹2¯0²ó%­åŠ•.ÔhBgœW¶n ¡R' Ÿí<ÊÞ+VÊzÜ3¾ÇœØ€™ß˰%½y‹´jK3ȲÎÐø»v€¡WÉ&o7ƃTëÏýuSŽX^­¬güŠ3hÒU«ÔXÁMÔçvrº±}4‚Ï$LÆõòtkŸÏË"ÝŒk‘ËAªÄÇïº MуDÛ£¨ÄeÒðèÝg•ªv4XÆg›œ%œÚbL?îæQšÑæÅ®áÍ+5<ókÃ?/‘Iô€æÚ2/8qÚíϸ«lDGrÙâ-4N+uŸðÎ ¯ˆ-ðsgBi,qü }¬´½í'ÑÓÝ›ŒÄ–ú‚\µôàµRSÿûHaN¾Tí\¶6رh¾Ù”Êþ  ¡3j£_С`yˆZçÉ€þ­Lðqý3½-p…û<QMd² þƒâ(abõ4 Ç”š0Ãeé^ì?ä:nŸÌž6M ˜lt¼]ò»–^ Í34´,zPUL¡æ1n¼Ü,—Z‘™Ïœÿ{æ?ÍÔ´“JÀÁ%<ÆÛ¸ÂÛŸtn¬:¼&=Ä;Y¤²1Ø ?Òù‰ %^䋸ë°Á¨0ÛyàÀ[õcªìø&LÁñ6Ÿ½¢oÜÍŒ.Š€´9e BqøúâºØÍÛÇïZE#ö®—«pòf[÷3§‘¼’À).“ª®H :Èuý’´åTaâ!¦.!¼Ü±Ñ©p6È€’¢ …6í« ÍBïw`V’Áf× üÛŠöàÍ#„Ý-‡E ƨA¸Z¹v¦‘¦£œy`òÀ…T•tœì84wŸåýfÄM„…>°å_ŒDtTç¿|e ’“žVöXËÇ"óÑv“žé&ùéÂ’àÿcJÕ“¤ÏÆèl<ˆÒ¢YmzEÆ:ìMÄζŒÆ•vÆCŸ  qk㮡7Ðb/PEøéͶT`–Ú.§³6ç!qLH;´Š…¼ö£Øü¤Õâ÷^Ò˜”£++é)†h¢ÝŽæ@Q(«ï&%Úáß‘˜Ú¨éÁW½Ç‹©Ê%[qу/x-ìCÌʨÂÐùzÚ?·l¡euÙ± t•JegôŠcOzºÐ@ÔN©ÙÛ¨D_O mnns9vU¹Ê%b_ßÀžUç¶/o]Ï8R§OꜪCé¡ É&ç+è¶ã˜v²ß·ýq§LÈkWoSøÉM ûHRÝ2§¢€€M“fÃ2¹àñ¬žª“RjÆà ñ±Âö!ƒQ~*¶Pò]¶œÞt 7*AUåB¾¤çžæhꇂ¦Ðý.r.ôk ¥sÉrÞ‡èOØ”ÊUPGѶž¼cu›¡µ‘BC`LÜÙõ: s$ò…uFýk»Q •¶f7g¯ËІŒ'Û)ÝÌÜZ·HÅ Òùãõ“ÏE?"Mbt±^øñÔ^øL£ÒIcpå¾áj×eç$?ÐÇX2ŒSüû½ #"Ë; Ïîâ–Á&f‹ãMüŒ/ªåwú¸!ù™~&ôM©É$ûYäX? Î6 ž/)F;²©è·U–âò˼É<˜í– v*ȺEÞädƒ¦ÔÐ0¢2Ð&z¡¬8ÊuºñéÖ\Vb`ìÛb†ú`OìÎHZçœ<@íÖ™yõˆg+4‰äÛêÝÃg$qWÖ2<„™Pá3&ý» iþ©‡›Rú”<äÿXž£>A·#ý2M2æÏöº­¥iìnéGQ‘Æ—JÍ™I—4¶9JÉqÜD÷:qB»ä¸òÞý™p‰{©2Ò 1%Ú OÓ+–±\ÞKb_WÏÇTÍA] —tút4’áâ­­´0”¹Sªqb #c´ šikV_Ó+éõ ¢†þŽuû¥#"XBº=Ño†!±èåAÌúW[÷þ0H‚·/ú•uµíÜçúŸh "Š6.ÆàS}ŸœÏƒ›¾é£|óøÄØî,'KªIÅ7F°˜†uQ{%–)ÜÈÏ©‚@–ZﻃCf–vVëD¹ŠÑéY[Nkg÷{`v’3¹;ü‘›Ú·g3ÎÕ˜?+`ìÎÐOSpM 1—¶.$ `Ÿ¬Ë¯$… È5Çsy‚l_Ö›ÄìÃø [¸•?Ý­‡jü_ &ã°»Q³Óè ¡À#¡Ÿ ÐíHÀý1ï„Â|\ Ô·u:#„±0ýçgçÓÈâf½fÙq)(²Æ÷ò3ÐíéüŒM]‚YÅdpéBÎÞ2ÓŽ×v`t‚DôØ¥ ‡µ¶"ó{ͨýãÌûíŸ5TBbÓ”ˆý9úÚ>NËçÚý¡EZ`E‘•ù:‰ïªaªWà 6*ש֌ü‚ìNæ4`‘ ÷ñ½ÐñóÿzÔÓA*¼-øº ÉT–+¯ýy"^|Ÿ®îáÙfâ‘A mý*´¬Çp½†öÿ'ÞÏUfvõЂrXiòeÊŽÎ ÄB 6‹†ßµœÂ’FVâÓ6ÒB³û缉p¯Cß½dWÙr>Z®‡y–êõпðôˆ=­é?îðª0™Wrj‚Ü{„¨8ÿ½ÂDz mdiwÜûâH-Yµ9™QkÅŸnþ¯F¾ç?ÜRòÎ©å€ ùvû ” §  'ŠL·szŽs–QäÁá ='k'ºÛ*LêÔ8Šÿbw<äÉpe‹ ZŠCøÙúñ«»«‰'¡‘ ܪüw4„¼Þ¥`Ì1ýiûÎäC1£·êÔŸ£õ’Šø´Œm &¤¼SZyþv7^>’E4òD¿ Uq¿AÁPŽ¥¬@„ÛMI—‚'l܆7•®ÀO=Ø4çnàKò E]Ä;]=(É¥þ¾²©ŠÃmO6jð<ÚÎ~/a:é? Q¿J¡ÂÂHRõ³ò_æì]³„¤ ’Ѹ¬Vâ!a„:‰– ÿH“zg»ßô£: ‡W<ÆžûŸ _?&‰¥µ÷,ÉÎ<ÉÆónÃra)KY…kܱÜ&'CV2¢÷v`xKë(o3}é>Çd'Ý)¾¢ÐŠ 1¹Û¥šË&ýVå@–3Ö½`ò~ÏRùf–…$¾š¾´pP‚;9²¨~^òu(¯×‰oDìÔ„Õ™Ó²=,ÍÕcþ2#±YûcõBnz]*Cì5m8³D㿾Á†Š¾Çð&µ8›ÂɲN4¿²› óËG§B¨hâY‚À`#‘†¾ZÁõ½áæçb;¥Ê`ù)°ÇùåtÙ&:8–×Ù¦]œz•;=!—~Â/­þ@äZª¦uí«#ÑÉ@ÇiÚÝ>ƒ§'ÎOç0O¤¿õ¨ ËÃ>²rš}:¶!L~ÉDDe0æ¿Ï\C±Ád·H‰Hí̹Q¸[MXhå€}ÆËž²|Hb0°ÐÚšeÊŒ^ûÇÀíµÞÿ.yoç´RÔˆJ9I]ËÍ&0ù÷Uy>—øá#é~ûª™¡5¸ÜÍ”¥Ñ]1Gz»PTÌ™¢Áð_°ƒ•‹¬›&k˜£Êëi¿½êÆ€`Q[̵9ñ+n(OÕ•˜_ÖNª‚÷ÿ<"}Vy)Z‰E?Í´æ¨ç/XöÎÌÊhý ¿eŲµ)óÓá‡P6$Q†·ðiDžij1±‡­¢o=’?Ï¡z9|_`Ù% /U_¤DµPD9¨ùúHŒ²{úf,vÖΗ…; Ç­<µ§"f-xú5ö£†ÚJ.t­¬®LTiÇcÙqí‘®Ó¾?\d3ŽÒnuÆ¢YIÊqÀb\[gVI[:ó½ágÐyÕ15u{nñ¬öHéʾÆú~a(âjÔaÞio‚«ÇEÌ {¥ ©±©1÷è{’ "'ì³éÿi ٦ݞ>ßÅF]1CŽà!r0^Y.Æbt}Ãq« ¡@~ùÃs© å럞»öµ˜BÎxÈ/å\r·š£öŸíÁÉ,û땇‰¨ÇrÚ>ŸS¢i'$W¹òÆ øø³Sý—ç·IåÒLtë}qV–×úæ+§"cÂiOÓ–'ê § üzÔîä8@…^m?X8úÂìN„x`Aơӑ*q›I[Öo ÙÑÙ­¯*åŽÙ)ì«5Ô©Gn£Üã0m š{&!ß3>õM < wÜÖfEª“ îJ¢—êÚ=|w'¼­m-¥±$Ò ^_rBTÚXŽøO†~LZØ@žŸéãÎjîþYG„#ù½±ä‰ɽØœí‰ùª½h´.^ç–Ô=is64gøVš³8áUÆ\ä ©ï!Þ½“±¦Óý :2õãšÙWtÆÚéÎ+[ e×—^ž']\>ë\¯nµ«áauäÄwxwP«Üh1Ü…l›Ž´J,)û©°{ åo¢EÞ¿ä%Q$Ö¿Í„RïÑ?.½:êìyì­¹ýÈÔZˆØÂŒŸnòÔtH¸sùW4E²sÌï,dðWž‚d»õí›SÏfhøcÁõ,ÊâèëÒ ¦Õ(Q<Å †®Pt)¥,¹r]¯&Ï5Þ³ÅïÕ Î–Éú,x¢s;”„/²ÊÍ商ž½Š? Ð] 6ûÜV»™X&2ÝÍBdÀáeb»Ë.RÛÌ8;ÿhÀƒBϳUø$Y(}ªÕô**ÊÄo ª,´²œ¿Ïn‡3Xꣷ4بãηaSšx—ò3X°¤N¸47n{†'ÅoÌ"íÕ)Ù¯–ä‘!5ü±ùrÔ+ÈÅ€S¡³Í㕚iØdƒ bB~:¤ý`åUºýÒªjaÄñ¾”äoÚR ~• ³çó€CÕÞ.GºNó§Ô tè‡_ÂúuŽ,˜hšPZò æ;×Á6÷…ý…6_(ž§ÿ~“‡ö]Á„ÄGþ~@x—d¶32Œ¸ÄŠ×Q}GÉ®§¸Õ DZ8þg½ƒÿ<ÏøÐÍÆ§›Ù2;9ãGR÷ùÄz¶$¨1ïý'¾¤¾(ŒiÂ\mhLtÎè©‹°AòÍX*ÀÛ¨[ô )XÀÙ¿êuø‡ë÷&‚K+MP~^ÆË‘ÐNµ'½/~~¢'BÄ庒½o[pÜëQ/p±5PñGéÅþ4ˆ¿4"¢=òÝÖj-ŠØ3 Ö¶gDŒ…µ$‹‰H»=òÛú­×º»ÖÌV+»ðÞKmqxVhêRÍåÙyÚÏRËF©ýC^š;Åáü,™5;ÐÏûÛ(p›Q{áŒÑªxúFÛ}˸p0Ø@M=ñoOQxšÞ<×ëÃ^¸‡H4½bépƒSžÊ“ɘÝ,…žØ'NÓe•Ñ<^¥®¾Ñ%ò”c<<2éH6/´¤Aú#÷Ùß—&©óÅ¥Nì+ã™8öªTëñðíòW³Ô|f¼hÛtTc`HN;¬ð65þªíBÜ~iÀè×0’z±Š@¸ Òï©ÿoÿƒxàQäÀÆ®‘Qæâúxf-<×~pÇYD#ØBNƒ²+Æ+°×…Ã.bËpÒ_"[gÑŒöÈ«§6’~c¾`uòÌ‘¦er3Ÿy4¬œÑË×g6E/¢{˜­.ó|”È;ÜNö•!ºš' Í„wÏ0¤„d´–Š´ØÃÔ²`q\°g4×c/$¸YÖ…—œ!Ç×.ÞÜeiñ›übØ9JvBü æ5¢ؾʕójQ٬ݴ•¢—\Ò'{~NéeÈ ¦ä¯–lì•2SùšB ¯( pšqˆZ)`=¿X\ Iö˜Ö‘{ …ÚÕwwñ6÷ú¸ÁÑ.P‹Gó‘@¤ZLQÜׯB‘HχÛ]MÃÌjë†õãØœjI?èúøæñ¦®„¿„ƒ–L·ŽM‚úXÛÅÕ)a«ÄW°[wœ±Á Þ ÷Ù¢´éÖÒ!ÞÝl'² >9^}‘à$Fܨwp>×v¶UÆž.P)÷/^ òW‡¤L‰¯1Å‘úš õ°h‘BËò5Lcúø VW¦qþüô÷2¢ ñÙ$á&9‚øT$‰åv3û!®T„8± ,@ ‘tq…’ut6ýË\—ö޹OtÞ#ÓÃØf7¢i”gÀ­×»ü™6¼œéÖp@h¾­ürŽßHÄ" Ø "ÐÇÈ\¥HŽ˜ÒÉÇoGh÷´Ò×›’¼À¬š‚'Š%E“T·öÒ7u(Ÿàã*½6ÚÐ@ohó³Ê­M.Šf‰…øõksò7FnØ‚ýô†õO0ÃÆ"Ñ94ÙKcdWLVy¶«‹¿üš× æŠd¯+ãÃöh…{R–¯«Ê슧ÏËÿ:ÓymÐ cþ®ô1¹­ÉSG-Èpÿ3Å Ë*ZîvèØ®Ùè34áôØ­—2¡9ÑÏÁîœÐ¯/¬KþOãVô6šƒÃð@=툤¼›UgI(ßÎͲ5]¤¼O~|‡§ÐŸ7«8JÀX]Nñú.qE %½MDijðÿhf éòÍí Qð×Óö!{Ì3Zn<88êûrFÚª’Cð‰äH¼ÆÄ¨ 0»$® ÷«ì€Y @ÝtÓ6Å›+°œYO¬ÄA‹¨ùÉÐ3ö$Ç ¥Kæ²rR{`ÆzöáœPÎê4Q58Û÷[¢f S;y (qØ š ?Š;èü â|3@›÷>k3Ù7Ùž5Tc tˆ> nå@!ú¸_©hí÷z-ÚýsB¡Ò§5”rŒ!Yû|Ptg`Ù@rœˆ¦ Ju€Ý„‘€ÓÁ¸˜ƒʳ`Ÿtfçmh6AkÊÖ‚Ÿ¾ë4øNh.7H®ý_ÝéÂÊ÷ØÕÙ/õfà€Pox69>܆EÞe=‘´hDžݳÐC@mƒÆä%#†LÀB#Ë­gú‘—W€,šƒ¨ð<Û$·r§v;Õu³±.BœÜ~š€ðe*÷? 2v4a â9Icá@⇉ÐÁsxJ{ µrmïÁ¤¡¦‹dhËãZ¬@·ZøÏÂ%7Ùcâ…㪥Egÿth ®íâÖ<)1b©'åö²J+$žô¯ÆŒÖÞ!ÇäPcò@åÒ"Ú’9ó¬Z€}Ý'0ˆû4•ŒiÙ‚…ÐÇôC ü ¨œxAUUô¦ff‹«WjÂûÔÊ·—=›£)üªDH¹çDÕrñÎb{31kw¢}¸‘_gmÂ6"¬.™=7êü“.3pP¬R¤°LZé1Ü\¿Û•çÅÔ»«åŒ=ÝõËëøNûÈ`¹ü)´GÏÙг&Òf¨ÕAÛZ 0hA®–;ð Œý¡ÀµÃ¿DbW1XwUøÅê¶NiœÏõ†ÌÈ–]’œ2GÄY¾ùmгc Žýè‡j uÝØçCÚ$­/0¼¤#ìÙÊ„‹ónŸ#ÀTMÊŵ½0T—«:Øw:Ë?õ¤Êv ¥nüÏ#„IÕ’•{|“$ü÷ŠvýMµã• O.ö»Çx s£'ô–ÓÎ|@_ߎªòæ=f¸”Êï]äæFÆïEØòjÑÛßW]‡÷©ÏaÒÈÕŽREÎB ñ3îÎbÏs0g_ŠD©—¼WÀ;‘ŠQ4ì ¹Qxß$e n˜S•·ë¡$S1òuCñGNbœ§É6ÄáßaDýu ݇ƸàñOÄ:Ú†ÄFm½4õ$T…ÓˆëéAHÌ vGÿ]¢?–£;^ѪÈÀò­¾ïÊÒûîGX÷_þ|&ìÖEJæ”î4Ûh÷S«¦^ŒC©Zh£«‘ ]Ÿñ„ƒC² z²êàEŽmFW“Í”DµÚ†²e&FJÓêÅÕ1Õ=ÌƾÛÜð¹1;vbÑãV½K§è3Ó4 ôÃW÷¬n¾³r,qaòµOw{ÿ/Û?]&ü‘i’æ>Ö´€A M»nkÖ’³m•oÅ#aFcÐ. #Qn À=äØxKHÍuòâä‚éÉmŠvˤB Uòˆ[®iÌY¥;çG®UÀð£¤ö 2Žœ8ÙT)%êþ÷•RȨòÅbȨÙuʵnòýµ4ùï:|÷OÛSþÚTý´ü)5þµöÔñóÝ#ç¹_mWËöÕ_¶“ÿB–¾ÚŠ|÷>{>Ÿ=±Sç´~Ú«öÓ¶–ýµWí§¿kÇû]ÿ6œý®Gíiÿ5µk?í§kŸíwý´Ðõ-#¶k$tŒ”È­“yFßnä0wíúäÅiæê^Fvú¾ØhÒɡÚµüvä w·r`ÛÛí÷  £ Ý.R•r´mœ8²¬Š½3ã'°Y0]®¦@ŽFB~ u3°¾øû{ú%²¦#‘¸{Пÿ„µAñUá+c¨•Å}ù ötA p&Ô)—‡ù†í”u.õv4©Ï“’?My2[^†Þà _²ßéÒ V/KÌFû§êP}„b±´j€2÷•EäÏ{þƒ]éÌ;±7¥ý•wï#% ä¼ ˆîYìø¼ça°3äê:iß ¹ýõw,GÖRŽÍè®6X¦s%1•’2ðz¾z;ÿ³ÙN̳EühÌ» ` k¹_âsz¡ˆMï×úô™&C–…Ûk5Ö÷ŽK£ÆÕú¦5ÐynÃ|ÒiQ´<´…µû.U§7ØÔõÑDûŸ¹öÎßå *ÁçÑ¢Ti•]žÍ‘3½èÿw 'qŽ[&gx&cQë„ödð<ñ—z7žº'siŒÂ¿öTCJ+¥"‚zŒy¤…½MV_w?upB$ëÎ’­õ1žØ&oÏ´Ôä³ýEÆ8x޽OŠžjºýõCP`lþSÒÎò›òm:³=­¶Ô7îFZÔMØ`^;G}ÕqjùeÖšVWyÃÓ¥IíHŠöÚ¦ Ní}“O+¯\ddÄLðÖr×zýš·=Ѥ¿ËHV„…‡aës €sé*¹?oc´°_œj·-o(×»°êœ Å4彊ڋ¢…¬ -Áƒ+wû¦ ,;Ža,€ƒùš¡%PzWÛòþÛ¿?ÇŠË œäWlÿ6±¿ý& æp‰€·ºæSÇnÂa}”QÞÝ OÝ‘V¤ÍdXÁ+¡~¶iÊJQz«¹ˆ“îsshIyy€Ër·FÞ1Úh1ÏÛŒ¶—ÙË)$ùeþSãÿUmÆa9ÿ kôVxŒz§WŠ£ I%5ÿw˜"{Z`÷Crr…MŸG¤»#›á›/{>pëkã›(Ù–E¨']²ªÿuرŒ±a3]«h/Nª%b´Ë¥;ÊóYÖ<…áDŸ§™î¡—ýÙ¥¿'K VJoÄ¥–™ À5b°wêŽÞu‹?-'Šƒæ4VäÌ"Û¯$ãEœ†&‹x5Sg±ü‡e]Í—Û¥ â8aΑ¿^ÖЗ`G—fØÏœÔYCø4x³Vóã»Zæj,¥Å³ÇW¿Â8ýþ,ìÈíÐZ¸s0e‰Á ¾å±|AMÔ$Ï-FµÃ ±‡o«^ð+äUrûìí.P>…¥1}ç=ÕŒ{¯ß˹4úÆ7éo¾áF·ö+mèà8ùöègÛ'jê%|/Û=ÝåÎ̤Z_»·`íãÎ.ŒŠzç½£ùìY‰iø±é…¿Q^ s¼îC gc žj„Uôª3œp=£ö¹?#F„L‹ù.>,ø[ÃSÜ)WpÕ*Þ¤â9˜iRecy-Éi,=³6ŸsŸŸ3¢VTýñ$ÔQ¡è8Õ%w?ô ;dJ|S;WÓmÂùÝëA’»Ï +,–™‰AÏyŒËâžÑC¦€_ƒ|—s‘\Ü»€s8ø¼ØÙ~‰ìòŸ„F\?¾µ ] x ¥ÙD-ânÐZ_°ùn—õtæÙFÔûÌŦ³À‘x¯ŒtˆºŸQ|zùkÕɵ¾ž“q8 \šeq×èÙ ‰]])LÔëôžè®‘l­I #ÒL´GOýtÂz¬ù™:ãq±²¹?upl‡wÈÊýIÌQIY»_øGÔ‰BbA»¶µnuz²»GÎÛ³–ŠPM'¥ì‰f¤ 0e8êÚëm-0{'Nñ¦äÊš„oM\ý½á‚(Æzçô›nÀ¹ø A¥¬û"(»ÚÊzñzkÚŒÁ*tOOø«yù˜Ä]Õ!è7eNŒŸ³aû)€­„eðZߓ֮«(ÂDǾeïÁI¨ýPc¡_r‹Ü%°áå…W©ïÖ¿»ÙOƒeà4øÛ v0×–¬HOZ}#©7@ö ƒè©:¥)ï†-¯ ;«ú@-Ç¿bIƒä,<Êÿ1ߺ³5/Æj #ªØÂ@‰¼„p0é7ÓU (¬@=pþ¡“Uê‰w,z¼£áŸ&©éØ*s®•wÏù-³‚?Ìy5@µóŒàbÚú¨ÇºæëóÒ…•ézÑ; GÿZÏZ£"Cü Ôè3ÿ»EÅËnÍ¿îáäLSo¥Ï¸OëŒ7>6–Ðÿcà·$ªqÉ,—‰b²ú#EW¨æ9~¤½.çï*Ï›[—O8wz1•RGxüwlæÿA£‘Ê Ô„gn’ZÁ/9Û%.ƒ,¹Û´Šæo&µ“¯€Þ ú¬ëld`V¡ >Î8E1£óâZ¯7ås{G;Ÿ¤e&}P –;¼Gr Ã| ¿ “Øë†;Ä@Q‹Ñ »~¯%ëj~b5›tæµõ~©4~Z"wÎ/;,èÖ·|P²öàð9(b}ÁÑ¡‰Ó!øª7„z|[Äô?ÙIÓ%å‰s;ðÓM³\ŠTþöã~cl¿“s'O-õ¶”;ã{­œêÑ•ÑjpjW ì%¯L8*<‘N 2—%:¼Hö¤N"¾Ùö±ws› ®¥vñRTÀžò1ÏcÜQS"µU{ ÊÁ¹„ðu7Áê´´'/ÑÑøU/ ~bÑÃY^2؇^ øFÁçÆlIX¿=„XÉ•ÁŽˆ2ì+û‚ú@£8k¾ ¥dDŽÇö‹ó†?Ðõ!ï¿ApÉ¡måkL;@ $…zPªÖC)”ú—øŽIã1…Në™ØÒ$çÒ÷=«»J­^¬( ³ùÎ@4@J[ªH}–•\îønA‹NÄ´Á_ÁÌ÷7«j\ õ¹°Zߥåêâ,ÆS¾žRsýÊÌÉfĆ™JÉ+†mƒ§¯‘º)¾M?üíoz¾Ñì¾`Ö°˜„bJ‹ì²¥z³Aµè#ÒÓöÌ‚´ˆãŸ¿õ_ŠO= XÀ™â ü¤©Ñ.WûälXc†þN½ù_Æõ>„ ¢“8»ÿ|:ÍðqÍ.ÝÚsóîþ©œnãŠÌŽâú'ŒDw¥r.ó:­ŒM‚ê`Š›ÚÍzÒ~,çÂx´ØÑô˜¤aûŒ& o5¤™…°Ø¸¯&,¡TÎâ矘9q“[øÞlÿ^‹º@­m«ÐHÐxò]ˆD*̓W’©V.ÒPe³C\'ØÖÍí¢í±ìã ÉJœ‡¥!ê$ÂdÒ®Úå•lM^˜=:iPëú"åÜn(—%øÒ›­H`Ø—þN¿ôÏÅl øé8S9MÑ~¾$Ä%H–ûéwŽQÚödùί`Fõèü3ÿ%!Dâ>#$]i–ð …‘“:×P¯&&nË[SE—®†oS¨ºAKå‚-ÅÚÍxH0—–ÂâìEóPø}bÍ~Õ%6®óë‡ÈÉO5cÏ.JÄ…©ü–Ðç{/ìÂ.•d Y õŽ=cVLi%SOó^NX`ÁП’ NZqøSÕZâ IÄÞGÁe˹êÊäŲ%RÑÑ£ éJ®ÍodQˆðáz`äYF¼> ¨4áP “V¨ÝÑ-$¬´¸ö;kFó|i%~0Dú°ÈÔ %à\™V(Ês¶ïàÌóø(O[i!c·ú}GUÝWiÖž<øæBñ& Ф­èžmsÈžZ(è(î…ð<µ¿Øšáé+?ÍÄž§Hgã÷ÒÑ'¹‡¢ˆ\Ãí‹ Óø®ß´þ€Ó€Ç·èD”²ÝrQjcÓmÁómI$zô›nYÀ„ºuªnaæ w±áRTÈÈð2žp?3p3tB„ï3UR®m gÿm{ "[Ú ){ü:iñ¾“n_¥8ܽ•iTb‹•Ê/òo«w‚Û Ú+8À«u¥.7ºØO*|te4§[jñGµ´€§$±MÜÚ’_ó±4{TÚô*áí'½ˆÊHñf0ÿ|tu›¤*úT®D¦…1Y(3ÊyŸp‡¥[ßbqõ¾ sï‹¢‡¥±ûd 5Vî°¦xªÐõ¢®ƒÖÍQ­›©‹G$0på~C`µ‚ Öÿ*eú4thÌYÊnI÷¨â™^Ê}ò>ª¦ƒqL0¼ðýQiB[¹NÐpÉT¢å3*h6>~à.[çl<)*šV¿žë?e"®öÀáUö^=|TÃgëŸê-x—¸Ô?¹ yè)\‚¬‘ ]“Éü> "ò+D¼ÇÅéýÏê„-bñ‰\þÒÎêÉŸIò ›Àžu³™ ô¼è´ÂæÐ•=½Ä¯Ü®\á\ð ÉÔ–”1 ÁCKɵ‡ y ç bõìûØwéQkÏñ]ÅS.†ì°âÿyñ‡Ú´)TyD?÷ÏYÒÆS¥†W€&fél§ß3”õ)ôšGã ^Nøì¶¡Ld÷3˜¡ÚtҥȲ¥¶!4ÐËô:¡Þ¾èöfY¥ ‡ (¶E&ßÒª ¾]DMÌÀñÔ€KÆØ{a4àƒ¿àµ½2ã Ù>,a,A`ƒ Fõaù£ cS3_€!m«ÞbI}làÞ?âì<ÖÊR7È™O%®ÑŸ›tû¢¢º ¦Uÿ Ï(•âà¤8®,“€Ihþ«£]‡HìQ÷‘²_eþŠ^;ûÎáýñ@5ã%®‹‡#÷7+ëöCšk°¥Ï…¹©> 9Ú‡XaÍ©?$QUßTÕ‘¤ž(ONãçÄ”²ÓáÊÊfÁè‚éŽ&÷ʲp·BÁ èùu„6Ž,Àçª\¥ì› h´ü úõv¤žÊÓ ßÄë!Éd…ܦûÈØ8»„‹=ge HŠÞ )s˜íÚµâçª)F&î(DâyX$æ?!…ÜaD´]a[9[ŒpÞòûm‘|¹Y-˜€E¬íœÝ™[}%~§ÉèÿlQµšJ}¤¿º×r"ÃŽ‚s°A}Då8~œdã .*¡ïhªõ¼JÖ2Ðm>„lÊÔIîAMo5DûÇ*¨˜jïlpcN·z¢ñ¥Ä ¢Â7lTô\›d›ëxÅ‹T-¼0¢é¹z‡,ˆ[?˜/Ó€`M}%š×'¢¢·çñƒÓtÝÛoUöZÙíÉT¯r<Õ–©½`oAõGNõµæ»ÿF ak“~vÁpÞ*Ë}òcE³ ŸÀðß ½VV]«ì¶rW±œ®SМ+'´V>÷%tv×ÅøW“­¿öç÷[&6|Á‹&yz$GíxÌÈþ¸qhÌXýÚîñ†ÀÏâè{æý¤ž Þbß&- °$¢p²) ’üÅ€"à`Ʊ¤­à0‰¢ÎÆ9Z¼-ÕP¥–ß%šï•uÃö¥µìÔW»ù 8ºyâ>¨Xj¼•]ßvJ<é±g!ðŸrW/Â]]$’[ÆT¿lõÇ^BÉÐüW(Ø¿Ír8NQV_¯…ƒ hßÄlE3C§Ëj*]¢N÷UåVŒ »Q£=_yåšiè<Åw®þ×S0éÔLf Ÿ¼ D(CùêšeÒJJb %L&M\[²˜—»Ý7r©…‘Ø—>ÚØåé€ î™&¢¨ƒ§p2‰¯í«~X•+)6­ÕFŽnýmI °ð(™R¯ò£¨8ùÆqn“áeíüju¿?Ò¯wÒ4Ù‡dÊ‚;r×?sÜß…< ²Pç@:Vûôž›x|ÚÓíqáeË i™“™¡7*Ö×ôUˆow²æ+Ê f˘$³ú)œ!SƤ)Ý”X‘ ÏÒM‹Þ[”¤“pT[j‰jWÚ¯ •r^Ûî2ž[¬·Ó_š¸ÐA¤‰6ýÚ³„EµßÒ:s&ô›s½Žº¼Ù;”ƒ{$A“¦ëëÌg9'ÊÎ)±>Fžü¯ð{g„—ª R*t"÷¯xPUŸ´ÃkUºM õÄä> ª1÷”çD‹®†uÚ%§ˆ.ë*Qx­õLYó ísödªå†žM¹K ¼\J——Fï–u"f4!:ddåÄ>¦Ó‘Ñ[·DúßrÝ{%}Šrb5¨“ õUÕۆÌG® «ˆþÆi!VÔ½*fÐÇ:ri²ÌŒúÚW.9®Gª ,ºGÓ4®¯L°ž¨ðÀ"º°S%íò>§w‡èNêÞþ㵘Ë2¯ V¥’àŽï1AÕG»‰wç„N G‚ Þk5j~¦Ç±×ÙPÿÙic10=Ó jP ‡ ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cÿOÿQ2ÿd#Creator: JasPer Version 1.900.1ÿR ÿ\@@HHPHHPHHPHHPHHPÿ]@@HHPHHPHHPHHPHHPÿ]@@HHPHHPHHPHHPHHPÿ]@@HHPHHPHHPHHPHHPÿ <’ÿ“߇eÀ37Á¦¥âGщ°TK‰{ž^ô|Ft…˘O0Öe|9 qEhUúR½aZ¤|ŽT K+l©†|8íÒyð–¸UƺO&¿/PMRùK¬h„+"(žìtçM:wKl>Œíÿ`ÖÇÀ#¼uhH-rê5_á’ 3H &wm­†)‹ù*—_¨Aò€Œ9ô4è-‰/ Œ¥ù{ësL_Òi®¼qwNj‘Š|‚îýÃð±N)\à#–Ø¢«že)%¯ '¬yh8.>ƒõy/ŒååEá4ý™Z±h>­HŠ›[—˜·0 "ÖºF4£g-¢%v’Z»`b© Ò@:©ÞYÚP°±Š?ªby¿Óžð/\}ɽ]wþ‰5ܧ´«„<‰ÁAǙԹœÅñlâÊ¢T™Øôµöcׄû¹„€Ÿ5¤€Î†±ðsrfÚ×x‰ÃŲ¶ÀLN<}´~xŠC´ûû.õK ýµ cÞ· G·²oÒ%µÙ2üÁ²å üP„AË5R7Þ[áž*`7RJèUÞ=ÌÒY0¯»îËЋtÈ6gC>É™Çój†GmiR×[ Yk€óÑg6i?çÖ6à´Yß‹[pC"÷›H>âTŒO½Ñgw— u@oˆùØŽæo¿=I)Ä¥xßçN 11>óþA^óá¢.d«µy"°HÊiù±‰X붉vûÓלS/m7÷ú?\³î[â¯ËHÀ4´3DŒ÷ØãË=ÿ€NqøèÁ „P¹2÷zŸË?íôÍþOãfwÂÐy,=X3öÛ7©ÇɼÊœ…Tüª&)ñ©Þ À~d±]•ã|¹ì›$+€Æ³,Ü`Œý[§Þ‡Çc!CñCa¶yŠgQž?ïO¹f`áúUpÂ,Xgy"%‰ì-ÖÆj‡x&~P—çBìþC~R„RX˜#£ÀôÁÂWù{Qó-s X•j냺ï iý¥P:Dá´—&»rªöÕÚQ5HÒ©ÄTA®¹ù„H„4|¥}hñÁçHÞ(e¥œî“,÷š_߇l37Á¦¥ÛVô§9QŒu\û­$~³y/¸ï‘xFµ{;(Áš=9{báNtZ_ÇÁ„éQï(„ÓËÂÏÓ)´üƒšd¯žÖ1ÄJÍC÷<®o€55ö;XeÍçÏBe`ÓãkaXk7ÅŸ CÖWŸú+ª¦Lß] Fçà‰i½@s̹’~K?ñZ:G þSÊSkPû¯VÏåÎR1¦WŠ¦Ù ¦Máþ¶²À, øÓËù'YD|ml)€“y@¹öë).ÒåYºû?%+ž†¹EË/ÜàÛÆüROò ¨u?eVQd5n!$¥J‚`E­t‹ŒÅIäß“IƒÌ?qÒ-Âä !—£pmœf‡ø9‘„9™Ûœ(€ ÷Ë¢%û¶ÕŸmºÀÆdˆ'ùØZêrñŸºº~α¹SŒ‰|!6cžð÷a&®^Æd^  ¬ZHS¼ôW­« ¼D\B{—ôÍ3KFÍ ¢VYè½'àp7ªWÎÐ[·o[ß “,äåh}""È\7‰ªHh^Q ƒÏó$Q¾òß¾”òüeT’ºŽ31æ «Àïe{´Šk_J5§€µC8ú¼6Ô•85û°¶ (IƦŒGÖ6à´Yß‹ U†EN I=ª4ŒO½ÑgvVÏTŠ aÑ"îýálþub¯GJ·Þ…Gu3Õ”£Ão?ä6»a`&s¯#qøË°æ¼¢Vºí¢]¿,³+”»ÄÛMýÀ~×,û^ÓuŸ{’ðdÍ3üö¦8"ƒOx ¥ ?ñ!ÎN‡ñY¹2øÔÁZ´ü)•ÚðAæuú67w½|º$„ý“Ð?m³`aWk ãåBÏ×*p=5ƒz#˧Y÷¸€üÉfpWáCÎÂ{Ò͹°aeC²+99îÓ¡òH¤hzª @l¨ÍË ?ùéxúL:ÀŽ À6£vœæ àw¸.b º_âÂ…<‡B[ 0甡ye}§ÀôÁÁHÙRÑþ \ÂV%Zºàî½>ˆ©¥À¯‘8h|á}òûbfÆìpÊ‘;¥R/ˆ©ƒ\£&$B>@Ò¾´xÖý¨ ÎM–Ös´¥®Éé߇i`37Á¦¥ÛVô§9QŒu\û­$~³y/¸ï‘xFµ{;(Áš=9{báNt'˜ã·ê™ß5kÉþúº7*_"ïþ̶EuÒÐbEÖ éÂK•×¶óao}ã¯Ù”5ËìcT7 ¤ÄI¸ô›+¹Ø¼ñƒyàrúîÚVjïµ>Ô”ªÏG­f¾wÅhé -ÈËý¹‘Í4§ý@:_ÌÉÜv¢«Àµ+ ÊÃÈŒU&ör +ªî芛+. 'ÊKç°Úþ(M±ØöÊx¥HoØ”ö›š²áu=^,6qC¬‚„Z×H¸ÌQ4™Mù4˜<Ã÷!ÒÜ.Hö«1~À4é¯m™ç0•]>¨6wOËEµ ڱܚ„:JíµgÛn„°1™!ÁhŠ{¥rC´Aû:ÆBåN2%ðl„ØYŽ{ÃÝ„š¸!{‘x(Z‚±i!NóÑ^Y>Îf`ºÄ·‰Ëºà<¬·Ì÷lñKü·àào^jâ¾Ð8[·o[Åß óJäåh}""È\7‰ª+”цäÉ&¾òß¾”òüeT’ºŽ31æ «Àïe{´Šk_J5§zƒp Àõ¢oŒõKcgf/ñvh7iw}˘ÏHeÛbÑg~,6=iXê<ŠIíQ¤b>:ôÎé P[‰LEKk‚ôq$«}èTwS=YJ<6óþAS`‹¶Bg1ájò7d:ŽkÀJ%`>|Oíå#„‘¦äRLéڣɣG n‘ ¥Ûê-N†@ÏóÚ˜àŠ <à,:”0ÿbC!œâ³reñ¤Ú§iøS*´!‚¾JÎøC—¯—D‚ß²zí¶l *íd|¨YúåN¦¯ÃBytë>ưõçG[ªu.I[ô*òh àxÂ*Ëð+öÓ§$·‹í½ùÄd) j‚†*3rèþzAÞ>“°#‚p ¨Ý§9ƒ8ô¼ „2j‡x ò n€ÃžR„å•ôŸÓ%i½¥|¹„Îc|à7°¦e÷uýµìÀâ¤ã ºC¼çpð±É£Þ4´å1"Ñò•õ£Æ·í@nrl¶³ ˜…-vOK߇CÀPO¬ŽRO‘rø41Ôêæl“êàÈTGÇ9¤íç7GÅ&o) 5—CÚƒäwÓdWoº{wÆWó³`Z`¶>Yµ¬å„‰»m£Ï€4   ûòõÌ®6PÏ+ˆÄáæk¬êvùÑ×–þáî£!¾ „ÏQìg”,.a®º}Ál¥xÍî7g/Š«½ÆžŽ¿¹ª4#òZNb±æã=lK‡É•„„ÈúÅŽ¯­±¹‡¨/i[¶Ã Œ’áTîðn!d*ˆ0;‰´ƒnP7VÒIíµ àÀ÷%ô¨BÆÏ2ÀI+lSž‹Ê\‘ƒÆf®l'…Q…µ ZÜ\Äò×{¨žN’áí­Ã–V±+ݾZP3ln£–QË6Ö¡…EÁ)zƒCö£ ˜„öÛ×Åÿk!Çd¿«£PKDªé}c‘Yçµy˜jQ=æ[¤=QÇëEÊ}ŽJì.–0ºWao´58HH›ˆñ{Óz8N”ˆPPüæ¤ã^$ ÎqÒfÞ¦ï"p0pΈÏ~0T‡­|½èHã`Õ%Âä-5À±/ÍÜ5«ÖΡ¥ç6Ú˜ù-~]%2Ê)…l7ǧ£3j;“ï Ô¬«ùÃY t¯NÏI‡›À­+'óþûP½†’ø šD/KoiˆDËEc”R»>R'\[ïŠi •NƒˆH¸qšä>ݱ&o®ÖßžüߟC³óßÂë÷—ªu¯œ“I+ºº‰W4kd|ʪ-p1¿èç¿Õœ!=$îL ÌÃ8:ën·‚¿:j*³:sȾ,.›´æÙý_UT@œîÚ9ä%nW©Zœ˜h—”dzWõ¨ ¬êoŠÅm²ÄJŠÄ«tã7ªÜÖê ®þA}Éóæ0ëúÙÓÿAøv‹¬¡)¶ Ö Žò¹˜yÆ/·;4é M®^½Ìà.¤ÒÚ¯âº8Ûh澕ˆ"Æ3‹Øš.eÅ•Õ{9t3føÝU^¿0KN‹G¥Y즑\ðß 9 |Ì/û²é®[6“YÉí|ý¸ô¯{þÀ_¤†„znò„¥ü# ‰×þ;(¤ä€(–“QIü}•Æ®m̯wDèHÊÀçÇrOð8³dPXCåL¿›`¦/ ê]ôZT2¨NmߨÀXˆA {‚»·eÕxàÄ1*kí¼ª³ (Ò©+²}ðhËé《Ûg¾ÜôXܳ›×‡êýDoCMfˆð—{ÿlÿÑûѰzÄêgåû±xn<+h×ì¼”NýE¹u7QIWô¾µæ>•ÚTK›&4Þ½Z«Á–VÔ!çæòš€Oþ s×X`€ÁúU­ÃURŽè9å„ ( Y¶4Y4Â9K-Pؤ©ibm’t}˜Tüî5ÝN÷cF:@¹´+ŒÓTONбp$µ(«VCQ»ÚaQ©!‚Vdá³`¬á˜×ÿP œ™öVµÔS¯±’tXÿ(áhÀ[ë”Õa¯Â=•F§§<ò6ût`®K_ÚMåh )8%ü©œÎå^äCY[àž9MUØi5;Sö•ÙƒD#ʘ.Î_™ŸT]µ¼\Hôö@䦱= 24Ö= ͨý$þ©Éä¿?ןöÖ+r Ï,_쥃 åÚâÅáb9’¶}Ä+žkšÇýn(,!æ²øa¨|ºc}1W5…+)Z¸=´ugy¼V óýÄÊdŒéWHÃì«hÒÎóé­ò~Üw´Á;dŽ ÅPDY"àd!èîàw»¤+Ñ·8ÁG3X ZþDT üØ9Ïše›+äú;5µ k©¼šö`ì52©XK²ÁgÍji¾#@Tq`KÌíªÛÏà8ÕïZý¾~ saò;›ÀæHÁÚ~âjú§\XAóÌŸðömÐÞbѤêº&m5,w¢8¯YÍè÷êÒ=¤—ë\ìOÒå»ÝØ™ç™}ÀTòø.Îë&©ÿjŒ‘&u‡NÌðàÕsñ¾ñ/ÂÛ¦³Èoüzãxûm¼,«­%cFª]ß (Þœe×R\mì±æÉßí¤D0KvĆ Œo¤feRò%s]¢¥Ð„ž‘y@Ó”ÖÂÎä4`Š(_=µ*B¶köÏ5{¼=¬jÝèÂð燡+NiÞµÿt-æ4Ϩæúþ/ýòhH¢è³YØ×x¸h „‡÷Š+4âÓÉ”&ï=aã¼·4x¶] Z­ wÙ´!÷qM‡§?¿ÕÈÕ¨ño÷#ux¾D¹ä8½v«ÎIÃã†_»¾ ýd²@3ÂŽg´Ï 99ÒÈU/äñf?ôÝ›à3áë7:Ëci¢­L6¬ÀÓ€ WŸJï+µÒ‚a¯•öAÜPýzNÁAXêÝn@ÞBÏã~ʹqñ„Ðoû×O®@™+ 1ÝÌ;óråzÃÊÀŒ† Ü&’Ö!œ>‹@“å#Ü(–ùbÖÙÜž^…«×+”FbîƒKïÙ¢&¦ÝpA'ÊpÒõÁ]‚š³­=}~2Pe| ¡|üÐTŠø’ÔuöYæ)y´¨¹'¨È66~²qÐ%¿·f/7¨CgLÄK]¶üW[׊aÈ…Åä|RÛðïp¼p'æù·™m {Åu䎫#>B`DCfp„Ø–±ƒ%¥…¥ó^ MSV>á3"Ÿ9ºž·ëßùú9Ûò þWå—"s›;˦KùyêËeÊv³€V8’È®µ&“ „ó.®–ºã¬™­Ûm…YR{?F×ߟG÷çÑ$üúÂë÷—ª©hF©¸– ï½mjà1êgk=$xtÐ{ã9«„ìíDh‘²æÕÞœƒU "Ðü5T*ËîŸ85d ØÄ$S+Òì†6UA+±5j's†ëeCÞ°&➣²¹¼9+F@™ÌfãùÛGá?‹^àè@ _\zZå…4%2©&tªf±Þ‚r2,Ï*sׄ‡j<˄ބ²š³A pEHˆ´ŽÙŠÒ«ú`sÕÑòxË0Ždíˆkö¶Æ?ôºÛÝd¶=WÒ–°Ë ?)Tt0 á3­äÌ~ù™0: “™Wìòq#n9P/T‡ÊG<ŠjÌPÄofØÂʤ¾JÎZŽÿ[ä¢UT]Žcªð.·X ‰À‚݇½¨ÇØ+z¹÷·Éø2òüRëýŠß &KÌ¿Èý½ñ³'Tn¸·»¦p@5Â.™öÄ7êíʯaVaàú0µÇ´W$Pñ›‚O+=‚*ŸþÌí]êMûmA;)~™5DÚqãɈòúGÕnQìw”s}ªhúÏ­‹’S—€—.‘/rò¬f :Û‹Ôqˆ…šÆbH˜àªˆxW¬ö²“fÝ„{\º]Ï“%“›‘÷§•à\l  · œ48IM@»ë‹û´'o¸‹M†+Ÿ|kÉpŒà €Žo}4ë3V¸O @¢ù=“*‰5<¯Ê]tF›ìpI ëŽQ¸œÁõÖ 0}Y*¢ˆ’®ð÷¨œ„tY܇zY)$>‘®{9K-Pؤ©ibm’t}˜Tüî5ÝL­Ü=™B!o\7³äžÑİ͞ïeùš„ ô()¼1ÙëdCeä ª›x]<‰Ø]B·…¶”J3V$i2ÕâíR¡9Ï\u*Ó+þÈð/8W6CUÉhlP‚’òJ{+LW›Ý‹†‰ƒ‘¡¦íÀ{\GýI0¨3ú#<©‚ìà%ñY™õEÛWûÉÕ@ZûF~ö…×øRâé8)Kúš[í¢ˆ,ódGC¸ÿWc°ï^²FŽÛñ±Å‹ÂÄs%lûˆW<×5úÜ:PXCÍeðÊ„±…ƒømªüE‹%"U&LøŸ¹¥¶Ç†½UùWŽåuh^YU•œÝäC[äý¸ïi‚vÉŠ $ˆ³EÀÈCÑÝÁî ¢º ·ôåV׋Éý$5)ŠïbL1/)ºÙe4Uš_L>¤Zt³p‰ópI.ËŸ}õL𚣋^Z9 ž§Ưz×íóðSœ;%ŽæêmïjÔ s¨háj²|c–“¸Å¥3cøfJâ÷YxQ3BŸ_^³›yîö¬åâ{òsS\îÒ(FŸþAcaÎ6/­-åÜS5ý¦‹Ri¿Õ!æÓÙSþéðñ8BÀÞ Ø0) à}ÙS®7ꦚzT—íÔøѼboŸÉ[Ó“ÇÉ.?¶ö Øódï÷5äïÅäÂP|IqóÄ•ï¢L°:#ƒU±±‘y@Ó”ÖÂÎä4`Š(_=µ*B¶köÏ5{¼=¬jÝèÂð燡+NiÞµÿt-æ4Ϩæúþ/ýòhH¢è³YØ×x¸h „‡÷Š+4âÓÉ”&ï=aã¼±Èøà`uB‰¾ÆÍ£Å5O1 E¥é ä°IE<˜|xCt)ìH|7zC#PÄûÈ"HP+%’œn4s=¦xϯ‹xèƒðƒf$~XöN›©¹þãÂ?ó±Jìv…œ\x‚+#ÎËË9a…qX®” |¯¹¦6 <Ì6Å%c«u¹ky ÁôPÌ :? â Ò³wÄ©±þälí¿zè>ƒ3îz%ÊUöôcÏ C 2ªÑ^’”9âß'[G±„¶¬£-`Mëß•²50`†€EUüÿT¼“'ù4”(p²'Ôf¶g`dn@h2¾о~h)ç’¨õ:û,ó¼ÚT\“ÔdF›?Y8è6`ìæLþ¼­Yf¤ˆE€RÞÐ"H£ã/.`‚k“tr_!g?ùôÌßuI*ËÄ®ÕÒpoÛ>ʱäµh^-g/w+20M1ù]k©|Iu.bÔZ1#2Aí+oë²L7àCcgyt±ª…n†Ž\›ô/u®^ÊëRi:L‡]-uÇY3[¶Ú ²«2ÍIÝ?ߟHç¾ÓóèÂë÷—ª©h~&j Ònµ¡ ¢È*GFS*>åkâõÁÒ…;sr±ahPÏAé²ð.ªƒiÃÌCÍZÆòkχTïóåÐ¥§oôá5„ÀÕlòŽŸ‚k~®¼Q."’ 5 "’<†@wñ©Ì^pÝ„þ-{‚Ý…™C"2¬¤C€þŸ-ˆ¶/[t´BfœõäÒ›h3Ï6ul2á+p›Ð–SVoâ]J ûγà¿6niÎ6Ã{0c–íÆLeŽKÖf (6Ç ÷[v‚OTwôÈ(lòmÂsáSæi¶‹÷ÌÉÕ˜Ž¤,Á¨‡Mß<ç¢xo´ .Ö2½èÿUôÅÔ˜üu"„(€a¯>B[ê â¹9Ño¦>éeâJM̈ÿCú9Q?Ðe:.ÃdãœùÇñw³uTÌ=\4wô¸¹(¢I/ØÙ7rÊ}3&Á±4·Ó§œ²vT?¦„\‹@ôÓp@iåg±°ESÿlÌ:ÕÍ¢‚e¥ˆR3J}$Á¡Ew75«~¹+²~„ìÇ[T»Fe+éêq¹Ðæµì(×¹Þ Ä…~TæVÍþpöŸÒåÀ&’,û*CtbípJéts>M—äÏÊb.Œöáópú£â“#sñûnDõO䀮І’€{WɃY—8ïÉP9š€Ö–ß~bs.E 6–˜ž[(ȯØ÷Di¾É‹i/¥ZÖæ †¿ç±.•ž­™çyÃß•aJÑùkèß…(?vØÐB`Œ{9K-Pؤ±“@I“ëªâ€ËŸ „? `Õá}¬ö!i;/’&~94Ÿ‡/iMUøcžLþŸààšX¡f@««Ò'§2Ïç çàŠmwõÅ\7QŽò ‡AK¨ÉëÂ6iŠÏPª)“m¸æÊwßúÉÏ»ãgIÄn’¥@ŸÑåE>áÎl¥›WŽNk¶4å L8 bú3ûWçáG¡ÕH·7Å:b?kö¢Yñ%ÆÍÄt¶OG™nSêìv2c¥Kfu¹ÀûzPÆÈ!¿:u‚ŸÀgw c†H;¬SKÚSKÉ 0O$-uD\´˜ùG†Ç~ÊÎnò=Û0͆ À²»`ãyBaÓ¼@d‚­ŽØCa_qd·Ò %Ïx?Йd[Û±ê€÷>tÙdžÚ0†–¨±v“$¼& v©0¬Ÿ8T@*ai•Dö®}H‘øˆ)2ðGc¹ÏZùb“ƒ-½ÀŠc¼Šå†;Ò¶&ÃÝwV‘.ÍÚâ^û©Í‹Š’}VcÇ B‹|™Ï;ÒóÞsònΪ&¨}Ñ3pÈ4>xAzÁo)ÂâQ]ÂL j|?ÆêGAŸÆýTÓOJ’ýºŸú7ŒMóù;§o ^Ûnð!P?<œ—ß³¢âBö‰*ßD™`tG«cc‘y@Ó”ÖÂÎä4`Š(_=µ*B¶köÏ5Š0pŨõÿ*$ä£O^*Ã, 40åj%޾Ï´¿—Àý¡Ê³ ­ŽnÇr†&¦ÖlthµñÄß X£Q€Äåèz$o‹çq´j U䘰‚3í¸—@Õi,êq-Ã}]×­ðu*ú¡Áׄk Ý|2m5ˆ´8OòžÞîÁG¼.AÆ{QNN‰ìãõP³úŠ#VtÛ”øÄ%ò©Öì²ÀfO*ø¼ Ê*Ämt ˜lZ³¸åÆDJTC¥ÛÐ #uõÕúOš…šÿYi!Ò617€ÌÝßqJUýìáY¡Z‧o' ·ß=¸qfmZñô‚wm’rC3«æÒ6Œµ7¯|BVÈÔÁŸ9uçÒåñémðâw›#€±p³‘«Ø…P ¯t/•o/›awæ{§P{0'y÷ûL9Šá­xXåðÑR»óæ•.6³ ªÎì‡QËn´€(òÆÈ…p¾á)\îK,ð‘ð‰/‚Š;§Ðö\´ ÿ1„Â6d¼¬Ó´±Ó³[ÎöÞøô¾úc'´:m¼&·»,»$ÃåEÅ,lèn–ƒÐˆ³' –íkŸž®ýi3}oêEYI£)šÝ´ÐˆU•Y–jNéßž‡ßžˆGá àÌ`y Ö­ûòŸ.2oÊ^ÖÏ,ÒŽ*È]ˆvcÝèpf÷¤> [é—hKê÷ç·Ð ³˜+Cä«àij;óÑÖ¥€XÖÉæo" ý ú¾ÔÜc `ã_»ÄÌ¡UHöäX¡›äf>ÛÚ›8éáÞt73Û²ÊX¶:9Ÿb,{k'ˆÃ1¾ùIðÝÂ]hì$F†¢*%r–›Ú«¹Ö˜cM‹o?Aݱï„Nçš]ŸÙ\ÊÊ‘—œtjY”¾ôü¾"/ÆÊè͇˜©‹WbÚœá_êÙIEʤۼ`_3Lo¿oVÖ˜@ñu÷¥YЬۢúigîã¤BH˜¶Ù‰dy¨÷MrV' òâSofi™xž^¢­!­Aeó}—• H‚mŒª¡Ìè©*'7žZ¿ó+™$ ^¤Ðåž ¯¢;É…ì÷xžâë—¯jÝÙñ?‘²1йݣmz^¶Ý»P[bÐÑ‚=œŽ³Rv`^’«ØÞÅ_faoä* œ˜•|§Ð5?DR4»PYP×=–H´«°ñ˜Xõö?: ívª¯GŒWdÄ5ö‚›,Fî'{n1óölTô¯à…íß—uü‹ñ¸oIEh„°þm¦M E?hÅ2ÙáGXœÍÜ<ò"¶žªŠ;»ôý­KÀs¾f qEF„yÇ  ½‡•™Táæ§±C{oƒgñ›–­ç7U¢ïû§¾™c/­ŠØ€[("Õá»o×8Mqn‚VU7i}³d×z7­¯íÖ·ŠØðXG“Н›8 \ÄþÒ':bhš0µÔlÑŸ¤¸b,C8AÊŬ¾¸Dk£[$tþi*¤K><µ= SjòðÔÞ]EUQUYÜiˆÇÚƒ÷Ãñp’8ÑõK'Xœ-QÁ·ˆjÍæ¬ÌAëÂm–Uqm„ô!¿SÑ䔯Ýú0¶õO0P/Ûçë'ÄãycݲÑÿi¤éç!ïíçU`P…]W˜ô‚LbË AøKd/lpx›]S ;k:çu™È~EÁx›ÆæWTMñ’†l¸å<šÔ-÷ߟ§]ùú¨ÏÏÓ°í:ÜËÞœC¯†ã±ŽÓ…ô·©å—@Ó,Pôê¾û_½Ë]pâmt]ÑÒí¹øVô`¢¢Æ¼PÚ–º6.í”G·ì°ß5¹?Ù>¡š7 :¥´#•KÚKÑ+ÃðøëzW•€‘Ï7 ÂRÔå. !YIÓ͇W*‡Ý)Ðk„M%ÞIôŸ‹€‘Ê¡h-ÐaýWg¼‹ô‡ÊÇÐqÂ0Yþ¬Å b÷»)°©äxqŸc¿¯ÍŒ¶t3[W@†Z2ì*l|H—ѹ†&‰¼d ¤Þ|r|¿CØI©D¹\fbÇÂó:™Ix4<&’–PÓa#ä&ú…“¡Í{ƒº,­+%,%œ¸aÔ;¨}rMœõs|ôć\¿rÄËl¾{ZO8…A„êIG¥;ñ'Ø]ê#ÿl‘úœZ%¹N£jO¼öêP;´¬ÒïPäð¶·¸ËÄoFeSÌÜëÄB÷Piü+ÌQ~lcÌUÎÜDv7õ×®½&vΪšé¤"k †x„ž$˜ôløc=o&¢=˜ ¥mÀާ”$?>ÉW™Ðç6Þ”Õ=žKE›‘P¢§Äoñ+ééÂwj¨Ti8À"×6ÐT  ŠÙ2M^£ÈŽãñ#ÿÇ«"ãåZÎlm½Ù¹SfãÞÞOI,æÀ¹,5´yy[÷ÂQ­ÞØ[~›e`Ø®;þ]‰‰¤«4É1 ¯h¸î ³ööŒKM㪶7Ìé¡=èÄ%Eà î«4LÚúEzT`$]é{‹ÁãMZéÔ·kÉ_§© $¿¤ñŽáF7ë–H†&nçî>A$Ñ ÕµK¤ä3Šme‘‘C·zrc—¯SJ˜ÇB¨Íœ;©yþHT\ø`½\ܼ\“Ë +ìÖÛÂõ›üñCoM,þ»·-ëãÔÜ%ÂH…½~/F õê0*4€ÑùfÿG"6 HÝSÐeÞi$’ErΫ“c¡Ï¢â £Çzo—ãƒnp7>|H¢Å½œ.ò©Žs[´ùë² Ø ì½VÇxÍV9ÿ7 5×t‚Ôã .—įD²ß;ksÒ;º~ÞÚ÷$ÄbpV¤Lºx\=bƒeÌ Þ”ô¶ˆCÆ ¨jhÝá?Ó…¼ÅôÁ\¥À“ååž>] ÂßgUl}{ªçD˜ž -Ã{ùæéb”«p¶ ŒBø!¯GŸ{bwµ%‰´E°w/ 3bRÇQuF¤©¤jÙˆ‹6gØ/ù%åðöÁ4ÚÊê?˜t’\Þ‹ û¢¬uË:RÂ1»Ô‚U 9jÌÍ>½jŸq„ T¾øcÒ%TüòöÔ2¡·j_]Ä“þè"ƒŠ$`g¼3†«lç¯v;Å쇾„¾-|¾#*m[åt) ïé8˜È…ÍQS}V­mÃþ±€ÝÕw_OŒé‰åV^• ¤u쉞ìr÷íVÚtËô}D§Ïœšwk^ð,®æã§­ä€ÓµY—¬”bõâj£°Q—dR<ü>’aOuÇÍ¡‹›X0I8vrfÊp…Ü£þ'‰Š™šO礯™kãF¸ò&–зYq[X Ÿ{ŸsHs.i@áßÚ¹0*§ VâÒLb|Ôƒ4ôäåÕ¯?ÜAEÉ&*m}_ÑÕò~BÚ ,¼xôs3ª ÷~æ©4@Lào®‰5¾¥ÉŠ £F£Í©ƒC™ü°çî],´#ÓѺ~«ý7w ^+€»ZTz}¢¨¥ÛwËÚÖLyr TâÚ÷¾)Õß÷#þjÒLÎg\oƒJì·ñJI±™‘Qêâc¥àEÇyˆHrl@¼­¶à¶ÂC€œà@·7bÏâ€5"ÝZÌÿxÈŽÝd†­‡PºÐ! ·ÑµUQ3X?¯‚³jª€û}Rƒ°ó9‡Øçõj‘+ˆÃq Ù~ýñGÉÊõf§Å'v@̸2¦M¼[brazSTÿr<é P_=TfxF [^U²8×j}žk¼þÔ»Õ*s¬ÄTmô.º ›,žî8Q—!uŽ"E9ñ¤h`½¾ ¤Å!ͨےGÉhàØDºgãШ®CóØŠ·‹l‰:¨’-þC½;Êvþ¾þ €ðMõ±¾Ÿ^§_XqV}<+ v]ü…ä“ödrƒn*-ªgo¼Åè¿~a#á ½“y 'í—ˆ&Ò ¥äT MJ±K¸é?{ÈñïGöõ‰Q¯Ê1éúÎ$p&¥¾þt%?q¨tê–‘þnÜWü%}¤á©~]zíãÒSt¼q÷- ä¯ÑøC†¬HÉz|öËïÝ¥³¢£ ÇIwò…•|éÚÛŠ/r’rI(*Ãñc6³5EèàÉ•˜âÐJñïX˜’„¨YÔ¯âù Æ€\²]`Ô)ÄÛÒ»¿]âÛ*#âÂG[SèüJ&¥–®°ÎÃÆ‚pGºžêã·T$慑̧˜¤K ßû»ƒüùÅ{ìÚgÆö…O îpàý:GÚx„‰“.™=Ù†$øÚ·TS1;ê}Z®….)¾ ZU³¦]^è+/M:A9Ö†R¥}Áµîoæ#_³‘Cß9$xãmî÷UÃwÇŸò]ØŸ|D32ørê8ÿ_¯Tâ•2Æ•¿¼î5¹>E°¥\rä·>ZεoH²‹yG¯/3¼aPÉ‹âÇ(€U•ÕU%yÐÐ2‹àµ{¦4 )ÎñÆ@W^![ø¼jé[Qš_}p ?·ôþs6âJŽlÿSp_[S§ifš³ù\£8¢Wìr¿ž HƒGôv|NZàâ_B‘Q¹ÉÏÀ®ƒ”åèêN pŒ ¼à6÷'ÐíÍÙÚ‡­%ìëÒ<ÅÆ]²H±9oleÐtpwД_Xϳ*cÊ9 +fT/œqΨpï¥(ŠŸòZXiŽ3FÎÚñ >Ñ,ÖÚeóZhî2S¦¾C•„Ù‡ŸÇseô|[JNè6ŸŠÓE7ãçÍþqn># Zz79×a¬É˜¼_ 9£&‡’9žÒ>C'Œ~Æ™ŒE?—eðV·ßù"Yáað¿ 2ø#úæD}`}^µ¦-7›ûK-ôTœu]Žz„êX=ˆ|:½Vë“vN<§ÓÆ’*±rÎîCT:'é³T¯æöu±0Þ¨Î2åD°ßpÊ~õªÙY,³ E3eµ3œ'Ji³B8à äk£Ã«Ô'$ˆÂ_KûKx9É ¯£ªX¤ÁÆ45ÆìûÙš:&²3LàS‰5ƒÂ[â„NUè$Ó½P¿žÃW Wø‘WKèͳJ¨Â5|?9ir‡âjVbÿ‡ é*y1lrhŽa6 R²òþlÖ»ºŽõÞÎ ý°ŽÚW6ÿ8{ÜŸ“5…ô‚žQXXƒ}n0ÇÕL—èÚä—«(:-|(¨þ[wLâ2Á¸•`j@Ù¨Gä,cHoc˜7„ᨋâ,ŠþËó#íQ <¾w(Ã3æ9Ù†L’æœyÁ5íå Ú ·ÄÊNROï±°¢ó2cð»4ÛiÏK…ª ”G³Ã—zZ»B«dñ?{®\çìÍÕ ììÈ?”Œ¸õ› ®Ä#(ƒKÊvì­\ñv¦‰•X·9ä³AëD*ó8Úâ+߸)•a…Á 2öÑWpúGÍG„¯IÄ×ÔÙÁç 3[ Ä ò}9ñÎØ›Ç Jˆ6Èþz}í2~S¥ &:Ù½Ââò_”€_ýEÜ$lëJhÂΛ"ðk°¦ï­L¡›ÕÙlÉåe i€‹ò옄æ=,°¨e"﹞rQ˜IöyÞ+CÑ2Æ 0ÑoÛŽñ@¯€øué5ßÝq,ûhòÚPé8,iÜk)¦ÊÞ)\[+ÊÏUg}äôßHßÄäBû3²~ÙÔ“˜#2ê÷ˆl½`ÅSÿ&—!Ú:÷V‰¢+þPÖ•Üz–§vH*±`õ†;(f*Ê¢´°‹®+.‡}=@Vá2\—€}¿/LΔ¸æ¬|ºî³àq¿_­ï&u?×Ý–´9´œb½’¨xl‚¢–Õ+WW}ïÑR÷拟ò}LšÍíU/ÏZܘ«‡É^¨Ó…¶ÀÐ@=«Á"Ëé‚ÏÎîôvGØå!.ì”v€3÷þºMz^´–ÔÕù$e a,!EÀ[ò5†lðsm‹Á‚Ô‘®ûbÇžíݦ‡«Þ¦í[Æa œÃu¡ÏQTGÎêÞ*rÔ3ÓÙŠjÖe{ í¡|A0˜)‚Ê V'×)Ï„AÌÉšû$×Õ÷¹;ô¿ÿ  Gx·m”Cl@Še¯ÀíÏ^’O‡Êl7YѸüñÑ»YGR+*j¦Ý[Ó‚‘tY…Y$X¼È4S» Å#kz—~R¢ÄR•“—tR•|Á1&ÑS'J"`-º&o˜°ÃB°>@ð†oùGÝ5‘ ÷÷Á‚I.èç`Q LÆAIíng ˆìø:@‚— !Cq»²9^zhÍwÉ(®¨¨+CÐ&£)%:©³ ™œ¬öcIÒØ+³º@ëÃs)ãqr"–ªSh_ì ]xá&x%ði'ƒ‚Qfe¸ù÷¨ac5^®r–?Éô©ŸfD‡ÿf²ÜeJœÿpC7?Ë¿™*ƒꌌíÔeyó¿ús¢þ®Üu$_°yKÈ{a¯ïÿV,ž…Kè#•,bø{ IG¾Wb×H+¤Œd §¢®„Mñ)‡íÌì[ô¬ &Få¤.µE+âdº¶õËþ_ºÚï8Wíohf¡V¸3a ˜9x¾ﱪž.Ãe>0 Äfmw•‰[Z0uò!í†ÒH§ò\Á?R(*è]ÊÄ5qUô•ÿ}Úó3Ãc1ÎÛ¶þ)ˆH@Þ*»Ëù÷—¼&|ƒÙI ¤2p¤eº+CeèSWà®bò\ëv &™­§ckViíPÝÎ\¨ZðYfk")o?°ÎĶK·‘7 µ†á·ÆåépY?Q³\ßõí‹xUÛÓŠ>ylþýoÈÇZb*¯®MIˆZ MsY¹ÍJ©þé6À®É< cãH‘õòEù-a¡5CT#¤Á|7»0lÙh~¾ŽdùÑF¬™¼•èi¾D€Ï~ËŒ#lðÊ\ÓŸŒU,%WJLóJ^Íy@­Z¨Â#¶µ–5ªëc|c›V€ÔA5rjgXß öÿLQ«,‚„fwdöY4íLäœ?ÈèH»¡8AÕéö þw8sß]¢N%µ£–‰xm›}Î ó¡u­å¨¡±h½zzMÎ7.”¨D‡Ïò›åvßó§SŠRj]þГÕ@PYhþ‹é•7uÊôjí ‚4³Ÿáú¾¹Hý¦L%DÕM¥Ý ”(1$ðY³6³.Q»hnÖê>À¬ñŸ'µ ƒî•¿ÀÆ«±= PE˜ž—}ë‘Ñ»Ñöàø)ÿWÖ•¾®6èØ¹¡GéÏ~ ÉÚ³nK>‘ÊgMá)°DZò*2Ÿcw´é’ÈjèÌÿ( Â9jJV~ >‡ïò¨jáYË‹‡Á^êRë”–ûÞŽúúN $‰ uð䌗˜àX®Ã­'*un¾þôH&;섞7°J8Ì»&Ñ…ìφoʤ‹öQÛ…M¶™)¸]ùÕ0«vÅÞ¬ ·©o{6å"½œ?*Ÿß雥c&À—¬EàøQ14ý.Ñ0ªÎ’r0#ß\L+Ðí°£•7‘€tj€Ÿ9q=8ðùIÒçw%ÅÎÒ ÿ(àÑ3%D±tnQÕÜ\Y+¦O©g‹ \Ï ;QnpkQ“m+¹…Ûlͨ$δ-{ÊÉZJã' ì|8‡*& J³M@tðFÔÔÀ¨uåŠ5¢Îã ­Û B¼.÷RJðñ¸Sܾb$˜²¬¡›¦ßí†)¨ºQÉRXÎ÷JCŸì4øH6ßì¤Û‡ŒrU¶ÎGµFžñ`™¼‹rU®R‡ÁcdƒóîPþФR‹¢`§ ?2z•à‘ª• ÎŒÛ ÎòIhÑßÑŽ0_±bÒLEþ’Äœ5TWªìKú¼‹Ið[˜–óG¨Â1C\Ýj•áw÷¡BÔàˆl?èòsóð‰þ-z68Ú0ë´ŒAu½:°}³A¿½—^ýùs%Êî0å ·_3šƒEñ'UÌ=̽©k9&~Ž+§ùèº×£8ƒ'sV©ÜڮǬ‘? “VJ½Ž`OñzyÆ:}3%ë HZ+æF[j*e·4¶…ºËŠÚÀLø;ÜûšC™sJþÐ5É¥ºC˜¬£2+Jèþ›á•å2àyÖÛr§Ó×ñ]‘”ÜèÑí¤Ö 4&~åÐŒ¸¥›íé1% ¯ôlôÿCNMžŒA±±/šß˜Ó?¢jkø ú×ä®s.&å$Q_QòJE–f¦º%˜jûuÉÀywcïJ3\IélÖbWµåp„–+ Ï1JâH90¶f9A6-OñŽF›fÑKÚVìÑõÂ5+Æh´cØñéÅ?OZ‘k<ãR=dWVÒ¼×j}žk¼þÔ»Õ*s¬ÄTmô.º ›,žî8Q—!uŽŽê,ÏHÐÁ{|#;IŠC›Q·$’ÑÁ°‰tÏÇ¡Q\‡ç±oÙuQ$[ü‡³ªÇ0s9ŒáÏXGÔ¾ãZU줠!ÇÌ •BLœýµä'$ÒäŒ2²ÓUÿÇç_pj FQËÝÔ}ç&DLööFŠ:{QÒA¸¨àЄTx1=äQÙ`ŸÍƒÔýu™Üœ^¡)üçžÖ›Vb"ßÎêüa\cƒ·ü^$nxྒžä~å¡<•ú0?pÃõ‰9/O©_¦‰Ù¦än:K¿”,«çNÖÜQ{”“’I@‘V‹µ™ª/GL¬Ç‚PGzÀäÄl”%BÎ¥ÈNXÏT®]a°õ– ¼Œ5}ã[¥/½Hÿ#zSÁ4–:²©c&?ìBˆ‘ zÃŽ!tƒºgua‰óì Bó7£rp{ a¡[Õñ>°Ø•ªilPÙÃ,0ëj ¿Ÿ=à·%ôSi¬Î„eÔÅNÌ"¡BR‹FKŠo£å JwHeÕî€"²ñ”ÓxdøšJ•÷N×¹¼H<7˜~ÎE|ä‘ã·»ÝW Ü>Éwb}ñÌËá˨ãþýz§©–4­ýçq­Éò-…*ã—% ˜cb¤‘ä¹E`¾½dú>«‘cIiÉ™Á˜ølà@â.j°*Õ±´ª ̌ҞԃݰÒÌGS=3?Šˆ·ß4¿z*àFfB¢_lËÈ—‘sœT ÿtÜmTÆÒ­ˆÂäT‘n„Bëƒ`ìQq\yK"ø1yÑ@÷gïQß"üKèR*799øÐrœ½IÁ¡N·œÞäú¹¢›;Põ¤½zG˜¸Ë¶I'-팺Žú‹ëâeLyG!%lÊ…óŽ#`›z  ž i"§ü–£4š@²˜GÎÚñ >Ñ,ÖÚeóZhî2S¦¾C•„Ù‡ŸÇseô|[JNè6ŸŠÓE7ãçÍþqn># Zz79×a¬É˜¼_ 9£&‡’9žÒ>C'Œ~Æ™ŒE?—eðV·ßù"Yáað¿ 2ø#úæD}`}^µ¦-7›ûK-ôTœu]Žz„êX=ˆ|:½Vë“vN<§ÓÆ’*±rÎîCT:'é³T¯æöu±0Þ¨Î2åD°ßpÊ~õªÙY,³ E3eµ3œ'Ji³B8à äk£Ã©±(¯A„ÙßB6 袥zuÊ Y¤ˆš•O¶Í^f-h„¹§?­ÇI›nÏ7CQ@f%rjySéJöü&½{€à \«›4hª=˜fŽh•­‡b~*}´j™¥ZÛKYç èãÈÂR‰zé ›JNõÞÎ ý°ŽÚW6ÿ8¥i:k è <¢°±úÜaª™/ѵÉ/VPtZøQR„wVT¢ÃjÖ˜±¤ ›áõI§û EåUÅ÷ÚVOŦÎ|×ÿ063ÇúÔ<–~, >ª‰ù†h´  |ajbŠ"¾ï¶`æA*Vµ¹Ð(£a³ £L2ÙÆžUY´á{ ·²'y·º[b%‚WôÔûXFµÒ@"9áØÆœÞœ±ü?³ `þR2ãÖl-þ»<Œ  ,)Û²µsÅÚš&UbÜæ’Í­«Ìãc|ë³rRÿ†SÑyÍ}S¢bÊùg\´Ô÷u¡ÑV-O= "؉y`$‘$-Þ“C Ý!Ç·ƒûò*è¢Ë[q&bŽög'¬#Éç’‹Tü†"þ#à™ Ýà•©”3z»-™<¬¡ `í"P~]“œÇ£¥–l·Ï9(Ì$û<ï¡èΙc˜h·íÇ xƒ W€À|:ôš€ï}®²Òâ.~V`vvI(·>@8©Þ:¨+Û¤x‘‚K¦Â':<¾År!> @DÞJ3¢aƒ…öWë›)P‰$áb+˜5!“Ú ­y9 ÃDÝR ~#Ú 7:»Ð16ÂÀýg:™œ )qÍXùuÝgÀã~¿[ß]Í”ŸjáKZÚHN1^ÉT<6AQKj•ˆ««¾÷è©{‹óEÏù>¦Mföªƒ —ç­n0ª„l0ºooHÄ“šŽÄ::²<Ûç}È¢–Ô0zuMðƒb¾Y±ÅÏP±õì F£34R|tE˜íI°Å2É9ñ0OßÁWП}ޱcÏv÷ÓcÐ#8T{í2ÿ.¬>;¨ž¯G¼ Ö‹T_Ü×—s´„[n=böqÙý@¿†LìA4oœ¦#­q-¯=ÉN‘_\t(\ôIèûõÿFn?WÃxfr‹öaÇ齫ۅz–¸¾éàjìèý6œQÂþEÞÑ/†¶Ü")¿a_+ðp:¯‡:°«uàW’‘=¨­n¸¢@>:„q*ýþ$æ-©­;y„ºõ‰dÅÐöZ©ç²ôÃDv†“JVà–ÌzuS÷ž>ãÊ/]Šе÷¢^„Àö#X¿~ ìÈ’b$VU¬cêŠ×sušÛ:šü[÷Å£*?où5n•'s‡Ç,ŸßŸ¬ÝùúlÏÏÓÀðœÉôzìËÅ3ŽäR¼xû¶*±õ‹ºLn¯—ØÉ´åÁÏ5“>d^ð £}€g·…¤àìË…‡5KNju§Füç'fØ€ÍQM"ÊqRæ¦äÙâà8 >øy#š’‘ßyãøÄƒB°&PÊäz‰»&aS@Ajº>pe¥"¶bO*V`ª/wžbGúŽöKp\úe­Ä]꣩¾eŽÝ.ÜIIb51OFkPÙž}Ëü™wª‹6Їù¹3ô²"¾euK­RÃ#r'ÕB‰ã±¿Eƒ«®µ>² ÙÝÃÃﵦ³ü<§~Uq1ã²qÖ³±ö¶S¹yjÚ8TQÒŽdÖ\qï©=xÅÄl©žÏžMS‘=Óþ[Õ»j+-‰2ù¸ì³[þ™æDÞUÏ€T|€ÛëàCàÔ85(tRCM)¥‚ü÷g‰t]êd™¾e‰ Àù¿åtÖDFƒàA¸pÃ$p·9)Q“1`ØFG˪l!ýŸHGERU¨\µö¨L²6H{!Ü ¢Â‹ ?©ó5`¤õ¿ÛZe$ÜžaJIÔŽÇK°Ù*\`ã ®lrDGÄŠj|ïjæ×Õ¨ƒ±ŒçîÛËd Å\ŒÇw7¦›—«7<FþbEwÿ':/êíÇREû”¼‡¶þÿ}`bÁnç±5ÑbDÔ^¬Áª+ݨÃ\úŽ2ÞÚWP]^#ïq%ÜP/€G½‹~‚5”ÃÜ´…ØV ð‡úÒ»¡ïeŠ FüÚßumƒô©Í¿^ͱÓçšv“Bê=•ñޤ.™&åï]±2(óØë‰BdD/¦Q~¡¥Aµ¸Ä³:Z x³<63í»o☄„ ⫼¿Ÿy{ÂgÈ=”ÑjC'ZF[¢¸Ô1&:ü›ñå«@íu/€æõ£f`0”?“V4ôø O?µ#n›4Ÿ=Á­¾ÿ1`Ù=«!¬»p‰z Xn|n^—“õ5Íÿ/kóÅ[Äø‰21sCœ¿YÓÀŒ×pA!Åj…Vß¶P,Ž HÇ`dKPÿ2úo7T™ÒÎT0‡5¹ÚP,”Ž}\–‚/|Ù7~l©øi¾D€Ï~ËŒ#lðÊ\ÓŸŒU,%WJLóJ^Íy@­Z¨Â#¶µ–5ªëc”ôaúÇ:Té\¯$Ñ2fŒßýœÎµ„~Žû|ÅKî yí) ïU qK°J„¸^"‡Sè­"îcØ ]ÓÞÿz?¿0«lÛîpo ½oÊ©çN§Eüþpb&S5` FO˜©I1ó²{n·Â~j75Bø¼º‰ý€nK÷ͳßßH•ýfÁ‘ê?ï<ÿfÐGy¸A¸­,3¾’x,Ù›Y—(Ý´7ku`VxÏ“ÚA÷ ÊßàcUØž…("Ì OK¾õÈèÝŠèûp|ÿbÇ5õ»^R•×K¿½´’aùíÙpô²pøG# ´åÿ7Aê`woh9Ó%ÕÑ™þ ,/då©)X!ø0ú¿Ê  «…g..{©K®P:[ïz;ëé8,’$$u×ï7K™MÂÖÕ¤V&Œ"r[üŽ+ n°XxP©ÄÊ}xòÙ}ÿ*"¸2à´Þ„ŽÜ*m´ÉMÂïΩ…[¶.õ`õ½H£{Ù·)è áùTþÿ&n•Œ›f^±ƒáDÄÓô»D¨:IÈÀ}q0¯CÚý>Ð.ãÆ->º×İŠÛ‚âÊsáP £¼q}4í<ûÞnÇÖ2l¯oo¦™>¥ž1gÎ ­©!Q  70+Kª9¶Ø›XjÅæ%h Z÷‡Sn’!pÄRW!ÌSóÐù¦lÙ üøpŸÃ Í`Ž f™¼|à64"òj% BñU£>‚ÓŤL®{בW–°Ýx}—ÓÕ y]¡Õ ྒྷü5Š0ÿEí§ÍéÆJïç4”cY&¾_#ç<ÿCïø 9§Ô©¢ï`Gh|‘¡w‘ÖÎâÒnY"æcËÁ`U,²ßÆtå³²ppcóÇÃÿ}Iqö©ÌÆP‘U$ÖÐàr/DVþ‡+#ë‹è#•ÿEþuÒß’M"z€K»T¶—`…¤¶ _óÞUkÕö)­T¿em§[ƒg©úÊÍNjû*UŒ$Ë5ÄÔDÄfdð¤îË|À/»’(+"º¶•æ»Sìó]çð¥Þ©Sf"£o¡uÐ\Ùd÷qˆÀm¿ºIy‡w/)uSÀÉlRA·qõ¶DT@ÉÿöuXæg1‘ü9ëúƒÙR®÷ ‡½pÑ)¶îYVbJ¤ên{g† Ç’(¢Mœé9©F¾F[ù@$àÙþšáô’÷8@)‹9ÿGÛá~´U›MŽÿM#áàn˜js‹ E“\ÖDéÃ+GT%?‚<óÚÓjÌD[ùÃ=_Œ1«ŒpvÿEâFçŽ é)èGîZÉ_£ð†þ½i^Ö¼Ð_äÊ` ™£J#:äl°cœ0‘ií#}`qï J®²‹ä',gªW®Œ°ØzË^F ’gýp`{ò«\Ëæù„µ!„’–„ÚØ—IPÔ§t†]>‹ßÖÞ£DÒ|< ëòfš”†c&&ÿýÔ£—¾Z_{'½/ëÕ8¥L±¥oï;nO‘l)W¹-Ã$%Ê+õë'ÑðõÏ`4ˆ 3i å*§ù Š«Ÿ¿f곤Á5ntïævµ¼ÒfJÍA™ë­ÛKàOâ¢-÷Í/Þ€Š¸™¨—Û2ò%ä\çún6ƪciVÄar ªH·B!uÁŠ0v(‰¸®<¥‘g ½$•7^u´ÑŒ%ýí,ˆB»4£Ô.-ÔŽßdæ7FZ%½`9ðÙ^¶ôUfùÌÚ&4Š ¼ˆ°ØÕLxÉtkšµ ç1ÄÁ8ßÒm#d‚   ât«ËÌ­ÿÎÚñ >Ñ,ÖÚeóZhî2S¦ŒŠeºú@’ŒÚV2;à„¸·OÊ5œ×îgÉ<¡+ÄòànBìS.µv×.çaz"Ã"<2¡]<ÌC4UÒNM´€ül€qZ'ÆPì½Ñ}ÔÉqN¸6æ*£ÐÒÏǰU‚`Õã£ni'uÔ¿6g®a.xS»G‰WÇB£úaJV-ìeÿ_îëªt`xÊü d´h€ÉÓ{jlÝ•.(VXðÞÖÎà둵!_.›¯DVöcl´:E ãŵ¾ZPsŒý5‰39Âq䤅ë¶Ð†…ô¼:޹úðm×Yiq@¿+0;G[¿r*ÜSEéÿ‘ѵœÉ}_ÀÙè4ÝbX…âÐ¥ W誆+aã¼A¥¿1m[ s:£“ô–%BAU #'!Xh›¢ TB/Ä{AfçRz&ØX¬âGS3e#n9«.»¬øýÄÂ[bÑ¡ª£?K}a=Ì®·ÜOzs(×6wÇL­ÈæQ¹éßS&³{UA…ËóÖ·U B6]7·¤bIÐ-¢Úqó±×‘ é 5“Wûël§äé>Ûæ²^›ù±X«d…Ú¸hʰë*eËܲ˜0ÿU\˜©¦œÑá ý J"=ö:Å=ÛãÍHŒâë<ÍÏûa,r‹öÜïT“Ssl5üL)9–½@Á€«Šh—Yt*ÑÕ~ªjêœÙö¢éMp&º°«uàW’‘=¨­n¸¢@>:„q*ýþ$æ-©­;y„ºõ‰dÅÐöZ©ç³P€Iw8œg à¹ÈéÂÖ¿m}1‹§RuŠÓ«0=ˆÖ/ß‚û2$˜‰•kú¢…õÜÝf¶Î¦¿#ÖýñhÊÛþCÍ[¥IÜáñË'ߟF÷çѤüú/ñ,¤äÍf&¢·šñé‚àäsðsœP9n Em Š¿0⮞°qn­Ìï¶, +}ð»¬jth¯ŠëVue«CÆ`ȶ;yûT ¸-s¬[ú§xŒ¼Mq,£»¢Zñ«Ëè;Hóøûÿ_â/'áá¦g|†x³÷ª½Ok÷ècX-65`oÝŸ¬¨`49}©˜ûr#€¸éF!Â,_B?QûD‘߯ ®D,´oÊÉ¿?H/Ö²@;±êCD¢htT,ñ×øê-ÓÜïzw©’9DºÑ ,Õ`¥Âp†è/øï‘µÅ{€âG °¯÷Ï´ª÷ÕÞ¹dÒñ椅S—YÁ°¾ŽÃшÌCU–vïÌŠ|¸.œ½¢ÝKÎk.µð‰•Ùz²ò}¡ØSÒ™Aè¬{ûã¢fæÁ¹ì²ì…AH($Á Kõؼ;%ìê¨X.ÅJ°ÙþRørÚXáSjߤ¤‡X.@9l™Ee(ÛYL=HÿqeucZóóQÚ§ælÄ0™$<*xÂõ ÑÎàL¢±!DÕ·5½Fëf=g¸÷ÿˆ¶~Ûªc­|7Ö‘ëQú¢Îœ^…ñ ðïÀ¬Ü†1™Œ±‰ˆrѼ¹ãŸ!šj0½Q_³qŽ8ó4'P‹‰3aíjݑ٠©…AûšÍkÿ$%9Ì©!´ƒ¦¦cg¢ä kƒÖÍ™‹Ïá3,”Kx oïfþÞ=óZ0’QY®@é—L÷m,PøpŠ ùçú"™,¼‰Û]'cn_úWÚ+ÏY“ ·GÒx÷—”Ý3Íô|ôZÔ¯Öߥä!ÅAͧøÇŸ\e¦K™áôr·Ë]ü]5œ‘²>Ø!H"èqÖš¯â„ßอÌ)|ƒ<¥Â¸éóO¸ªS’+x؇‘;ǦRCvAÅ~<©Ÿ[<Æ á$#åXV?4ØÛü¦4¢üö î ÿW•R5‘­s¤ª+•úü‹áA–Bܽþ2çcBf[ÿ|€#E¿\Ž/m©xðlX*˜ZµoÓç~Ê«ª+Ŧ¤¦; A7'®L¶H–‘çq¯.'”cÛ„ŠÌ%Ka^ÈjÝw}9e—¹lŠäAÇ™ðn­Ñ}eÀ+)®VÀcüfeaü‘t­Ù]³vƒ¼²ÑˆqhGí~yÀucèš= S6%£(_«ó€ì1q1WǯŽk‰xö9ªžj·7ÐÓI°tD9W¹æ®<É?5wº]±ÔìïZ/äµÞã}»owÿ<>K²£ö{„&qÔÝP͘9òŽÍSÍcØÚïë\÷±ûÙ/œo“N Ž œW44¥í ª+´–­ÙÁM©Qš^·sêÅÙxø ³ÿ"©ÍjßáCü¾ÌÈøñÐz ΉOf@“פÂióæ‘w¹r/Éá$¬¤Ëó¹™ÁWQ†aªjíh~z×ãe7sÍà ”µ8ÛÎã²2V0Áu²Vm<»Aoýk¬u:¦;0áÕÃëüP6Ö¬ZßT, Vh¸ÃDD|ÀŽþÖаPÉ6¦)Ô¸úœb¨¼Dðå XBÄœ×ÍÎ ²ðíaðPç }ÀšIKÐ:Ó©TÖû‹aª5‘¹¸2d®³¿÷Z¶nËýÜqÔ+V(Œ¾‹tA¸?„«pNÐ 54 iÎ=ï󽛯Þ3t!nMšAÕØ¡Ë- ÿ HYUMó÷øêß—[ic¸àruˆúU’šŠ'V=ËRz€~g”ñY£Ñ¸TN7ôËžúYÀ°g'=üÇ·‘¡¿£N°k6;Í¡WBA©æÆÉ²u$+šZ.á×q‚9Ò¡é’Šå æ«$há‘´‡ÐÞEWmIùÏ"lÛÎì.Ó覹ÅuZÿn\IÉ:šËtؤ_ï‰âѳ‰àstz–‹ ©lp¾?Æ‹Ÿ¹àe@p$É5´·}4qè²Bì^ÔŠLÜJÁÔ¹¤EÌéà]äõÒ} * / ·q²#RÍZãñõYp*÷ºòOm-Ž¡é'FÖbuP¦¤ c 2Ž˜ÎÄ0eµ óK#QÁzð®á’{+1þ6(ò(4š4mÿ2™óÕÕX‹©±µb¥Ñ^Þð£óÒh£|HË ?›çiït8s€JYˆ9çãÉ[c{É`‡K1–ž39{ÈGvï®ï«K‹ ÁX ô ”´ÝÓqmŽfÖ€GWËïçÕõøw~·ß‡Kûùõ»üû¸¿æïèìþ}gÿs¿Ï¶ÿsé(õ¿CŽzë‹™rõ·]HyІ<¡ˆr/€àì •…T¶©Š™yÑ»"D›M@r“]×Õëi\iƒ®N°·»¹Ãô=KóÑìÌž2‘ ­LÐåÙ12’¼$ý×fÐ!k¾c6±¬"bOƒ¥¬¾·±ÐJgTM>Ǩ°¹ä=Ú”yÃl5–ɽY™¡UY ‰ÿLpwÿ»Z£ƒVv4µbXŠúzû©òNÕg³;²‘ú¥ì¢J0ÝaÔô"gñŒÎɇ‰È5TÙ/X·?7(­àؘÉ`s€ÂÊëÏî׬ڟ]4ZÝB v7ØøÚ†ù›ÎJ€ó¹€ˆ\õ©WŒZ‹õYã¶£x#ô ¡R—*¿Ç%qãséøáÓ BƒU©«Éó«ŒÉŠ÷ð/eaN %>bµ ›âÔý¿ðe`ˆ–¡q‰Æî”×.º˜¬ËÉ3žöÜâ ¬0šPø×,þŒªz¥@º¯¡¤šŸóÑ|è€ëX•t–$‰n¹ »‰lœ§+ŸÖoAz‡ªjÍ9õLƒÛ|)œ¸ :GRÑpÖtAQ#k&fòé¹ÇÌ×sû¯Õ̲H Zºñ—ò>—¦¿ KžØ5o£¯õÒ3€Qȼôj6°ÍEA)Œ¾×Gc\«w;×ÍÅÁæ.¹­5{ÎJGŒR‰D¶xc*¢ý ­Ä3–©l(¡¼±m¿[zˆ:º胢@ôS‡¦!òíÚì?“±ëR|꽌 Ôý±ûÒ0>!¯H5CȼúµÆ9†‹‹Õ(õ“šþ¦Àñ-ɦ-fqþjêÉEÜ;Úiý«N)XŽHÇèËbôl7ìÍnêóí´Üö`û)÷Èó‚_ÛÑ­9ÊSÞÖªUM²ÛŠÊ0¢TAs9%J¦åÀwe-}§Ÿ·L.ÖÀN½ßqÓ–Ùt~WÎä× Æ¤Ç»£ÛÎí-Zþ,—ú*-Üœqý†Ž8\9¯ë[~1ŠÚÐ%e†¬k‹zºZàþA¥\”°ô)h(͸0» `RL¸DÚ.Åe±Ã¢j}~¯$¡[^È–OÖB:7 éÞ§&­ï¼¼/£„äÌ¡!û›•3aDËÔ!â´Íú¨BJÍÔS·,:}®¥UyØ­!s×§ÊBQ§¿ÛÛºi´°%Tß/}ÄSÞ>`>ÜÎÛkÆB•¢8ݬ3 …‹PŒIÆ›)*ôºå’zïô§¡Ï%1;FE€®[ˆW5¾– ï%,÷ Æþó“G wYä12P޶}Ý4ÊFwx-¨×u×—l£ôŒË_Ýp<¿Ð*õoòž¥ºÃ4J«½”«]“ó-Ηœ„ í³â¨aéÃQ!ô.Å@¥¹AcqÞ=$Êg6Ú‘Æ7ÓûÙJ·ÒGy‚+¿Îƒ2Ñ4JóQ޼â™&@9N<(Ç]}¸Â]Ǭ½}¦ã¢¼£ÿ&*J ‘@¡•ø6ÝÎÉCDo—ƒ¼Áhû°%NT|*Ÿ¥êΕÉv· óÕ§'öÇß £k ¼÷az9ã¿(-o/7®_r¾ÛD2¸w‰j¶8.zåh“¸ ¨–VX›*É*ÚF<ßeËcÂHW=ØýP'Ç}=ÈëÂM2Ô76ºEÃÝ ’‚â>mäRÆuïcÝñF2F¶71\ÉÜ挺“O2¸*š(ëªÆòˆ×íG×F†X ÛE(Ñ`˜|Ñåó’û‰¹™]T±õ¥c7V®ÎÌ1€÷(Ä@“%vYÿeÜkD,eEØù:§ÿsÐLÝ?,“W‡8*=í˜È.Ö½MŸÞÐ Š4pRû쥹ÜÀ7&¨ûÂÈ2%õ¨htêÔ sø ªÖÒRÓcŠ ØŸ1îá_|ñ½+­tH3¥Hן²Ð,7ä7ðLW#­* yÆ9Iÿ%Bä,F˜wÔµåu ±õçà˜WXÆr¾Ö¸add+ªLCqÍMÚ|s˜;óB ªyË¢£§Ô_{-Ty³œS)Ž4†*å'ÈËb ­"Ô s5‹Þ ¿ÈÌþ[Re=\†[¤¤‹(ÇÑ6?=þCºKÎ:r·eã™Núç¿W8‘ö!Z?Søm,.Œ˲è®B+õ+lp!:b–øî9ƒ!ÆÁÜON€ÚžˆËF3ÐG  Ï™¥GUå¿ä,û>¶L—4ýr⺄ÍwÆÂ¶Ì„É*ß.¡-õ hØç½¡Ì^¯Ë™«šÞz•ˆYÚ0€ ‘Qõ®‰ba”–‚»³SÀÌÕT,¡09oÚŸiY7^t%t½Ü@ãט]S7|…—`óÄÚ¼ñWõ@@¼ÛH¢)ªà€1àVbq”„ZŸ(óÉ$9[à7ÔW(ÑêJ}Ý‘ Ä”le6BÃ$ÁVK”(4üéwÌ]šƒdîO.ൃ…Lîb$¿^L8(î,%EI…ÓÔ!£Ó):Œµ ¼%3ŒÔ(/œÛ‘C¹;«)‡|a·.ôù"}ÔÇ® 4ZôÂ2+Š8QpgÈðšå{yŒ>P1ˆx¤\ê_j'ƒ”6¦chž!ªŠü´æRb}|<ÁzøÊ¢J7Ôö“¡<È #69<“wvz®½iGIEÂËRÒÖ.`ΆÒ Sw«óa³<Ñ5ŒÖ§ýßÀ ñf¿fnZÐ?·ig–*üj…ùçÁ@´Ãð@'©úáØ‡šfX€Z”æÙċؗjŠÈ…ÿ_@Æ·éö!éèÉÅv€kÄð•ÒŸš:qU[\5ù®¨´”Ë+F5ôbM+,ÁfhåÌÆõ CW@2íÆÚh.ÏŽ“>É—Ðj:Îué_ÀaÎií?&Ðd¾qç@1œceW`è.t|Õ×”ìNL¸e œ¹ØÈ€Dà Æ3xÌy&wTʸQ3mgÙ^Kh>ÔßP›yˆ|lPi/‹é{;Kšë¨oQa[ºTNU—8· HNbσÂÄ~ÿ&Àû¡ŽÐð®"ý›#ápª¥L~gÅ­xˆÁ²”èà2Ÿ•È‹hå+HžE•h©;¤Førô £Ï;IÀÎ2 ÕÂþÅ÷Û¾N‚ØÆëJô¹“²Y S+z–ÑÔ Ù£ìZ"ãx`#û¹vÆùžy®Vþ‚£jŽ'C°5ÚTaüºq×É^f˜ýĵ…XçÞá-=ùž½ÒÕÇf œjmºD6å*0Q„[çn¦IŒeë`@hhâoó5´–m8x$vfS§¹y3SoΡ¢)̦ËõHBi¥‘£Kªl€PïQ$Fêxˆí½X»bËͯ›yèUóí`fîÈ”v¿×Ò÷Ȩ'•FÚÛë1ÏAkýfwþ åãòûÜJÙvÿU¯=bZ¡ºY?î@¿Tset‚毯«»Y ȵ‹ýÍK~Xš$¹Ó Ÿ«gUܲ%H8’\2Á]hæñZN{y]€Ø‰?<2ÓMŒž;0öœ’¿UÝ6ŽÐÒ<œV”®¾¥[“äíty©'ŽsIUϱøíÒÌùnòk¶+‹½L›Ã5e>•½-›O¬IÜuž¬iœ¿ˆáÐr>*c])d²ßùYé¤VjÙÇ ¡ÈÑœl0Gb ÌóÔêˆ`L€.¦ 6 Ùì8–åøbøü4’<Íõr£Ò¼Ðw§IÆa=Æ6»þ™ˆo%£M>&;ò¿Nc¿ÀA3Þ ÿ$oÚ­Oñhmûå¨ðeÂÐ÷ЀK¢ XA€Ý‘“&tgJO¤%9bèàh~üð$&äeÔÔÏVô¶&BÍ¥2“æëóºiœÑŒê'Y»'µÙdÀ?.VYVh(U¶1Ihð>å&j@Ù·\d¥ŒÉäú>ƽb=ôGŽˆžX¿7aoâØ]ŽåÛúØTÍ7HJd;ÓÇȲl¿Ñf0þ®ÆÑ•Cói:ø¥IÊ?>—¾Q zèÚcËHcnÇÉÝGµ#ä©•R+õÇä^2ª&àm|‡gÿk”à¿.ÿW»ôÕ«¬3Øìl çxjþ¦?ýòå@2mÂô§ÁcrÅÖsÑLî $rêò-,ÜT+3‡o…)C1oÝä¨d2€{’¤þb.lÞîte+Ç,>8‹×Db»Í¶R.4\©H%,åÞ^® בpj4{Æ„ɵnöö¡$Lòs; iIë~É¥å¨h~Æ+82E–\M×7ÌŸ«H–f¡:Dv¤À½ìý—O EžÃ”)ËC?¸|¾NÛ¼vÀV“!Õæ‚dW• q« $^.¬sBˆ,˜9[ cÆ ¿ø9Š—tQhžx·k·/{´“”í”ÈÇ–³èõÙ/C³–ØNÊ JXWü]»`1¨†Á›¼ƒÉ›¼œ´W@gŒ4dx&tšLŒ«YWr®3Ì:sÿh$!ökVÙ‰Ôø Ì[Dú“>YÞU¾òÞÖãCLHò~©Q/ÐØÇ¨¦çh9ø;c×#B3–;Pàrá¢iº 8wLÞ±»µêK˜`ŒY2x%F&ÁT8FÄ-±P`y,p)?ˆ{UiÏ¢ó©ae™£Ú÷ŠR±æ¥šk¶½¨1'­±¯scSd _:‡Ø; ¢¤Ïë5gŒvÃ?È­4à `_ÖJ·{/‹°we Ÿ ÆdUá+"‘‹S:bÀ†À›9–ÊCobµA¯6·8Î@Õ«ÄoŽ?žük'Pýöó‹]Ü>$z™nFˆÂi»ÖòrÇ3htÓxQV-mXá}1Øä™7ÀRPŒóÀÞðƒàó•àèÈ{{<¬~,¦Œ©e“%  ó¨XÂ/ ~ït ‘ãUÑá¸çŠæþÿÁ~é¢Ð ÚÆ¥È.éäö¸ùµí;CF7•@(Š©» XÉ6)‰±€Y§øÝDp·…›fþPÞàÚðQ‚VØW©ÊŽ5nŽÊY1 NIÎ[¹´ï-––ÙlE<Ñ}^> Á¥¡Pç*ýê2(ãÝW–ÇÖs'ÁvöûÆÙw•’xÚ–û _PÈ鎭†] ¬Û×tô" ÿtÒ(nÿ:ð*œ½ íŒpFw–qƒ¥–Fe °žQ$¶¨¶7?“2ºQò= `-‰°“66÷ŒÔ+ß»~µF«Óµ«u°m¤ºšý—ТŽúsÏQ-"ôØ<>dR9_ô13?uüØáYº·Œ8öèä2{#·©ñ= õ>ŽÏçaQ¢.Ãó™± EP¿æ5à§Ðµn ¾“èaçF“¬€FC\Ê£ùl’„ì7iÆa ލ¦§yñ ù4Æ«ç—N„¼ºBÆnž+‰×Ī&ÇŒxìŒÞÔSQ¯e°Ì¬ëOšnùi†m{ó´däC„0ÓFê Ì9™0*4¡¯ {ì´ûZ’%‰èü¡g'õQFÊáKŒ,[«¥Àðã:®™ŒL·;¤“v2ûý-)QHw¤h³–’ðjrà±ÜÆÃU/]ÌAÞ"ãH«{’ëç¾Þ[=´^ªþ£ïP¬ÉæÝ´HXÏ¿æ<(4?U.OiÿeŽøÍ˜¿ÓnìFí™­s—Mk»0)8” ”° [LËÑÙß¼>(ˆ‘~$2%†¡#ê…hvŠìö&>¯­±<(Û;êé7ÎÍï+ÎW9o5šF¼•þ£M&ª,×md7?TëƒpÜxic9~Ö81Æ·]dÔíR`®©?ìIž“ä}š]â ÒYZÛvé{fp‘Ïáê¸Áûé÷ÞçõüËúöï.*Ó—~¶Úà*"'oµ?p"òunœìNƒ© '¬'cåA<ÕÎʃ¼Ívžl5ß"íV™q'È—ñnõÜߌ†ÙÑ™é^ž—Ï;DÎ(Í¥®±¥ÝŽîõmû‰¦òˆg¶0<Êwã°î<¼öÖçÙ»/[ÇÊíä„gžTÄ7Þ¸SƒµF™Äƒ¤ˆ{,{y3·J¾ Õy{Þ¨cõþÙkôd 0õñµ]Ü›ÙU Üɶ|çhsq[1öZx‚Óܽ1þü6·/UvêÊÎ"1F¯¿™x~Ky9VSü"Þþ7#³ ¿}Ih£1.áô,”¹òv€¨†S‚iù©Æf(šœ…ÆK÷Jp-@ñÚ¹‘ЍN2Dàµ]ïbn%—8ÏõÐW§µ¿ðm\¼ø—=•ö³,$ÔÒ nh]v!ïµ³çl.Ýq(ô*E'œšÕ¥Ü„y–vRÔÀG„7^ß„û,/°ó6ô6ð¿‚Êâô%XÉR ¥oá9¯kÇ5ò[%âowCî‚RßéÛ4®ýÛç6®!ð¾ÂÏï0•[˜SI_ÆÅ“H6—ìVðRÀK¼€^ÓÂV¾Ì•&»½<™þØ–pZgÏ^JÉQåó9"þ·¼W“¨„‡îÇqT%ÕžbÄ›3KÒÕ<¥w—NšÐ‹ B¢¦Ð¾Rž¤™´ÍnîÒ,¥½ÚN}ö¨Ãž÷¿k !8\+¹3f‘Èf_6(ȳªAoZµµ¨%A Ää˜[J?nµ4òñ´÷º½m‰ÍY9‰“eWsáükìî=?šxýuää²þNK™ßƒ@G›™ áÄ ö£É=m¬(ø:ßQÍo@î\.(r±—°åÿ q~\8ÓÙ" ÏO9;˜·:ÖîPC™µÿï"VLŠ9§9™ŒÔzX±NÕêB™ˆ¨|Üžæ¦vFóê ÏÚ ztëÝ’Ï6þ”ޑßN„Yí²‰‰‚­1y/ŸÓg¬…fæÖ²q4Kƒbrc?ÓÇ’Ù Ž7sUâ•ÏÜO:;$¯ÐGI¸¼LÙªŽg ÅûÊ:êT¹#GÈÚJÁ}28 ^†ãˆþíÊBCWjÒ´%«û˜,Ô2¯‡’|8ÿ4[óð3²¶­wƒ´'*€Õkˆ<í èú©*à1­8äÁØ,=‚OÞ-T¬ìŠiYÊÄ7u¡ìFt2[¿y­(Œö:%³E°î§ÕØ“Í5ëïç×øwã~Ó߇YÛùõÅüû¿çïéŒþ}iÿuÏ·OçÒøHæg–ôéì3²ïwÌç°(¶~X¬»pÀ°¡Ÿ­KÛ>{†BvNAì]¾Ý1/¨Ïâí ¬YÂΈ…6×ÉÙ )íFqØRCº¨³ïu`ùa!mUÁ½ )@³²wu]c<íó .éM»J_%CÄAܲËñNÉFÙNÖm¾)LoÕÀu½OœSk)¸ÔFóúÊ$‡cf'M‡¸éÖ û“¾Xîú4¾÷ŒõŸ,Hݸ]ö2ÕÍœÌ'o-ý6¯fË2aQ|i9.im´çŒ¤®Ó«hûì†P{Qã´{ú[iÙ¹|^ÐÛ.fèLdé›Ï—§gTÿ2õ×ïüfK©hp`¤cÏ~žœçý~K¿ò^}^ÐÌ¿¸ŒÆàa¡WÝÄp€E ¯a¥&}ÿCðª3?ftÅøk*³ ‡¢cX‚íKÃ;áq]Üo×½Z\¦½¬Cưvô¯V{8 ôrO~yoÔ9ά‘„p øFº¢ÒõIXµôC ø½ã—Ê\4C­ÁkÍ+÷Ù`6"®ÞnÓ¡ì_=›Ë“š¥¹ëúøó©á6ÔݪÌ\ Ob>hÈxþu\ dS*9Qëg¥€ÈòW´9^Ède]î ¹ÆÙÒÃeØBd‚˜ Æá°6•¯¥Ñž5PŠçÈÏŠ6–y5Ì3ƒ•Àâc“33DXÅÛoõn­Ô7 nöaçn5œ— Iª ºš,büÊt†ž|dùÏ×½wglõ¸óÞn{Mó<¨fU?y¼^³ŒKQ /ʵe”Ë%SÃ4“öyM¢ýÚT ÒѵªœDkßxxXŸñnS yº!ðæú¹¥îR2Õ™^£?og0½X'vihä6½Ÿã‰%ࣣ˜–…ƒc j~}£ !0Øo\!~üÛ¦¬­œÿB—Òró6è,¨úC¯î ”i;dr°öÏN[¾ßß¡¢öåÐfÍ^` $aÿ)„˜ÅDP¦Pò·¯Å½ëVtLP¬žF…䦺 "Ü@¢a”»â+m‘k᧨À\ ƒlk{•ÏUH ܧ§7ÿ(Gè>l™M›5(¾ƒvHõÕÜl³Ç5•1íSílÐeºr•uþGY¥ãp(â`ÝÝLq¶>F-³or’Wu:Úï9ß4§ÇzÁaPfÆAžksýÈ=+…8w ||üÆ‘­çfp9xÆç½|Þû`óߣûŠC,£±s³[.ÍÊ´6÷³ µÁá"Â~ôé=±Ð†wÀ  ßIo¢[ö’ýw¥¿(†÷ùk(Q vr­í䬜ÚÈ&ŸòŒo8„ƒ\%ºùƒ!Y™$©€q ’Æ[ëâ†QßèIÀÓîÞ;-ïQßö{òd&TÜÑFòJdÌ€Ós+ )Ft=×@VÇ;ø3«Û<€¬\(¸TÄ*Sì» ‰ÈnžíËͼp€ôÓ,í0b6Ò[¥){ófE{º°ÏrqÖš3VÖŒÁñ%v6åA0›Áªq ®‚4ÑÇS°ÀâÒMª¿<ºùq8N› 9-Ç"iºùƒ9z£€¸¤ü §M Š;5 Q.˜”{èï+X¢pP™šÊ }þ3¦êȪcñ›ÔU [sÖ%s—æèœšÉ¬ X“”œVÓâž2wAnn 4Ö¬çðJQô]ø]dY’/Kð:²"ç.4„'x…΋¿SŽlm?eùwªãÅ´¬e[î£7¥îâ×ï$ ºÖ.o÷äÛ÷J¶‘àßסO £þáH5@¡kÀ¨¦ŸŠ$œ¸ÑŠÜ4áÎOs²ZøÝ$sÓPO°z9bºžšm=€¥ž 7CÛu$?À×éì'¥¬ö\ØÇÅ2…½Sj¯ˆæäWÿÎYÂrq~‡nì~¡ [\ÃIʲ¬dÛöÛ‘ò¤µ±ÂåÕzx\Œ¾¡EÎþXîKä{ò3ZáL”.:Èün4‡ç¸ñ¶¨‹f}±èˆöö‹îô5Ê8Ï1¶Y4CpBä¾ÇUìÞSÄ¡»ä*•÷A@1f=9ØÄНÝ.’ˆïþYÁý] ¼(ŠŒÑü¬´é±÷¥Sc±êß8y8´‡Jþƒùѽ5Qï9¯_`°P¸qªðõ~H`„rèA4”%JÍðÈ!Q››­òp&H¶Š;Ò„.ù£”á²b¦OÂ-t‡š†«mãK‚ ªHÛ¸çvA¨á—ä ­¦Ý£TŒtÖûªÁ:À± y=WHÎeJ©@‰Ã×nd˜‘»Dô.)Œ¾Ø¡p1æès•bžÁáðôHá~òù\¨Bô­]’ÿ{GÏ èµÆ w T&a×ê Ož_Ží"åÝz”¡@œtñãt½?Ûè;;¿‚–O¢^R’Ï8äÏd«Ô›£OèUXe¯%Œ§Œ}|7ï6Ü?³+ Zü Ñq\ ¾ò'Ãpw®ó‰¨D>…beGu‚PÔö`î…^jYîJ³o šãû: ¡¯¥zã“䈞zR\â.q«q±1K®búÆ’Ìo›h5¾Q½MÔ›×Q\ëpÍåtû©ô#j¤Çøƒ€b*ö?”YlýÑ=„˜z(”J9ȈEgÞ+„aˆxö»ÔìˬºÃ¾¢…”ƒy™.?gR¤¿Sù§’Cûª¡øJ<±ŸÀWóz\B­„ãúëºo]` %­¨xX(# ØÝvÈRÕîêÉø‘õü¦«ïvÚ¸›}›¦ŒûºÞrª3i³ôÚ5+Ò»p½Q9Yµ÷]P~Ã©Æ 3Ç"7Ä„ z0**"£ÒünteTwQVÒGúúw™G/ zwÀòÈg§ûèÛG’×zÀ×+ì–€9X¹ 8@„´Ð02!2sß‹š¡±Înxu&†oë—ÄÐŒqÞwQÔûˆ…æ?Þh‡‹K³‹v'?E,@¸±œñalÓ«t&ÿrN„V¨zOŸòÞZK'|¸ 9µ²1RŘúIÆ4tšiåz¢w“WA¾*ö¡;ó™E%)Ñá÷¥Œ@G×ÒxûoÅîE”¡Îpnþœ/£}tÊr}H|·d´T·°ÿnzÀ0 ‡C&£(&y¨Õ®Up½½µ‘MŒª ÄkÝæfñ,œµÙçµ æ¯w&QDQ1Ý ^>®Â‡ÌhLöCs­0¾PÌá°#ÀÞi>A™ÆÅ#¸ÝÜMëê8¿§®7ß‘ ˆ²ctur¥1zÆ,·bCºök¾Î‰º²‘7bfÎqç9~Á0¦¥Ôß/C¬YÆ@w,,̘yŒ—˜"åï‚\ìΣ l™¦~1'¸ß<ɼQÊ“‹1uô¯ý.ÔþÓSÛ¥½]:,4ö?÷ÉSBÏô ´" šM¿ö±²„wŠ=CIœ<ÔAÔlù=‰Oß.„c÷^fÙVÎåõ†Ç¦†åKàð:Æ tR“$›C$:”êbŒP"$î>c×ëÅy‹ÊMÝ¥ºëƦùÖoŽ=§!•ÒûHˬmŠE*9eƒ\‘§h'ªÎ/tùŽÊÕ=ËKhk¢mŒ_áx ºHëê 4;ÿJ]é”ì5Ë&üÀTÇiÓ§¨u6!æ7Eâ{ZôÛ™Ó›ë1;¬A„ô¼”cŠH»'ÜÆT¾¦¾NXy†öˆ&?Ý  ¶ð}'ϡݶ·ædEÉ´¦ ümž)¯øm,.Œ˲è®B+õ+lp!:b–øî9ƒ!ÆÁÜON€ÚžˆËF3ÐG  Ï™¥GUå¿ä,û>¶L—4ýr⺄ÍwÆÂ¶Ì„É*ß.¡-õ hØç½¡Ì^¯Ë™«šÞz•ˆYÚ0€ ‘Qõ®‰ba”–‚»³SÀÌÕT,¡09oÚŸiY7^t%t½Ü@ãט]S7|…—`óÄÚ¼ñWõ@@¼ÛH¢)ªà€1àVbq”„ZŸ(óÉ$9[à7ÔW(ÑêJ}Ý‘ Ä”le6BÃ$ÁVK”(4üéwÌ]šƒdì×c´€¦°=.¬“þûlzç"ƒnÈTá3ÜʪÕVA9WÖ(a#aPÅåT… ¼À‚–[rÖc$€dYû¬#¸Ì\¯aæÜ«à ûCÚ:³äxMr½¼Æì bi:—Ú‰àåM©˜Ú'Hjâ¿-9V°˜_p^¾›:6ÊÖ˜ëæ©@ûX¾ ; 7-5‘Æ9e” nb¾ÙÃ7'“Ëš¶ºÃ»0~wq] ¹š„Þl×'Åšü!™¸V28j3m)3º ¡KNFµ¬–˜oà~õ \;ãsLËâñ¡ËRüÛ#اø–TVs¡äCìtË ï7ô\Bž‘/Õj ëÖq]Ü5”Ž$Èu\.«äLq²ßïóZÑË™ê6>†®‚Ÿƒ¿î6gÇIŸdËè5g:ô¯à0ç4öŸ“h2_8ó+­ù½šœ\’ÖÂùš:a’€ É— ¡!“˜Ú—çA(R’ ôÚ(]%œ(ïhCËdËBV¸¯Ín,»ƒ:Ø Ò_!Òöv—5×PÛ&¼¾©U•eÎ-ÂR˜³Ä`ð±¿Ó`}ÐÇhxW~Í‘ð¸URs¥5ik^"pl¥:8 §år"Ú9@JÒ'‘GåZ*Né…ørô £Ï;IÀÎ2 ÕWûê*d4ðx0þS¦[cg?j@|ä@l¾]‰íA‰ôl•5ŽMb?dç<­%GGþì]ªÉßH:Õ^¯´¤A=äŸ2Œv,S;Awx"å½8u …}b[¹í[̆(çƒ5ê ~j”+¥î”%L2ë,X‡".·§^æ'ÉbÉêxƒò{¡«ŠŽ¹ImÞß¿A9C°‹^G´G—óvÂr¼.®ßlÀŽ'}‚Ï“/‡x¥‡~AÜÿE<Á§‚´Y¸ã,¯$ã~V(ñòûœ^ź†m1³÷ð£FŠ!äã³bÛVyÈìûI.›Œ²ÆUª nÆÌºäz°V~q › Rï·w¤˜e³üÖŽæÑeGÜ®TuÈÔIÆM[‚UûÊ’…‹ˆMÜä-ZƒËá³ú¦Z†õ&š|¦’òïöÐ$åëÁû)Éxúë´÷óúÞýÉ/ xg燹1d);‹²‚Òê—IÞy\%1…Í ·P>·˜9Z]D4èÚíP3ª°bÀ*0#ˆ@±åªS¬¾lÞ4”=¤)«Ú® ®²×}e5ÍÏ’#´Û{ˆ Y¦£P|‚O?««Âúnp‘ª÷pÉ5 ŒmÒ³n»³~5ôWˆ…[okãó4M¦’RT¼£¯<]¹ vtï ãÿºŸr¨JCíRwÍ_M凤ïšÝºŽÈLñ¤ŸÜÃxÛ¶•›bË×e@¡€ ù‚ëþT< ßý³è{Ò.”L‘·¢ Æ(LÚUxå4,ŠÔJô¹“²Y S+z–ÑÔ Ù£ìZ"ãx`#û¹vÆùžy®Vþ‚£jŽ'C°5ÚTaüºq×É^f˜ýĵ…XçÞá-=ùž½ÒÕÇf œjmºD6å*0Q„[çn¦IŒeë`@hhâoó5´–m8x$vfS§¹y3SoΉð=DMÖ6_ªBmL]ƒ`¼‡zàp0÷SÄ@k•èÊÅÛXæm|ÛÈ@À¢¯¢ëBÑCÞ!ññxF.ƒÔ±h?o¬Ç=¯ôLe™ÜOø/—ŒGËïp+duÛü"­yëÕ ÐzÉÿ9ýQ̓bMÍ__Vÿ;Y Ê‹­ÛÜ‘sÎ?»VîÕB&yúÐ5DÕýÄ=ÝKêÇð¸?ìax ªèáWÀ |_ÓÍ'@%…ÃÃæÜN61l¹'ùPÄ~°÷ mi¬)Ø}K7'É`í*BìøOr ,;Û¥™òÝä×lWz.™7†jÊ}+z:[6ŸX“¸ë=XÓ9àä|TƵÙoü¬ôÒ+5lㆌþ“2 ‡ÀzøEŽBN®Ú×E«¸=‹¸bÔQé5u7éT[BR¸,OhÑUÇpx(Lø‹ª¿ ©•ÜJ`poeÿ&bÉhÓO‰„ü¯Ó˜ïðL÷ƒ?Ò7íV§ø´6ýòŽTx2áH h{ƒè@%Ñ †¬ ÀnÈ„I“:3¥'Òœ± tp4?~xr2ê9ÒšÂþ–ÄÈY´¦C|ݳdñ¹º¾ÑT`»†ý².jŠñwÀ9òA ŒQ^TßÎ ¸ÊrÏÒ¥1’–3'“èûõˆ÷Ñ:"ybüÝ…¿‹av;—oèOaP4Üm!)|ïO"ɲÿ"Ìaý]£*‡æÒuñJ’)”~}.ÿ>Q zèÚcËHcnÇÉÝGµ#ä©•R+õÊŠ»¾ùá¶ZZ6_ýrœ.ÿW»ôÕ«¬3Øìl çxjþ¦%ÑÃÜ 1X˘ÿVâ]Ã}X ¶hcpcä‹bt‡ÜÖ~YŽ{ª>9.CêS5Ì1ˆ\ÀÔn]ê<  ffµßJ†ãbPˆ {Þ÷y aŠH{ („WS’žš·1£á—É/6tÞ1ý;±X«Ö·ùNÆ Fû'<‰‹´uO`®Ç¢©}Û´¶m·¬€«R—‚8 ­"d} <TÆ yÎÐ c“P·p€†ÊPE©zŒœµº[d¼ñÆDX@TïçiyÓ-v7Öí«Ô”UbSÇ3Ê„L¦íq¶åïv’r¯¬fo3¦«äå©”ödJñyh'°ík(ZªŽY'•¿£_«ðÇ-[Y_,$<·È»-*âÅÍ· cø.̓§?ýQs‹Áí¯jùÇFßm"fP뼫}å½´[£»¨ëæoç˜Mûu40R,TòÌFyú8%ý¨ÆäRª[U\GúÔ‚òOüx´Y97Q‰´óÛ¤§æRü #:|þL/‚¨pˆ[b ÀòXàR÷ªÓŸEçRÂË3G«x-]Ç|æ~Hl(åLmx-Û:Å_ߨaÙ˜œÆ³ÜŠLÀ xê«Ær†…½•#ÔZ®J†„]ƒ»)sÿ¬È«ÃVE#¦tÅ 6s,)”†ÞÅj ƒ^mnqœ‚R?ùñÈuØx¸ºŠúçyŮ6dülª™ß.7§sÔíPPÝ…;Žž`nÓŽAi“|%øÏ< ï>9^Œ‡·³ÊÇâÊhÊ–Y2PÊ:…Œ"ðÇî÷@¸AwŒxn9âLûuÉ °Aû¦‹@|+k—"QMäö¸ùµí;CF7•@(Š©» XÉ6)‰±€Y§øÝDp·…›fþPÞàÚðQ‚VØW©ÊŽ5nŽÊY1 xHëãF©‘SÚK• (ÏzÉû«äpô‰g‚lk__–ž¥ZÌà„œÐ­)¸*dhzFoô™J´Um§ÏÚeË$¯©Ô݆ì[UbBp§_cÓ*[Vå&fŽàµDúû4¡Ë¡,¢A1‹A‹(µL–” ”{Dâ݇*²xªgö°f>ÃʬKØÙÇCߌ\~ÒÆ²%µÑÓ›¥„¾ðµ6]n,~Ž—•Ó'5 ‰PÈäv+]Øð¥ âŸ3Y‡Œ5ðœ,q¬˜L{òñbT™â|¸B[Îf=r½ä¤'Ë0 “ß.uaÚt¾ž\xñÐÃzvkägz o%ì¡©¦Ë?×9Ié52úÿJŒÐÛy!øø—ˆPÒ•‘þÅ@®·g8Ô %æðEN%0õîâæ4ø újnÒ€ëËd«Ò÷òõÉ’ºË ”®É8ÛeÞVIãhn[ö²7 2,[ ºY·®éèE@-ÿi¤PÝþè_Àª„VJÙØÁçfØqÄZ–Xz”(ÂyD“êk̹yô>/€()â–ÄöôF´æâ€w]žb^*=õ¤Ëa,†…ƒŸ¹Í!E)ô瞢ZEé­V÷Rv=RB¤‡øáYº·Œ8öçTöÚõŽ7¤ù4Ý\UÖEÔh‹°üælB‘Tïæ5à§Ðµn ¾“èaçFL9)qG-È1[Mk»0)8” ”° [LËÑÙß¼>(¤W ¬Á:OE#Wê…hvŠìö&>¯­±<(Û;êé7ÎÍï+ÎW9o5šF¼•þ£M&ª,×md7?TëƒpÜxic9~Ö81Æ·]dÔíR`®©?ìIž“ä}š]â ÒYZÛvé{fp‘Ïáê¸Áûé÷ÞçÌ,¬«æ&@K¯Gà͆Ø-PúÊÙ˨: Ÿ(ÿƒõ­ÞH}8Dœ…Ø‘A9’›þ–Ý ÔK[©™Ðb7íÅäó¤`,¯©CšÒ D!­‰Àr~‹Ì à)b·.+žêiMü6GÖˆúh3 ¬ïoÑr{W”U¦ùI8­Z[>}¢4'ù› ­‰¸Þ– .„TÞt¡i¯ãÐÖ[ÿkÛ¼¸«LF]úÛk€¨ˆ¾ÔýÀ‹ÉÕºs±:¦@4ŸU07”LF!¥ž2R§êU£–ʱ¼Zælt‡ntVŠ…ú8îR´‡yÄIZIB¼wÜÐÅß£ÈøZ=à(§B2áT¬¯3NïšOÛ±Ï Wßý: °¬ÄàV+!#ò§^pÀ¨G ls«"&!¾õ˜¬ª4Î$$CÙcØ€ɺUð^¨«ËÙ”˜×ûcâ¼cI޼3.{îõ>ÕôL›TxÈÞ»m»ÿa›‰ s2¡ß¥ ¯yUsçù”=-ë=¦ˆ‰®67ÐÃj]‡@÷V.ÚÕUüAO(I² UÜ@góÁTšÍ Mg_èZf—Ððòˆãœ¥<µD2÷œs6ßQà+?›ÊØ-+ó5”´zÇï)À°ùÓYs“ W»!ƒ{ÁšV2ý$ß³íoxa|–;'L…ã9pÑÙ!åÖÁ€ÆP±× ˆ!M§Md4€ÊÜÎM¤ æ~³ƒÂ>iÖ²°ç÷ƒ¥š‚š‚kv¥Á}ëJØL§;މ0þeàeù.ËǪ̈É™_"7³ð4Wk¥šaⓎt ®Žb³Òy?K騗¿^¡’b5û ޤ§~zŸ†Þs€ž¢DÑÑ3‡PÝz{[ÿjà½çĹ쯵™a&¦ðSsBë±}­Ÿ;apþëˆG¡R(ÈÉ<äÖ­.ä#̳²—æ A£ô=ðܶ¥ÔFÀôÁ8ôúåjù~¶Vr{œ{Ì— iÕ2à$Õÿ*¨_> ¼ü9 Ç§N½Ù,óoì)MéðQèOÁÑ­î0ik`¨$ñ‘î Ê”‹}Ï\"I¼bñÖÉÝ»Q|£]¼+HÛF·j{ àÍl„Äm%3Ù5ù†ô_LSýOuù]ŽÌ®¾GçFôÈà%yøk‹ÁÆëသœÅßÏÌÁfš¡Ý­ç}ºüèŽæ¹ çšDÜ ÊÉVWtÕbî¯G8äÁØ,=‚OÞ-T¬ìŠiYÊÄ7u¡ìFt2[¿y ¾À©€nó£þúŸWhÖš èïç×5øwã~è_‡Yyü:ÅþÍÿoäÜþ}e>翟t?ϤÀøHæg–ôéì3²ïwÌç°(¶~X¬»pÀ°¡Ÿ­KÛ>{†BvNAì]¾Ý1/¨Ïâí ¬YÂΈ…6×ÉÙ )íFqØRCºZ¨‹½‡RQËšmɃ\òlèHœ$[IæËcÿ3› Õ#õ*°æ&Ñî†8ñdÍ·Å)àÚ¸.·©óŠ]NŒ2Ý3vùŽ A`ØÂ3“à‘ÿ}òØú™V'ì-!¹æçÇüß:FÈlù< f†|Í©O¬jV.Åär‘v5ÿ%£›¬›“&I(^ˆ'˜7;ÓÚ—†(ó«ëuS ƒ‰¦èLdé›Ï—§gTÿ2õ×ïük«µž€zÓ®=ß RA߸ÆÂÒò²=õ䣪Vdæ=so®<ˆ·Ú½§lî¡ð£ù#G4¶[ _aªg‰Iý:e _qÙ½Ä× ˆxÖÞ•êÏg^ŽIïÃo-ú‡9ÕåkZPú0¶B³çÎC#£+'ÏŠsG$e(tº™‚ïdÇ:M æuÔ¢ÿ;­£„fLJqlŠ´2¶ª‹ÿ X•%ÂG)‘Úz“äß_û-¡»™ðØZÎŽýÓ¨:ZTúÃb~qÞ5¥eøÉóŸ¯zîÎÙê qç¼Üö›æyP̪~óx¼!g–¢_”5jË)–J¦6%†iM@XÏW:Gж›˜ð3þŠ‹”ñ"Ó÷,ÇÀ ƒnÖ})7ŒÑUÓfŸ”à?”/ò!mŽN¿ã‰%ࣣ˜–…ƒc j~}£ !0Øo\!~üÛ¦¬­œÿB—Òró6è,¨úC¯î ”i;dr°öÏ%`õÏ¿CDÎã~j“Í^` $aÿ)„˜ÅDP¦Pò·¯Å½ëVtLP¬žF…䦺 "Ü@¢a”»â+m‘k᧨À\ ƒlk{•ÏUH ܧ§7ÿ(Gè>l™M›5(¾ƒvHõÕÜl³Ç5•1íSílÐeºr•uþGY¥ãp(â`ÝÝLq¶>F-³or’Wu:Úï9ß4§ÇzÁaPfÆAžksýÈ=+…8w ||üÆ‘­çfp9xÆÛFo}°yïÑýÅ!–ÑØ¹Ù­‹—fåZ{‹Ù…Zàð‘a¿ztžÈXèC»ƒàïŒ$À·Ñ-ûI~»ÒŒß”C{üµ‰( ;9VöòVNmdOùF7œBA‹®Ý|Á¬Ì’TÀ8ŠI ‡ã-õñ Ã(ïô$ài÷op–c —²çJX0±x©i¶JdÌ€Ós+ )Ft=×@VÇ;ø3«Û<€¬\(¸üñjú›Ô»z!Óâ?n)R9d÷¢Rj}‘™Q¢¬y»ÓÊór²{L]/+ýæ³gƒ˜º¦»øp6µŠƒVÉmÿ…ü ’O¸ÎCã}¶{h)€7lä·‰¦èKæ åêŽvâ’–w ÐX_|±5ÅÐA«»©¥õ¢séhhn†ŠÈFÆ{›‹ש¾t=^1…Å]ÿ¥\òÕí{©âÂEôzÁÇb—€ŸË¸´4ª·¨ ËæúøÝÊ+s—²/x5eÿ‰3ŠYm¯ïÏÂçgÿ`x=¤$7îà#¹!Ù²³XVò®è[ú§Z9v øC…Ãü$eqX°ŽcçtWºFÄx ýyçZ©R‚í3˜Š&z'䎡©…F½{¸E]í•è_ún¥–&£iZí³š²<[΀ «`Ëï˜^PĬýØ¿…Gc=ÞÆo¤°¯ø/—™’ÔBM¾ê,)ô<(OíuT46v‰Q¬Ãpê’dÈÅcÙX\ý(ùºŒƒû ú6òÈVþE’“¶Àó©Î2Ÿ¦‹çxÖZk³;ÉÔÓG®h·;‘ì¿Ø¹ ­xkqóßs|`×Ú:`šÓ¶Ø“Ü ¨ÜD:Œ†e4£CùÒ¦KD°3ÁA€F.ª–÷MÔ¦•UÇWT¶Q‰Œ.ÖBÈgèl{9S1SÀï³Dàù`U25RlT~†6§Áe{mµgD_ÑÙуóCÒ.@׹•ÖÊ7-£ÁËÏà-ɨ@ÑO|ã]«ÃL{D?w¿Ù 擺җ¦)öÎNö/ãÉÒñS[ý;Olú‚1gϰ ~'DŠY LþT΢3P7¢&\Y¾¾¢ö–Ekm-’j½ǤM þMûfGEvþë~K¬ÚÇR¯O/™€¨»ÁŒ‹as×#¨rgB!V/' æ£Å_EÕCI™¤ïý¤æŽ´¾Y¾<£úÓ§vW“åí7÷øb à Ê¿ h s$\3ûÀN˾ ‡ÒìêT—êbß4òHuT? G–3ø þoKˆU°œ`Ÿ]wMë¬$µµ a;®Ù Z¡ÝÝY?> ”Õq ÝîÃÛWo³aÿ!n‡{$Þ;¡~¨ð•€‚4™–qô¿1VŸ‰#{îš]S8¨^¤Úâu—í_šÃàß»gïW61’ªg"蟭q4…`üÁ"W¦ú„‘¯:úѨæ*:®Ü¼:ÃR2„ñhJ] ·ïóÙ:Vj·! ^®ƒ&]b˜F;r×R°@T„]É•få˜#þSŽ<‡‹K¢R 3˜Jÿ§vºaÍåj¹=ºl-™C¨ùÈcBÍsÿbÒÀÔ‚è“Zhp,øIÊ!†UÖÕ@2µ‘zÜ׌ÚÔ9Ò2ýÌâÍöß Y2q“('xO3JÁÌ;´âS¨žGí¾ºe9>¤>[²Z*[ØîvøÅamp«Ñ>„–’%‚]ÇøD‰b²Ig1s=#¡OëÇ• ¯¯'mÐ}hH®¸1A“ß°˜[`èfpØ ‘Šào4Ÿ Ìãb‘¿Ünî&õõ_Ó×›ïÈ…D„Ã3Ñ3ú)É”PÔÁŽœb¯F@¢·O”˜óš=kæEÊ Ai:s4‘³ üƒd®%OÔí¼¼*fïv¸g9ÁÔ»\Ló&ñG*Ln,ÃÆî[þ-«¢'…%57«§Iõ¤ãÞC?cð?q,•4,ÿ U¡ÑBéÄyÌZÀõqêG+¡ 93¾!À|ž#׵ؔÌFÇ·èEGšÇ(èݵ/äâFiÓ×7|9×n¤ËÁÓLñ†¡?H¡à°·S½xÔ_:ÑOÓR1ÙZ<2ÔŒºÆÐ8¤R£–X5Év‚z lâ÷s ¨”º 3˜Ùž“±1VÍŠÏ¢~ñóÀì5f8Ý­ö@º‡ì+††” ‡$$éAç¢4uÇ„™Èp“~¥ý–k²/ÔøZ‘,`NìŸsRú˜Hjù9aäj>Ú ˜ÿ:AmàúOŸC»moÌÈ‹“iLøÛ<%¿›‹L7÷4Õ¾ ¢aªs©¼¶cÀhO™¿kn¸$òP`:×G‰Òè].øY‘Q¿ý&%¢½77&½Mæi+â lºèɼf'µ€2Èm„£— ŽEJ*ƺ¸^x5$R+¬“4ºëæ¬CA½:Iš˜c‡öT,¡09oÚŸiY7nÖzo{Ød±Ú>µÄ8ý‚P «è¨˜ôWßc¶Åä?}UËÓ½œT„ÖÕè=8z+QI­_ÂA~t*_ͳÉÀ]¼‹Âõƒ`ÎÒã’"æGêÇDƒ2.õ’cÍʳé ðHVXnäÛ°d¿—3-Óôü=.h?Ùå1º—Rê`ú`Œ¶”«í¢dGóC^á©_“&¹&üÞ& Ñ*ž æË˜È™b²kòe7ÅïW±fz:SyYu’©ï‡óÁÊ›S1´OÕÅ~ZtGrÄ ª¸‰·: c Yþ¡Ôlýºh¦Y~U† Ú5ÆŽœöªíØÏ2Žß††H, kžlihkƒJ¦¨Mi{9 o›€Uc#†£6Ò“; Ñª´äkZÀ i†þà0€ORõñ74̱/:º’dãŸ%bNœ‰›o z¸Â ùv1ècª¬qmTš%,‰ADî ‡ â\^¬mæoö\YõÒO“®ïÁ:ÒPðàý?°“4øaJŽÆÙ"ŽŽ³u×ðsšFûOÉ´/œy•ÖüÞÇÍN.Ika|ÌëÌsÃ0wþÇ¡Y8ú HQù;¼QK¢ê’?éÌÎïgôÄzú 1€B?È ­5Ú‹âä:^ÎÒæºêd×7Õ*¢r¬¹Å¸JBsxŒ#÷úlºí â/Ù²> ªNt¦­-kÄ@€Ž ”§G”ü®D] ^PЫHqë ti0¤&}XýŠ 7ÅOÄX—x¾.[9ž÷é¤Uî•Q¢ÄïûÉT!UVí}\þe|4øÿKÐæe/¬Š£Q›@ÃîóãO½ëžðÌY])*ç œ8Ó«YYÉK™“pd/â­ÚX>‹öùŒˆÕ-—/lìCS‡ŒBÔhÀJ†T÷cR\º\=WѬ µY¹Ák>l¶Cì”_™Ÿ¶¶vì7+ȸŽâºHÌñý^QöüÐT+[Så ‹íލ\'OÓUÆ÷÷–rùÜåél«W£¥ : Û#ªˆ>ŽžS\[¾Þ\W²Š¸ŠžHôâkĉÚH™yÜ?H·¸ïgÙÑõÙ‹„-udý¾*%^Î&x&ìÕ`K5¯´låÔú‡ÀxëC(‚ «u““%ÙáOþÙ0”öFœš,Nc/kÏ ¹p;BQü®&óÙ'Dtéó_]ç<óÀnAbÀðöSòîyX?xoõ k·šfM í¨öl<áÑÍŠ†//+8‹ ¢A°=LíÝàD‹–ôáÔ*õ‰nçµo2£ž רùªP®” ¹þP•0ˬ±`ˆ8¶®ÌD’?Y™Ë£°æÉi¤"6^2×¹ Ï=…\n·È3ŸÔó!èàºÂÀ ðÿh…(0…€â!VÛÚøüÍi¤”•ï(ëÏ—nBä;è8ÿen§Üªû@”óWÓyaé;æ·n£²üi'÷0Þ6í¥fزõÙP(`‡~`ºÿJ‡{ÿ[>‡°-"âX ¢¹%Õý ­< µÒ^Z=Ðêß–RâbVÿWh»(ÒÉÅã@)xÑœÊDMŽ3&vü6!°ãÛãF\ï‹c óÒô±ÁxLI¡6\-?€¡³_Dq7&W>ó*ÀWÿŒ…KÆ+§Båðž$ÍPß»<&ËD¬ØţM=ñžã G- ‡ / Žï†làfE1õÿQ-fxè¨ý)Îuû.ÇÒŽº¶4g>1Aá‰$?Ñ䈱pFTOAsÃ;ìø/š&6Çÿ@$!KSip!_:@¶'±D‹\xö::Ô›Gü*n +D[^›¦Vi¯emÔÝäsJ P…ŒHŠûoˆ ˆ†B0ˆÆ>Ë’´È“º™&v1—­³ÏÌ<`ˆè%@U½iˆî‹ü¬©=†°}%”|ÔZa¾6PEé6 ?°VÁ“êŸJ­’ÂT{=9 Ñ"VÅr<AßÛ*¦•¨†;%qp»Bô…”o¡ÐÞœ¦¤ÛG GËïp+duÛü"­yëÕ ÐzÉÿ9ýQ͆1Ûš¾¾­þîdƒ*áq²ëþ²\eH«à¾…\UpJIµ#(Ûet œÁ0™ùG…¥‰q3\æÉçBjÑ “Ì€7¥:Àûè ÿ ¼&2z‘PÚ™nBY$:-œ(äiËÑÎíïÿ#óp>K`®¶} ÷30¦.ô]2o Õ”úVôt¶m>±'qÖz±¦rþ#‡AÈø©j"?²ßùYé¤VjÙÇ ;¥³#ºñÁ 1$ rm&ôG1°Þãk6J mî[ÕÍŒ÷[Ón£kÒ ˆ"^-#-±}.HÝÀ˜ÈÀKrÝ9- &¡Ü^v¢ørÏ& 'GRññž´¤$¬5|ùüMû帪ôeÂÐ÷ЀK¢ XA€Ý‘“&tgJO¤%9bèàh~üð$&äeÔs¥5…ý-‰³iL†$ø¢ÇG1ŽŠmÌÛKœX +‰I¼ÍÌçÝí,ΙäÏ›e€üÿGì'äºÐjÛÚ55m~1XR'.C™–μ§ñt¶&N˜éUì}`ŠPá¸ÚBS ùÞž>E“eþ‹1‡õv6Œª›I×Å*H¦Qùô»ýòˆK×FÓÞZ@»sþ>Nê=©%Lª‘^®P UÝ÷Ï °ÚÒѲÿuÊp_Œ-XÀiåãó› ùezƒŽy ™Gd¯èÅîóÚ¢·Sš$éÿÍuÌPóøeþ­§+ZË2§ŠáSIÖ@±kÿ~žGÄ=&Ÿ w †1µz •EMOq%T‹þëózCN!Êc”ã—ÁŒiw9k>mÜSW˜B땵nÑÈôËý.Ô±BÒí-ÒÂ2XLBélŸ{PŒ\)›@™õ¥URFDa 籉EÊíÝ„R}\§ÍrÃ’ßpC9°[c<¨AÔÊn×n^÷i')ÛŸ|·ld§`˜ªÊ^ñ9'/ÀÎâû‰œˆÌÞÛ Ø>^V¶ØðO$ìP0ì‰bBU,+c K‹¥ÿ/\–¢µh õÞU¾òÞÚ-ÑÝÔuó7óÌ&ýºš)C|”Ù)FÐÃeû"xŒ (Ø;Üf­ ’OÈ×Ñ‚kô¯;Uüë•>íÓ¹JºÈ¥¿‡¾? i†žãÕZsè¼êXYfhõo«¢˜â¯œÏ …©±©JÔYqâàÁ¤uÌݬ\²4›»)Nø*'èVlH#².åCÒ±²Ö𼓔½^¬ô©é0Šë!èxg3ûÀKÖ­7kÍ­Î3JGÿß—]‡‹‹¨¯®wœZîáñîËñ$¾Ü=䈒ÜÈ9Y.NS/¹%ž€ñsxÊ:w²¼úWÃðÈšHÀATç8«e’âªoxMAlщ›$GP]ãŽx“>Ýrh,~é¢Ð ÚÆ¥É2 ¾äö¸ùµí;CF7•@(Š©» XÉ6)‰±€Y§øÝDp·…›fþPÞàÙù„‡þ‰±¥5r«7ŽŽGzæ®Å9Ý`q£ÝÃp„|ô6ø¢Q1ž½§"ˈß!Rß îXp1 kÿoz¢¬:ø¬wÏ52&|¥ñn(y6æ<Î$¤k+•Ãx xfèb»ô¢šÅe Ÿ„S9¦„ÝÌXŽvEOi.T(£=ë'þ¼7 X½)à·’EwðØåSøíi‚Öt!aMÄÕ6K‘âNž¦Urç——é9D7ue¨erÕÎ.ì–A)ë÷§¤Ï÷~xˆÇ·L#ðÇž «“0YÔ5.—&4Ò3µ ”„ÝmÎe>gS×4Ajä{í©‹ÑfxŒ½=«ytMYA½J¶þ32  ‰G¹aûø …s?G_ëãN\ÖP‡€\÷ÏO„Ζ+q¬˜L{òñbT™â|¸B[Îf=rªËXsM•l…­—]=?_{hN3Ê8úqø‚hiéøAåöI€Ñ(é´·©s‹À‚‡"PÄ(HiJ¿Èÿ1P+­ÙÎ5‰y¼OÕÅ`¬’u×µh>n›¼þY·xÖL•5Н'Ÿ~z„\õª…ÆÃPm¬ÛsA­ÙtïŸr™ÐÑʾLŸmߪ1^cõÔ5'7-ûY­†] ¬Û×tô" ÿtÒ(nÿ:ð*¡’¶v0yÁ¶Üqƒ¥•÷G` ŸÌòð3P·Sú•q ®êPñfFÍ=ÑÈï³iBȱö =¹a>^>NÌêöšë»֠§Ñ¹;¿o„÷FÍöIï®É@$„ [¾£`nñR<º û„Fê,‹*‚}ë°ÖÍ µã oIí¹²?YQ¨11ä*Š lŒ0¿æ5à§Ðµn ¾“èaçFIQ§Z¼>eÖ`Jz /06‚ï§ŠeÏÔ•è sh¡Å½øÌ®“k ×ÎÚÓE$x=Öò'Wzt)›–Ií.L€9Ï‹Ñj[ø^–žU‚UX¦§âX.\Ñçú7æô˜û ÁÁïã¯I íyž¾¸-D¨bdÃøu«Tö,q]Vk~µ¼HFÀD ÚfúûžR!5Ì|[è×£.“f÷|÷FÑÕD¿)ΔK= Dfo…ê>  ¥n}bøÉš¡â¹ ˆ`ѧ`ó°‹Øs[¿;§ú ߺw£º‹ƒwU~¯~nðÀÇ ªoeè”w×çã‹2Y–?®V¹g^ëËiº²|LÄN_gO¹}MYͪT0"ž¤ 7P99Õ´†&§tJM'Wë0¹Sû´¢å•Ï°ŠÆœ¥ ò‘Ò=yeI³‘•\t8ÂPC‡Ì =XàÄÜg‰å…g<3Ó©Ü.3ÙààñŽÛx«D>ÌvžTœAôqû(X[e5-×ßÝ0ýVékºJºV !Shâ}ŠãQª>¹ðøuÑ:ú¬6qYIãëGÞ¬Ýègx‰•Œ®_"Ïp»vtÓaBSâSiûwé’ûÞáhëW}»qÔµYs 6sçšåÃ7~c´f”È1µúé‚4 Ì9™0*4¡¯ {ì´ûZ’%‰èü¬8§¥cZó ØÇ@1VûdÉ2m¸‚™67EÚÂ^5-Á˜ r{äøDõÛ™+ ¿F«mé1‚(Ô´#Iší@›šmçlöÍã‹B™eî7F¬ÉæÝ´HXÏ¿æ<(4?U.Oiÿe‚K¶~qòaÉKŠ9lîAŠØºk]Ù„ìƒùIÄ \¥„hRÚf^ˆ¦ÎýáñJ(×<#¥|p ?ê…hvŠìö&>¯­±-Ù?Ç,7- u ­ÜqÂsR± Ê*ê€Þ!ûÕàæ[µ¶“ h1ÈÝaRÂŒ¯0Ú¾gggc¸ûgbºÄU¢•§»§5sê}~Y:äEá·ñ¿k»›ÿ.`[â¸* aQÐþlÊ[±ÅQÂΈöÑ”óz¤ºÑüŒdØö8°PžR(ã ‘~òkIjФ â  7‰q(Ͷ>ÊxÂkeÍ€’MofÍú[;®·h  ƒà’<éÝÁäãÚ‰ÌoÍ  üDL¦à½q´i¨{ŒŒ˜qü)Ž™Ì›OÑ¿¬©m\ Oò‘w¸³,ù.v"$þ°ý¹£2²©n®áM{àPâë2>ª±¦EÊÆ#§|õBµöÅ£‰%µW§-VçG$ÖY ßû•Æ×dT¼$×vM ]rý2xd˜ÐÃåß­¶¸ ˆ‰ÛíOܼ[§; êdIõSy]±¤ª^RÖÈÔ}¸e£[ çl[†ïvV¨—Á^̶µü©èô{Ç4ŒØ~µüàpª/²ê\µÅ×åH?Þƒ4'* ;ÍM-SüìXɸ|ãí)@£ø|ï3·ÈÅi†K†69Õ‘ßzáLVÕg’!ì±ì@ äÎÝ*ø/TUåìÊLGëýºPü RàˆÊ)&Š%µ&E?ËìÂxÞ^·Ða(ª<Ûû SzG|A:ðtk{ŒZÆØ* :^3ØÂ Œž{«³CÝüòZ4ÁÎ O’€x1­#Åü!\²“įïÔIB.ù¸©<—ïñ[S»¤˜"£±Êãm—¿ûBÚÿz¨Wh¦“¹qd¾‚KµøX|ØÓ.æÐì ë]®Æ¸ícÄ Ÿû+ñàÕ ÊŽ—cêÛO¢íhW†“Œ9aÿQ­Âƒ ƒæù˜,x)~ÞšÒ0ic²Ü,vûG“ÄÉ=ÏjzÛȀ᤾µ½iç%ý•±y€Ÿ˜+r)G"»pGðÓ Á]Xãƒld¯ïxÁ$kÐ)°µ$‘@Òg`Š5ç&¯¤$8Ü®¬Õ†Y8:Ò}DÖW£6ݦ-¹X ˆ¸šBt³Ç~–ÑØ°þ-CÍ<€^l° TÄJc8]nß½ÌÐ^k96Àöºê#}v€àoƒÂA`Xf­X9¦›©·‘xz§x¾Ùžqâ›Ýù°ÂÈá°èÎ¥ì³ þHóL2SŠªW§¿ o.ÅÜ¿½Cލ »^v2ú™FÍAŒSÆv…MKšvôšp1Ï>Áä2ÅbfÄTS#<ç]§c|—±Uä…áO}B¹2I®ýºÝ–eRâ2­C q7ò­7ئ[ÞS¢^šÚ[¢;PÄcü%!kæ=³…‹T—T\èט¿Ø©qÌk*nK‹¼(Kÿ( \¢åø> ß ò!ŠÔ:ó‹°L[§­¾3Xu¦ú Üi>Á7Öõ² z¦³Œ1·£R]ú¯ò':x2ñöž ”³r6…×èßTˆ:)²ô¨óÇ9ÓÍIÞÈ ïèK$¾#ö“6ˆ9HÞ-¦f±Äô;rZIZ®0JÔ}GGô_G¨þéDŒœF‰.»Ç<©’[ý¡–vÙœe ?}ŠCòÁÆÄ6ïST—”þ%ú[r’UÅ\U¯‹Kñtz¹¶)…Tž)ÐÊáU™Ë߃þ D^oR!X Kô7_™Úh§=f÷ô~ú°|Je]ܦ(ö|ÙÆE¤ÔrÄöÍ<{f÷ÑÇÌÿqŽ–ˆeÏ¥4ö ŒZ,.ww!i›:k&®›Š’–þç;ˆWcŸòÎrª—‚ËÆqæãÿ*“?ÁÿA”_¹0Ak8/¨Z:cïÒpdÜ™ ¨w(Dvy½vè1÷Öf÷(ƒ_UßîIZ²E[”³.ÓÌcð˜ÄJÇÐÙܺpÀ ¬ÒrO56ô“„Jæ¿(UpEWmoå‚ã÷Æ®¾ßY<ç$ˆ‡ÀVBË/¡zt<ÏÖVîÓ°1‘‡ø\‰AR'›ì4Dˉ¼…Ù=Àd²&cå žê-é~®é­ë3µ¼èÊ“Ê:n¡'Fç”UKlÚ‰8¾¶À¨ÆœÙãØy®¹©MEÂ:.ÉLgU·ZÍö¶}Ò·wÔ&Réš\T•þaËY@ urÐÎ1¹°hyåU€lNQ˜}ˆÀu$w‘"¯^Ä f6{©ðÕÑ~í™å_ë)¼ÕbÅ¥Z®ÓîÀ§œ¡Ò‰Æ|0u–ºÂœ(nÌV5Ê…û<‚°µy[{¶Žòù/ŽYõh±™³ìá)5ðŽïõcÍj0¢!È‘r£“ãCÙYzJrÙ›å.T‘I64Ô^B5S-È´WοKE¿¼¯)ý„¨Øç6Hª±Ÿ—¹WZ‡'?àˆq/“ôôë)3¼cîõ3EߌÓ<¢hÉ\Fœ¬x4Ë¢-·cÿcö{êÛd(Á`R.–AѦ†4Np3Ô*Q¶æ©~s~½Î3_î ¿¹6¨<®É"ÑœÖcbáóUlaÿiŠæÍgRÅ&õH9à!åK÷‚²š¶äÐ̬|®¼``Õݽ*Þ5Ö=ºsd2ÅûMs«cgQ ]ê G™!  yB¶·¨õnLH„1V·kŸ„˜ÝåºcWI¯ ïCÑ~þ4/=TTev){grØkä.‘È߇-cèü£Î2IWŒ0J;xhÁ“w§h›nÏ[›Põ«ÄˆNÝö[Ôf «ñ/¹ÇR˜Ž ïÚ“åÝ÷k,=qNÿv¨z‘K²7?Ô(M¹gý¨¬²˜’n^’³~†>yµE!à:ü°ð4Æ'Eà¼/49Ü#»ˆ8ï¡u¼ž™ÁDy… %$@–·|ß,7]—½~24º¸2¥å•æ½ç6¼ÝÜÁv à@~ÛJwЊŒÿ%zcY'HÏ@d-p®' A\Ú«ÿ[˜»iëÎ9HJ ~­ˆ/MÙA U'H.9¢è{ë¼î¼ôJ“¥I+òo¹•ü*ßÉËñèŸo›37 Ù ÇzŽÿ2Ö7®ºAÓ×ZNrÔ¼€)áËîföꄜ˜ûfð¿öcŸŠÉ‘KÏEóQÏp!îýd/s}TµGi¹lñg·î$UÅï:›·29†·2š’B^ Q@ÄýÅùæ‡  Jðxy_©E¬˜¶»òæ¡È|Ð&ó÷¥¿uß”…ÄþªBö¾¯QœNO•µyš·¾ É #Vr¯Øsí ×k:ÿY=jň0/ýÉÊë&=0äF2‘ÓQ*ðÕã^qÕLÜ×. xß:ïÂöóçæ“X£÷nh݉DOîöM åÏ,k¥Þáèg T-7Í Øûò}®=¯HéSÙÖÝa£B¡f¡eѳD\¨f‘‚¼¹u«j¶Õ‚È6ûN®—™X†Í”¡"¼Ä.›)Ç£5^©x'‚:P7äܼ^˜¦Ä&jC¦ ã,j;Š‚„Ï%åÁ ªV!kµ–'%`—Š˜lú”#g+¸*ºÁ°Mm54ƒ´´᪷×é“k8:¦¿Ê_D‹îö–*&TƒTø¼° ª¹ˆ'¸O)¨?Ø9ôüùÅÊÛ‰ÏÈ‚@¨<½ŠÄUö!8dÑ)gDƒ‰¾OAðKF^ߌzムGù9’²“S“3«¼-µpé™Ût‘;NÅ—õZD»h—sg,ùçÓãb]|#)øÉ pÍDBà5…·øµ>ŽÞ°±P;MîyÆu²~x ŒXÐeŸCkÚ©c+H~ȧ=CÔù Å®ìbÛò—öF±©U1 kùÚybš¢Ò%óêÉÄŸNVÿ,¿S¶$­Kù¤g,öÒð¬ÐššÂ¼ þpˆÓ³Ï (c‹™(`ÿO|ÃSMí¬ï+ÿe.}ô*ùÏ0F(Æ1Òn€â&Ûª‘tŸŠã¸?ËÐp‹ªþ…X^$®š%²&æ +>/EYkLõ/üŠøù=ããð`©1MU§(wµÄ‹—м8†|\`ùôFÇ7Œ¢ütø÷"ab³î: r¥Kk °5¡üc£z$Ý_ÔdCt-Wh.ÿ`û(Í¥,ZŠqäõ`UC@*$’.v×òù"v@l¢šRd¿†”–{»—öc̵D»Ñ5Ÿ#zðëˆF3o1VhºÐÚ‚î±LZÒ8t}óÊ–þ¯Ù¨@opd§\•T¤ÎAµ0d³æl¸æú?®jjÖ‡ÐÖŒ$›þw±ÂOðà ã$»ó;sá‡× nZžÅb7d Ö`3©“¼J©T*¢ øýúù¿ÒB­_öYŽm{ÌèƒNѱnS(ßà‚Úr™ð‰ê °Ÿ[‰®<£€Q!;^ÉðÍTbâÀòUI¿ÉØ:¯î™»œUºõXj°|p×KRPi>Ù#ªÇ¤;„8|{1úz*QÃã·E—Y?q@»à/–˜Þ@J暘ãmätWtîú¢j¾À[Ù\•’'$­ÌΗÝ"wòΡS½*/,e>äÃÄÁÐóñ i þ¨ØFÚBiÃcY±IÑp ãÐ{:^ŸÅ.r¤ð’ˉ"ZÐ/ [œ|„ËK‰[É êÖG¯” ¼XJböŒEÉñL4>&M—M¸A×Ë#_wlÆòÙój+§TÒ˜T’/%NšR\sjHÌô.Pýî&t& äS^Г &Ô¥i´í- æ½"ú±¼í|Ã,=÷q†Ûs—ÎoŒƒÕêf«©¼3°¯öƒü2Ñ(«{¨Ëzƒ >è>ã eåF®M#ŽJßC€©Èa ED7+ríš”L]>‰uâ8iA¿¨kqŽºÎOÎ0—ƒ…t;|ß„:˜€¥tÝ‘±¾3ÄÃÂ+y¸(âÛÊ9øT“)óü5²ûu¾ÝIþÇü::þðÛ¿áÕ?ü7Ÿøtsÿ?ðÛ¿á®Û¨wÛ©_Ã\ùþãü5þÓü5¿øtoü,_á½éønÏðé§þßÃn?†µ nþÙü5ÇðÖOá¨?ðԟᬟàëíª¿†ÚœÿpÚáÐÏ}¢?Ã_ÿCY¿†£ JþÈõ-ƒJ'ÙÛ4[cÝSÄì[bwŽ D×—Üì×ÿh¾–øH*†qУІAúŸ+|q:÷ \ÕÀz|î\³Ö*¤91Œ‡+Æ>›÷¹½l;êPiäNQ•+xV3“Õi2wü”² ‹ò!) ñŒjй3-€^="ö ´ŸÈY€Ó”?¶sGár\‰t}þgþ§çxHÂvåý¾Qƒ†`áEöBÊâäš’vi|䈅bÄòbKü½H]ÕØ$ÕÞî½ÉÚGé2ñ q`̵ÀÄ{7„0 ±Nøƒ6欥°ˆ4Cu98.ô®ýbKÃו2ÆQînÀ‚\ ov],K„?&LU™ËxБüÜí2¼åáaA/&2gºõD/ºXÐIÌ}pżí©ªä<"<«á ómÑ F Ϋ°áXö ± \ }çeÒ½O¤ÏÕþ#=x”ÛNr[n^d…í×GŸÁI v ¼à ifMòÈ¢ÖçÆÇ±Ä_!I´ÿvwæÒÝ=úñêY¼)¾432k¹å;§+ÑðBh×þG5løíoo1‰Šüb!”ü6|±D^vh1lÈ}ì~Õ(Ãð¤jX7Š~ü:ç6k¹u±ÙMï”…‚-#U$,¿gÓw²O uð´¾ÑÔod=÷hÿ5¡&ÉÕÑ^'û¿ªâ Kn4”å¶x‹•âMì˜<Ÿ-ˆ\ÌÙuØ!þI‡ç÷Áô­;ÀÈÙøûn‡ÿ)ãE–¢¬–©E:b <ÝŽÐØ¾Ü½(%XCÛ2½‘Œ'¿éa2/|ÎdŸHf*ë;¼ëF‰Í Ï~sÎÄ3bš ÑÕìì@÷Ú£¥Nj¨¯«ÏM®.MZËNÝ_Bù¡œEÈX‰z&>‰:%¦nß œ‡•žÉ’¦}n-. ý !™H0C€œ<nð7ç|Æ´–Z¶¨»­L¸Ú¤~…䇮ô½å { HªRZÅ´ëkÎ’Kø¤ù–‚o=;ò¥˜|×¢8¹qdÓ½#ëó9Š3ðèùÒ›noÈ•ˆ”g‘ÜÖ»”\hÝPµ}P J­#¿ë-Ç2©hÌ+ä\Ärs‹9× À_–Ã2Ɇ”Ñ`Ôè}ôÀÝ¥_té÷£/}|«àªM|-¤G ¡4¼>ÜòSͲ]¼Á=˜øóìǰ…0[Í ï:FÏŠÂ¥tU4êìxl{‡òÄfQÕNöx¿%ˆeýzãù'1miáóð¨)Á&§—¤uÅ ;'çØìžÉšó«ÐÐxìøó .²KoõÞ¯BròMÖΚ]Žˆ¡&–ð.\~°ÞÖ„¯¶yÏ~ÏÝœFî'®¯DЧ$ó¡UðG”õèÜ—L³;-­#_›g裌G‚™9¶(!Þá2F§Ý'f4Vƨ¶¤­–uu[=5<™¿;î0ª ™«Æëøá—”ÀúF<§u~Wq¨fßÀõ“p .î×ëœ2ã¡QEÐJ¨a)تx}¼¥¥ºr/“DƒÐÿd*.¡âÅvDØØi@Ô0óÈòBÜĽZ{¹G( ®Ü¥c„Ý%­¼Ö±Gý/!Ûž/ÇvkKúœ¸beŽu¤SÎ^7µû_bÄœËR¾‚öh]‘ß°Ô¥y‘ð}lQÊFŠut1K<¬yÁ"no¶[fÿ âGüb™òºžEÏgL‰æ€ ɨCp¶°`"éÔi.{˜ L ­g ÏÒÀ’[¯d·ì#p@Bö—{»éé³ °ÇøÁ4û˜ÿ#KÐN‘¾¥(CNFoŽˆ•Øê%wiÙ2„ 2G?°Énw6Ô̯víÈ;2|?Ûó÷ØñÔ¹Ëü†û‰K`ÿB,[oà|Ù¥µþxNqÈϨm¿Eºßc7~ì$Šy÷ h—SžY±¸m£••iC!œƒ00Ú†…[o×<tQ¢¥ƒ[ùõžZÖ(v}·çÀùþWàÅdPs@%·~ǃÛ.63®êñœ'`~äœì(G?DôbÅN7DlÈ cñ¤žŒq‡·!*0û (rS·«Vh¥®n¿ôí_&õ9b7O}ŒJjºowkM&Ò.èÝv§†ZÍ£ÔIÍlòòWë0¹ÛzÀJªµ'yRÝŒ5WAD°ŽBÀx`ªêŠÿk±+n²`VâéJ‰ë+ú´8¦¶ì…è:—I„Re›š ª#HÃ)OçÕc6O7¸í7ŽÞÁvBql¬næã¡~â®wÔ‘ [¡ý¹‡>Éÿk1bJ¤¯–p'ˆµ*ÛSW–éa$³‡•‡à¢/å¼\›ÄFK¥R{°rsPð­"3ˆau®Š)ùÙŠÈ¿Ÿ¡þ(Ÿ@ƒ`ÇT«äògÙ&à¤ty ½8øºâ"FÀØ)Ôh·†ïåÔ›óäò­Ðû߸çD¼¥‡^Ÿ¥Õ”X£ü @©•-úâýpõ­{ˆ>xƒâI¡!ôÝ«öÇDö@{\”(²Ò !ßI{Þ™ JÜJk±¥gßÍÉG쬲“fUR–ñFnšvÒ¥½wWŸ79z ¶îb 8ö¤šÕ³gªftúz‡7u¼ØÑÆÜôì–«§íœ+yAjqïkeh€Žˆ$Y#)¿] žFY’nsš¥?„ëÂ}î†;ýR\Ôíh}‹.aƒöPpÆívØ$vfkôèïÐ:>Ú|b©·D$¯þþp1üqªïŠY°(7»{C°b¬&”¶½¡| VãÛ>#! ð}µ‰†0±,¬|¥2•é>ÿ³ì¾chF›²ÃG^n‚"Þgó– s€ ëü\@6ж\ìSc©Åz²Ñ`j*žŸ)¡'ªª~‡¾hþ šsºJ5ÁÙÁt¤ÓŠE›.ðçYCaj Ç«@ü{ñT†u¢ìßΩ ¤£6M*–Ý¥újJ°+OdŒF1«‡j¦çÍ…m åùܲ8ñ§ú|§”Iü“WBZmÜPœê"¹mnÍ_b=qE¬7{¹µ¡=kFö°¬ÝÔŸôH]ƒ3yšDKkŸ*ìõâi%MÁ”¹Ê[Ìžm›(sm³K¼„3íXPNÇ•ÜÚ†T°zëáütÜøÞÕÄqÒýü–ŸUôC¶/¬çm2ïDØŒP©XxûóÕÜ ºœ˜6ŸðS/¬ðÙƒž»«Ã·qo7ÓØ „Éš»±³Ý{“®°€øµ2Ø#øKOÝ„cWfvm¢G±Î—Z˜À-Ж»;b-¼Õ±9w}Gõ‹¶ !—GW ±íI êó1ß!iWKÌ“½‰Ôâjr «êSÄ=t¿°þCßþ}E Ç÷ãkÔ,˜úŠ£˞Ɩ<¨P¹;x5%û“¬~0skç­¢´óQBwÎï?«>²ú ‰¥†×‘ËûÙ?}+ó1HJ¨PÙFÏv2exU^Ò9YyÞ¾;åýdhΰ¯à(c4ÜU›þYˆY`£Å-|8¢R'ÛÚ¯Ï êé@¾ým BrÎÌ9iù@¸®l2̦&*Éw7u®ÚFèË©&¯ý3m­h¶²æ»CæÀBH qÌžýÝTGÕ>¸³aî5§õ¬ý2)Ö‰b`ªnQHòÊwÄÊsÿ1èÆQ$ß¡Þ(g`v¸ßv±œ¥œ}úЊ› H æ4íOõF'¬ïG6ËOרiç4ú[ŸÜÇJ~‡À;&w*˜‰€Õ,:•탗{J¾o=¼qžŸúuB¯Ê^þÔìg„÷À4Çiú3X쫛Х–î–^´èÈ¢*Ø×ÀS"ÀºÝròâ(&XJøCÕ1‹œtL‚gà$yhÐÍÚe†e}`âÅr?Îq$¿e× ÝT-*º´Wùé8¦UKrh浜T½ìoîp~SJ«˜ªL¢¶™ú›·Ô¥×ôìv¡õ ¤™ó5Qð‰pHçh°˜“â¹v"—ú2„ž!§,àZºçÚD}ÊÆF7È„5Màc‰ô¹ÕAx x‘ÔÖvW‘!¤efcCî{4F¶€nzÿX˜Ü¨û½È®Ûí&^½˜Tnñà::òPö…s®šOcƒ^t3Œì–˜oš|'¶.nDõâÓìMfì3r´Eu²Ž¢@óïký÷dÏî.3à0囪¬(¯/OùýîÏT·p¾7âyêÿSðH0@‡v®è¾ÉÌ}ÕêÂàžÏÀz3‹|í6"OΓ’m?ùb´Ä57¾“.¶UÞiÙÌãøjîA%R#´iT%ÖHðçªÌ·…:ŠZ®2'ÿ>˜T¦1Ø T4ÃÀBMrß*áÞûlu¥ÊMIa+»HMæC#2~CIbëÚÔ ±áÅyí_‚ë8@)?G ïô4· þÍ2ÑÞʨE0š˜úêžã3¾œK©û—Sx©Ù«Ð3 Z¬ßóÛèÑì /¶ðǾO¬â³1¶K«0 ·Á¡;êfïîb .Yá¬/ësZê”ï34æ³ÀöþbZÈ¥3ô¶Ž ¶¹¤O¹'mvÐþ¦ßNvþ»UFØÝnÿ Ëo»¡æÝQº1ZBâòÎ%iÑã¦Y+̵ÒO²Uˆ<ÿ5iµõ*ÅUy‚tǨӎÚÛ°¬)0pÀ}‰½¨¼DJõø…¤¤TwãÔbDéÎl2†]wÆÓ7¦0ˆ ×tü3 ;JI+xÍï{˜šaÅÑ,ÒIËniã†Zýû°ñ ¶à™\¡CtˆWl‰>ðû·lêQ‹nøÉuòNëèh„Ã-ü(ᮺo®{ØQycA ,s#õ¥jA¢ÇYÊê$|Zܦ6Æ¥\÷£ôX&ùÑÕÿE,× háRº&‚Dhù½·KY/é"¹ñ]en$&œk–vãü*J}Í ‡àéyÆï-ÕÜ'æÂâ‚ ¹…˜œ+?õ¸ä€h:-Ñ÷ZÙ)>JèâJ]oëð‘\)9rFsÿƒ‡¶¤1“äX-Ú‘,äpÄ€Ï%êâÀ›ÚÙŠ{ÿq ö…å;É‚1rbM“O–‹4En²/G~#s–€È±ž®þR‘ˆÛ•oÙ«‡ähfmöpè?>áìJÑüÞQT´èÓBäq½årvvZ ú,ŠI¦’w=Õ%k¶ ¼a4c&Yön~ÇÅn%ˆC™ò"Ê‹=¦¼rúù´*#ÉŸ;Œð[àçû¤ežœ7+j †i›¤øæTPŠŽ×>ñÕ–#8³ ƒ0%ÔX`žžnü¤%§æ‚–§gìÉcdݲø†>ÂÆCz¿ÿG>|Å90ó/X!HÁ‘inK köµð1|¨sµ¯ƒ½”Þj¸Á± k¾Ë…çŠðB .£(*îIð1ñ¦[ú>|ôˆÿW åÒ€BÓ²6š´iGˆV'nžw‡^T?3ïCáœ[Xœ̼¥ó7¾c•½èXŽÿQù ”úš¸BSÉ+|J žË2ñÛÿ= j'Òbý³ŸwwY‹§gÉáþðÌ :æH¨{½øv…sè³{'gÊR"Ë’/AýW ù)[Zn˜2É Ú2Ž /GaQ9C¾€ý–ÿ5 ‡½+'üOԃb:°­­-fòE~šéùÊùÐ*¾É —IúxV¦'`½xŠKxI ”l½Y¥Ü‰‚…pJ£!t×îX9y—&‡3”í²…/‹çN µ±Æ¦cßñy›6äŇëœê¬Ã‡jü}º $ ›nA?;Ñò>2ÍÒ¾ï½vrˆÜ¤f_Bôü&]Éç©D^§õ†1_3rÑ”4gd /·dØG;è[…®[§¿¸/чI§·;ÈÁmpTsUu„øªç±)FnÂÜ×W ¦“o ]ó@\Mê:cËè\3Güü)W®\„qÎ;á=b}©K÷ôÀ ÇßµB`rN±ãÓ×òíýÜû•ݺ;»?´¢°ÂRÜÓ>_ ɦæR0¤?Y)¶ª n4Ë~ÝÃp#\ù}¨pñÝC\M”VuÖµç•<§71£öäÐtׯ0÷¸zMìX—…ð”B³jä «Q-@+¸ÒHpH̾…–,í(㥷’b•­ÞTâN…å©Íò?Ÿ¬{üïëÞßr¸ ›ÒRêGQTÂÿsW÷µràŠbÛ\å|ÞáíXû`ý·Ë¥¯á_›‰x2,ÁÎBlºöÜcëñ( Ɖì‡ä$àÛä¨A$9 O3>m‘Ølq‹\ë÷L·øÕ©HÖþ?஑˔·ò@×ÁÕcMI°@lh'ë[gj \%áµ$ÝŒÎGy%‰¼³«²øJÏQDåw²¡éh“*åXD|ëF먢g¦ü!vÚ&olØá°LDR»iYòÓÿ?fÎ[«àôíÄ[Q+Ïî Ò‘îޜࣦt m²xx™Éëb³>¹_¼å4ið-l©Tš‘ºíFʘ"|þ¶©ï» ôW_^”Wû²~æ:/÷ÿt@uÍEVs÷]I ¹ç%•Ý)'ê°$9JNiîJ÷ò2¬„3+tÁŽn9=HWú±Ï8 r(¨Bù~m ?ücŒÌ¸’*¾„/+¯/ïgG/±F’`ø†þ-í)7N„qÙ²>@ùÑ&Ö“ˆæ)s-ÏŸã›®N~Z8ÉE–ZèÙŒ÷·{бšEì´ö˜É»©Tca­þâÛƒŠòq i=5x¹b]ßVSd‹üQÌ~ì¹ø?kÛŽÞºåÁ=L¤_'%OV×IÒµt^ Ó7U²&m€ D·ÁG]%dYDnƒ{Bƒåˆ„ç&.ý%Q¹ÆMߊj7,µ¸ÔƒžÀ¥/+Q^4&³XMͤ£kPÛДLhÀ‚?ÐmM±0UçC»ôKû#šZ9f—óíkû|;-”„|ú2¼N$QÄ´ñ9C¬S­Pµ¢Ü’@ ç6 ªtI14.È…]pøœŽgÇ_ÚR§t"ÂøŒ9ä&iŽ×ñ½#_$sþ“}gQ–Û×¶öÍ×8Ÿ|ÎÚÖ¢²¬¾ èK»¡&»ñ«À&«,X¬)Žj´èxÍm)ír0ì»ËÏ6ýlóÛÂÕ*c‡ºÌîÔA¿çÄÐå’ÚÿyŽŠQ˜%R¸<|ÏGc¨$ ÑR?Ý܇9ÈÓ=–Ú/Nz{¶]ŒŸËÍ"PQ;¦‰x—öNÓïé×ÛÉ3<‡ªþóQXo"ƒX I¾ŠRáæ§òø@™‹~¼žKJŸ´é¸ªõØ+YMמÄt•QÇc‚ÐU,qŒEò2ûiýß^ ‘®hv7ÙÈ ;ü E6›É"§wå8^.,dŸðWÙÌrn²Ø®p éêÝ.ù¦+%Ú´xQ%…*óŽôÂçU¿‹sã²Á>½ðhu‚ºO†àÂN;á^c‘»#½6Y…$Øã¬ }W\q!{ô{bn/™`:í°åiƒ—º‡ ˨xSMq~GlQ™5ù£4VÀÁë<ú/ƒ2|“;P…T W+å4Eý4°§xE¼}n…ý‘‘íÛ˜•+² ÓüB € f X“MÕ¶%9úeÏvFpÒÉå Ü{ +Ï-zqçbh¢÷lPÊxiÎï¾S¹ä® ̉öÖ6¤ù8nª¿îXÌ]á |C¡N7“ü7õª‹§õýTñÎY6Jˆ@ç(_yò&s¢e;Ȧ$<‡— ·Y%VKXJˆÖˆ÷3¨ é1¡«¼àt—›sàgÖÛÎyfî^úÙíí*¤ª_ˆîE;ÐwÆ…J‹zjÈó°rÉ©}þŸãCìPXÏ4Ld±ïUë˜éš¨ô X †˜i¾!o¨ªÁ²äÅ¥õ ’˜¹dªézŠ×Ùíê)hqþÄm/áâ:¿¢)¾ö–Î¥·Yæq›8&hfÔ—® ¿âÊ÷Ëøa|ß‹ÝÜÈ|@Ó^£ÂÏcdD‘å›7Xô91 d”¶Bu/wÙŸÒ ÕP7be®k¬ë9©ãR8CÀèB¨VÛΨ°Û®ÕýN§J¨O+v€\á3L¡'Ôãâ3Tã8¤ÿ÷U˜£¼‘°!c-ÈÌõ Õ¾Ú½3?S¯²÷ã¹pí~>¬t—;TˆÖ¡8Þ¶•îeqœpAW ûĸB¾úy©lÁÎ+Àïï0nÇçu³Wæ!ÖêÇ ík‰²·»î¿IË¢ÞÁÓ˜r¯’Û^+ÃC·f¤¸ ‘WPœÜñËT= ÅÿKe½_²67kyÂ*\º_uÁüjÀ¸X\t§f¿]TkÔã`<ÑLã¶ÛÑ*” äó"ng= $vä~_Ø¡HXPiœ Ú(Ý[á>ùøP@*‚3Q>ì ÷pK®Åh®U ã7MFRx}¥`¶,4Ç* ߸ÎàÀBÌ€ÁG%êa«ôÞ™†kCäiö ¬Æ„8*´0oN·ZË „(sÖ³èX8Õÿ™Äd`RxŠ»g`/uø‹â P^–<82dþÚ‡ÜDŸ®óW×Vnn™8V}nѾkÞmMЪŠÌz+Y"ÏÇb±¨q0C4 «Ñt2Ò=FLGÐ3Æ[.«!n°â{ðu{äZCˆŒ²ÐÍv«*J0´ )áU4"1,‰knò7ëø`ݺVCnëº5*õÔq~°«¢øŽUçY9©½Ì¿zÝ==˜&@鯔ê«RÚ5ÈÕ{4Ïj˜/†ŠÄ ûAÝ +ù6œB¶“­×T„,…™Ü4†öùƒïÁOñT$¬¨žpÒâŽ6ŒâÉͽ‰CxO«Â@­K£sF®Ãì_Î0À6#Œk¨#ÛÒGíé“ykæ= ÈÛ…èàø‹Â/åV.áŠq‘™.«ŒvŽ8Uwäà£bлdÕòÿ")-³í¡ž÷"§\QioËC=Ì¿…L2©P u_;»ÐlTcÚs¾Í]°’ÝOŸÞ¢"&…Ah§Ÿæ±7%Ð# `ø§ï[Âa|"•µ¶]ã®Óm%ÛÕÖ‹µl!#žyÛ5À±Dýä=­íØkBYýŸë(\,ËœÝÔ«dº¹¾Õ¢ê_OBHæË>«Á"eÂÖz^‡t|ÂlF–†'M æÜ¬DóøPHYaÑ Ç_ꇔH:QjÓai¢ü|ᩆÕ?ÒúâN‚ÄteVRõRšÙ”é*›ÐmFT«\P·1>c3§üØn‚Øú$þÀáÒ£óÁ °ìq±Q–¡Í+¾×ÑCÛ?_‰©øôð¥z 2à|t%‰†Œ¡6€˜ª§…/(!ß$È”EëÒû"§¹\ßÔšÚöͯïŸi¥X™*œ¬Ä¶wG±–î›ãc—É5ÖöR•ŒfTPýŠC¹7 û©å·”œ÷¸ƒH1ëSôY@OUKÓca,%—JùØE2îwˆÁ¤V[l-dÖ>”ѵyÀmÈ•²yY¾¢û× h½hèˆÅW¥´%†à%a@v< È>‰\’gBèŽI‚¦ÂJ%²H‰¶Øš†·ÿv £ ØóXÀ*.Jþû¼3úá™zˆh/µ 5št¢Ñ"Õ.f1y­ÌU‚M@¯>ö hìP’­z-zv¤iOBl3pƒÔ=ñB'pÞ@ Øúª¯PùLŠRÿJÝ{o„„¡¯_~îIÖGåË÷µ²ãœ1#ÝQÚ–‚(÷æœ&i"O»ýÙï–kE&.DEÓÛ˜ãyΪÌ:sv¶èƒN¤ $—ª›Â¤w݆¿r›_°Ï£“ÓT–—BÁi&µh #σ©;Tnu€WŠÉɪÊ6ÿ}gFpQVíú(N?Ak=%¿ë|ÞÚ¦ý#eûo óö$As 2Œ·er4Bî¬ ¬²¸=°>lבdà5ó·ãã¢xÃö›UÈø„©äÖŽV1\eþó]»Î³tgÞù£ØeäÅÉQª~ü:¦pܾ’á#dòç®ÐÁýuæÁ²¨Çý6osÞ Ü¾›y^™lv†_/-e(3  B¸‘oËþ÷ÓÇè‰]—Ëe»ú–¯¾ {Ko²qܪH¹€¸±-äû¦»ÚÈÌ`âÖèiŨų¿»c»¨ÍõEÙÝ[ãÌrù¼-4Ç ¤EÚÚ¹§€n‡!Ÿêç. Ä!̶Ð_Í/Ó÷ÜjžRÔäòÜù§îugÌkä­9…—ô»Æmd‘¹[”;3Ï °a¸¿„jÉšì»A þªŒtîÑÛ¡9JÂÒA_ jÓ&À¶Úä´roâ.§‹#ˆ˜³ &h%ÂÃØ<­§Š4°øH5rjGL!×[q©õ6°‘ÝáDé1 Y]„v0ø© i"5IÓõW§I 6àŠÏ'·á =žx!öÀ½ýjéÈÖ%¸3*MnÒJÝDwQËÆ…ÿ/íï]„ƒÝº€ ¶:܉q!* ‹xQÀ8ÂAø OçsäÁ«"xß`„„$a!®žª)‚6¥=Tç]¿%׋ñîïu|5Ѥ‘Kt‹¸¸ÒnʆǘUøRÐ’Ù¥¼–Ky™q>^r {—ì’§Ž\wN )e´ÍÌÃU î)°Ê˜É¸S‘/Ƭ¹á 8ÞKA½4`¸Ó·ÿm@€?›(ú¿?+Óº=Ç5sÿ{Ïï=¨æëÞîÄ’Hº@ ²$æE˜ny±w1-¿’SeJ— “`Õ4´">xo¡„fúAG°#–ˆôÿT2jŠœ_3´QÑ¡‡Ü˜f¹Oè'I›Ô—1·}¯’O ½}q±ÐvdÕ—iS•,¢ÊÂ)jÝ4l¢’Ø]Âé¿{³T ªæˆÖÿc˜ÚÞà[T…ÈÏè°›]æÔ5¡ã>iÄôΤúE– ‹´q2wûm+7b-?’w³ÂP| qd”O3€ žŒYç†cË«:ò»ƒÃúK¦œÎW 7¤0b:óݨ¿˜=ǼˆŠÔAIaܤ¶k*í¤øù½.ÃvÚsóÈØ-à]b@euvj ¦¿¾n¬œì ØÚÿ!;ùßcz½²»ƒ%a¡ŽOyÅW"$\ÔV´–À­3ãò ê%Ât†ccDV™"à÷·n±Öµ=èÖQ³·€Ï÷ÿ<Ê#7|?Óž¨ðИ¸^âVAì •_„Úµy,åÍÓ‡ÓMþå¯%Í¥á¢¢ÝÆg •ó¹?¬“³=>#¯:Ôosži´uá³ÂU›—íRÇý@*js}sÊy½B&$?ïU—Í¥±ºØ8©§YÑ7HC©ˆ©*4÷¼ò€áÞ]ãÂڤ#ígš!Á~ѵá{}CÙQ;ð…Ed¯òVR IκGÞ$6dÌÉ‹ýÖe1A ;Ei®IIéä,Ë_Z~e¬N±ýŸ©_¬XÄ…có&¶ó‚‰Ýµƒ9GçÂZ†C’[ˆtùz$ ÿOH³ÜÙ¥^Ø‹F†0¿(í¥\KÇÇsoC^T9µöu°M N¸k» ûø1*œéT W-ÈOˆö°)s x4Þ+†A„r“€áf‰·.t'‡ÈCžôïn½¢’Ô óÞÜp eO¦•n5Š'â1MjÕx°P“¢w:©ê•¨YNÇs,)v.åƒU7b=2tìü1Œ Žtãß “b“±„»šÐx(„lH°‘9ÆêCäûúºJþ—z¡„b­*¤ÂôZ“þÈý­RnqN"$·ŸTË0Ö2Æûˆˆå‘(#GqÝÏüMÝ•g‚žÁôeoý¯;+™rà÷ïtM죂€»M'øŠóåŒÏ~ ùpói¯„á,wnƒµ¢`ý8m0?º™º*ÁÕ¥/W€é¿²Vó<€N5—âíj§MlÈ”=6ó‡×#Å¡¢ØbL[LV×$õÀ1KÈÛÌó~V¶Þ:„HǤÀ*>gûàxû™p²]Íý 7Q^–ZÚöá0ŠðI³­¦†k‚ã`ÒX{/»ã‰èÛ1\qìÚmÁ€CÆã9©,:±*È3Ãk[Æ6¢MȤìIõô[ª»O½t0*£Îi4ÑFjíÜÉÉGÆf±ðÈ$í&èöžH¿uŽo|–Ipˆ’ž[6U‰&K±ß‡¶©á$Ã.]D¶èj¿Ô-†ò–%ôŠ2îêJfK—L§ØÛþʈ(±~1ðÜvEdlúi 4hI@¥ÛÕo½G¬cóVuûb^ç2¤®ƒEä×}„lX×n2E‚EÊ 5—Œ`¼ÞS éød[ËÐÓåÈßðiDžgL)‡15ýìž Ëˆ©zŠð^Ëc˜rÄämI¢¦Äçü»¾L¿5!¨ªØÞ€¸Ä\ÈŒ»SœKö„NCGRFåD)ó>Ú¿q²'HÙiôÍú¦t7ÖÔrou¸±O3þ6\ˆdãX-%Í1m&%G#•a,7ÉiÝ…r,Ú½v:c˜[ýxʶB ´äw ×ÊZ„‚bk|WŽ´í7«±f’R>ê+~À½Gnº5(ZŽÙ;·šeZÈ’ÛjÐI+M9ÎU–jJ¿˜ÑZøC:L&2UZUÞáôþ¾p<Ì0ìp—OZ"9 ¨‚~LÖ+„xšÆ¸gÖ‡öd’²Ynôç§x¡s¦IMËÅÜrÔˆåZPäz#»ŽJ‡+M15ë„e‰Vƒ #XC>S+*’øQÌn8—Q!ZñJ›>ZQá(¾’¿ IÚæŽïô&¥ˆÆ}çûÎ\¯åŠXkàXˣ롯+‹(?ižì½}9úMR<4ÖeP“ÿÛüà@ð»+U»í¾ÖG:²£`Á飦,ÀcTÍWå:½{£–x.ù¨ÜÎN±=s?º¸úø¨ÇäRUR3)»Ÿs¿¬u|Â÷Ïÿc[cÕ ·€ÏÉØð¨‰xé°ÝÌxåº<ÁßC¸Í¼ÐÌ#п\Q Z¨X¬"Óâ 9y®“ö|êö5)“UÔ ©q äÁ‘R¶ üF$èGt•j—l.¢â´ølÞ%ÆÛ$pyYºA\)d‘:CõÙ€£¤¯A Þ,“KN¢K¢ ±sè§”ŸJëâ1nÍóŽ9£ÇÚ׊ŠG‰ÑèdÃ$гB#ÁháŠg²ß–£¸d´òp™wÛ="ä7BÌLÆõlŠ/\âsÂʾ—n¢JðÁÀŬ ß™k`oä©W8¿ý*²ÒáZ¡m&³Ô`•Í-ø<²© àoSè ©âL"üø‚mhñÉ;dtNêEOì€)´]ä,Ûƒ{ËÆ 0±Ø:rÁøð"}¨É¯Æ/±_¹¡ãC&XÊuÈþç‚@­3´¾3’UGÈHd—¾…`uv=qÎëvÛe-: ttˆe (Ö„ÿQî°¬Aäù2K}ƦNR­Áç˜ù™€<@n™úÝâ‰X¹_ëÿ}ß’9¨Òìw+Õzõ ý¸U€«G'Ä’îr7¹ûu(N’”ÿ-ÝÊ›Œ]h ´/ÜŠ\w¹èGxéô8ÈIšœ]êY*D½1¨Ó^~12u†#èt|JS5§”^W…­E±1Ô0a/ê­ÿ)ѲQ9¥ý ì‹ét|ªOÖƒ ºÞí–”*ßÿ2ìR]}'0CJ ÿw̯»±Ëw½6µÜ‰]$çnTç;¤µ0Â,ñ'ÁŒ8$ïXL˜ã·Ó]¥8Vˆš>Oµyû »ëúiE9ÿ©‘®;œÄ•P¢}'µ5åZ¿ù†îO¢ý4“³2J:P5+ezÍtYXx/ÆSÄ[®ÉTœ+„Ü,E·tX*¿à)yC³S—¢ŸßòxÄ!§†OÎd{Ô|–cŒcz£/mþlÜCL«¤06+aôk}“ÅßMùŸ#ê¬àØ#b&š˜ÐÔ/üpŽˆnÜU‡T\4×&™[ 7IÍ[ÔØCñ‰#á›ÛAª‰Äï"hIØ_)d¡Ïlz‹š¯^ô€ßA{«œ¹N{×I= ép…êÒn‰J»ë6:‡N@àBДÿ.ÿi cí·±)-nÿO°Ù̲Ìüb„LËÃ7ËÈ&Û¯®ñ݆÷¸ú'M7ót!ÆçÏ4žÁ-Uë¥þ<ƒ—µµ=xÓF;tñyëìþŒÂ-›ÁÃÂùDé* :ñus_ôÙ'©°[Hîâ·ñbÂÄDMœzt¾ÖµÎߥµÓ«ž–IšSí;%ʶ„!éëCd-úÛƒ¯Á‹ dÈ;îü™ì{’øÀg¥zÀÛan–ÝØ;œ†Ÿ ×$0N‰m!ŽÇ¤á*¶P)ìM"|šó1J9 eâɧty@Ý€:ä¥B®ò0oÿ+½–ÊÉMøo{áî6kkBÒ2C  ’ Ðº±ö¨¿œ¥kUÃýC5Ýï¾P™HIúáªÝŒ[Ù‰ 1×=æc«\ó î…‰ÏL_(ügW»›X´q }ñBèÈ!¡@ª"Ì>0‚ּǪ0 &CWv:×yqÓM˜¼›¯³Q…gBŒv9ýøôð…Ãk™˜—÷êEºâ¨ù=öË™òv.„@3)¢˜{½µ[ˆšläKIÎÍ64¶Xl‡ØöÒÎh´b ‡%ŸFttÿÜ ¾Q:ÿ ¾A­=O0¦ïEˆðŽvÏ¿¿èp)ñŽêÖŠ¸(zcRΑaì ÈXDÁ—›Ô"o5Âö¦%ˆ•Y¢i5I¯;Tü«šÖîdƒæa˜¿]eC¯çœ µ°oýì$ó2ûœjÕo·±ƒ¯Eæc'Wïgö0ìr¦¼X¡ˆzÝMÞ³ üÔ€#ëLM!ZžUo8/-Áh³í€çý0&ÍËùÕ±VX‡!ÅÓ¸IþAÒ•Ë5¹:ß4?ÄsxÏ¡ÄR;†\¯ArxÝ+ïqÝ®}FßP#‰uZPÓÇêGqÎ{‰0ш÷.3Rݲ®<îp°Ä2^ú“cR'½ÖCcL5Ñî7ªn@xùÍf¤Ö©ìNú«ÍA0¦GÊ(^ä8Ù­­ìôXïX¦Ðt9ñKŽ…ÔÓ¹¯LÓΪë“(dîÄalH[Ým›°Gg× !ÜÙÎYt‘”÷;®cX)ü¹¿”»ºÜÌé ÃCô°ÊaÒ£M¡ïj{€Entq« ¿5èñJ˜‰ç\wTNx³ÈA ‘o}Yÿ %>b´–Œ‡Âå@ºN¹GpKz“ïOx?`H²™Úã/ðζ¼íCVÄÏŠä…F\Ù €Ñ»Þh$?ùЯ 4ö»Áøð·b«%Qù*nbéE·äç_ÿ^Ž‚BÙ}ᬷ ¦Â“I[yàèm•ך­6íÊÀ¢˜NÁ•v~2¸rÛkõ3øèj-°õ4åaZ<á1H'E+÷X*>³zß™DÙ9È#.")Þ¶íxQŠ“MžLýø1ž@Ž_éˆÿwÇH†­'®ˆî>~¢&0ýŽð>2&ìŸÞhÂŒ®ÄÜg+«‹{†Ó•FƧ³ ó®)h>f0?½‚ƒ#ê}8ÖCcèª{_˜DSFŽ }ˆ„7yÍc¨¬«<ÞÈ{Åk¾8?Áx81 bÖ­ iù Þ”å+ï>P5ÇÌžCcÈðâå[çoV{cžIÃíš.u}øTd3&µLzÝX\\¡£p[•“Z{ fkbB ÚiKQ«? ëvtxDq«¢Ùµï*ËÖ°.× ^lwã¶…N\ÃÏ j!&tüMˆƒƒ³!°i5\qf«#f¸ó dôtªu =N—¯@– ~&µ¥6!òÓºÞ ‹X äýq’rIú›¯PÂ.€ÜÈÛì«AcÎXp˜ïôç/+ ª}–6‰:È@Ù&B O$.³5ëNxý n«óoXkÇ5u9—¤LÊÝdÊ~ýqà3_’µ)êâ5þ8øãÀôÞ4¨Tyˆj/r³U-|ö%Kâ‰ÑÇøwtßZ-W`T åUpÑÄz_ÿ4B  ñ¨ @¿“/Æô²`©F!çÝÿg™pìëì-h}ñÓ5j> í·çÔ/˽ ‘0tË>„dc쉯aª!Œµ–š$³ývo7¨zWvÚe9‘nË(çR/¡ÜýcÛ­)™çÃq°ZùlE€¡xö² ¬çû±ÇÖ2,ø/NIWt¿þy Å71S=7ȆáÝ»NÝ@†óâßòüå C2ðáûÞž÷d òôßr´±&ȧ¢eÔõ³Ùq#qá;ºͼ¾¢Oå) ºeìökäUF«8õÍØD¯Qð´ ]ˆG&U@ªoí\Ί`×ø'}¿Î/£hg”É \+]A‹æ¥Õ”`O£X7 u nÝS•+Dס ð³HÜ"t|‡(Q~3–Lj.I’!Ôó˜™7fOCê­œVoçnÓçú]!{U¼[‡¯a ®os€ç¿`³²>yÛ  ku¨‘ ²+Â4.¢”j"£Ìž VãH¨y4F“yiìÌeÊ$Üëœ{ȯSçÖÊ’Á¸ Àu >'îÛ˜ bÆ»òy¤HÉbÙq´?6¦ðFä®”3žv6°?ÐÕ@°ó¯  Íù1*³•újäõÏÑÕÑÊûõëð‚Š6šl@ø²[Vðà5Ú? Ô­Fgf}°µÉeCtù”'•šP„Y{10öï3øÓH³ôß'>Zeh ^ö¹„ÄÖy±XÏrEå“ýžßùí<{à¼fGÉâ8¶ÜGâ´ª÷óÓ'żnÆ A`€h5ÏÂ06Ä †(bq]­Ä_Úà ‹àjA4ÝŸÌ Œ]”$µÓ¬rˆAm ,U ªaV¦ý%,îìXûÈRlTÒÍk~³Àü®{å;Œã‹Ê†·¬ééƶå_o‚éጦý2$ˆÌ©¼ Œ ‡€ÛůÙfª]!Ý~IqWqÙA²Ð±yÅØvf#(ÞϾ²Õ&žÀf%S‘2bù ¼ð8‚L3¤YÈo@¨÷À@°°ÍDpO™ùÀ6“̇Í®ri¤ñ«Bxͨ^âRTgú’¤ò™‚¤ÿ}ï?dF„ (Æ™A€/&730üGPfÉ_vWý´²“&ž@¿„_/»óĺñh/ƒÕNvïƒsRS•цß7hŒÞTŒR]ìEë&êT4ÕùŠÑ'¨œQ§kEJClÉ¢‘_bïƒÈg¤Ôïôž&Å/RI•$ý22¬ý3ô«×WPÊäÌ<Pýh„Ü‚ÿž4ÕÙðm`»ÖƒòÖÀpŸΦ]'†)<³^炨üßßjpXÔ W¾jRå×ÜÄ£e‘·ÕPÖu‚¶‰tSNCò±O÷4ß°ÒúÍÁëÞ[|±Kbòº(Œä•ÏNFw R?OÜi±Ûc/°DÏ#;µF Ó È ‹^þe½G‘yP"·ôû*¨Ü™Í!3EGÝÕ°•ëð fÙÆœvS hø.– \²…ÓÓûÇòn¡ßŠã‚‹¢Ç+¡Ê>Në­*0n4 MÙh%‰Iªùn‚¼¡©äNÛ<¶V(ì¼Xƒ40‡0=WPâBPsæ=jä öMÊì§ç\ó ñ¬"Š•›NÍ™á²xlIßÍÍäª2K[ñßä‡áq§8úÌÑGFT¯ö‰1Ñ0¿Eà'~¸ÖNO§[?jÐulÌÿzõ¹°©} †m¢ê€Æ¦¾Ã7“Ú¡³ï@3—×ðétÍÒ É»‹Ã;úõ¶- œ¿$!¤fK«YË¿<×÷áZ!ù 5•Yó‰×YŸ4y•0KȦKš‡[©¶GW/ø„Wð&eR\¸¨Ù,IªJbì¿m{¹‹^œ¼twÈL&˜„ffî.U Ú6¤þl·|Ôs|0û"ŠKÉ/jâÒ·TNŒiMŒ^$iâæåœiLw1¯ 8r€G &¦û³•f^˜G¸®Tà†A^Ùñ³ß¤Ï„·:ϼ´ÝF8Ú–Ã ùŸú­LÝFF¯`×VµléÃÜ­Ÿô«ÝcÏ~Ÿv‘5r/åá ¿\b¢F‡“TÀ°¾ÿ„¤ ä±XsÝ'ÎÂ*Þäø@ôÕæ€Á8ÝÁ T›—1y1R0ÿQÿ Â(Öë6²@ÞYMû56¢´Þ&g ÇLFShÁD®JÕäÇPYV§dr% ë¦qe®2O‹ƒxÃB–U+οG;ßœ {ûníN9…Ÿ›zé}Ééy§Oðî(A:ŒÅs´ž¦æ}ô,Fš+ ‹)2ôW:ðïCó8Ʋ®nñŠ´ŽÜì‰c¼ ¨]Ÿ}4v [ÕËÕ•®à¥ÞÇ·õ'êû.Z7Öa÷Ç¢ÑüaþîCØ“¯ð;Œ¹Se¹ëêñ¿_C(&-=Üe{T5¥-lX¾ð°ÙéÖD-ak0Åv›:X¤oûsnNF)Iß¾ed·‹P˜o¡—.m *„¾‘÷ñ™xàZAÆ,'tÛâO³Z}³óùš7qAtav{ Ì׉–l4V_}=“?+ PÄ<0PcÔuJ²w5jp·"W)Ôt¯M¤Ý»ë±Ct\ÿT³m1ý@v^´ˆ„û(uEœqœ‡t÷ ]•Š>KìŒÌ·I®Â¤~ÚôÏ@fáŽ× <`[> ®•¦É„Ƈ`öÂŒû–æSõ:sÂðw0ô¹qÊû€ËX áõÒ±ƒ·^ñ6â%ªj”aukáþ*Hò]2ë”æH‚â™Ôü—yJ,*©>Ú ˆ˜=ðÍõáXÜ;Ö’n-ý/Ú¶¾R||à—mp^j|ÀŽŒÁ;´¶yˆÉu´ÇÑuÚ Åjþmfý¡×ú?2fv'p«QŒä)ž®ÅÚ>S+C}Uk˜èõJcåðÆáˆ3KŸãÀÿm›Ÿ „&Œc›WTÀFM0ª|¸Æ;¥W2ƒÆÆüƒ]µn³)\ðÈ¥g‡0rýCÿ…ÞÀ ê¿ûÃÔ§Ü œ¬XÇ.?€·K(ãÉIv2s!ÁÚMfð@×,B À|«¸ YIÇ—ó§Þá2I»ãûEK+š%HçVùÓˆ"µ{V ÓÄ¡1•=ÙÙ°üYú‡ˆ÷W&¤çÌ€‡ç†CÛP„eðË'ÕVMÿ2<â`øo7sR€NBŸósûw Ýè£+‡pâ?bƒ¨“Š‹ä3àã“”ÿL×ÖE¯&§#§{§Á-ÝV¢iä#áï(Q±ë[ž¾èÄ—% 0—[†õãÙæðÄ yù¡È:bGÚÀ£åenάÀv#()¡4±Ù“œÔ ¯Æ wiFop-ó­¥b1Äp[‹”˜ ^š 6ùp# vS.1K(ÀUà/cÃ:ø©Û GÔ{ðÜxüw ОŽ9o¿û¸ á[é™ÞµìÓ/·ä4é5"Ùœt†…¯©ª_ˆgáä>ô55õ8šŽekå%•»Éó%Ö»e §†¤«TMnãå[ËÆZôûY ÍïÜŒàgåx7h’‚~€‰¯§~²µ±?ðïÊe#ë<õ=— B²½C¬¯‰BBó) eḼ 2k³R™•Ÿ× ýLï½úv¯Ò^|´‰<†¾¸h½•é"U@êXìÇ@¨ÅÆ0—8¾ð‚^=‡)]¾OUã£Ju–rRºþN»ê›ªÚšžxß-P8úÉÑé …Ëî³nY€£{¶-ª h)¬fŠxˆ¾={ïý‹¾?] CºY罯5“0ÁÞí–¹ˆë@ Nyž”£îÖmèXß*ž$%4ªJ±'O@°+¡%Í'¨¢,äôè)m5IÍÉýlíŒñLW+~Ð(˜µÎt™¡l‰$ÙKzµÕ˜áRø¬¤¼¥L’‰¢U0ŽÚÑ!Í2–<1éµN@*¤‹óV«ì-qj;Mú’®­¨~׎…6~æâbW9O$Jõ£’ S Ñ1ƒû‰î Iw€æí˜/õ³nÞX;¦òÿÇo‹ Œã˜¬åØú–;Ü—;§³?öü5²ü5£ ¬þÇ~;cøt)ü:§ßÃyÿC¦}ü†Ýÿ¸ qþWü5ÏŸá®?ÃYÿpØá­ÿaÑ¿ð±†ô¥ÿpÝŸáÓOü¿†Ü jþçü6økᬟÃQ?áª_ÃY?‡A×ÛU ³þ9ÿa´?ážûD†¿ÿ³ Iþ¥ü5õ-ƒJ'ÙÛ4[cÝSÄì[bwŽ D×—Üì×ÿh¾–øH*†qУІAúŸ+|q:÷ \ÕÀz|î\³Ö*¤91Œ‡+Æ>›÷¹½l;êPiäNQ•+xV3“Õi2wü”² ‹ò!) ñŒjй3-€^="ö ´ŸÈY€Ó”?¶sGár\‰t}þgþ§çxHÂvåý¾Qƒ†`áEöBÊâäš’vi|䈅bÄòbKü½H]ÕØ$ÕÞî½ÉÚGé2ñ q`̵ÀÄ{7„0 ±Nøƒ6欥°ˆ4Cu98.ô®ýbKÃו2ÆQînÀ‚\ ov],K„?&LU™ËxБüÜí2¼åáaA/&2gºõD/ºXÐIÌ}pżí©ªä<"<«á ómÑ F Ϋ°áXö ± \ }çeÒ½O¤ÏÕþ#=x”ÛNr[n^d…çµ™ évN ¨tܼÈLÒT©¥¿+$9±{?ˆ=âi»4«/©ŠÀ@Ïl{¸÷1dð”ùÈÀçñ¾68ƒ&yxtâøI{HzÖ"¿OÄ€×µjbyѦ&RiPn’Ð ü”ŒÚË›Îo[Þ|÷¸ E©ûÈïóbL£I Ò®žpmŽÚôw­6)7ùZgô…45Ã#Ã>ƒ\b;»î¦ô«—2sŸ©\c;à”Í•f¨%+ßp“~ó«¢¼O÷I³ýn´áb¿šEY;È®Åf¡_‰ev‰‰3-éGâ˜6j®ÕW\…Õêá0Q0éy`;cPží!‰#ùíò*< B@·–õH<\˜ì„`¸Ô0^ñYx5Ui£½­¹3–÷^ N=£’}©¯J€_·ÈËjÐóïG㥂 ¤OÃÚ?œWÚ£¥Nj¨¯«ÏM®.M[w›·Mнh>ýæ J³¾¦¿äç¼Èï*Þ‹¤š¹f+fúÐ'Çÿ¾þg»Ñ€kðïõIÇDºY±àe2Ìyp¶õ¬B_¯Ù›èyŸ¥$bë` EMþ!+ø‹–->Y–¾¸7½Šðçö;ðÍÕ£œu‰°ƒù  Q4âÛ„ }c¿îÖ͹™Ü#”yÅŒüMæ*øgè¥e+ì©E±7dIJáÓÿý7øà•©(aEæ?¦®‚„‘·\F‡Àmt1©ÞÑ—<4ˆ«4œÁOB§aÝL_`(ç  ©Ÿ)ò¶ôu¨{ WXu'7´쯋|Ù ¼N¬I^¹ëN今®ÖaRi3ŽöÊÇ€ÿ$þq}– md3ÿ»z÷TOÏΦ9¸®4a׆j!«¦ù-¿ ÿ }ßûæ| 5Ðï†FTÆi…ÀIV¾š (ÿ[y­õÃÓ•Œ”,< ´ŸgñݵÄ>?¹E)¼TÊ*¹C׃`¿lø¬*WES@n®ÔÏà@¸‚O½1ðFžPµC²D‰°f3–`^Âü/Âü/Âü'XÚªgWj[…÷cóð¨)Á&§—¤uÅ ;'çØìžÉšó«ÐÐxìøó .²KoõÞ¯BròMÖΚ]Žˆ¡&–ð.\~°ÞÖ„¯¶yÏ~ÏÝœFî'®¯DЧ$ó¡UðG”õèÜ—L³;-­#_›g裌G‚™9¶(!Þá2F§Ý'f4Vƨ¶¤­–uu[=5<™¿;î0ª ™«Æëøá—”ÀúF<§u~Wq¨fßÀõ“p .î×ëœ2ã¡QEÐJ¨a)تx}¼¥¥ºr/“DƒÐÿd*.¡âÅvDØØi@Ô0óÈòBÜĽZ{¹G( ®Ü¥c„Ý%­¼Ö±Gý/!Ûž/ÇvkKúœ¸beŽu¤SÎ^7µû_bÄœËR¾‚öh]‘ß°Ô¥y‘ð}lQÊFŠut1K<¬yÁ"no¶[fÿ âGüb™òºžEÏgL‰æ€ ɨCp¶°`"éÔi.{˜ L ­g ÏÒÀ’[¯d·ì#p@Bö—{»éé³ °ÇøÁ4û˜ÿ#KÐN‘¾¥(CNFoŽˆ•Øê%wiÙ2„ 2G?°Énw6Ô̯víÈ;2|?Ûó÷ØñÔ¹Ëü†û‰K`ÿB,[oà|Ù¥µþxNqÈϨm¿Eºßc7~ì$Šy÷ h—SžY±¸m£••iC!œƒ00Ú†…[o×<tQ¢¥ƒ[ùõžZÖ(v}·çÀùþWàÅdPs@%·~ǃÛ.63®êñœ'`~äœì(G?DôbÅN7DlÈ cñ¤žŒq‡·!*0û (rS·«Vh¥®n¿ôí_&õ9b7O}ŒJj h“çùµèÞÂ3îè) ‹W¢g•SôÄ´H¸¬z€@ì,N.4Ë«HÛùWYT™û}\{-ǼAî‹u1v÷ϧOs²y'$`eï›*À4Bɹ½úØÈ1 ]%‘vé5ò³µ´ó±~ºFÒ¶± ½€z?@!Øf .æŸØW]Ž©·,v4Ù4'Þ¿¬vÿ¬Awa»/á4‘t=H©>Oé1?hi NÀîS³ŽÔpjàÉûÌãä/Ë$åðœ?“ç¶F$µÆ¹8«ÝýÐ—ÉøNè p&·×r[üÌBnaÙÍC1‘mšFFo;-L\š–¨Ä}†/@Åÿ ¼&¬d­<ç4NQÉ¢Ä Ù@š>Éó6‡We|çgXYŠT;{d¢\@)ätÖ/Ÿd k/0,ÿ#6;Ó'é×&w.¯…={ø‚'xÆy’t÷$Sò¼ÀUYø¤ÁÓa­p¢·´Ð-ŒJ+ܡފ˜À¼ žë‡s4…©4T ìk7¼à´˜Ú£UÕöP^  r†t­¬¼‹‡´@m†A1kk£sÄ÷"¸¥²ñ5•Ø‚²PéMK6ŸmŒ\]cŒ-/p<ï@oEö Å KVS¡bðÈóÚ¢çî£>ÖäMÑ+唚›äÿ&ö½ÿwÒ+¦!¸ê0Òƒ(VýÿoZ½}É%P‡ ia UÂ:Y [J°ƒá;=ðËÕ\^Âü(Ùˆ@¯&Ü8ˆ€µ¥ó%óãâ®Ö1.4bôý9ÚÔ˜¥“ƒ<.Ò×]¨JX¼¼dv`^`a$oÛÄ‘‡ —¡ «¨Ô10Ímæ –¥Ý l:€†÷/s‹„Km%5úØ-d»Î‰rûü÷e7‹gèĘ^ɾzÄšôùJøÑïœùŒ~{F8DIO)è² ‹ Â7ÿ ʺ51!šÿz-[¦gò/ÍSƒ\’ŒŸ¦àu³×Áþ†1¨K­N+õ:ƒ#‰KÈQ¢€6Ò`Üì­¹®+—OeÄWYíÆ›¾…“„ÿ:{ÿQ|c–V‰\ü¸ÐËi¥º€ã;·0)AËĶ<LÜG,¥¼¿íU÷(`v›M){ʲ?ýŠù»*`â §öÝ zlÑÁ ȯ61#{¸xì”æ$Ç›³÷¹Îã ©|üÌr@Ÿ/ÆLj¹J¥“ÝóÈzy(蟾xšT›¯ëÕƒÐ;Ϥ<À¯ $cøÅBÀU£†eÛ"Ñ?ò0ò×–Ç%{)è!Ñ…f¡+œÄbò¿í«eéB5Ó'ÔpGl±%˜žO‡EÁÚKSW.YÂ[%íIÖ²Òâk¼ÿt\ò¦ 3ÙY Ù…vÇãÏl~XÏ/èîå ]WïŒ?–êÎÇŽ»sáðýŠÒñ ·Ý8¦xmü ÓÿBb0jz;¡Z÷==±óŹN<Ûâа7lOQ?Ñ"Jéã²U=gàUEÑ$º›™õdœ:6͉ ¢Y\ö«²Æ¢XÓ‡¨.Ù‘úl‰O8¼ÿdç[iEЙõ·«E^¾\ zœŒpÏe²¾ú,}Ñ÷†J4ÇÜ#p æ >£ü @©•-úâýpõ­{ˆ>xƒâI¡!ôÝ«öÇDö@{\”(²Ò !ßI{Þ™ JÜJk±¥gßÍÉG쬲“fUR–ñFnšvÒ¥½wWŸ79z ¶îb 8ö¤šÕ³gªftúz‡7u¼ØÑÆÜôì–«§íœ+yAjqïkeh€Žˆ$Y#)¿] žFY’nsš¥?„ëÂ}î†;ýR\Ôíh}‹.aƒöPpÆívØ$vfkôèïÐ:>Ú|b©·D$¯þþp1üqªïŠY°(7»{C°b¬&”¶½¡| VãÛ>#! ð}µ‰†0±,¬|¥2•é>ÿ³ì¾chF›²ÃG^n‚"Þgó– s€ ëü\@6ж\ìSc©Åz²Ñ`j*žŸ)¡'ªª~‡¾hþ šsºJ5ÁÙÁt¤ÓŠE›.ðçYCaj Ç«@ü{ñT†u¢ìßΩ ¤£6M*–Ý¥újJ°+OdŒF1«‡j¦çÍ…m åùܲ8ñ§ú|§”Iü“WBZmÜPœê"¹mnÍ_b=qE¬7{¹µ¡=kFö°¬ÝÔŸôH]ƒ3yšDKkŸ*ìõâi%MÁ”¹Ê[Ìžm›(sm³K¼„3íXPNÇ•ÜÚ†T°zëáütÜøÞÕÄqÒýü–ŸUôC¶/¬çm2ïDØŒP©XxûóÕÜ ºœ˜6ŸðS/Îü¢5§jû(á_*pø¹ép†%rq#1äèq¼¢±æä¯þðXJ”ª;ÿßuäÆcJ}7AL}Ú¿},އtôý¬T˜lûúsý`2ö“¿‚7('w»J!µm¶è!Zô«Æ^Ix%I†¤÷×oOÅ1]ižûû³¢XÆ—ﺑsmWå¾Ü¥.†Ï Úº¯ ¢Év9|çºéQ1Š‹ƒBG=j ›UÚvOP»ÐÔÂ>3)ëUS3qEÏ;½4/\$²;îW¶f~Ãa~”ð’¼î­×á±Qk,ÿYyŒÄ€ˆÅ¡;;÷ekHt»9ú÷Ód’˜ÜúÝ­p—Ÿ™Q’0_$[©‰üÕúã;&}Àg¢9梊ɭ¸ß ’ÀêÝ €ÌèXa„›Ör0ë±%õ:û€d†ÂªpSdìCQ÷ƒvõöÚ@éjMic¯ ØaØC+»æžãråÙË*œˆü]ÑhƸAP©Sp Ðh‘{Ì{X—ržþ‰¦å#Làf |D@ž¤µˆçYŠ‘0<"îó@§|¬E$)%«e‹Žšþ:¶Oyä×GègKN÷òăÝ2=vF7„/ŒxŽ€Wú’ãR› Ú^¯™>P’ÖªŸQèðuGä™fJó¡ñû3!‹´C€uÑר¢î꟤b)‘|Ô"ºÕßÀ wt÷<ÙLq®KðQóPÛ“ˆ”1ß‘!_½•¹4ydêþÕ–ýX“”£™Eˆ +1!]îÁåÁ4ïÐ×8^áî"ߊÿÎo`ÿj†Í•7\xÇÌaV›ê%H@O4{¼DP" J)ÿxY}˜±cÔ*p \Cd¾ƒBb÷]q˜á~á~á~á~á~«PçÛE‰3í’Ì,¸DJi€ïd´L:Ò `¥’#À«±Æé3«¦÷>ÊwÄÊsÿ1èÆQ$ß¡Þ(g`v¸ßv±œ¥œ}úЊ› H æ4íOõF'¬ïG6ËOרiç4ú[ŸÜÇJ~‡À;&w*˜‰€Õ,:•탗{J¾o=¼qžŸúuB¯Ê^þÔìg„÷À4Çiú3X쫛Х–î–^´èÈ¢*Ø×ÀS"ÀºÝròâ(&XJøCÕ1‹œtL‚gà$yhÐÍÚe†e}`âÅr?Îq$¿e× ÝT-*º´Wùé8¦UKrh浜T½ìoîp~SJ«˜ªL¢¶™ú›·Ô¥×ôìv¡õ ¤™ó5Qð‰pHçh°˜“â¹v"—ú2„ž!§,àZºçÚD}ÊÆF7È„5Màc‰ô¹ÕAx x‘ÔÖvW‘!¤efcCî{4F¶€nzÿX˜Ü¨û½È®Ûí&^½˜Tnñà::òPö…s®šOcƒ^t3Œì–˜oš|'¶.nDõâÓìMfì3r´Eu²Ž¢@óïký÷dÏî.3à0囪¬(¯/OùýîÏT·p¾7âyêÿSðH0@‡v®è¾ÉÌ}ÕêÂàžÏÀz3‹|í6"OΓ’m?ùb´Ä57¾“.¶UÞiÙÌãøjîA%R#´iT%ÖHðçªÌ·…:ŠZ®2'ÿ>˜T¦1Ø T4ÃÀBMrß*áÞûlu¥ÊMIa+»HMæC#2~CIbëÚÔ ±áÅyí_‚ë8@)?G ïô4· þÍ2ÑÞʨE0š˜úêžã3¾œK©û—Sx©Ù«Ð3 Z¬ßóÛèÑì /¶ðǾO¬â³1¶K«0 ·Á¡;êfïîb .Yá¬/ësZê”ï34æ³ÀöþbZÈ¥3­r¿1H‡jcïÚ¤,x)f¦Â¹½¦£®‰Üµ!¶ê’­ïïˆE]ï4É&ä‡Ãñ :Œä+'í$ÎP@!éÓq7©Æe§J(V¤iiáž¼Uöm÷ï[}óUÀúýï©~ÙJ}°¥S|béæÍºwc®àœ*[Q­ŒÇ$›*ãÇ-\0½ræÈ{û½7†\ (ʷıS´é1{5hË^óër¢Î×.Æ># ïVðÉ•5µä && õÁæÃK"ˆc¹iÍ;NÓå²ë‚fAýr”·Ëñ S£ˆš(IÑÏãìeJ ¥RvÁ/…bí˜èÛ]NÇ3­¶r¼"I¥ƒ4jû&Ù_`çɘú‰ôg+tñhpr˜ÛÔ?½ŠB?9û¹…¾dÅT~£Á÷ív ³û°D9¹iþ9¾X˜±}÷Û"ݵ,݈Í32åUtA%ÞÉúV’GœnòÝ]Áb~l.( Û˜Y™ 5ò³·øûíiÛ 5‰JÝ</Љ?ÁŒLÿ~_Ûáî¢Ø°ŽÌjÕ{¸¡øuX’OPÿlJÉ.òe1îH¸<×­/t’íèj:y’>ž,É~YæÌ»Å—ÆȄěéêO@ wÿ~8رÑhpAÛ„Û´ÄÍ%#aû£ÈÉ>ßÚ÷€Ñ® £ÛëÀÂ@ŽGƒA÷ŸýW¥é‚õ0á}Ž›Œ·ÿ²í{½×q!kzD™Çɤ#õúÆÝ±7œ@™ÈÕušrhf¤Ï3ÿ%“f›8Ëo 2 `_Ó²«ã½~>Š é?°üÛ.P±;}‡ÇÛç龬û£öüKÑõƒ+tƒ”I@‰%ÔêlQ·OB]c›:®>óÔ;Âà/¤èÛ/ãÛX“I,;n6†°Hã…ZçÉd <¬0÷+‰‚ýšpCk๛›}.·“9Ö.n’…£Z†ä•7›ƒWøn3Uq{ ð¿ ð¿ ð¦[Ê8Ö®Pá_ÿZê›(0ÅwT jÄÕêælæPúnVÔ Ó7H ñ̨µ’çû§n–#8³ ƒ0%ÔX`žžnü¤%§æ‚–§gìÉcdݲø†>ÂÆCz¿ÿG>|Å90ó/X!HÁ‘inK köµð1|¨sµ¯ƒ½”Þj¸Á± k¾Ë…çŠðB .£(*îIð1ñ¦[ú>|ôˆÿW åÒ€BÓ²6š´iGˆV'nžw‡^T?3ïCáœ[Xœ̼¥ó7¾c•½èXŽÿQù ”úš¸BSÉ+|J žË2ñÛÿ= j'Òbý³ŸwwY‹§gÉáþðÌ :æH¨{½øv…sè³{'gÊR"Ë’/AýW ù)[Zn˜2É Ú2Ž /GaQ9C¾€ý–ÿ5 ‡½+'üOԃb:°­­-fòE~šéùÊùÐ*¾É —IúxV¦'`½xŠKxI ”l½Y¥Ü‰‚…pJ£!t×îX9y—&‡3”í²…/‹çN µ±Æ¦cßñy›6äŇëœê¬Ã‡jü}º $ ›nA?;Ñò>2ÍÒ¾ï½vrˆÜ¤f_Bôü&]Éç©D^§õ†1_3rÑ”4gd /·dØG;è[…®[§¿¸/чI§·;ÈÁmpTsUu„øªç±)FnÂÜ×W ¦“o ]ó@\Mê:cËè\3Güü)W®\„qÎ;á=b}©K÷ôÀ ÇßµB`rN±ãÓ×òíýÜû•ݺ;»?´¢°ÂRÜÓ>_ ɦæR0¤?Y)¶ª n4Ë~ÝÃp#\ù}¨pñÝC\M”VuÖµç•<§71£öäÐtׯ0÷¸zMìX—…ð”B³jä «Q-@+¸ÒHpH̾…–,í(㥷’b•­ÞTâN…å©Íò?Ÿ¬{üïëÞßr¸ ›ÒRêGQTÂÿsW÷µràŠbÛ\å|ÞáíXû`ý·Ë¥¯á_›‰x2,ÁÎBlºöÜcëñ( Ɖì‡ä$àÛä¨A$9 O3>m‘Ølq‹\ë÷L·øÕ©HÖþ?஑˔·ò@×ÁÕcMI°@lh'ë[gj \%áµ$ÝŒÎGy%‰¼³«²øJÏQDåw²¡éh“*åXD|ëF먢g¦ü!vÚ&olØá°LDR»iYòÓÿ?fÎ[«àôíÄ[Q+Ïî Ò‘îޜࣦt m²xx™Éëb³>¹_¼å4ið-l©T’!zð1¡8•WE)•也,«87Ë5à E»!Çîc¢ÿ?ÿ"®j*³Ÿºî†眖Wt¡U¦÷Ȱbt4Ÿf+4WÑ€­KYÙ™[ Æ sqÉêB¿ÕŽx‘ÀS‘E@BËõiÿqŽ32âHö_j:³eÛ×ßj¯Ü/±F’`ø†þ-í)7N„qÙ²>@ùÑœ\ú0s¹-ÏŸã›®N~Z8ÉE–ZèÙŒ÷·{бšEì´ö˜É»©Tca­þâÛƒŠòq i=5x¹b]ßVSd‹üQÌ~ì¹ø?kÛŽÞºåÁ=L¤_°Ø?èÂV ¦ú,[a§‘E €AßAt'Ÿ¼,ŽcJOG_¸m”(Óìîø$Ê&î-¯Ì[†žp>Ý™ï]Åtx­%\¡}`cBk+ðT€•èJ`}ÌXFžê8ØþÃ~i¦»Baiôó5·—tçì_{„Õ;KËV7íðì¶RóèÊìßù&$i?ÓÄäd$ ºìÑŸ»=Nòû®ýAT<è’bh\ ‘ ºáñ9/P´h$”ˆv°_Ó¿œGÖàCH4’ÙtœÁN×H×]À-½½½áÝ‘V>=}öüéØÂ hþ1ÿ4.œC.¨–X­þvÄ”*w3GÝÌÝÇœdõÇE:›§ú²/WyOýúU¹}S¦\ò¸ªÿ6¼ì@ý’Ò!‘çÄÐå’ÚÿyŽŠQ˜%R¸<|ÏGc¨$ ÑR?Ý܇9ÈÓ=–Ú/Nz{¶]ŒŸËÍ"PQ;¦‰x—öNÓïé×ÛÉ3<‡ªþóQXo"ƒX I¾ŠRáæ§òø@™‹~¼žKJŸ´é¸ªõØ+YMמÄt•QÇc‚ÐU,qŒEò2ûiýß^ ‘®hv7ÙÈ ;ü E6›É"§wå8^.,dŸðWÙÌrn²Ø®p éêÝ.ù¦+%Ú´xQ%…*óŽôÂçU¿‹sã²Á>½ðhu‚ºO†àÂN;á^c‘»#½6Y…$Øã¬ }W\q!{ô{bn/™`:í°åiƒ—º‡ ˨xSMq~GlQ™5ù£4VÀÁë<ú/ƒ2|“;P…T W+å4Eý4°§xE¼}n…ý‘‘íÛ˜•+² ÓüB € f X“MÕ¶%9úeÏvFpÒÉå Ü{ +Ï-zqçbh¢÷lPÊxiÎï¾S¹ä® ̉öÖ6¤ù8nª¿îXÌ]á |C¡N7“ü7õª‹§õýTñÎY6Jˆ@ç(_yò&s¢e;Ȧ$<‡— ·Y%VKXJˆÖˆ÷3¨ é1¡«¼àt—›sàgÖÛÎyfî^úÙíí*¤ª_ˆîE;ÐwÆ…J‹zjÈó°rÉ©}þŸãCìPXÏ4Ld±ïUë˜éš¨ô X †˜i¾!o¨ªÁ²äÅ¥õ ’˜¹dªézŠ×Ùíê)hqþÄm/áâ:¿¢)¾ö–Î¥·Yæq›8&hfÔ—® ¿âÊ÷Ëøa|ß‹ÝÜÈ|@Ó^£ÂÏcdD‘å›7Xô91 d”¶Bu/wÙŸÒ ÕP7be®k¬ë9©ãR8CÀèB¨VÛΨ°Û®ÕýN§J¨O+v€\á3L¡'Ôãâ3Tã8¤ÿ÷U˜£¼‘°!c-ÈÌõ Õ¾Ú½3?S¯²÷ã¹pí~>¬t—;TˆÖ¡8Þ¶•îeqœpAW ûĸB¾úy©lÁÎ+Àïï0nÇçu³Wæ!ÖêÇ ík‰²·»î¿IË¢ÞÁÓ˜r¯’Û^+ÃC·f¤¸ ‘WPœÜñËT= ÅÿKe½_²67kyÂ*\º_uÁüjÀ¸X\t§f¿]TkÔã`<ÑLã¶ÛÑ*” äó"ng= $vä~_Ø¡HXPiœ Ú(Ý[á>ùøP@*‚3Q>ì ÷pK®Åh®U ã7MFRx}¥`¶,4Ç* ߸ÎàÀBÌ€ÁG%êa«ôÞ™†kCäiö ¬Æ„8*´0oN·ZË „(sÖ³èX8Õÿ™Äd`RxŠ»g`/uø‹â P^–<82dþÚ‡ÜDŸ®óW×Vnn™8V}nѾkÞmMЪŠÌz+Y"ÏÇb±¨q0C4 «Ñt2Ò=FLGÐ3Æ[.«!n°â{ðu{äZCˆŒ²ÐÍv«*J0´ )áU4"1,‰knò7ëø`ݺVCnëº5*õÔq~°«¢øŽUçY9©½Ì¿zÝ==˜&@鯔ê«RÚ5ÈÕ{4Ïj˜/†ŠÄ ûAÝ +ù6œB¶“­×T„,…™Ü4†öùƒïÁOñT$¬¨žpÒâŽ6ŒâÉͽ‰CxO«Â@­K£sF®Ãì_Î0À6#Œk¨#ÛÒGíé“ykæ= ÈÛ…èàø‹Â/åV.áŠq‘™.«ŒvŽ8Uwäà£bлdÕòÿ")-³í¡ž÷"§\QioËC=Ì¿…L2©P u_;»ÐlTcÚs¾Í]°’ÝOŸÞ¢"&…Ah§Ÿæ±7%Ð# `ø§ï[Âa|"•µ¶]ã®Óm%ÜH®Â})#@:¿b3`žÑLƒ -Éb-¬Êi-ø$Š,ËœÝÔ«dº¹¾Õ¢ê_OBHæË>«Á"eÂÖz^‡t|ÂlF–†'M æÜ¬ïx-û…ð„þÀi”CŠ?F ð¾õ3Xw¤±©†Óÿ]#y”gnQª){~ ÍlÊt•Mè¶£*U®([€Ÿ1™Óþl7Al}`péQóÁ °ìq±Q–¡Í+¾×ÑCÛ?_‰©øôð¥z 2à|t%‰†Œ¡6€˜ª§…/(!ß$È”EëÒû"§¹\ßÔšÚöͯïŸi¥X™*œ¬Ä¶wG±–î›ãc—É5ÖöR•ŒfTPýŠC¹7 û©å·”œ÷¸ƒH1ëSôY@OUKÓca,%—JùØE2îwˆÁ¤V[l-dÖ>”ѵyÀmÈ•²yY¾¢û× h½hèˆÅW¥´%†à%a@v< È>‰\’gBèŽI‚¦ÂJ%²H‰¶Øš†·ÿv £ ØóXÀ*.Jþû¼3úá™zˆh/µ 5št¢Ñ"Õ.f1y­ÌU‚M@¯>ö hìP’­z-zv¤iOBl3pƒÔ=ñB'pÞ@ Øúª¯PùLŠRÿJÝ{o„„¡¯_~îIÖGåË÷µ²ãœ1#ÝQÚ–‚(÷æœ&i"O»ýÙï–kE&.DEÓÛ˜ãyΪÌ:sv¶èƒN¤ $—ª›Â¤w݆¿r›_°Ï£“ÓT–—BÁi&µh #σ©;Tnu€WŠÉɪÊ6ÿ}gFpQVíú(N?Ak=%¿ë|ÞÚ¦ý#eûo óö$As 2Œ·er4Bî¬ ¬²¸=°>lבdà5ó·ãã¢xÃö›UÈø„©äÖŽV1\eþó]»Î³tgÞù£ØeäÅÉQª~ü:¦pܾ’á#dòç®ÐÁýuæÁ²¨Çý6osÞ Ü¾›y^™lv†_/-e(3  B¸‘oËþ÷ÓÇè‰]—Ëe»ú–¯¾ {Ko²qܪH¹€¸±-äû¦»ÚÈÌ`âÖèiŨų¿»c»¨ÍõEÙÝ[ãÌrù¼-4Ç ¤EÚÚ¹§€n‡!Ÿêç. Ä!̶Ð_Í/Ó÷ÜjžRÔäòÜù§îugÌkä­9…—ô»Æmd‘¹[”;3Ï °a¸¿„jÉšì»A þªŒtîÑÛ¡9JÂÒA_ jÓ&À¶Úä´roâ.§‹#ˆ˜³ &h%ÂÃØ<­§Š4°øH5rjGL!×[q©õ6°‘ÝáDé1 Y]„v0ø© i"5IÓõW§I 6àŠÏ'·á =žx!öÀ½ýjéÈÖ%¸3*MnÒJÝDwQËÆ…ÿ/íï]„ƒÝº€ ¶:܉q!* ‹xQÀ8ÂAø OçsäÁ«"xß`„„$a!®žª)‚6¥=Tç]¿%׋ñîïu|5Ѥ‘Kt‹¸¸ÒnʆǘUøRÐ’Ù¥¼–Ky™q>^r {—ì’§Ž\wN )e´ÍÌÃU î)°Ê˜É¸S‘/Ƭ¹á 8ÞKA½4`¸Ó·ÿm@€?›(ú¿?+Óº=Ç5sÿ{Ïï=¨æëÞîÄ’Hº@ ²$æE˜ny±w1-¿’SeJ— “`Õ4´">xo¡„fúAG°#–ˆôÿT2jŠœ_3´QÑ¡‡Ü˜f¹Oè'I›Ô—1·}¯’O ½}q±ÐvdÕ—iS•,¢ÊÂ)jÝ4l¢’Ø]Âé¿{³T ªæˆÖÿc˜ÚÞà[T…ÈÏè°›]æÔ5¡ã>iÄôΤúE– ‹´q2wûm+7b-?’w³ÂP| qd”O3€ žŒYç†cË«:ò»ƒÃúK¦œÎW 7¤0b:óݨ¿˜=ǼˆŠÔAIaܤ¶k*í¤øù½.ÃvÚsóÈØ-à]b@euvj ¦¿¾n¬œì ØÚÿ!;ùßcz½²»ƒ%a¡ŽOyÅW"$\ÔV´–À­3ãò ê%Ât†ccDV™"à÷·n±Öµ=èÖQ³·€Ï÷ÿ<Ê#7|?Óž¨ðИ¸^âVAì •_„Úµy,åÍÓ‡ÓMþå¯%Í¥á¢¢ÝÆg •ó¹?¬“³=>#¯:Ôosži´uá³ÂU›—íRÇý@*js}sÊy½B&$?ïU—Í¥±ºØ8©§YÑ7HC©ˆ©*4÷¼ò€áÞ]ãÂڤ#ígš!Á~ѵá{}CÙQ;ð…Ed¯òVR IκGÞ$6dÌÉ‹ýÖe1A ;Ei®IIéä,Ë_Z~e¬N±ýŸ©_¬XÄ…có&¶ó‚‰Ýµƒ9GçÂZ†C’[ˆtùz$ ÿOH³ÜÙ¥^Ø‹F†0¿(í¥\KÇÇsoC^T9µöu°M N¸k» ûø1*œéT W-ÈOˆö°)s x4Þ+†A„r“€áf‰·+?T[Ž]vr%lm8äÕDÔÈ›óÒ‚Q,Âb3Q-ÛX¢~#3ÊdØ’¾ 77ÍcÄ6š%K¦!ƒôf+´Þ,H¬¹ß;òÓÛ­ƒ›èÚ=UÄÐûížcÿ]Íh<B6$XHœãu!ò~µë Ùg½QýM³pÏésR`ßÙߵɤ›­ÆCä–óêƒfÒ@Øßq²%iɱ¼‚ý”Áiƒ>ȇѕ¼{ö¼ìª·Oü®>‡Y&:zŽ í4Ÿâ+Ï–3=ø07åÀSói¯„àµî+~¯3æÈ$é· FŸ±µ¥2iÀÞ½ZlœÇÔê§¶`¤À³Ê©Çµ=ò÷B‚&Y(·½’\q€@Ïn o&¾,CÙÝ‘ÁNOäÂùs2¸0 å´ÃXïT™“1ðRIM\øÓáIGÅ_ðJ7oŽyyv­¿à(ŸþÀæ¯ß<ÑFjíÜÉÉGÆf±ðË6~ýó—]ˆ›?,¾{€‰)Ç™$íÊÃX® ¡:ˆÚ§…ü“ ¸AuþÛ¡ªÿ([ A2½ùb±–ú,:F ¦¡6a-oÖFvV>¯a˜žèi Ð9v©s€¥Ú1ù‘M2>ˆ—r &Œ‡Ü›=0—±\búÇÒÚœPN¢DPt ²öz¶ïG[Êæ£ ±ÈßðiDžgL)‡15ýìž Ëˆ©zŠð^Ëc˜rÄämI¢¦Äçü»¾L¿5!¨ªØÞ€¸Ä\ÈŒ»SœKö„NCGRFåD)ó>Ú¿q²'HÙiôÍú¦t7ÖÔrou¸±O3þ6\ˆdãX-%Í1m&%G#•a,7ÉiÝ…r,Ú½v:c˜[ýxʶB ´äw ×ÊZ„‚bk|WŽ´í7«±f’R>ê+~À½Gnº5(ZŽÙ;·šeZÈ’ÛjÐI+M9ÎU–jJ¿˜ÑZøC:L&2UZUÞáôþ¾p<Ì0ìp—OZ"9 ¨‚~LÖ+„xšÆ¸gÖ‡öd’²Ynôç§x¡s¦IMËÅÜrÔˆåZPäz#»ŽJ‡+M15ë„e‰Vƒ #XC>S+*’øQÌn8—Q!ZñJ›>ZQá(¾’¿ IÚæŽïô&¥ˆÆ}çûÎ\¯åŠXkàXˣ롯+‹(?ižì½}9úMR<4ÖeP“ÿÛüà@ð»+U»í¾ÖG:²£`Á飦,ÀcTÍWå:½{£–x.ù¨ÜÎN±=s?º¸úø¨ÇäRUR3)»Ÿs¿¬u|Â÷Ïÿc[cÕ ·€ÏÉØð¨‰xé°ÝÌxåº<ÁßC¸Í¼ÐÌ#п\Q Z¨X¬"Óâ 9y®“ö|êö5)“UÔ ©q äÁ‘R¶ üF$èGt•j—l.¢â´ølÞ%ÆÛ$pyYºA\)d‘:CõÙ€£¤¯A Þ,“KN¢K¢ ±sè§”ŸJëâ1nÍóŽ9£ÇÚ׊ŠG‰ÑèdÃ$гB#ÁháŠg²ß–£¸d´òp™wÛ="ä7BÌLÆõlŠ/\âsÂʾ—n¢JðÁÀŬ ß™k`oä©W8¿ý*²ÒáZ¡m&³Ô`•Í-ø<²© àoSè ©âL"üø‚mhñÉ;dtNêEOì€)´]ä,Ûƒ{ËÆ 0±Ø:rÁøð"}¨É¯Æ/±_¹¡ãC&XÊuÈþç‚@…]Hû'Ù·ö†ÖRä3`±MvºÝ¶àYKbUÕ£¤1(0DxcÛ£wO~$uÏæ¸šºTÔñeFeÛ!€'P3(eÉì`™bå¬ÿw|rŠ\¾4rþÛ̳ìßÔW‡lb(œ¦”Œ¸^\–c+·ž~N’”ÿ-Þ1 <´á?r)qÞÚ¨á&7Ó¿Î,>ÞŽkD¹®åÒês6©¦¢°Ä}‰Jf´ò‹Êðµ²¹ñt†°s»2” Зí<Âhyá¼dy¯†|˨+ª‚‘î=ðÕ–¢®gžìŸ® tzyÍQ`"¾ïrp6¼¨\÷çnTç;¤µ0Â,ñ'ÁŒ8$ïXL˜ã·Ó]¥8Vˆš>Oµyû »ëúiE9ÿ©‘®;œÄ•P¢}'µ5åZ¿ù†îO¢ý4“³2J:P5+ezÍtYXx/ÆSÄ[®ÉTœ+„Ü,E·tX*¿à)yC³S—¢š$œëœ»¯¥†Ojøå¸Í{çú"n‹ýÍ)•~£q E3n˜ÀØ­‡Ñ­öO’½jÝë:[Ø H’ïä¤0SbÙÔò¡-)Ú½ÿj ÝÂ"no…›¤æÈ-êl2’>½´¨œNò&ÉMÕíפø& W˜±çUëÞè/ubâ3—8âL°@ɨ'épˆ ã ª¼@¾_ŸÎŸö‹¶õ[ÑóÄL34;(–¡.úÜÖ$h%ìb„LËÃ7ËÈ&ÞŒõÇ(sØW{9i¸‡›¡1çÏ4žÁ-Uë¥þ<ƒ—µµ=xÓF;tñyëìþŒÂ-›ÁÃÂùDé* :ñus_ôÙ'©°[Hîâ·ñbÂÄDMœzt¾ÖµÎߥµÓ«ž–IšSí;%ʶ„!éëCd-úÛƒ¯Á‹ dÈ;îü™ì{’øÀg¥zÀÛan–ÝØ;œ†Ÿ ×$0N‰m!ŽÇ¤á*¶P)ìM"|šó1J9 eâɧty@Ý€:ä¥B®ò0oÿ+½–ÊÉMøo{áî6kkBÒ2C  ’ Ðº±ö¨¿œ¥kUÃýC5Ýï¾P™HIúáªÝŒ[Ù‰ 1×=æc«\ó î…‰ÏL_(ügW»›X´q }ñBèÈ!¡@ª"Ì>0‚ּǪ0 &CWv:×yqÓM˜¼›¯³Q…gBŒv9ýøôð…Ãk™˜—÷êEºâ¨ù=öË™òv.„@3)¢˜{½µ[ˆšläKIÎÍ64¶Xl‡ØöÒÎh´b ‡%ŸFttÿÜ ¾Q:ÿ ¾A­=O0¦ïEˆðŽvÏ¿¿èp)ñŽêÖŠ¸(zcRΑaì ÈXDÁ—›Ô"o5Âö¦%ˆ•Y¢i5I¯;Tü«šÖîdƒæa˜¿]eC¯çœ µ°oýì$ó2ûœjÕo·±ƒ¯Eæc'Wïgö0ìr¦¼X¡ˆzÝMÞ³ üÔ€#ëLM!ZžUo8/-Áh³í€çý0&ÍËùÕ±VX‡!ÅÓ¸IþAÒ•Ë5¹:ß4?ÄsxÏ¡ÄR;†\¯ArxÝ+ïqÝ®}FßP#‰uZPÓÇêGqÎ{‰0ш÷.3Rݲ®<îp°Ä2^ú“cR'½ÖCcL5Ñî7ªn@xùÍf¤Ö©ìNú«ÍA0¦GÊ(^ä8Ù­­ìôXïX¦Ðt9ñKŽ…ÔÓ¹¯LÓΪë“(dîÄalH[Ým›°Gg× !ÜÙÎYt‘”÷;®cX)ü¹¿”»ºÜÌé ÃCô°ÊaÒ£M¡ïj{€Entq« ¿5èñJ˜‰ç\wTNx³ÈA ‘o}Yÿ %>b´–Œ‡Âå@ºN¹GpKz“ïOx?`H²™Úã/ðζ¼íCVÄÏŠä…F\Ù €Ñ»Þh$?ùЯ 4ö»Áøð·b«%Qù*nbéE·äç_ÿ^Ž‚BÙ}ᬷ ¦Â“I[yàèm•ך­6íÊÀ¢˜NÁ•v~2¸rÛkõ3øèj-°õ4åaZ<á1H(Ddßì±ÔÝnô. ĶHs²¦¿v(`ê³Õ•³ÁìJ´èä]IXí^;a&r¥ÏéˆÿwÇH†­'®ˆî>~¢&0ýŽð>2&ìŸÞhÂŒ®ÄÜg+«‹{†Ó•FƧ³ ó®)h>f0?½‚ƒ#ê}8ÖCcèª{_˜DSFŽ }ˆ„7yÍc¨¬«<ÞÈ{Åk¾8?Áx81 bÖ­ iù Þ”å+ï>P5ÇÌžCcÈðâå[çoV{cžIÃíš.u}øTd3&µLzÝX\\¡£p[•“Z{ fkbB ÚiKQ«? ëvtxDq«¢Ùµï*ËÖ°.× ^lwã¶…N\ÃÏ j!&tüMˆƒƒ³!°i5\qf«#f¸ó dôtªu =N—¯@– ~&µ¥6!òÓºÞ ‹X äýq’rIú›¯PÂ.€ÜÈÛì«AcÎXp˜ïôç/+ ª}–6‰:È@Ù&B O$.³5ë<äÙ;o[zë’ºNE\ËÒ ‰@¦en²e?~ƒ8ð¯ÉZ]¹Ç:Âÿ<‚ë])ouÇæõ ÎÍØ/ÂXœ«£€­ .8€œÉ¦#*™Ev@®UW G¥ÿ{D b€Ï‚“/Æô²`©F!çÝÿg™pìëì-h}ñÓ5j> í·çÔ/˽ ‘0tË>„dc쉯aª!Œµ–š$³ývo7¨zWvÚe9‘nË(çR/¡ÜýcÛ­)™çÃq°ZùlE€¡xö² ¬çû±ÇÖ2,ø/NIWt¿þy Å71S=7ȆáÝ»NÝ@†óâßòüå C2ðáûÞž÷d òôßr´±&ȧ¢eÔõ³Ùq#qá;ºͼ¾¢Oå) ºeìökäUF«8õÍØD¯Qð´ ]ˆG&U@ªoí\Ί`×ø'}¿Î/£hg”É \+]A‹æ¥Õ”`O£X7 u nÝS•+Dס ð³HÜ"t|‡(Q~3–Lj.I’!Ôó˜™7fOCê­œVoçnÓçú]!{U¼[‡¯a ®os€ç¿`³²>yÛ  ku¨‘ ²+Â4.¢”j"£Ìž VãH¨y4F“yiìÌeÊ$Üëœ{ȯSçÖÊ’Á¸ Àu >'îÛ˜ bÆ»òy¤HÉbÙq´?6¦ðFä®”3žv6°?ÐÕ@°ó¯  Íù1*³•újäõÏÑÕÑÊûõëð‚Š6šl@ø²[Vðà5Ú? Ô­Fgf}°µÉeCtù”'•šP„Y{10öï3øÓH³ôß'>Zeh ^ö¹„ÄÖy±XÏrEå“ýžßùí<{à¼fGÉâ8¶ÜGâ´ª÷óÓ'żnÆ A`€h5ÏÂ06Ä †(bq]­Ä_Úà ‹àjA4ÝŸÌ Œ]”$µÓ¬rˆAm ,U ªaV¦ý%,îìXûÈRlTÒÍk~³Àü®{å;Œã‹Ê†·¬ééƶå_o‚éጦý2$ˆÌ©¼ Œ ‡€ÛůÙfª]!Ý~IqWqÙA²Ð±yÅØvf#(ÞϾ²Õ&žÀf%S‘2bù ¼ð8‚L3¤YÈo@¨÷À@°°ÍDpO™ùÀ6“̇Í®ri¤ñ«Bxͨ^âRTgú’¤ò™‚¤ÿ}ï?dF„ (Æ™A€/&730üGPfÉ_vWý´²“&ž@¿„_/»óĺñh/ƒÕNvïƒsRS•цß7hŒÞTŒR]ìEë&êT4ÕùŠÑ'¨œQ§kEJClÉ¢‘_bïƒÈg¤Ôïôž&Å/RI•$ý22¬ý3ô«×WPÊäÌ<Pýh„Ü‚ÿž4ÕÙðm`»ÖƒòÖÀpŸΦ]'†)<³^炨üßßjpXÔ W¾jRå×ÜÄ£e‘·ÕPÖu‚¶‰tSNCò±O÷4ß°ÒúÍÁëÞ[|±Kbòº(Œä•ÏNFw R?OÜi±Ûc/°DÏ#;µF Ó È ‹^þe½G‘yP"·ôû*¨Ü™Í!3EGÝÕ°•ëð fÙÆœvS hø.– \²…ÓÓûÇòn¡ßŠã‚‹¢Ç+¡Ê>Në­*0n4 MÙh%‰Iªùn‚¼¡©äNÛ<¶V(ì¼Xƒ40‡0=WPâBPsæ=jä öMÊì§ç\ó ñ¬"Š•›NÍ™á²xlIßÍÍäª2K[ñßä‡áq§8úÌÑGFT¯ö‰1Ñ0¿Eà'~¸ÖNO§[?jÐulÌÿzõ¹°©} †m¢ê€Æ¦¾Ã7“Ú¡³ï@3—×ðétÍÒ É»‹Ã;úõ¶- œ¿$!¤fK«YË¿<×÷áZ!ù 5•Yó‰×YŸ4y•0KȦKš‡[©¶GW/ø„Wð&eR\¸¨Ù,IªJbì¿m{¹‹^œ¼twÈL&˜„ffî.U Ú6¤þl·|Ôs|0û"ŠKÉ/jâÒ·TNŒiMŒ^$iâæåœiLw1¯ 8r€G &¦û³•f^˜G¸®Tà†A^Ùñ³ß¤Ï„·:ϼ´ÝF8Ú–Ã ùŸú­LÝFF¯`×VµléÃÜ­Ÿô«ÝcÏ~Ÿv‘5r/åá ¿\b¢F‡“TÀ°¾ÿ„¤ ä±XsÝ'ÎÂ*Þäø@ôÕæ€Á8ÝÁ T›—1y1R0ÿQÿ Â(Öë6²@ÞYMû56¢´Þ&g ÇLFShÁD®JÕäÇPYV§dr% ë¦qe®2O‹ƒxÃB–U+οG;ßœ {ûníN9…Ÿ›zé}Ééy§Oðî(A:ŒÅs´ž¦æ}ô,Fš+ ‹)2ôW:ðïCó8Ʋ®nñŠ´ŽÜì‰c¼ ¨]Ÿ}4v [ÕËÕ•®à¥ÞÇ·õ'êû.Z7Öa÷Ç¢ÑüaþîCØ“¯ð;Œ¹Se¹ëêñ¿_C(&-=Üe{T5¥-lX¾ð°ÙéÖD-ak0Åv›:X¤oûsnNF)Iß¾ed·‹P˜o¡—.m *„¾‘÷ñ™xàZAÆ,'tÛâO³Z}³óùš7qAtav{ Ì׉–l4V_}=“?+ PÄ<0PcÔuJ²w5jp·"W)Ôt¯M¤Ý»ë±Ct\ÿT³m1ý@v^´ˆ„û(uEœqœ‡t÷ ]•Š>KìŒÌ·I®Â¤~ÚôÏ@fáŽ× <`[> ®•¦É„Ƈ`öÂŒû–æSõ:sÂðw0ô¹qÊû€ËX áõÒ±ƒ·^ñ6â%ªj”aukáþ*Hò]2ë”æH‚â™Ôü—yJ,*©>f|®¡®3}uŠ[/§ž½qHI¢³âút“ÀœüÑÊ·°a&X«<4}ã õíüµÅÀBÆÍævKh섬§&)Ä­²Í6T¦ ,”úCFUÈúµGÂþª×¡§ñãÉIv2s!ÂÍÅHwR*š`‚h±u¥VÕ*ø™”çE¤ÈM%ü^òõõ,®hd%&_# Ejö¬@+§‰AàJ¨`S>å]`·î¸çKå ú`kÒxd=¸õFrâg6ª²q$Ž%#‰ƒàI¼ÝÍJ9 ósûw Ýè£+‡pâ?]Gê&ÆÜös´±xDq/Þ£Þ¡œ‡7gÊMC÷¢g6AEðú%p©ûvÕ…5H3R£lŽƒ%[ZÖŠ…‹QdçÇ|ƒgç¼ÈUŒ[^»-©µmf©‚»XLi×_øœ¢8gBèm&:»°Pøðþe㧪ö~˜\y Óžë:ºG R…:žŒ?!¬CÜFRIá·î¶!tÂfFxü’d`ŠØõÒ‘`·‚ãñPD7ÊH±1¨=à ³@œyKkºutxRèM9œt†…¯©ª_ˆgနßYˆ4ÇáØ“ï8Ê­ˆv·x²7áÿâ×\cH„\°‘5»•o/H=kÓîwÏC¬cŽ#ôLÞ‘F9vµîÃPí9)ù×afü¦d¾à¨õ?W(B²½C¬¯‰BBó) eḼ 2k³,B–'Ï ýLï½úv¯Ò^|´‰<†¾¸h½•é"U@êXìÇ@¨ÅÆ0—8¾ð‚^=‡)]¾OUã£Ju–rRºþN»ê›ªÚšžxß-P8úÉÑé …Ëî³nY€£{¶-ª h)¬fŠxˆ¾={ïý‹¾?] CºY罯5“0ÁÞí–¹ˆë@ Nyž”£îÖmèXß*ž$%4ªJ±'O@°+¡%Í'¨¢,äôè)m5IÍÉýlíŒñLW+~Ð(˜µÎt™¡l‰$ÙKzµÕ˜áRø¬¤¼¥L’‰¢U0ŽÚÑ!Í2–<1éµN@*¤‹óV«ì-qj;Mú’®­¨~׎…6~æâbW9O$Jõ£’ S Ñ1ƒû‰î Iw€æí˜/õ³nÞX;¦òÿÇo‹ Œã˜¬åØú–;Ü—;§³?öü5²ü5£ ¬þÇ~;[øt1ü:§ßâáÔ¶þßÃt†¸ qþWü5ÏŸá®?ÃYÿpØá­ÿaдú©oḿç¾ûw§øt}ßh7ðÙá­_Ã\ÿC`†¸ñþÉü5þ¥ü5“øt}µðÚïáÓŸü7×øt…ϨømðÖoá©?ÃT¿†²õ-ƒJ'ÙÛ4[cÝSÄì[bwŽ D×—Üì×ÿh¾–øH*†qУІAúŸ+|q:÷ \ÕÀz|î\³Ö*¤91Œ‡+Æ>›÷¹½l;êPiäNQ•+xV3“Õi2wü”² ‹ò!) ñŒjй3-€^="ö ´ŸÈY€Ó”?¶sGár\‰t}þgþ§çxHÂvåý¾Qƒ†`áEöBÊâäš’vi|䈅bÄòbKü½H]ÕØ$ÕÞî½ÉÚGé2ñ q`̵ÀÄ{7„0 ±Nøƒ6欥°ˆ4Cu98.ô®ýbKÃו2ÆQînÀ‚\ ov],K„?&LU™ËxБüÜí2¼åáaA/&2gºõD/ºXÐIÌ}pżí©ªä<"<«á ómÑ F Ϋ°áXö ± \ }çeÒ½O¤ÏÕþ#=x”ÛNr[n^d…çµ™ évN ¨tܼÈLÒT©¥¿+$9±{?ˆ=âi»4«/©ŠÀ@Ïl{¸÷1dð”ùÈÀçñ¾68ƒ&yxtâøI{HzÖ"¿OÄ€×µjbyѦ&RiPn’Ð ü”ŒÚË›Îo[Þ|÷¸ E©ûÈïóbL£I Ò®žpmŽÚôw­6)7ùZgô…45Ã#Ã>ƒ\b;»î¦ô«—2sŸ©\c;à”Í•f¨%+ßp“~ó«¢¼O÷I³ýn´áb¿šEY;È®Åf¡_‰ev‰‰3-éGâ˜6j®ÕW\…Õêá0Q0éy`;cPží!‰#ùíò*< B@·–õH<\˜ì„`¸Ô0^ñYx5Ui£½­¹3–÷^ N=£’}©¯J€_·ÈËjÐóïG㥂 ¤OÃÚ?œWÚ£¥Nj¨¯«ÏM®.M[w›·Mнh>ýæ J³¾¦¿äç¼Èï*Þ‹¤š¹f+fúÐ'Çÿ¾þg»Ñ€kðïõIÇDºY±àe2Ìyp¶õ¬B_¯Ù›èyŸ¥$bë` EMþ!+ø‹–->Y–¾¸7½Šðçö;ðÍÕ£œu‰°ƒù  Q4âÛ„ }c¿îÖ͹™Ü#”yÅŒüMæ*øgè¥e+ì©E±7dIJáÓÿý7øà•©(aEæ?¦®‚„‘·\F‡Àmt1©ÞÑ—<4ˆ«4œÁOB§aÝL_`(ç  ©Ÿ)ò¶ôu¨{ WXu'7´쯋|Ù ¼N¬I^¹ëN今®ÖaRi3ŽöÊÇ€ÿ$þq}– md3ÿ»z÷TOÏΦ9¸®4a׆j!«¦ù-¿ ÿ }ßûæ| 5Ðï†FTÆi…ÀIV¾š (ÿ[y­õÃÓ•Œ”,< ´ŸgñݵÄ>?¹E)¼TÊ*¹C׃`¿lø¬*WES@n®ÔÏà@¸‚O½1ðFžPµC²D‰°f3–`^Âü/Âü/Âü'XÚªgWj[…÷cóð¨)Á&§—¤uÅ ;'çØìžÉšó«ÐÐxìøó .²KoõÞ¯BròMÖΚ]Žˆ¡&–ð.\~°ÞÖ„¯¶yÏ~ÏÝœFî'®¯DЧ$ó¡UðG”õèÜ—L³;-­#_›g裌G‚™9¶(!Þá2F§Ý'f4Vƨ¶¤­–uu[=5<™¿;î0ª ™«Æëøá—”ÀúF<§u~Wq¨fßÀõ“p .î×ëœ2ã¡QEÐJ¨a)تx}¼¥¥ºr/“DƒÐÿd*.¡âÅvDØØi@Ô0óÈòBÜĽZ{¹G( ®Ü¥c„Ý%­¼Ö±Gý/!Ûž/ÇvkKúœ¸beŽu¤SÎ^7µû_bÄœËR¾‚öh]‘ß°Ô¥y‘ð}lQÊFŠut1K<¬yÁ"no¶[fÿ âGüb™òºžEÏgL‰æ€ ɨCp¶°`"éÔi.{˜ L ­g ÏÒÀ’[¯d·ì#p@Bö—{»éé³ °ÇøÁ4û˜ÿ#KÐN‘¾¥(CNFoŽˆ•Øê%wiÙ2„ 2G?°Énw6Ô̯víÈ;2|?Ûó÷ØñÔ¹Ëü†û‰K`ÿB,[oà|Ù¥µþxNqÊ¿’ PÚ9~$Š23t ¾ÆnýØIóîÑ.§Š3|³!cp8*ÛG+*Ò†C9`aµ Îô9Ív¾)~+}g–µŠŸmùð>•ø1YÐ Ò$Õ%ÓßðÇ~©Îb|šaQìå8ݵ¦¢»œÝHå ß“cÇ0ä½Õ¾Ã|¼ÂrË‚õj͵Í×þ«äÞ ƒG,Fó©ï±‘©MGŽ•«¬ÕKcáN›Fªo“™÷A^îæ=gci¨£øÏB!–m(Š9b/fIŠ¥cº·;Kê{~ó@ê„_€úh!Á”9wßQ‹M6‹žP*8)òƒ"™‡C ˆ`ƒ­áb¦Ä=O­ß•åV,èŽ+°^ˆóÑÿ¾dôJ{¿I×/hë˜Íá#°ËcMµ£ÅAÙY&*«¶ÌŒÎ‡7½®Z×(î\·<Îwߺv³]ÍO¿@)vi%ÂT¶¢Vò´¨† ÁOѨ‹­JyŸ0’C½Õ•Òï TúÉ6Ô]†Ì©ŽUá?ù¶Ã&ybQ¾;˜}â×+P>´2ÇeCK®u ñ\¼jÒ„Bs+ôœE‡£kÿ4‹W¢Ælê8“ü™7Lö±iý)àŸW,ëçY‰ k÷ØVݳŒþ€?ogr$\ù&½@l¦¹…¥åé´Jjê~Ï!7»Ï°nöß,Îõ‘û¿_Ø#ŒÙºÜùlN~רq rD¹ÿ€Éío'Ïókѽ„f#á¼5JÒ^T’EéoÊú|€ÔßÓn[˜ÀgcS»ìpà:3ž¿-ŒK··Ì‚›Ho¥‡œ“×\pFË™5çÔ”ŠÛY8ŠËQÂ:’_­jüA#µÒY¬äo5ò³µ´ó±~ºFÒ¶± ½€z?@!Øf .æŸØW]Ž©·,v4Ù4'Þ¿¬vÿ¬Awa»/á4‘t=H©>Oé1?hi NÀîS³ŽÔpk"$Õ lÊc{?@¿äS"‚ô¨ÁQ‰”½Q™ÞB»®×ßh Ô´ïöÙfèÛk.ÚPºØlïT¥|UkG-|,èÁêTªMè ­¬FøÝÚŠ}Œ7óÏa Äh(d# ¯ìûôe ØÎæ»uE§p–”­ðÆ¿öÚl*ѵéÒB:¢ïŸ[Éœ0ò~qrgràjøSÑW¿€"wˆûò5+À¾ä²-wˆ,Nú豫‹{¹pjŠßnæ—ÉlÖbR¤µœÀ䮂¨ìñЊf÷œ“Tjº¾Ê ÁbâÁ®PΕµ÷‘` 1Cõ<=©?úg•ï½SjR°‰ ã­º±Áæ®S•÷1ÞõRU;!ÄCa’‰‹“º ' ZiGÃ'cRÕ”èX¼2<ö¨‡ƒÇùû¨Ïµ†¹tJñ.¥&¦ù?Ó{^ÿ{iÓÜuiÃ<@áSZ‘Mž7†ƒv"˜JÓÆy ¾îš}u±PO¼Sî°.ªâöá<ªs޾36xrûkKæKæ ÇÄ=]¬b\hÅéúsµ©0=K'x]¥®»P”"±yxÈìÀ¼ÀÂHÞ%¨«‘‡ —¡ «¨Ô10Ímæ –¥Ý l:€†÷/s‹„Km%5úØ-d»Î‰rûü÷e7‹gèĘ^ɾzÄšôùJøÑïœùŒ~{F8DIO)è² ‹ Â7ÿ ʺ51!šÿz-[¦gò/ÍSƒ\’ŒŸ¦àu³×Áþ†1¨K­N+õ:ƒ#‰KÈQ¢€6Ò`Üì­¹®+—OeÄWYíÆ›¾…“„ÿ:{ÿQ|c–V‰\ü¸ÐËi¥º€ã;·0)AËĶ<LÜG,¥¼¿íU÷(`v›M){ʲ?ýŠù»*`â §öÝ zlÑÁ ȯ61#üvÊvDÑ£Y ?ȉûkÔüÌr@Ÿ/ƨZ¸èÈí-8Kx*cRæª]Tt%ý±?Çø¼hRPÊöùx²F?ŒT,Z8f]²-cÿ‡–¼¶9+ÙH§AŒ+5 \æ"¬¥“@P!z°KË‹íl'^X{¨¾T‹j®÷w×ZeûMžg5™ÀµvmwÙí†O°ÈGÙY Ù…vÇãÏl~XÏ/èîå ]WïŒ?–êÎÇŽ»sáðýŠÒñ ½ñH£ŠwX˜ª£ü&#6§óz{î]œž/Íqæßˆ¥}°ÕO÷^ƒî¡–áÞ‰lÈ5wÀ´•\4ÖÝ'nnì o…‡3ÞrþÅö¨<=A{[Ãþ ³k—°Püëm(º>ÿxàoÎÎë&Ï÷ŒÒK+ï¢ÇÝxc#L}Â7Î`£ê?À¤ ™Xòß®/×løÉw ;ì‘c¹4 >› ó£‚u~ØèžÈk‚’…¶ZT;é#{Àó!i[‰@Mv4¬ûù¹(ý•–RlʪRÞ(Ó­ÓB¢ÎÜ%cÃË[ÍO79z ßÙ¯í4%IQ§g Ê;èF9W˜ü¾EÊ-’ž÷"ôPõ¿x1-r¬7¶ßõÙ BÍ,$G{à2ëÏoâ^Î{ysQÅÓs˜LúŒ•_ñÎKˆ«.K`†mïõŸQúg"v÷ÉÌr~QÑ»¿«1i9U»·Þ^-è…퉗¹­’f G†_¹]‚_nãð`€U¾ª,Àg¯Ø²hYc€±`š9+4 m“M›ˆßäÄØ¡r’cþ|¿Œo«Iǃièy,^½~¹{ ðŠ‚çÐù¿¶¤CBÉÿ; ïv+kÐIÐý0|5?»¯ï”üñ¨ñ"$ßI@jB‹ÁÌúU€`hŽ¥?”YØWÓ†ÁoÝ4BcŠÂ g«{lš3»f!8 Y²ïu”6 ÜyòóØ„ð4OÃ]ôõÓǧŽ U3ˆÉÇ/G˜±Z†uØÅýΫœfÞãòˆƒÕõSsæÂ¶†òüîYxÓý>SÊ$þI«”ÿXÄÙé’üØÓcŽâ|¼Xi§{?’] aŽmã#vWs­‹æ\-ÈûmoŸò>úŸÙþmv%$“âu¦±é@3¼íxå\;]Eé%ªëêÈ Ð ÐáT=_vZi°Sƒ_¹I]Á.%lÍý†Âý)á%yÝ;[¯Ãb8¢×•CJ ¹»XÊSÌ{Ú„í.xŸæÿj§´BÕ¼‡7Àìbô¼¸tÒ“åx~²P ÿX&á­ì⢧ ¶÷´ÔZHwÕ»Ëc?¶ã|2Kw«t"4*3¡a†oYÈÄ*YË¡ÌÞp¥uxàðHn Î2r‹zKÔ&µtiäШu‚ç»CÂ+ûr àÆ¡´ü’»ë³Îñ#’ç´Ð$)FQÖS7YÜ·¿eÕâhðÝgÜØòËØ2jÚç=ƒ{̽E×j¥CŠÞžz÷¹«0¥kInmÝМ,ÉÉ:¾k3»¤?ˆÅVƾ™Ý«ç¤ œ„(£÷¤Í)·jÓ@ãÏÈ3Ò©¸R' 'Ø.âr3ßcÞÞEôŸUá#šyà¬x”±–o¡¥Ý®éX—ÿX"…æ³þ2,€µ*'÷Ï‹ü~{Œ9õ(F›x†•zwpt‹uu÷ª`‰j\Æ:zrD”—U£)V³W·i;ú¦õ>Œ–žËkîpžû§X´”|Ù¨Xp±<ùëPÄR«¹©ƒÇ×YvzRìï[ª)ØÌÂfù†©¼ q>— “=ééªòÅ)Ý7ÖO\·8àë°éÂ3õ¥üMòFB±ÂZ›Ljºç?Or+¶òA¤ÈNär 3¹}(w¨¶t®ªOc­et3Œì–˜oš|'¶.nDõâÓìMfì3r´Eu²Ž¢@óïký÷dÏî.3à0囪¬(¯/OùýîÏT·p¾7âyêÿSðH0@‡v®è¾ÉÌ}ÕêÂàžÏÀz3‹|í6"OΓ’m?ùb´Ä57¾“.¶UÞiÙÌãøjîA%R#´iT%ÖHðçªÌ·…:ŠZ®2'ÿ>˜T¦1Ø T4ÃÀBMrß*áÞûlu¥ÊMIa+»HMæC#2~CIbëÚÔ ±áÅyí_‚ë8@)?G ïô4· þÍ2ÑÞʨE0š˜úêžã3¾œK©û—Sx©Ù«Ð3 Z¬ßóÛèÑì /¶ðǾO¬â³1¶K«0 ·Á¡;êfïîb .Yá¬/ësZê”ï34æ³ÀöþbZÈ¥3­r¿1H‡jcïÚ¤,x)f¦Â¹½¦£®‰Üµ!¶ê’­ïïˆE]ï4É&ä‡Ãñ :Œä+'í$ÎP@!éÓq7©Æe§J(V¤iiáž¼Uöm÷ï[}óUÀúýï©~ÙJ}°¥S|béæÍºwc®àœ*[Q­ŒÇ$›*ãÇ-\0½ræÈ{û½7†\ (ʷıS´é1{5hË^óër¢Î×.Æ># ïVðÉ•5µä && õÁæÃK"ˆc¹iÍ;NÓå²ë‚fAýr”·Ëñ S£ˆš(IÑÏãìeJ ¥RvÁ/…bí˜èÛ]NÇ3­¶r¼"I¥ƒ4jû&Ù_`çɘú‰ôg+tñhpr˜ÛÔ?½ŠB?9û¹…¾dÅT~£Á÷ív ³û°D9¹iþ9¾X˜±}÷Û"ݵ,݈Í32åUtA%ÞÉúV’GœnòÝ]Áb~l.( Û˜Y™ 5ò³·øûíiÛ 5‰JÝ</Љ?ÁŒLÿ~_Ûáî¢Ø°ŽÌjÕ{¸¡øuX’OPÿlJÉ.òe1îH¸<×­/t’íèj:y’>ž,É~YæÌ»Å—ÆȄěéêO@ wÿ~8رÑhpAÛ„Û´ÄÍ%#aû£ÈÉ>ßÚ÷€Ñ® £ÛëÀÂ@ŽGƒA÷ŸýW¥é‚õ0á}Ž›Œ·ÿ²í{½×q!kzD™Çɤ#õúÆÝ±7œ@™ÈÕušrhf¤Ï3ÿ%“f›8Ëo 2 `_Ó²«ã½~>Š é?°üÛ.P±;}‡ÇÛç龬û£öüKÑõƒ+tƒ”I@‰%ÔêlQ·OB]c›:®>óÔ;Âà/¤èÛ/ãÛX“I,;n6†°Hã…ZçÉd <¬0÷+‰‚ýšpCk๛›}.·“9Ö.n’…£Z†ä•7›ƒWøn3Uq{ ð¿ ð¿ ð¦[Ê8Ö®Pá_ÿZê›(0ÅwT jÄÕêælæPúnVÔ Ó7H ñ̨µ’çû§n–#8³ ƒ0%ÔX`žžnü¤%§æ‚–§gìÉcdݲø†>ÂÆCz¿ÿG>|Å90ó/X!HÁ‘inK köµð1|¨sµ¯ƒ½”Þj¸Á± k¾Ë…çŠðB .£(*îIð1ñ¦[ú>|ôˆÿW åÒ€BÓ²6š´iGˆV'nžw‡^T?3ïCáœ[Xœ̼¥ó7¾c•½èXŽÿQù ”úš¸BSÉ+|J žË2ñÛÿ= j'Òbý³ŸwwY‹§gÉáþðÌ :æH¨{½øv…sè³{'gÊR"Ë’/AýW ù)[Zn˜2É Ú2Ž /GaQ9C¾€ý–ÿ5 ‡½+'üOԃb:°­­-fòE~šéùÊùÐ*¾É —IúxV¦'`½xŠKxI ”l½Y¥Ü‰‚…pJ£!t×îX9y—&‡3”í²…/‹çN µ±Æ¦cßñy›6äŇëœê¬Ã‡jü}º $ ›nA?;Ñò>2ÍÒ¾ï½vrˆÜ¤f_Bôü&]Éç©D^§õ†1_3rÑ”4gd /·dØG;è[…®[§¿¸/чI§·;ÈÁmpTsUu„øªç±)FnÂÜ×W ¦“o ]ó@\Mê:cËè\3Güü)W®\„qÎ;á=b}©K÷ôÀ ÇßµB`rN±ãÓ×òíýÜû•ݺ;»?´¢°ÂRÜÓ>_ ɦæR0¤?Y)¶ª n4Ë~ÝÃp#\ù}¨pñÝC\M”VuÖµç•<§71£öäÐtׯ0÷¸zMìX—…ð”B³jä «Q-@+¸ÒHpH̾…–,í(㥷’b•­ÞTâN…å©Íò?Ÿ¬{üïëÞßr¸ ›ÒRêGQTÂÿsW÷µràŠbÛ\å|ÞáíXû`ý·Ë¥¯á_›‰x2,ÁÎBlºöÜcëñ( Ɖì‡ä$àÛä¨A$9 O3>m‘Ølq‹\ë÷L·øÕ©HÖþ?஑˔·ò@×ÁÕcMI°@lh'ë[gj \%áµ$ÝŒÎGy%‰¼³«²øJÏQDåw²¡éh“*åXD|ëF먢g¦ü!vÚ&olØá°LDR»iYòÓÿ?fÎ[«àôíÄ[Q+Ïî Ò‘îޜࣦt m²xx™Éëb³>¹_¼å4ið-l©T’!zð1¡8•WE)•也,«87Ë5à E»!Çîc¢ÿ?ÿ"®j*³Ÿºî†眖Wt¡U¦÷Ȱbt4Ÿf+4WÑ€­KYÙ™[ Æ sqÉêB¿ÕŽx‘ÀS‘E@BËõiÿqŽ32âHö_j:³eÛ×ßj¯Ü/±F’`ø†þ-í)7N„qÙ²>@ùÑœ\ú0s¹-ÏŸã›®N~Z8ÉE–ZèÙŒ÷·{бšEì´ö˜É»©Tca­þâÛƒŠòq i=5x¹b]ßVSd‹üQÌ~ì¹ø?kÛŽÞºåÁ=L¤_°Ø?èÂV ¦ú,[a§‘E €AßAt'Ÿ¼,ŽcJOG_¸m”(Óìîø$Ê&î-¯Ì[†žp>Ý™ï]Åtx­%\¡}`cBk+ðT€•èJ`}ÌXFžê8ØþÃ~i¦»Baiôó5·—tçì_{„Õ;KËV7íðì¶RóèÊìßù&$i?ÓÄäd$ ºìÑŸ»=Nòû®ýAT<è’bh\ ‘ ºáñ9/P´h$”ˆv°_Ó¿œGÖàCH4’ÙtœÁN×H×]À-½½½áÝ‘V>=}öüéØÂ hþ1ÿ4.œC.¨–X­þvÄ”*w3GÝÌÝÇœdõÇE:›§ú²/WyOýúU¹}S¦\ò¸ªÿ6¼ì@ý’Ò!‘çÄÐå’ÚÿyŽŠQ˜%R¸<|ÏGc¨$ ÑR?Ý܇9ÈÓ=–Ú/Nz{¶]ŒŸËÍ"PQ;¦‰x—öNÓïé×ÛÉ3<‡ªþóQXo"ƒX I¾ŠRáæ§òø@™‹~¼žKJŸ´é¸ªõØ+YMמÄt•QÇc‚ÐU,qŒEò2ûiýß^ ‘®hv7ÙÈ ;ü E6›É"§wå8^.,dŸðWÙÌrn²Ø®p éêÝ.ù¦+%Ú´xQ%…*óŽôÂçU¿‹sã²Á>½ðhu‚ºO†àÂN;á^c‘»#½6Y…$Øã¬ }W\q!{ô{bn/™`:í°åiƒ—º‡ ˨xSMq~GlQ™5ù£4VÀÁë<ú/ƒ2|“;P…T W+å4Eý4°§xE¼}n…ý‘‘íÛ˜•+² ÓüB € f X“MÕ¶%9úeÏvFpÒÉå Ü{ +Ï-zqçbh¢÷lPÊxiÎï¾S¹ä® ̪~j§)é˜_$­M"vz/DÍ4Èö¶‹6 ú¡„I÷RpÏFfXÕW­BB„‰:g‘de̯õø§Œ q¥Ý½Gû¶ ‹¢8ƒL¶ø !ó–ð³n;OWÊp÷A¥U-Gd`èjgoý‡à‰ß>–4~Óá‡XTô ã²¶Š©Ì§žŽö)¨cÝ«ó鑪'fZ ž&}Ö†6IGÝk‡·„ºŒÙ º¾v´òÏͧ›¹€ùÊñ(™à@ºüÍ2?.(8xë|f¿(Ö ðf˜+ÑÒb‹pÉÆCÀžN:ÿjâö­à)NA@ʸ £u1>”LÍØÍ0sšGíºíÓÕ–ý¹W ˆêIÿ!Ç ÞR§~§S¥T'‰•»@.p™¦P“êqñ¼@A=?ë«ÑôÖŠçˆÙæa¾&¶¨a6O ¢õÞÛµ·ú™ÞOZÞJñ¾Ðkt/~eÄÖ|‰Ð~hî8”„Ûúÿ€BîU —Cüx,´¢•_7˜‡[«ƒµ®$jÊÞï¸Zý&Ò_awçM =®ó}“Ì+6~µºLîš\ ýC?‘?¤8`#JÈÄÝa<Àc¶}NÏ£ù¸?X Ž”ì×ëªzœqïìš iœvÛz/åR\ždMÌç¡‘äŽÂ<Ëû) É.óˆaªóÅñ&lŽ=EBU§?=;ãœV ¯Æ”nØet }â’[Aš‰*qäèûñ3SëÆåF…£žGåoà ˜u–€™Ë#jkþð—“\Á¼¸bBŒ@bÜ̾)櫆×·å´{káí%ô";ñ}f7­éxOû3×`üc³ÐI&¥‹Cω“¾Øl…ºÃ¢‡GäZCˆŒ²ÐÍv«*J0´ ,YL+_PÒóŵ-°dëÜ€‘>½nÌ#­ émÓ/"Ý¡’eg $À–Ø$I~°P-LcñÐÝß䉜áqéÇÅSÕ=³øü £L>†~u–_'¤â,Ø«Ç~¹^žÕ‹>VÿEݸ7+AÏ%ÏǾåtqLCY”Çt‡™{R>y3­µH­U‚˜Æ#¤ÛÓ&ò×ÌzA‘«;§$HÎxª¤ˆ`¸‡oÛpÿ)4[Hš$vê>†mÙ|Ѓ̥2§ö}´3ÞäTëŠ#m-ù`‚cG¹—àeI¦lc(&y˜8• kÆÆ‘ÇfŠ]¿î|y=¦Å%™ÜõšÄÞ@—@Œ5ƒâŸ¼xUo …ðŠVÖÙwŽt"9ë1©ž¸J“; `À{Ùpí.1Çp f„ëÐÐè§@–Å'Rv¯äŒXˆßjÑu/§¡$seŸU‡`‘2ák=/Cº>a6#KCŒí)ì÷s É7†dàvíîGýðündïÚ á!›’©Bºù@ÿ‹Ü£=‘n žò-™€gK¤•Mè¶£*U®([€Ÿ1™Óþl7Al}!»óÁ °ìq±Q–¡Í*Æî?Q8Ââ²cL[£ÝÑ ßÌ1xs0á,h‚ZyF­‰­û¼Ûå–øè­(mÆv‚ô“[6Áf€7ðjB±û'"†ÂkB&O9¸ÆuŒ4íÊhqéר¥ùŵIÔ®Um7ðeÃðzÚVˆ±¹aÆá âè?½SWãw@,´½‰þ›ò“Û<¿K"®5¡€R€ˆ|çTšßŸüiÔêø"tŒtcå=c)Ç?ìTö ‘/ÝBV÷ꎢ3©Éhö·ËŠî8 c+›¶ã¶4h¸2Âï›Ú~¶áÍE}VdÇ×GõÑ$qK]ŽCQ6agñîñ±þŸ¯Øeø\]vïLlϼÀh»²!€>9/줺èÌîã;%Œa™;`iHë¶Çvùnù‡É\ÃL£-Ù\ { k#Ã+,®l›õäY8 |íøøèž0ý¦ÕrîêŸ',HuðÎ$Ö¯€¡‹iuSíTsŒ,ÖlÒÚTAª o??^I#=éy¿Gw¶ü¦Ì2-×ûžñiPç¢ø»cžð2ßâÖ¬õ±”íÄ‹~[ÿ{ßO¢&=v_-–ïèZ¾ø5í-½þÈÄ;r©"ä"âÄ·“î(MÙ3UÞÂÒù“¿†^˜Þ¾#¬Œ¶ÆLõ È÷0øá8QÏõ×€†´ qó«)ØõÆØ[ œ4uƒÔM0Äé–)Öü¥FÉ\ae|·)™éQ,c:;.ùf9Zi4Šž1›©S¾GAwý3­ùû^˜”øÃíyJ¸oÿPº½¦+¸fâ½ FK‘ýëùÔÑQÉeØ‘!‡™ÔØå[¢ãÜùsü êNß/€<[ p !uHýoMÏ:'¾6ÂT­0D®áhQŒ5 %5K ÕXv¾üÃÛÚwdöù¿ŸÕ¸Ñô›xX„ÊDÿ=P¶QmªÇßaM‰Œr‘û6A4I(¨ñ>'{ïsæÀ˜Ý¯P’¥1:¶Ÿ=b_ZÕLú}ƒ?†(!ȧ…vÜL üòaî®òjUJíè!%«W’ÌÛk.‹WlžˆDÓe(rÇØy‡´ÀvˆB§®÷ãK:MX5Ý(JB.RÍì:äãÖÑá¾Ñ¡+ŽÆ>8-k{aPª®àÆC¥VEõ ‘Ö¤¶r×ga. ¹dè†Ø¾vÐ5߳КßlÌB $ÆoO`snÀ+¦ï‚¹;ÛDH«ÖŒëxìà!n»Z€®TÝñz_Iè6-oS ‹…¿óüpÉ~‰ꞟRg•`{EÆæk§ò€V` Äÿ™°›ç´'pn‹)ᮟP$ë Ùµ,<¦!šV¢ŠÓüóÜr,2ÿV+nr„ÌH_Q±Û1œ[~îˆÌµ €ke'jáYzRhÄMaÜ9ŠŒÕ ñWLbâú)Éç®Ð‘¡·1¯ïð%¶ÇÐ:\ýfûÁáÃsÕ*¸|M¿'¶‹/…Kª×Gª/¿¡ÈiceQËŽÙO)ZfŒ˜¢(9¤ñXïþC\ÉK¶䛸9­e(dýk0Ň1þ2íì1µBK…>_ÎþÑΆһ›Õ.°›Í¼ûúæŒÐwY‹cMË7‰Ð‰Î6»‘o9ˆcz§JÃ.­r>ù9*=ò˜û«ÈA¡÷R(ÖÉ¿6Þ µ¥,ßµCì~è6•/rÔøQÄ膺ÿE׆A¾øÞ–[X{žãå»È:5ÿmgi.ïÅØ©PxE´>³cÝ+£òÞ•nÎjÐÝMC ³ÚíÍs•*0œQ¬síà²ÄWTYBüY…y: H¹kÅ;‹{DÕt²Ó]ÊÚ 6Â÷7¸AšÍ;Ã@‘ËÀ–œ6¥ÏÏ©6<Ü{X( °ÁÒ”çЉá‚C›•Î@Õ+:ÿæMMK ç"çM"X˜ŒŒˆªH¦˜Ÿ¨½:I·Vx=¿P£ùìóÁ¶ïëPÇNF±.­‡o}ÑO°¢ŸòÈ–X¯ë¹‡W;¡^óŸXxI&½én”½YlvÓU´yꦵëôw…—TžªÔ¡÷*øÁ‹ºV3Ç,D” ?ç"¬?4jqÈ|~ð·Û„@øÑ,(ßÓ`ÿ0Ù´, RMÍy 7Nš=„^\DŠ}–AXnóÄ 'üÞd¥Ð¹¬VIK5Ó=EWݳÍp]–!~¤¦v}5j\¾¤}•é¯h}5ÓNg+†Ò0õ>Xáø& Õô`ã bl¼…’³ß‘]çMXÈ“?e¦af«h÷E}•ØÅ(µÈVÀ½¯ô'"ûìoW¶Wpd¬41Éï8ªäD‹šƒ@ÒŽ ©qÿò ê%Ât†ccDV™"à÷·n±Öµ=èÖQ³·€Ï÷ÿ<Ê#7|?Óž¨ðИ¸^âVAì •_„Úµy,åÍÓ‡ÓMþå¯%Í¥á¢¢ÝÆg •ó¹?¬“³=>#¯:Ôosži´uá³ÂU›—íRÇý@*js}sÊy½B&$?ïU—Í¥±ºØ8©§YÑ7HC©ˆ©*4÷¼ò€áÞ]ãÂڤ#ígš!Á~ѵá{}CÙQ;ð…Ed¯òVR IκGÞ$6dÌÉ‹ýÖe1A ;Ei®IIéä,Ë_Z~e¬N±ýŸ©_¬XÄ…có&¶ó‚‰Ýµƒ9GçÂZ†C’[ˆtùz$ ÿOH³ÜÙ¥^Ø‹F†0¿(í¥\KÇÇsoC^T9µöu°M N¸k» ûø1*œéT W-ÈOˆö°)s x4Þ+†A„r“€áf‰·+?T[Ž]vr%lm8äÕDÔÈ›óÒ‚Q,Âb3Q-ÛX¢~#3ÊdØ’¾ 77ÍcÄ6š%K¦!ƒôf+´Þ,H¬¹ß;òÓÛ­ƒ›èÚ=UÄÐûížcÿ]Íh<B6$XHœãu!ò~µë Ùg½QýM³pÏésR`ßÙߵɤ›­ÆCä–óêƒfÒ@Øßq²%iɱ¼‚ý”Áiƒ>ȇѕ¼{ö¼ìª·Oü®>‡Y&:zŽ í4Ÿâ+Ï–3=ø07åÀSói¯„àµî+~¯3æÈ$é· FŸ±µ¥2iÀÞ½ZlœÇÔê§¶`¤À³Ê©Çµ=ò÷B‚&Y(·½’\q€@Ïn o&¾,CÙÝ‘ÁNOäÂùs2¸0 å´ÃXïT™“1ðRIM\øÓáIGÅ_ðJ7oŽyyv­¿à(ŸþÀæ¯ß<ÑFjíÜÉÉGÆf±ðË6~ýó—]ˆ›?,¾{€‰)Ç™$íÊÃX® ¡:ˆÚ§…ü“ ¸AuþÛ¡ªÿ([ A2½ùb±–ú,:F ¦¡6a-oÖFvV>¯a˜žèi Ð9v©s€¥Ú1ù‘M2>ˆ—r &Œ‡Ü›=0—±\búÇÒÚœPN¢DPt ²öz¶ïG[Êæ£ ±ÈßðiDžgL)‡15ýìž Ëˆ©zŠð^Ëc˜rÄämI¢¦Äçü»¾L¿5!¨ªØÞ€¸Ä\ÈŒ»SœKö„NCGRFåD)ó>Ú¿q²'HÙiôÍú¦t7ÖÔrou¸±O3þ6\ˆdãX-%Í1m&%G#•a,7ÉiÝ…r,Ú½v:c˜[ýxʶB ´äw ×ÊZ„‚bk|WŽ´í7«±f’R>ê+~À½Gnº5(ZŽÙ;·šeZÈ’ÛjÐI+M9ÎU–jJ¿˜ÑZøC:L&2UZUÞáôþ¾p<Ì0ìp—OZ"9 ¨‚~LÖ+„xšÆ¸gÖ‡öd’²Ynôç§x¡s¦IMËÅÜrÔˆåZPäz#»ŽJ‡+M15ë„e‰Vƒ #XC>S+*’øQÌn8—Q!ZñJ›>ZQá(¾’¿ IÚæŽïô&¥ˆÆ}çûÎ\¯åŠXkàXˣ롯+‹(?ižì½}9úMR<4ÖeP“ÿÛüà@ð»+U»í¾ÖG:²£`Á飦,ÀcTÍWå:½{£–x.ù¨ÜÎN±=s?º¸úø¨ÇäRUR3)»Ÿs¿¬u|Â÷Ïÿc[cÕ ·€ÏÉØð¨‰xé°ÝÌxåº<ÁßC¸Í¼ÐÌ#п\Q Z¨X¬"Óâ 9y®“ö|êö5)“UÔ ©q äÁ‘R¶ üF$èGt•j—l.¢â´ølÞ%ÆÛ$pyYºA\)d‘:CõÙ€£¤¯A Þ,“KN¢K¢ ±sè§”ŸJëâ1nÍóŽ9£ÇÚ׊ŠG‰ÑèdÃ$гB#ÁháŠg²ß–£¸d´òp™wÛ="ä7BÌLÆõlŠ/\âsÂʾ—n¢JðÁÀŬ ß™k`oä©W8¿ý*²ÒáZ¡m&³Ô`•Í-ø<²© àoSè ©âL"üø‚mhñÉ;dtNêEOì€)´]ä,Ûƒ{ËÆ 0±Ø:rÁøð"}¨É¯Æ/±_¹¡ãC&XÊuÈþç‚@…]Hû'Ù·ö†ÖRä3`±MvºÝ¶àYKbUÕ£¤1(0DxcÛ£wO~$uÏæ¸šºTÔñeFeÛ!€'P3(eÉì`™bå¬ÿw|rŠ\¾4rþÛ̳ìßÔW‡lb(œ¦”Œ¸^\–c+·ž~N’”ÿ-Þ1 <´á?r)qÞÚ¨á&7Ó¿Î,>ÞŽkD¹®åÒês6©¦¢°Ä}‰Jf´ò‹Êðµ²¹ñt†°s»2” Зí<Âhyá¼dy¯†|˨+ª‚‘î=ðÕ–¢®gžìŸ® tzyÍQ`"¾ïrp6¼¨\÷çnTç;¤µ0Â,ñ'ÁŒ8$ïXL˜ã·Ó]¥8Vˆš>Oµyû »ëúiE9ÿ©‘®;œÄ•P¢}'µ5åZ¿ù†îO¢ý4“³2J:P5+ezÍtYXx/ÆSÄ[®ÉTœ+„Ü,E·tX*¿à)yC³S—¢š$œëœ»¯¥†Ojøå¸Í{çú"n‹ýÍ)•~£q E3n˜ÀØ­‡Ñ­öO’½jÝë:[Ø H’ïä¤0SbÙÔò¡-)Ú½ÿj ÝÂ"no…›¤æÈ-êl2’>½´¨œNò&ÉMÕíפø& W˜±çUëÞè/ubâ3—8âL°@ɨ'épˆ ã ª¼@¾_ŸÎŸö‹¶õ[ÑóÄL34;(–¡.úÜÖ$h%ìb„LËÃ7ËÈ&ÞŒõÇ(sØW{9i¸‡›¡1çÏ4žÁ-Uë¥þ<ƒ—µµ=xÓF;tñyëìþŒÂ-›ÁÃÂùDé* :ñus_ôÙ'©°[Hîâ·ñbÂÄDMœzt¾ÖµÎߥµÓ«ž–IšSí;%ʶ„!éëCd-úÛƒ¯Á‹ dÈ;îü™ì{’øÀg¥zÀÛan–ÝØ;œ†Ÿ ×$0N‰m!ŽÇ¤á*¶P)ìM"|šó1J9 eâɧty@Ý€:ä¥B®ò0oÿ+½–ÊÉMøo{áî6kkBÒ2C  ’ Ðº±ö¨¿œ¥kUÃýC5Ýï¾P™HIúáªÝŒ[Ù‰ 1×=æc«\ó î…‰ÏL_(ügW»›X´q }ñBèÈ!¡@ª"Ì>0‚ּǪ0 &CWv:×yqÓM˜¼›¯³Q…gBŒv9ýøôð…Ãk™˜—÷êEºâ¨ù=öË™òv.„@3)¢˜{½µ[ˆšläKIÎÍ64¶Xl‡ØöÒÎhb¸Í‚‰‡šW«Ò¡óW9ÉÜjBÀE°;;{­—M«£g¼ï,q™5Iœl— ŽÞŸÛµ xÁtÅö §¯bzÎäñÑÐýqN }³±Ù“ÆK*³D¤Tt¶–mm7Êaσ©õgvUý乯qõìk\eü^…ºV$þ˜°ÓÈ^$ð GgjÆõ\$Ešc–€Ǧ¤Zbh¹ Ôò³Ð¤ î}´ ‰fmqRXlQÝ#€úy,þ×zïs…÷–K9ûcIâÊ7‰uòŠ=f¸Zß²±¤N7àøøKüëéÎ'†[Ñÿ,놮K¬j#{%&_…ÂÆOˆÎüŒ¶²¢n#»ú 4ޓ¦”¤Ž¿v™A)©9’2úð<¸–)úÜs >9Dw&ùa­SØõWôqLŽ1MîУ0n7•ù›?è_jÓOÑ_òy^B Ø)ÿ^ËA7ó›PDîmµ ÝØŒ-‰ {­³và úà4;›9Ë.’2žçuÌk#?—Cﻉ®¢7µ?>·®4UfYŒè§Ô,VÙX-tÇäf[\™Ž–áQ?*‰&ÑË31èf$‚‚éû°‘×»©‹"ô–Œ‡T®¡†³8e¼©…·§¼®ž:5&ˆß_ðζ¼íCVÄÏ‹Á/ŠBôY´-ÏÐh¸=Ęεɼ‰Ô•Âæ~  ?}ªfs_ûaX'âà‰Šú¾ 6í!Á]¨ßm™v¶²Ç:mÛоDŽI¦3G•ƒú96õpEoæåÒl|Ÿ_*°|H~¢&0ýŽð>2&ìŸÞhÂŒ®ÄÜg+«‹{†Ó•FƧ³ ó®)h>f0?½‚ƒ#ê}8ÖCcèª{_˜DSFŽ }ˆ„7yÍc¨¬üزÜò*¸êÑ~œ¬çý«A²4G6jUªR± ×àM<Óå\|ÉáÄ6<ëoõeóx¤Peý ûeÈ­Ä¿Ug[?¿ƒ*Ââå ‚ܬšÓØk3[_ßf)|¤&H¬ùôV¯Ž«p6,4¦ÖBã7¸˜kLxeàÞ¥áèljóÈI…]?b àìÈlMM%>N"£é#ÊpâYˆfFþ+Qó`~ו ôC„njw[Á1kœŸ®2NI?@³uêEЙc=•h/ík-Í,F{¼¡‡¡ë5 ÀJ03@ý\VäV*Ý^"xß96Nûª± ëb#—A¨©Ì½ Ø” fVèÛ&Sáôh¿9«?ãk†â*ÑóÊÄIsEÃù…À&"÷+1•:Ü«£€­ .8€œÉ¦#*™Ev@®UW G¥ÿ{D b€Ì)!?“/Æô²`©F!çÝÿg™pìëì-h}ñÓ5j> í·çÔ/˽ ‘0tË>„dc쉯aª!Œµ–š$³ývo7¨zWvÚe9‘nË(çR/¡ÜýcÛ­)™çÃq°ZùlE€¡xö² ¬çû±ÇÖ2,ø/NIWt¿þy Å71S=7ȆáÝ»NÝ@†óÞõHµA ´3/Þ½éïvA¾¸ d±núS6)èK©bûh* ôï\h¸oÑSñóð?-U4(ßw|ÓZ§½µ«2[¨Ÿý_õX,5«Eo°¿xœ^™Ñ¢q0eÅÓ—VzŸž‘=_·Ph°ê/ƒ³oJ D fm½ùL†Ešd»TŸ]–Ƈ×ʲ«ú¥9pZï*m€ø‡É±Îw¹þ_üìQáì ìú‘x“F;Ÿ¨¨‘Ecèn}š­÷ °ãjÖLÖtŸk[ÐÍ6Ÿêä|YîÈ|«v…,¡]¿Õ]ìC“}^LJ_Ï,Õ¢)°‰^£áh$»<ŽLªTßÚ¹!À=¯ð$NøŽ/¢ðg”É  }õ¬•Hý=ámáq•ãf%VŸÊõ¹65Ñ ;ôQVÍS· @à÷*q¾…LOgÿJža©‘AþæCê­œVoçnÓçú]!{U¼[‡¯a ®os€ç¿`t¿.ý\pêÙö˜waM›•‚Hc§(jAaê¨H'¬5_‡icwp®þáÍP;syê|úÙRX7b ¡‹Ï‡ ÅûªeG…±c]ù<Ò¤d±l‹8Ú?Ÿ›Sx#rWJdwBIPQkd÷k€y×e|2:‚‰3õL<ÀuÖÄËýÓ‰¤îÈßn³4;…'ÖqHöݹҮ½ø«ŒÓ¡ÇûRAržÒEhKx©Aüüþ}"P¹ÐÂôXCýwÉ H¤Aém:VÚ”P¥Ž²"3¾ô—ÖêZa¡–AL êIÀfúÕïk"ê«s§ºÓ9‚B;KäügÈør>’~))_ ¨~‚®ö–@œBäÇ™¯Ôz£ŽÞ¸Ïå}…ùÅ.ø ¢‡ø4ž•*kÇo½ÁVݨ% A-;õ°ÌqÖÐÌf›çð]ô-ÐJ.®TQbvôcòj"1ÚX2xº´“蜅{´ó§–«}:Êñ9\ÇhXu.½p!ŽgJÍø„Û€$Û˜OFãuMêI†"¸E4#á§ñUÉoM 3ÞdËÉ‘‹°´Î;­¡>gãVÛDt^((…pÓ¦Z,Î[Ñs¯B‘Öýì•ÏßYÙ£$ “hîó} dÑa§.q¾ã–?È8A§³vf}˜¡¥Üí+Loü¯ÉƒG£‘›úÏàÔR|P; vÇnA¸5’í^YFTs¤&¥×ß”$Xå®kí7àô›s¶P“¬ÑÁ¤$ŸA7N³/ób§½X'%E¾u„wkp(È3õ8¯{….ÆÕ4îÏø‘F*²JÀŸ m½2ÈÍ~ÿmñõ$jNÌ—µÐ*E§G§¬o_°~Љ+ÿDà>þgfyB#EºT}ÖÖ°ë™[¸L}`Ú‚d–u¢' 0°] av Ÿ”%ìò—ILÐØ Š7ÿKiËãÍïî'¬ÆÈ„q'¾Ø‚ ¥ˆ[Lõ§Â]rñ¶±¸3Õ:úFÑ£B!‘ÚaëYFÔzh+Ô=G.[òXøü°Ûª¾DáèHÒŃ?âôü›ÅÊO꺄j°N*'&֜ߦ Ë6ß‡Ž ¦ý–€¾†l§üö˜ܑ¢€á¬­ÖzëB$rϦ;hG)U~ßBvîl8“u‚Œ¦,Ô•v( —Õd*Ê}./»ãª•ʦª·Š/ìÚÅøO ¡¢ðúÀ!¨¨ÙY±tìÙž'†ÄüÜÞJ£$µ¿þH~gs¬ÏÏ^U‡w´3žCÔð§ùŒšÏÒhTtZû ¹òÇ_¶m¶Wφ›Yõ¾†C¶Ñu@cS_a›€ÉŠí ÐÙ÷ˆ ËëøtºféPdÝÅáý y­‡`/T×÷áZ!ù 5•Yó‰×YŸ4xÒ)ØY—»“Äù*þF¸!XI±@ á×\Ï9‡¿ºŽœ±ƒ~¥ †DÉdƒRjÝ©8’j‘«°ófkI ùàˆæ 6úÞØÂÀRè{ôùh;Š®c;9+苺¤2Dþ´ž÷·Æ¾ãÒOynTc ‘çe·})ðŠš„ÌB|ø ~Æ…CÜ'„#= Âe@aÄU”ŒZþU0üø>÷Ö1"KHqÐ7@Óâ¯@]+«ˆ€êÚòŠ)„ΠꊪÿKÄz•ïÄ úqMvêÄÚû­ÿgµ 7s?ˆgOŠgÙUËRAü.M©ØHB¶V÷'¦¯0Œ ÀÆî Â7Ê÷-îeÿ;00‘ÿ7Γt"´5ì'î$](±éâÆSâË9䉷]§B²±aÁîdz þ#OI'¿QäyN›…Ov8çê@=„ÍŸ^áÅ&´!ijd³· -/Û_”,ÒB<Å6ž,þvå­iФf+¤ð¥73ï¡b4Ñ]YH9’³:ðïCó8Ʋ®nñŠ´ŽÜì‰c¼ ¨]Ÿ}4v [ÕËÕ•®à¥ÞÇ·õ'êû.Z7Öa÷Ç¢ÑüaþîCØ“¯ð;Œ¹Se¹ëêñ¿_C(&-=Üe{T5¥-lX¾ð°ÙéÖD-ak0Åv›:X¤oûsnNF)Iß¾ed·‹P˜o¡—.m *„¾‘÷ñ™xàZAÆ,'tÛâO³Z}³óùš7qAtav{ Ì׉–l4V_}=“?+ PÄ<0PcÔuJ²w5jp·"W)Ôt¯M¤Ý»ë±Ct\ÿT³m1ý@v^´ˆ„û(uEœqœ‡t÷ ]•Š>KìŒÌ·I®Â¤~ÚôÏ@fáŽ× <`[> ®•¦É„Ƈ`öÂŒû–æSõ:sÂðw0ô¹qÊû€ËX áõÒ±ƒ·^ñ6â%ªj”aukáþ*Hò]2ë”æH‚â™Ôü—yJ,*©>f|®¡®3}uŠ[/§ž½qHI¢³âút“ÀœüÑÊ·°a&X«<4}ã õíüµÅÀBÆÍævKh섬§&)Ä­²Í6T¦ ,”úCFUÈúµGÂþª×¡§ñãÉIv2s!ÂÍÅHwR*š`‚h±u¥VÕ*ø™”çE¤ÈM%ü^òõõ,®hd%&_# Ejö¬@+§‰AàJ¨`S>å]`·î¸çKå ú`kÒxd=¸õFrâg6ª²q$Ž%#‰ƒàI¼ÝÍJ9 ósûw Ýè£+‡pâ?]Gê&ÆÜös´±xDq/Þ£Þ¡œ‡7gÊMC÷¢g6AEðú%p©ûvÕ…5H3R£lŽƒ%[ZÖŠ…‹QdçÇ|ƒgç¼ÈUŒ[^»-©µmf©‚»XLi×_øœ¢8gBèm&:»°Pøðþe㧪ö~˜\y Óžë:ºG R…:žŒ?!¬CÜFRIá·î¶!tÂfFxü’d`ŠØõÒ‘`·‚ãñPD7ÊH±1¨=à ³@œyKkºutxRèM9œt†…¯©ª_ˆgနßYˆ4ÇáØ“ï8Ê­ˆv·x²7áÿâ×\cH„\°‘5»•o/H=kÓîwÏC¬cŽ#ôLÞ‘F9vµîÃPí9)ù×afü¦d¾à¨õ?W(B²½C¬¯‰BBó) eḼ 2k³,B–'Ï ýLï½úv¯Ò^|´‰<†¾¸h½•é"U@êXìÇ@¨ÅÆ0—8¾ð‚^=‡)]¾OUã£Ju–rRºþN»ê›ªÚšžxß-P8úÉÑé …Ëî³nY€£{¶-ª h)¬fŠxˆ¾={ïý‹¾?] CºY罯5“0ÁÞí–¹ˆë@ Nyž”£îÖmèXß*ž$%4ªJ±'O@°+¡%Í'¨¢,äôè)m5IÍÉýlíŒñLW+~Ð(˜µÎt™¡l‰$ÙKzµÕ˜áRø¬¤¼¥L’‰¢U0ŽÚÑ!Í2–<1éµN@*¤‹óV«ì-qj;Mú’®­¨~׎…6~æâbW9O$Jõ£’ S Ñ1ƒû‰î Iw€æí˜/õ³nÞX;¦òÿÇo‹ Œã˜¬åØú–;Ü—;§³?óü,9õQ<ú©á` üþßü+åþÇð±çÕHOª“¾ÛŸáa ßþÏð°'ÕFê ùõQ‹>ªøXÿa] ÿ|,Î?ÂÈþ¿}´çð±…$ ;¾ÚQo¶þ?ð¥ÿB˜þ ø!7Ùëh!šøßïCg™g3*­J1É3êq3Þÿ\×-Þ%Y-mu¢uÅߦ…±ÐTÒ;g*ç¡ fæw±­t{[ä‡ÇŒ4 ª_h2œÍMZéaؤnH‰]û*.V/ÏW1ɫݕœ8ƒ£ñúQòÍ#GædÊŽÌ.2QÆ/©)t„#ùGñ´l²ôêýœJ¾4”`è£åZ¹ ðÀGé §\…ú Gbxq ¹ÀX«ï¤Ö?ã°[m#à I$ ç »è mô²vÇq*}Ô†Í궒ΗÕá&)Eý å@E2Ã^Z5DPýŽ«KÇ¥²UT²Õ¸V­¸/+f—K2Jª i(Cìbí6ž“I>˜plÞ7r%™E’¬Ô›±r®ä‰¡SÁœ§Ò»æ¾Höó‰;ëÜ)¬|µ@Q2[²DãpIOÖXš°âÚ»µ%Ÿ²Çì+mï•{8óË‚7Ñf& ¢/£€ù-œ$ˆî‡+PMé={ÞK1~mp‹Pf¤ì|äËšú¦%ϱ¸Ü*øýJ¶èó‡¶Ê܈Úü>Œ´ô¯n4ìë)ǧ(‚ömAžÇ!fÑ íQ"ýÈoø~U€e“ô`v±Lô }wV‰ætK­´ ]×b~‚^•R¶„ Ä‘¥t‰ÚGË3·~ó#PD¡oy€Å…¨œÀW=[N6ߪ½;žªü`ÌT¦,ì½Õ ñ VáÛse0Ý^Šž]“õÝsh7kdÝ*#8¯3§](Gvâ~ØC!6Þ£úÑ.0!izšÁ¦)Ûœ7Ò“¥6ÇD_mQh_Šˆ$…6µ§ÆÇïøóÐg·.Œs¡ô«ÿr£y¤¤ ;Ór¸€º|QšÉ‰À¼{ð( ú&…Š;8øàµÃ‹¢ïwljš YÏÁúÆÓ¨ÒþÁÌïši™Z˜/_ˆ „òFQ¼FaÆz7íY¢lè<À·?¢A‡^WÅG\k·r='áSÄÛ‰è%³ÓŽ1LÞØÛÀ$»! ·µ9@¼Ýk;…è‘!U÷žâxYŽ“Ÿ„' o½”‰¬…¾/AgÍ)Û@·þè:&3Ùþ¼i\¼m1çk˜ píMô½Nè·#Ke¶RXÌØMvÄ^ë2Ž[kÿ]‘ 5\Qgž»6 Ü¡ÄBK^ÃÍL{)¿Ü¤{ck2Ò%ŒVò¤EÚäQZÒW÷q;íY" ¢Aç®Ô±|ª{œ`@ ø<ª>Åò;BB*^¶@±Gð|/J 6 öüÏ2ŠþÌ|f´@_¼$ŒFiÑš²µ¹zB4#"@ùâC׆cZ·1ÖPª~ðT“k„½Ã"ÒlßjÄ!s Fîñ¼†™íÁfp+ßÎŠÇ Ð{¶žM"yL.+®€Jà«qŸ‰U t¸®zÁJ—˾rÖWÜ¿å)ä¹àMð&5CV»·GðªÝSA=h#çÛíÔǶG€¾÷—‚XÒu'¸­Do#廿ê1W_ŽËo_;ïú‰\È#²¶ŸÊ}lKÿ|ùi‹cq ûd‘°pïÊ,6šMÿhßx¶÷”±#¡r—N“ŠÒvS*/ŠÕuå—­«wq¶Ðq¾Ó™è©’9ŒyÚ.¡=šÁŽd¨ÖÝ}$%¨Z6Òk€LTPsŸ¶…t(ê6 B›}ÒAšnÐu‚û¿SÙ4{ñ‘p¸`}Æq;õQA¯P¨Ööy›‘@]Q[9~t7-vPY¬T/S×Å5ÄšÓ°†iU{Œ‘7¶O9!íÐù2µBù¥ôV±nB¡p:(Þ1”w´ç7<1Öavµ¯º—¡ Ð+WdÂðù¸«Ä“”åîŸ#½¹ýÊ¢'cp@%x}¦ü'[¼Vk÷fªµ­Vcô=§6ñüÔWñÓoI2X:‘Õ0ßôŸf, žRdfiÔ¯1½ƒ‚ƒ˜qïøÿ!Ÿñ²Œ³q‚=žÙi ùÂ{Œr…£1³f~´æòe£1Žlf,%~h 4¡Lu<•P™o {&?õ¨eúØly) )  Á^Žùô„ˆ0ª¨¨¶Ó:¯ßl S0ŽøÔ}Æ6ÒzÉu;'ñü•+è?(£„š`›’JgϼÁLæ5Ñm¨‹.F±ÝºUÓ´­ØÌ’°‹Eøò|½áí¢‡=“¸ˆÀÕuQe áˆ;îîߘ³ LLöÜB·ëÜ>GOdQ™k’!Yñ#­˜—Ôw|vª]]*AaFz‘ú2¯44×^&ìØVxü"™@à®Ëd"~tµqÉŒ£pG =òPrØíznkéòÍGIÐD¯BqxyHÈ8î*ª†£È£ÀØ ¾‰Ÿ¥f”(o󬲷—þ ª&‰B|i¡0ù·¯ObßÜ6ƒ˜öMv8ºÞ ÄÖ„ Š7vp©>ŠÑîŠmö%iÖ[åÈÍ&‰kçw^ÓžŸùptŠïœ„}8Sƪ‰y#3 ãôt!·é¦ÿ5Qõ ľJ‘¡º:u÷—yÇÜ[_À¼{Ùò˨ÞĵCQ¨øR 3Ÿ²>T:½Þ¶ƒ!Å,úeL_²ÙÎ Y1ƒœÖºO^5Óíqd¢Ñ±N2‰Î¢ÒÔ6I|ª¨²*æÿÄ{|Ⱦ7b¼xtú7|îi•­Œ¯¯öÙRôŒŽ€† ^­¸*…T7°…ïI`lÜ;h|6œ’ºØ¹ñÞŸËôrq ‰0Ø€Õ»@5袧¾ dPº«gäœóؤd¾ë!=*Êb À…­¥NeÀ9úüvu”J¢°UÓöÜ;pèiÛã<¤› -dפFUà£Z£2UñŸ¡šÿƒ´|nÜBý?™îLÍÁLÙ(WJÚëY —S³¬Ú¿>>üYäep+½™® ¤3ù=Qºbˆ[;Ë5+wÎcöúò¾êóœhÒ@GðÃ0CT‡õìÙ¿N¿çÒ;—™žôqªO,*R$øTC¤cvãìwPLEï-¦Uè£ +õªxOzÔ“n3¢] ˆI†#3‘ÑQ!Eí…l.kM·L4<܆mF`*Ÿ¤ÖÎpC ¨Vòyüü©òÀÁm’œòÈ• „r ÎV¼]½v%ëêrÀ»Þï´Þ3ÿ2sJBüÀÑU&›O„ß; >GåÁÒ·ºúòçšR H!Ó~ím«û¤ZüysÁÊ@ƒ¨W¥¤–1•üþ8y~˲êˆHÎ9³Å)†÷Æ$ÌtLIm¢YÞG‡!‚‹™ÃÇ‘æ?Íèó°oüz±_MÆ‘÷.¶]™'á·õ‡¤x¨¸)±¾? |Û–ö€;Ö߸iÉÛï™h+•!»æ†²HþOL_Í–¹ E÷Å?·Z=Ù`©~Á‰Æ3ù‡N¾˜¥A™ÌxHÿ>Žhǘúß'sHu4GgòJ÷¹Z_6í`€¢þ‡œ@;2{CäÐû£¢ÒrÇ?U¾·†Ó«ÔÛ¶ Y *™M½à¡N¸öá%îØš¶±ÚM8Žü@öš¨ ±R"²ztRÁ) ‹"Ã=óšìTh9¾¥få-éMðSÐ|ǯ÷-$×Ò0|.ûSßÀVšºŒýìd­K;ÖÝë²9Z‰·­œŒÙ8n®P€/$Wp üTY2¸îK‰ÌMK¡#%¥ÍÏø+ø¦@<'¢"vuÎú /.VŒ+ÎÕÚm!¤æ÷ÓÃl¼É§¡áfC>43|½M&Z‘ŠmËq î(Ùüã  ÁîÞA©øƒ  ëexjþ S´ìgU÷"¹ÂÅö˜W)„ÀEÒ›%Q"²«U‰Éß,ì?0X1?Uÿ/#XP˜,T{­•m•pQâE ÐjiѪA²r{wU`Ú˜æ&_?™dƒzXˆïŒh Ü0Ô˹§e’/ Åãî´ „ù;^kr!ô¸µÒôˆ† P F›ßÚ~ËÐ…'ÒÿÊCÕ?¡®¹·w.J&6-;Œ6çwBž¤p Þ5°ß;¨+Ìòœ²s aŸ+(ëHÅÇsÈÌ–º·ÌAüÇ^øå9£³'ëÑ™QÌ+ôz?µÅÀƒ/Á»]”ÉÆãÞ©BÅ<¡aäûŠ1rW3Ct4‰š‹&DEêƒìB¦1d¡ë0cÖ¾[lÅ5zÍ Û?÷…Úˆ“9`݃Ud¿…~¥‡%Q ånhêì†tæê‰ÿô¦]ç…„úÄæªÃ¡½º¤nº\¤Éu¢•âÎí%AÉx<­å)« Õò|€:3å!<÷.lXìŽjÏõºhŒÌH”%e tÓ–,—¸ƒ¶Ä" ð¨Bpx„ÎW%K¿']¸œá{Wfy¨]ïI±Çî=²‘eäY7ÍÏD±ðÚ~ µ+ LZ¹ þØéØã’‰/cÖÛnê‹÷¯Têžô‰‘´én:’G¶hy;"K?0…‚$Äð%Xaé Š)ñÈ*dbS7¾É'5ªŸ;º_Ç\£¢.ÉAÓö&UûLu©³Šû|òË %i*°%ï >‹‰nd WòsfÅÉD"bk˜Ô§¼÷³:mø˜±5—ÛYàUuû$©4±s1æs²ÜÊ(CdïnìÖBÅÔ¤^}¯üØÎQc«ï+v²Ž¢ :®,èú§‹õ, fYáJBçE=Ô¹ÓPDsd„SŸ×ÏG ‘Œ!ž·t¯îA6çòjxõGª«&‰Gv6öm.@v%¢e…ïãK:³:pâD’5šõŪ‘¬º@¤ êù:áD×ô ÜjÀf¡bŠsY[—ˆë!ª»-vuHgY­/®HøÊ/Ô@Ö$’3S’Fëð0d™éÖÜ+àoë™ ‰- |KákZXL@ßûœ%÷qZ•“8Mg^út†- B+^çÄuðShR–V4gÉ4V½ÿŠeÕòHE`<°g¸eùÚz ㎋0$©I†Æ("6Ê/§]WœÞwËR ½E8%EŒ”rÅZŽÿƒcŵë6Ÿ5ˆýZàrÈOvdÙÀ:±“|&f' ß‚ÒBóýúU¢ÜàX”[lƒÝ Ìé#:ÉÄ[žô ~BjVDÊ£Ûkl›HÇ™(ØF€­‹u¦]¦_Ô+'\$o;Ø×îÅÉi ïAXEÅÓj´ôÿ!5†ÿ2À¶™GÂW¥PânvuÔ–¯mJœKÅ­vç;P{¼MrÕ œb‚´ÿeÈÓCÔM䈼ÇJÙ‚þ…ùÛC­ÛBU4b ºV¾w1ñÃýU»¡‚ïœAÑ`È»½FªÇì¤K®ˆ»Q6þQ÷!ýMn 1‘àž¨ìò‰nø^­|"ðHh7~4jsÖ_VÇÌð÷]›†¬Ý´¤°¸x†P“8ú7ÂߦnåÞgøîÁÄö âÿ œp'û¥O•K¢¨Òñ¡ ã·4ì6äè“,béõµ⮣PóZ¥¬BŠß⢠Ögg{˜r<ÀrØm1Ä'Ù;9`CR~€O³Ø…CŽ|3~>úø<Á©äJîdzØOsyËs´™Á3z©BlU]™½ C¯wu×k¼”­™O«DÍbH@ùèZB*ºq­ÄU<=Zßo3^(‚Qõ‰ž½gåêò îÊ/@Û¨nåV¿ôžß~Z3tÀß…žÕÞ;l«Ësé½#L‡ƒ`N¯¡ÜsãJ·î±^~sÿ àóŒñúõÚž:Saÿ%ÌÊeVÓ´éoH— ‹ šåX& ŒÝ¾´ÖÃj‹)Õ é8Œ¾ lj£c`Q$ðùQù8Nr[e²¢âÜ›0®UlŽ®…ŒSoËem9 /N3…•Rþñ•ý Šÿ={õ¯ÊmŒ:`åÍsh²ðÂejµwîäÄWdá©à»A"e_‡p¿¹Óª©·³£Y”#À”ríúUêe@4Îhÿ'O‘Fÿ<ÜT/ªãáƒÊÉ`U}ôªÎÈÚM€³ »Fi.ç£ï){Ž@³ôòI„¼¡­iUJÕÑÅ’!R=«’$9‰Ã"d–ÈhÕÚŲ›_2bO–#?qG`K/²XIñÌeü8,JDJ˜EßÝÕDó®ŒéI’_žâ]rputŽ[¦” ß¡&îî#rmÞpŽ)3y‚ŸHÙFHN§Õ`]œæ-U+ùê¬em]j{F6sCC=g«Ã¯ÔsïŽHÏ™Hä ¶…i¹Uh§ÕšZZÆåÐ °â2 åñlO¢ðµq·`‘ z]¢J×·Ë­§ìcÌÜ`QÌ(bIÀå²`äʧV›(ë;Z4&LÇôï¶—ß·LmïÛEþÝ+ï¶“ øh° !þŸü5%_ü4}Gwøj/ðÔ«íº—Û£1ó‹¾Ý†¾Ý›þ—ÿa§÷Úyßmïü/þùpù Iþ†¾ÛÆûlÑü5'þðÐy?á¢ß–_mG~Ý3ý´UûhÏÛ¦WÛNºšÿCQÿBÜÿp·ÿCR?áL¯¶žþ<ÃFï¶™ï·KU}Döè-ö¢ÛíÓOáy $ý¢¶ù¾ÒOáµÿa¹Û{öÛŸµ;~Ý ý¶÷¿h×íß´CöÛß·J_¶ûý¶HýºWßm9ü4&Oøh¥öÓáP†£ÿÍþ?ðÓßáNº?áHÿa£_Á÷ÿB„þ3ÿþ—ðÐþü(øhb¿iý·?í:¿ÃCÿBÙ¾Û…ûmÚûu~ûuïø[ßü, í2߶循óÏÔ ¿ÂÃþý·?í®ÇðПøQÿa{Iÿ„ !ü)ðÑOàýþ?ðÑŸáE€ô„ Ë­ÞæÛÈkëýÍ?Öø5 lçð[ÉØµ)øü6åÑ”*+"C |«(©æÒeTÚ< £x4Åo¼_øÎJ0œïdðÊGh³ŒJ”ñ­Âÿ5µƒœ²º<÷p[NA'ÊSjÕr±{Q:O-1PH))±þèÈÅCóPÀž 7‹Qޱ¬b¡ÌCZ^ÑO¸‰_ãÉzwP%Úý@åÿ/Šâ»n(ý` Ië0•Š®öb2ÛNú—NR§ŸDi~…¯€|>ƒ·»ç Qmš$Miä” ¹ëg‰#){îÃk2†!ˆmÐ5oÆòEÚó†ì¸Ãä.+ç&CDDiUæ›}UøœNw„[½ío°¶^ þÚ¨©(®›"è-† <5:ãƒJÓuÆâ‰ÿÿNI?xT• ©æ"ôògöf;>ôö‘Á#Óm¤°³".@ûwÆÙù­U2.7L5C*¡¡»š&ÐÏ%”†¾*"¸Rh"©ôx³¦¨{¹|Õä£Eà ñ³ãÿbÊ`VqàL£ÇjY‰8ûÿåÝìáq;„Ž Ê©ÿ#ÏĹ-¡Ç¢/„~Ù`.a#e½ÎÅ€rßÔïüÒÛ"›Ë­8ùL{™íCÆñÒͽ>ý—Í<×ÄRÒ8eÄcPƒ_õÿ)@=½Ulç„«Ä2tgîÞ£f¾<4 ¸Õf SgºuŠ»E)TY:À:Ò¡Z¢^'¹ ˜Ý³.n²À=ï—¦:/Úþ|¤1V6“•Hoñ²Ø± /f{iG8H·¯*Jêù!Y н5+_àm”¬K?ITkYóv~h UA‡ÿïXl¯ûbnQLÞaM¢øxï‘¶+À¹b0@£ãØ«¯2žY¹’Z–È€»S^Õf¹ÿH“\MÈÝױ˫Þ^ÂWl½ò áÒâÂ¥øŸàØE+§®õå:ÐÅem†oOjð=šŠSB4XAôSq‚ÓÄuU-„-FÛ=³ÔCQ@Suó|û»a6þÃæVH1µËvó'\µë\þ$Ò«•±åz«ò½ñyÏ–“b$°A|Ûœ5ÌöÌ+z@atxO–¡æHѸÂ,µõ‡Ei×È[ZkÿAУèmÇ0wõ±e(\y—[7ûÜlTúë›PHG?”ã¡€Ty­|`2Vu¥.Ódç©+dVÞ°XAû6¢“ÄrSùbò‹]À I7^¹%°ú;¸0%!)ß›a™<2 ç¹OD׋6sìˈºzNžß¦L ê,@›·ÐI¤c£óyTñû¯;×d³„C‡xjµ_X„° ÷x¯ ’æˆbň;¯(÷­µ™Ýº‹7"µý¸.TýЉ žÏ·gôè× m/EL‚5-µì7Nc¤®I¿ õ9þSíð±ÙêÐ6OiuyQîÖZ¯òþûS…èp`œë9®æfTP­(¸ÎMvUE 6.¶Á®IP­˜CøvUx8˜ôûeW‘%B¶`r'mzÐKpüè, ß®WòQô#añc à6¤¦˜Â“2ÆÜ” Tm“í$LÚ{Ñx¼§Ø»ˆî©1SÝ–ÓJkàŠÞNž¶oÙ2¯ïâ­Ïa¾ß¹ÝÉNƒg§†ñÔ¤Þ ¸çØz‚ Ük]`WsQ«©¯WûÉêJòØb$» E‡¯È‡Þý—ЭŦe¡®¬/3¹ÉÈ¿ø.¸XüûwôQóD#å1gõqÛLÌWÅ%Ú×hf–z~›Gí9ÊbPéJ­+É`ÆØ$εX€jHsêE{—Ÿ…°ur)ÇÒÞUœB»´Ä;Î×Xd¾DráÇƒÆÆ{ÃŤm¸­:­ùuÿnõK䯤 k¹5Ë`›çÇrÃfÉ-˜'¬•£Ð_`,hIh÷—WâÒ´rÝ9dvÂÄù¼Psr<õ×YwýIú8€3“- N¯88¨h ¯ÅÎc¸ÙÖeè[gŽt´óôu|5²·ÉO & Ú#ï\¶Ûݦ°^õμ a€==þ˜óü1tsÖ>@Êxé=Gî­ ÷eùÖ–¼.Z°É~€L‰ª GMs>'²(wÜ‚©ËðY‡½ñpÐ’×o™àÙ$QH/¹±Mî†Qy*¶ =võ§F¤$¶G7ù•-L–¸K™óN¬k–dBò¯Gï >=¥—jœ¦ŠŽà&ü]YæÇõÛÇtö:®ˆìõ¤£ÖœåRæ¿Ôø±vÒþZ=6ñAÃXS€\¶üþR3Þ.ºå§YTAÙ¨¡,ÿ4¤méü^eÙ"bn-D)¤íæ)OU5JšcÙÃGÚ£åßôH€½*š¹Ç7à…D338sÜÞÆƒ¬ò)F¢¹a6 ±ÝQ§-…]áÌpàCÉÑÒc®µ–&Îvüb¬öA#ë1¼[ó¦#¦ Ì‘ö­¾+9t •³gÈ\ñüAÊ[k'·ÙÌG£;7¥/ñËúÐãè ¾¥ãf Ÿ¢ÚJ¡»œ <¬¡*–â±õ ò‰È8ð'ù)Ì_UÊnïƒkC<®“5­3Rµˆ¥gní(„R‹H݈ZeñLªäZÄ— а~÷„Ûr­ñ¯¾Å#‘= Ðí‹~jCõk9ÊÖÁ!íö#NˆƒÅèkÔ-CÛTð‘9¸zÉ ñoe«(Á¿œ&=À IÝVªPë è3•°I°VeÝ$™ARšï3gä£MÖX¥Ößò#™:ÉnH'Q3^™Kƒ€›s*ÆSÝJ©ŽXÀ½oÓŸ §b-³Î:¼Ñ­aé#D›é Ogh‚9€P´ç3-Û¹ñm†¬’Àï§ü¡é=%¯>V¶!/‰P•Aâ÷¡ÙÜOøNÂQe †s‘ˤx'æ×öF̤÷'*|=ééüP[Ñhb9 tƧ¿ó¿ØÀ]Ú(Úø¡rjXLNlÜþÙl§Î$'NÉ…ÒêœSlÞζ•¹ƒ!Pò?ÌŸ7Þö&ˆî%líe²°·¹†–°äõ‚x¸óq»[‹/Ú”¢ à af“φÊþì=–zz@vdp3C,«órqw†Ã«ø«Ú¼Žš5Jªœ}E‘nåï$ZcšbGvè _ ô?Ý’OA¥¯V_0;€±Å'÷€OC»h~ní1Ù×Ð'ïü»å/iˆÝ¯ ¬ÙÖÊçz»Mí]ˆý†Èë»é büÖ¤§–[œÑÞ¶,˜u¹Ø ÖÖòD°O^½’ƒÜv¹³­¼[å VfÏÎ?õʸNÖîÝNœƒïÌj(‡HO2FµÀtÉlæÈnžlœi§ÔØøß+àoØÌbgõšTó§xxç‚äßÀØã¥Íñ.Õ×ñ©ͿÌ\R4Zÿ y$)Ìjš8Ѩ•£Ü .» Œäcƒ{L ÕÊkâ8_Æ;¥í- Þ/›ÀZY«åÌÿVÙh+ÕŸŒ[ꦕB¤ò¦´k™÷|«_Ü•viuÙªFh«}Ý ò*ùÚàÐÚ>·ø 4ÖÎ3CoÆêf ¸7OZ ëãìTØÆçbËÆÔƒQÉþƒiX¡åŸ»ÐSx¥í‹ØaÿW}ÕZËrC‘|<ÌLÿx0ä)vŸ5ªüïïïÚÆ 4ÖОÆÇÇødÿ3ëàcp1…s1ƒ‰ííýrýtš¾¤×y?ý{eõ`—0wÌî§ëóŠ÷ÈBIæFfž‚®Žîy±š‘7y[¼œLk˱¦—mGû¿Õ‚TkiÖå&…¿Fr§³Ñ·û¸ÿPvsˆO'Αé9^SR(ÇPìZ´Ô"å ÔbE¸[@g>ׇïŽr>}ñv‘fZ‹ Jßl/ß-²³Ù‚±ù_6ðÇãm›oCáC[ØÄOÝ)ýnppŠÏ“Cã3[Žœw½©,¹ÆMÿÒ]jÛkC²E²Ü°ã¾ ¾œ-dwȿɯÞÿIðºQb˜™ƒÖó™í~~úý~ 7Ôj„@'¸X€´/¡(i«–¦l;v¿ªHîM{i: ½Tù@ú¤V2£Ë?ß#>¨@ù2Ÿ5fí¢»”zªmÛK!ƈåçåëñ’dçL„ø,õËqÈEúkbÒÖ(ë…8IT>4Q¥ ÒßíIx¿¦côo’$*‹ou0œ?Z¼Q\í7ÛÀV®0ü¨rTÁŶ åifY„@bÉ%¶ôÔ“úeÒŽ­4."jú2¿ë0Ðj´¨óÂÅ]C¢Àìɺ讼Õ!¼0ÂÖ®\Zá —ÒnT<JÈÍêæ[?Jÿ¬h''D­ËkdïwÁ6nÈrdÐÁ¦5Lp`aZLc)Õ×ò3¢‰7Ëõ(¯?0‰“²~m†¿ìhµ_Ù7<Ü¡¥¼ußnÚ WrüZ>ÕL”Íõ^üƒ;x¿ä-Ñ""J” Ì˵»ºs®x¨Å†f#²Æ'm¢J®GØÏµk ÕÙùZü!¥Þ묵*8¿Lê±y÷†'Iê"J0Æ4­ž|ä:%mº" t3yiÜ9Õþµë*ØÀ1B%_Ô•~nëÑ®ÒšŠº`uƒ5ñ%üû<®®…-hfAç€Ív‚‹l³áæ§JýnéÄ…-û$+z@‘8¬B®ÙmôPµõJ2=…u!'_žYT4 :s Y|…uKŽpšÖ²ÇÄâ§îëÆôÂØñÎA0åÕb`tëj„-–e7"š ÒÉe0×È^é{$Iq$È–Ž7è‘ç&ë|éš(äVéfä'a¬úS¢.9oÆpÉË»qÛoBnˆ ÀAe&á.Å"œ¬ñsæp’ŽÆ•s¦t ÌítŸ¦j5V·_ÐHF—ü³ è·*o™ÍW`ø4ÿªØÊï4ãSŒο»ƒ·@ã2LSØ }‚÷¨ŽZýέùN¥¸–¯3œ'VPõ†UNýq'ë5œBHÑ+ú3Ô©Þõa%Ê-UAË%*.»•ý3*]yN½Ã»«rÊ"ÝD”‰‡öºF5©MA@š‰@ŒJsȨÅ#IÌ-Ñ0µò€½mã0ÁÉM#®½f>7›xÃG/ù\‡".P+TÕk8ÓÂFýÓkº5=W”Ö3õuK ÛÍú~‡”B€\˜¢ddG£pÆV¾æt®)ЃŒ×ºÆ•Ee0mdŽzú5ÙÖ^‚§o8twsŒ«ÓGç˜ùjäáí}ˆ´1»±†YZÏ— ›ùÍ›W-7lÛ ¥-⢽“¼y%§%H…¿Ó¦, Ë_LèDqTn‚»Yn*ƒŠ7{E'jNæÙ’¶¨œb6"ìå2ÓHDnx¾ÿ—¼RxÛlg#Ü/¥q½V~lˆWÀŸE«p£É¨!ŸfÌ<¡ïòŽogŽºMLõP’¢’c°b„º )3›¡¹fóAU䞢XVTѰuÝ“…z] bùkKÊaC£ÆX›$©W„ô–3nç|ˆ2¢ ‹Òö“ؘF†«vjXþ†`vïú0š‡ø Z—œz‰þ—œ3õÂ…>p1PT,ñ-ÐSC¶tgÜ6"¨IÐ> ÿÊ•`b0R ¤ÃhçVñkE{RQ¶~„ˆEËvšø¼M„Ž$~oÇë³è°µˆ­wÉçp ×1ü84@ˆ…^Å¢ZÇ®fÜÅ-_æ €™¥Mýg9®N$¶s[ÊIû „Öq±ƒÒf™]ÀKMbF;éÓwŒÝm‰ÈÜ^ÒzŸýšHÄý|ñ’õjk/=ýïÃ ÛØÁ`h—½ÞzàÉÄpø]±÷ÿ';µ®–”'·Ýû6``¼õ±â)Ï$Þ¡'—.7%í®-¬jb«<"ðŒwoÌ,ã›äKÀ7ÿcª¢~&;wÚSÀ“Å4å½ã¿#-´„š×e)&W²iÇÐ%˜lmmþ?šž³OL6¸-ŒT7Y ]gèúð\›aG[®rseT–ÁV_ú5€ãåŸ@‰ŒXa}>Ôˆ×ÎÁiwÎ\¦…ä\- ¯l¬&Ó}­Õ™áÊÈ´™Ô#dï˜î€Ñÿ0'ææ¡aÇŸŽ}¨…Ä8™ã>gÞúâ–DL°0¯w”Vñ=oÄ]>â‹c¸þðåÀ€œ|Õ¯›Å¢œì©ž’E!wé­Å#¿BÖ`ûx+*«]gFRêÀC¨å…fª1 ²ü‡ýN[¿(’Ñ&¯ç'qò½º8™Ê•þ‹ƒrÙvh` v'1cãO´S„žÊZ?í LýJ°¡WÚÏêÉ•½¾‚ €AàZÖ䨆¶J¾X°½ùªÝÕàH§.ù*öåÎ\¦?¥Êˆ n^[•«^IeØk̯ÞíÜuÊB¢ôª}-ëUG\#r§|˜SYà…á^»´æXV|[¬ôA”v§ŽýÒFiåŸ÷Á‚ŸÍGjì=æ5*à)ä-úÙGçdl¨æRì•yëÍNê#^s RÌú«²]h:5û«ŸJEäwó5ïUlIx$ÿ¥lsîn“¦Á:KÏǸu‚•ºÝA »œð±bú   9+µÏJÇj¡e¶X ‘‹ÏMLo{'§d*N@â¹,NŽ$g9mqy¤Ãir‘ãNܺoЋQò5"öKÜÙqø·é°ú¨b`èÄô–©¼q›’áàæ Ú¢À޵‡xÛº¿~­–»ª ºYÞdTß»†û÷^ü–•#ûìöàè3;2Ü{¬ßRæòÈÆTŽäB8«ÿld8?¬¾hŸÝ±^DT« 7W=…¾øÆ×P©xþD—‚kX$~ÜٺХFÌ"×] ÃÓ6u-‰š¶ñ¢þ¥ é”û[–xU;H™F*œú¾YS¦X?H`”0ʬÄleT\³uÐÞt}ö!%'¿ÞnØL]ÔþšRÿD©9ûèÎ ‹'ìùfd«"¬HÛ ß–Tg>]›.*4#ËÆê É ›dz倨nŸ“º•» ë=g]àT ƒ:Òý>¶ÑÇ3”Kuts³ÜE·ù˜8ð—ë ’µ@¯-Çwÿ:Zˆ#á0Á.<ÅGôdçÅÓ..”¾úfE‰d´¸,ç~5"Wÿ!8¤Ø17} r/ºôð\ºV}¤¼™ö¯f,È-ÈR}”U-Œì«²!´u(Ät÷†wˆndDšn—?yúH!*âÙmBÈO\x‹wÈ4<ºÝÜõœlm|˜ƒBÿ,5 –™¶\Ò}È.¦&(…Î09Y~i’ÛWC~‚áÔ­ð̱§ÖV!æ>Wõ#¸i|䉈ó\- &¯ZƒÜBC„RâÈö·Y£OW¨Œ,êSÃüÞÿz—éŠèøßóùæi[Ѽ  m g´øëFƒšu o±œ´Œè¤ƒx©ù+¢6àKÀL#®ß²Åû>ɰM&˜Ë!¤“•®Çèü˜Qî—AÖr)ì¢o ‚ù‡+5VISZr—ÄŽOÛ]ÎÁò¾q’F¯UìÆˆ‚>y†™"ô;ÆZ¼ æËo‹>̥ńsƧ¿› ”ª}Q÷)åìå~Óß®3 ðï[¦IÄåºd›ŒF§f€¼9¾óŸÌˆ½QP¸9¤LË·°ÿõ£SÕXd""m:/6øïÔ-¾&ö9Å9]OG|¿– òŸŽ™ÄǯRöw~HœÆ†`vså,_y¨8»Ô¬½² Rœ´›u!ÂL=G1ìÐì©øfþFüé Œ±9ü6$ UaŠH?P@Z-Ò$ºŽ§G⃽¿ÖWW¼\O$å:æVí…z¹CÕï$ÅÚԬ畢(Ë…T p L•+ož¶Š.¸v§C‡$ª§0& wôzüè÷ÕyjNëŸ3dõUj-ÏÕVLg%ò7ÑM …_ø_æRF¼CKù’¸6í C…C¹$jgm,âbDù‡!î}M‰¶gÄž¨´Z2D¨ÍÿHùX#Éf1²ƒk¬púH ‡4xâÕQ¹ƒº®oõ¬“Š jÎy»Ù•7Ñ{ˆ›7½c­6‚ãqàYómgÚ•ûùñ>vÏåÂ.“w©‘ÔMÕéXàQA^Š$0L kÿeãeòÙ`pxÄôà˜Ÿ7Ä|œ;´fY,6𨉚§RžP ®ÞŸRrLŽ4¥p¼-&$SFg¬8 2Aç (X(}²>&âÇšI­%“\h¶£ú¹žm¨h¦órf\Ùˆ!ÒN ¼o•›ÖæS‘žµFñ”€e[ o6¨åŸƒZ´¢T V7œ18Õ=Sh ]ïéíº$Z„{©¢çÏŒ´—ÙÏQMmº(ÚR3xø5õÖÞ…Üm‘ní*^ËmÓí>ÇèUhvùܪR«á¾ºyópŽºq¥¢³¿Y,ÛrIPr O´å¬L¼“‘ èešÝà«þ¦Öª&Ch ‚·ŸzNç.bÆZòeÅJAÍš·'àŠ™ô…º =ùkÍK³¸aÉL×Ð྽öq›þÑKD™ •­Oʉê1”o4pe…ö“hž†tÃʵÿ<Ç¥îPé`¥¤>úûÏXß9BD(ijL¼„E^7ÕïXi‚Íd)ZP¦hB“+bÓ¬|Ëßô ^ Âæ˜b] [7¶‡ì¸Ðj  ƒWú£pTFF0év+ÙÿÜ…u³î»[P0üŒ‚~ ¡LÊ(?eK$÷0VŽŠ$O¾'ÍìŠ ìÃËe i1^á©bÍ[ió¾Üм)> .Åå/» gmì<|=\éñü¸f´ƒföÚxøôç›ìˆ ¢r8DÄ#}[ÎmHvÓÚ‘¹ñ^áYÅ콡‹è€lÏZ6N"6U°K®»‹A–=©ð$*Úkð×ö¢¢oì¶Ík†X{J“ÀX3nÜFÉò»¤å†­Çz'G×ì.ÿ¤fâ‚^—Jóä·°¹|1  Ø3+œªÁSç…@±¬¢Yur¦ŸQÅõÚrÉ·Á™ÏF4eÿx —BCnÀ@o×MÊ ¢Y[ê((úæcZŸVþ¥è—ÉÀÏ]ÀgMŒãb 3^á=ë¥| XŸw]utÓUlÒ•ÞíÍêæ>vãxÝÿ%ËÃÕRò·PÛ’Ž¬”Ì(>:Á²…Ht«I•…©*.‚Ù“†å2+ëc‚¶á;ÞPE’x@L¿æFø¨&ÃÔ(Q V]·¿×ƒ:àVyÀó½¿ú¾Moù‘‡‰E4TøFØ&Y ¹¨Ecé”E¢Ÿze*IU ÈV('z§ÆÛX|QM¦ë{‘-Õtðwb‰A*ë–Ô!9|í,޵ ÖÉ{äuI©HXU¸æöåâ®1“Þ›Ð*UØæNYÐ1‚´P8N†—èÕLH’Qƒ† æ¢1\¸pÁvÖ›ÞáÞ«çY¯£5YÃþÀqËá´3|žºiFø"™¬b”+쿃»¦ºÄ2p„î…|8¦ì`×éµ_þ»#cŒÉ =¢á„Ἣ~0üÂ…‘àýò{'ãkãÅE£úØbûÒõtŽúÈ4uæ<®LÌ;xÓ‚•y`Cªi:E…3BÛ·øßÀbÌúƒ#Æð²‰{Û"®¾z êe°ý­Ö ·q¤Ù ¹wP¯o“{ES5âév$%K[¯±Iƒ°g$ÍÀ9€hþšZÎ,Ó'ç,8ùS ˜³"eSRv]ä‚/¡É•[î×µNtvºJT’ÙKÑ·ksçGmöšîR®w™~”ÂYµ#D’°ÁOôOÑŠ~ö£ähM \û`uòü^‰~Â{ÞVã²ÉEÂd¾QuX‡¥3öøê;ïc ²;ÐȽc½º6lS鳟ÙS<1‰ž~ô}O„îŽÄwÿqçÁ*Åû̵ç^„ÇV* (ð,qJ¦Åák÷3g}^h‚6ª©tµý£h6hE¬ÇApŠú¯C ¢Aåµ^B]‡‹¢³Yö¨žŸƒ¤:Uÿu [#;8UÜRÊÌ_ºe§VËɨ¤öÞXº¦Îiµú-[6Á†û_ŠÙ¤ˆurI¡ëwôG¼ž!Lý‹¼7ëÿZ áÚ}õ¼}9”qýekÇ”åÔCˆjgi`ÆÚ¯4ÈÔ”p §„Á“›PØ •ü¾°à™xêÒ3DI‹Ñ«¤²¶*‹ÈAåÄF~ë;G¦Ã½¬9É井¾½}û5ð{¿»ºº§’ѳ0€pDYÿ‚ EÝ \™Þœõ'»(Ç»ƒP ‹©BüŠÅ«ÿ9;ió<¢Œ hÿLÁ4?`6Èó™'1ØtG=`ÿe&¸ÊÀöÿ-jSO‚Hâ·T"ÿ'¤!vF_bȪyõèÛÁ.# ¦"´º% +¡ŒòâŒ%èÉ´Ü`ŠGþØ •ì©SÓ@ªrc—½ æÚè=ˆƒÝ•KcëðdPä„›œPUÚ/¿“Î}8ÄÇÇøãw ‘ÜQH Ñó‚¹YA÷˜*W‰]T䈕€ø™o³MÜ0B8§Q'Ó‹®!³—”ãÿ1„>Þ°çqT°F2ɧâ­sé°Ú£ýë ²³,­OiüÒBFh™/—š#ñaÞsKo0F(DÍÍ@ ob8Å¿õëJ&PçÛóž‚«¾½¼À‹Ûr¤­¼°ï¡‹õY¢ß(8áÈsg4¾÷Ð/ß‹ý˜KÈrhSz½¬ô‰à®!èª_)Wo/ŰߖÙïTK+Õh¡HCí(À-ÐO–}jj…¡y¬„ÒÑ&—,ê´[ʰlR”[lÅ»?‡Š¨/pŽ‹ªZ¢YáDõð¡˜-$g϶{ôÏ¿–\æS­Ö'ÙêšòÁ¨…»—¯í‚xg'Á-ñTÙ㇛“^Q*¼ac÷_ ¤¬øRf›ò)û¯ã+«r SͲݓ’·™0ª …¥Ò¯2ÕuZ›ahX‰3ðÀO$U…‘†‡ÓEddaXör„hO5º‘_1¬æÞ èŠ™Ûç<‹%PŒ Õ4QFkNÆÅ€îì1L±a”hÕ…`nŸqW°T¬44.ìÛÐWÌÛ°uišÈ‰}âTUèzcÂU5P?ɼ,'¤3jjÕég%öMäuR‚̱Üá•)•]7#ƒuDâ¶·Vò¦:µ@4Ý›eW ¼Óá ´bÛQEév“È Òµ–°t¹xoÐ=Žç%¯a"×+èEFܪÇssr_Ý*ÏoËcÀBù¦—m0Tç§ð¨L ¡×+è1|áP˜qnÖ{0ºqâ9\¬˜H„–sÃÝJÚ¨½TFCå&¤÷ófsk‹{ݪjUd¬g÷ÙáŸÂàÙŒ‘N3¹W0­\È|ðÕ Æ@3C?𭶆‘Yúg°ÇG¤ÙÇn{Tbìï/v¥Þ«ãtý㼜b}ªS²˜¤Öpʆ¯-1ÈSü¶SøÜ Ž"Т‰OáqB·7ØzŽòÁ{bÃ>K$4Œodaæå½Q};TÙåû³*-NÒ‚:ꔸ(‚Y>U¼çMT$Ïâ‰|%•Nyà4µî –A:ÿ:Ô÷N6lþBn„nówkGô}ZF±´`K ¤kò9 … ¼r~|F¾¸×ÖKÀQΣ¢Ÿvƒ21BÕðxÀø·Ieoú‡¯*KÜ'ÌI¡ú/ îEi¸Ñòä×C6‹÷=ë oÒ8žEeéC ÜŠ}´Áá× c|J©y“pnõ“â$‹ˆ[Ë2]l0³_dy€Ý"ùÓûÓõãØ¯»:h(^¸Ôó¡ät@v†ÿ uû*“ü*¯c3EÖöŠqÅ WÌ„Œ=Ï5:,V–0S § º¤æ³8ü³'äYÜY•ЃŒ4:‡<*žÂi®©8L¢dH©X•C]…§Þ^& %€·Z:Êxò38Åœ”fktC„ªÎÉ PÍ5ž±ºˆ´k“ì›±óF1!À30òF§†§ÂiÖ±«®ì·‹WðSï›ö&cC¨ºƒd-—}ýKLÓ!©D@Ÿ³->ž‰ó;“ã „£ªfX½©ÚmgO¯ÜFÖlùiFrýb¾Uu… ýr ½A"«<ëIÍSTýC\ë`õcI‹K¤¡‹ÐD¥¦W„Sq`Öý®Þ}ÝèrÈæ çr–p«`ÙXéîG*!M6~íÓJØ‘è?Ñí:Ý5Cz·È›@ýÂðÚίûÝZtƒr£A±e[ˆ+÷¢q G ÿtŸ¨|M 4|5¼)`.G¶ «нÿ7œ'äkïD½Þþ§VÙôyÈT‚3²0aÔ¦ÐuÖ+YKÆ &?ó}å'¹Jä‘#ª"á4|ÎÖë1²“}ƒL!Ù<¥qõí)Ó»¡QÒ² ò&WŽ,+mž³gÜçéÞ$±ƒrÿˆÄ‘J‡u«ýµâŽ–"Ó¹…„C•fG§ÄDªÖ6œ‡º¯&ûÈij®ä¼F‰ý2y€.h°Ò"¤ªtD14﹦léSó–¾”õ}‰bé’ÿ‚€“úÑ<*ž=äcc¾ÄŠ0÷óÙ\–Á5ù”¢ê¬5vªÔ9ò¢²4Á€€m0š0rñI…‡®‚o¦5‚ó㑽ý|¬#ŠYí„û…e»2£ƒŽ­8KníVAäØÇî¨C…),¿4 yÙ.؉ÈTHŸ¸ˆÓ%Ï1°ƒ* ã¿Ù¾‘ÇŒ²‹ î7nª@À% aó\ ¼ò½å½lËŸ¦‰É7úRƒ8Ò‡ —r©…³ö†ŠF‘ÁS^7xùýz߆¿ž'‰mž"»y¦3¢)ÊŠ½³ªN­]o-ßUÇ­c¦bö‰Ut íL˜Ð¤ovH­ùÔ­¿ez׎¨…÷Ž®åݤ£èâOEs««ÜŒÖƒw:ýx$ø|ÔfùÜ ›7sªük$R3OÇàñ|v´œ§d2°Gქ ÈùÇ×Oy£ÄN…wê®]*´Šõ±>@ï+\ 8Œ"âpe‘–ÈO+ŠY¹V0Á«ý]ï~R¸¹5¤ü`¹'Ç]w힘¥Y¾N(×pCƒÝWvx¦ÏKºå\tÙԈǢ¾E¤¥C5}ÇØ›S“pw\ìxÇzñ›–S %RU•¥(ž8Rô§-yrÝ—î,,>"2kä"Îs®RU5,ä2¬9U§I0îrV$ÛÀ©(æˆmYB8™héôt²…í ¨X]{×ûý¦nÖó•ñ7%zo)JºÔÄŽ:õR~‰Ä¢×ƒÈžB}¾9‡ßs¸édÊRnàl OÖºô!gz¾’Þ´khßJûlž»w%-ÿ"C’ŽT÷Ûa®ÇüŸd‡®$HΉúK¡É`Áh'añf•j‡ŠxDiº¼ƒo¾‡/l/#IÔÄ$OÍ0ýjái°†àQÚÈeo¿Á„”îö?“6e)bab/ .ûœÇ!F‘:Y3(ŽòxV`;Ä>ÅTöツ0wÉt®·í!xM^ —[`ÇœŽË¸V(îöã†pa³> âÉ ÿ:n’¶1¿Œ3>¾ñ'i$ÝÂK[_ß0Ôšû¿u.ìÆ0™Š®â8yR@×ëÈéxy ß>IîÖ¢+t£u†³»§áùbuÁy[ãE‹_ÏÚ6û! ßz<Áv¹4Ùw²6©è‹U—Õi@>Òíæ ! èÀcöˆZñ¡€ÀslÕãA#|ºt2úc²“Nß^Ô|"à‡•€sÝõQÛvcW¿ÒˆÆeïƒ;É/þZÙ F±Øì“€/ײ+3µUI>ö‘·äÒ '{ðeJQ˜`x¡ìâ"3í¤cÚ™Y9‡J†‰oè:™Å8È­zBñ=Àö=O±ãÍX5Ø‹ó›HJq;ÍÙ/3¥¸Ä ø¿îáIaCøŒÚU¬sƒå˜ÂèÀ|î9(s]½6º¹·aJŠ˜FÑÿ ,×ó±ÍÁvywd×CqÍÝgrˆqµ\-ŠKáÜ^\ò‘N¸Ä$ëþ:üuSX"‹Ôv11 åJjëÂu›þÜÔÞÛ«ëygõÊr¾˜“aWÆ ±*÷÷A$:܉ؽt?‹‰¦ïJ°Žô·jÆnOO;IVyª¢–€’…*åh`Î_‘D ¥z#mƒx 0e€Zì–«y‹@³¨ßˆBÆá„•Uwxð kÌá™®ËѵøñÂAL|<2Ș?Lºü›vÇÿTQÃZw9±–G¢M”Ãm±qÍ ÝàÄcgñ™öŸ0êé{ZÍ)'!œï2óö.§“è€&»%æ¾í ”´ôiÞm›wŒ%̪N°R]Ñ¡C §|fqíê$‡+agë")œ+X—Àë;™ü?8Œé`QÛ…¹¦®-ö¿Náqª·—߇²ðt¸f¿·dé+ í)úÌXpu³öa͉ÓeÑEŽiÛVEý|;%“N¸Tº£VØ+ƒìž]ž+ÐX[!€fÁ{®Vx5‡GwdÖŽœáiMÀÂÏçžñßkXÙU?ð2-ø”z§‘‡ˆOcÓŠÍ›†ç‰Þ$‰íÔ¸Ž»KV"xFŽ¢•Uˆl–µgæ„ !õÿ©¹çR˜Ë¿>@{N.1Ôƒ|V]kÐI· ú‹Q•x7LòÌ2«±Ç_œ žÊ&àrÿ&úAa:LßjÈÚ)ËNΓù¤êg%o[rÁN‚£üÐ,çyª-`Pž]Ëá'‚Šêùe’Ù¶Ï8övsn$mù0Ò•G”Ÿ*(™Ò­sdèæ²â‚p¼y}?@o›úÔ¹©˜îµg” å98‘‡ËrIH_º°_Ém·„”GÃ#h…Á$F%…‰÷3˜gǰͬš,†\¡Û+"u§­HTûb _ɉOPrkÚ¯V3V‘~tOM¥î…Ÿ‡–nŸÿu4'ô=»îö2ž©}ø z<+DhÄHö¸ µ^š÷Öç|¯ù g‹ »LH7.õ’óU¯ }_tä[‡ä"z«†5åjTСíD]]ò~Æö+ÛªšÀ—|³ lB"?V­ù±)ÉÝg؇&˜è¸ë íôÚß ³,QÃ,DW˜Q:ù„/†{Û eÂylywº¨yje¦ù¢Àží)6ø ¹yS:þ}»·p<Ç—}nžÁ•ä–@Ù¡ž¶ú)ÆXIŽfÀh}ˆÞ­‡ú©%m"æß*©œŒžövÆgœ\®ØÃ2H}B‡øP@*ŽeïÍ@ÂB_øP@*d¯'^\N“<Œ‹w³ltô†þ",¯cS‚Š‹SŠÆËIJgÃoNåþaW îfœ)báOêФP;**„Ü—¾Ã)à‡¦‚׬¾YJ;y‹I¯Éßµ»“je[©çož%"®\ Ù |á ê¬ÁØ »»%B‹m‚yúi €^Ë:ýöâqQ‘£D°Éšf{íÿ*xÈÊUX""! j¡q åßìT(¬ê /wN‘e-ÉêÂÐ_ªÛ6ÏBãÞuÓÿ¿x®óÍl¡Úr A„žÀÝô¹8 2\E ‚F </­& ÿ #øbÀ*€é."Ë ÊæÌÖ‚„3èƒ4ÞÈHD<6p?\4¿ø•¢–<7¼6Õ¦‹+¦ü Rg”—z³$ž×ãC·0°_–ÊÏvê×ÂyN•dÀÝœl’õ”Ÿ\åâÜ\¾'â‡oÃ?x±:(¤{Ë4qY¤P4 ˆVûçÁLå¥5c'ðßDîÿ(WERÅrã ­Þ([ž<ú âA T<±Ž¯onEã .a0fõǽÖhØW õ¶"¼R]¥1œýzÔÊ ¡[ LºªßÓM:mà™vñÿk‡d_S‚Œ0©:³ ø“Êà%†Àœ¸Ló+ùŒ ¸*aìuNÚ}íTVNªÙ/y¹Ú|é'b$tTTŒ®k‡úxQ®«ðWÅ×¾-ýsm5 ™ŒJª4ÉbO%†"téì°G¶Räi”ìCù)ô•Õp”øS<ØW´qÂÆAò‡R4 ¶vKHÍåŽ6Z4>dX„¨óHD‰{­®^ÙÖ=„úå`#XÛzØ£e½ÁÌ5Åz Ñ$âÎi¥*Kz(¸ØÌÎÁâïøZ«z²vITÿPïš HRËÌ34Ýîëe™ÚÃõ·ö6@vŽ´í'tn£áëqS‹Kú˜ÜÉù¸Õl«zâp‘ ¦nÍœu#í¶: ÔˆòSb×îêÔø¤ÛÚ(tFY~Ê¡#K«2Ë=}ç²=ÑiÀÙ³\_R´éLuïÅ%›m‘µæê4ì¨FÝ^-f·°WWÄÒxí,SâX™›\’“õ‹K·¼´&8V³8Iª¢á™Ä—& [:ii¡˜£òÀÅ~ŸÊƒ¼¿øúä†d9Ëâ¦ü¯\ĵ*ØNHär”\àöY|ˆß W——ô˜€À7*('|ÊȯvЧN$5õ˜ª.…¢î!7ߟNŠeàÂÏ÷«Ô©Tø®žO‚âZ²¾×ììŠØ®•.“ÔT‰¹Ç4⓽û0š<|9_Yåßáñàuß4Hܾ}AbŒmoý“qV4Á¿Ï€R ÷BÊ7 ïI¯=ÞÛÖübùþäo.6¼¡ë†Œ¥¸š¤BÞL °0.äy)HÏø4òšçè›Þþ±w&jAänÔå3Œë ÐA£˜2JÊ@N4ñ¸@aê  âß7'2}0p.ÒefSàŠålTðs>jŽ=8 9³·Él½ãî]2E=ž!AÁCKIê(Áõ©`Ð ‡¸—¥†Ñ;mlÙ<c³„þV›—ÿc¬ˆG¼}ÈáT˜˜„Ã3Þó‹GI‹B;)ÒÚöB=©Z@G*‚ñŒür©u{Øȶ[ 8Þm\Ї5‚KÉLýÔÊ•¿DŠÕôÜ&þ%En‚(ùä5$ Õ”Êj<ƒ³’'?N™mr:½™Ô-p&‹q›˜­§1ûf|ßqÊåÅiÅ`+–К¥¼‚žEe²Â"ˆÛƒÈþSÓK·…ù°IÌW2epí™E£ê®sÎ’¨á·ã\*-AóÊ%²'‰ÇpQ¸ímúCº©Úhìù~ë(ˆ‚kL$¤¾³«»lA4ÓÍ£9†ËáÙåAS‰÷°jÐÔð³(Uüóñåm…Ï65ü„Kã7Aš›­lqùÆ»¾öL–?¥y$î…·zÏö2FB„{Í1Ü6Q} 1r3\°Î•;R5 Q%V='s0ežm§ÝÈê‘c9¥ÔýÛØ}Ow3º·—4Èt°ÂkJ -7 㘜ç{°M Ççwm¤"G€$n[øa»$êÒ‰Õ6K*}DÉõ-ßߦª“Vq±iË6,Eê¢6'OŠÞ=Èæë>»°VÏ‹DÀ'?~V­%˜ ¤ FJß ›<¨FéÊ›‰k;‚Vá6M¼5¦¾¦-¾HŽV¢³__{ߣd`Á¼Ð) $…ŒnCºÄð*X ºM•­] s[aµû¦$bÛu`ÖlUU¹8V”;´è€úÞKkŽËe𢠏…£ nf6ì|®e¥Â˜.‹®Á‚è Ø;³ô TÚ•×A@Ç-£èJObíÅ:'óL gÝÈê„ji®F'¦¦{Œœ¦ySkÔÕe>Ñv¼ÚdUw²ÔÃó+‹¢0 bú¨V™˜rOÿ7¤Ýg6,øZºry°Å› ³Ú#=2LðYþÓë¬Ãø‚}cÜû‘¢Ly¸Qª˜*’¹·;XÙõaÎq§$ÏÙü)9bxÝèõô1iF-¸]Ç#ê´€q>HþR&ƒZÙb¶'4Pjż5K˜ˆ­œºâ“:sÿd|×sW÷@`B_j™X3ßg’g§£ß+—®¼¨Oîvž(Tª ã†TÏà‚ ¤ÎŠªœÞÖ›ÆÞ …(^_OÝÈê“¢ßì>„„¿ÝÈê“¢ßì>„„¿ÝÈéñͲáK@ÂþkòQƤªé‹ßHÜ5)ø?Fê½Ç¨m%¼´µâ¹k”E;ÍŠaÛ®Ñ%*ЏÇ&ƒ&³ö"ó}Aí¿ýÔT7¨A/±?»ÍYKr§ñ«žY-*ØvUtÃe•ò&ÝøÑçŽ jw„Ô RŽ+ýÍ/çÛÌï&°_R´¹ªNCºžìÚ¹YÝ …Ÿ¨KM®™}¶û­zÛ_†þÞë7=4cNÄó!â´oÅ\Ýì 2ŸÌ|cŠåì&WÐÝ LÔ¢uŠ3$y«zT=®IÚúnëÿPùÝ"ve®BJ‚#½å-Œì¢ ‰F"îÜE»KA”-‡ Üð퉥/› _)ϸ ›:­m…Û«‚»¯Û=Ê™—Pа@àX/—i –8­%Æöß Ð:K§‘ÐTMf€¨Þ$RiÀÉ7²Øº5ì¦y\j¾I4~Én˜Êe\ÉýV+Ó¢·¸{2«ð~5ºs§JÔE”×ĺï¦áÖ¶ ž;דþ€ ÿH†q†ÀmD:oÂTœa›S1«zvqþ ðk±êÔúã"/v6£ROõy÷ÇCØé]ÑSâ Dw1‚^#kˆì(Þ.­/üNZ#857 Œ©,EîW7A™|v=¢Ø³©(/¥Ø.³ YÏïçBZ|I>‡Kª´šÆrÆ6EÑnA ¬NñaB ³Ô>?Í…|‚vRjÐà’LÔ¬ƒQÊëòœ×dÖ‹L¢×l;Ab¡ß)6­fIžêZºó@±Ôö“Õ%å«/\4¹)L‹Z®÷¤ÿC“\*öSkdñ›©*a¹±ó§hçV !è@œ£åô i“W8¢5©‹ÅÅX”Úy|Ðóbg{¼—¾Þ[Rz½ ¯(¡ÞZAû}ähg+UÇà{$ZR¦¥ÿ1£ÍwS%-Ú¢22¤å°·³×1Òÿ*ùõøõª ¬”AÊÖžz\ƶŷçË9VÑ^Fn7ç°ˆ ™·ó£]õs æ,]S¡Ÿ¤dúGÐsåK&ñ‚6lµ@kèÁ¸LÅA4̰'–ب}– %íõ3=b»-©óÏ´è8½4rqæªßtpÌmøã6>r¶Ž|lRä²Àö¹þ°v®¡œœ ô7`XŒÎÕ$Ò¤pÙ#íÖ²#¤›tyQþFn%g©†§>Úé;c¶Æ[›Ú.É"ÉŠÏËI#Ä&%Sv1ºp,µ^GOuÐ’i~i©åŸ{®ÅþoG¢ˆä5œA½ºä¬dxDÏGAz«®L|¸sXâêv`Ô Æ¸’bjæãP¡ÿCðCI+Ô)™ÃþÑÔ6v&xyÍ~²7Q·œ`À¨U¨‘0Mlȇ8±¿—Ú9&Ø À`ÂLY̆6C¥…1jc,Ö&øÑÆTÖò Èp󵿣~#BnP¹À«óÜáÍøE ZG£*–×^ò “ɤÿI7sGùTÔj ¾`ÿjêoÿ\#®à¯uMòYj™?¸¹Â'ð>ULàéWƒÏÓŽ¢Ob8· Èõ ªúÿŠ ¼ÈAþ„AYì•èhcvˆÝ÷¬¤"$XœÉÂÔôðRéR‡!Z䨲‡uöMÛðoHÕ: ¥¯¸Æ¤ß-v®’üE;Ó¿–W„â?o=“®ˆ™0 '©Óú§Ù½ì×ü©C™‘t ÿ`*2µ€ÍÎmO³¸ežQóvôvxh¼ªpbÀ놓~mnæä\g7ËU=ŒÏ¤TBšäb¡±LÔ÷‹`q·oK^Àû}Åé ócEmïÂWìè(D ]±‹<îP¹#è¼-ãö€‘N•¡@\õéÇ'ˆ‘áø# M~†‡!ú_‘Rcä0µsüT}Ò! =Áœzí]e:iâæÈI‚?Œ§ïO)v²åa…¡m4wìEYr®ºx0²¬5Ó’µG«ÝØÑ ³µM¢!‹Ÿ*‡ÿ>rh°È¢i’Á÷ –óö šÑ²EËŸL°µ.)ÕíÌø«°£ŒMc“ÍÀ<\Ž‹{Ä5SO}ö(â¦Úä+€Ü%JYÅáx}V“¿"# Xjƒ ¾ÉŸÎ(ÝB¶Œ‘@|”Ù†O{òŠÿÛMãË$–˜|¢†éŒü”IF{Us¶ºî,Þø¾5:},kˆåF6ÞΚ¡*_íQøôW'ãh=/¼N‡=ç~žÜø3œ¥Ñ5öêžwGGªì¤šJ€÷¾e.ƒÈÖ8ñ©H#Òmâ—,ÃbÆö’™êõÔ|Kå[8×:Ôbµè÷" #úJàØ~êäüa‹E¿Q9q‘9úÀ.VX l¸0¹ÿãö†`,݇ag r$·[½N_2ÓKÌ–:ÄÒ2ä“1Þ´zçpïÿ#á{¿yU^7–êCöt¤ù(I´d5ð & ï|aððl÷Ñ/eªúüHHüþýÓ@v ´záèðA¡ ;Õ²D³sÕ‡Œ„«t¬“ï)kÐÛ#êÅ1ØmÕªŒ¬æCµcÒýÌ> 'ÜÁ‚¨§^&ÕDt_>µÂgŸŸ8¼ÿ‚$%#Õ}Âu•ôÁ´Ý’‹R‡³oø½Ø¨ì|BS“Y¦þ™Ì´SÉØ¨Y³£ÓuÖªïç)^€ÂÝL—úÓFâøTºA¨÷‚­†ƒ~ˆ2ì¦L!.›zÛÁò†¡4žÑü°1Íå#Ž0éc% U»C†–õ»Úçðfa©ÇQ€áǧg÷©O[È3ññØ6] pSï}ûŒÓG1ܳ2òÖä|ßÂ韥Uè)…Øña˜èhtùùò«hä(£ç5pÿp_áµ}LðÏñ‘±‰`%q¾%NEVÙ½rㄯ‹"€þK[AuiáBŠÒ ‚r–U…Yl¿w6[­Aò&šØQøÅx*ÓÀG#쉦£°¾ÎÑ ýXxdJÌÛ;P©%@(}C¿ÿëü¨Gdz'o9ÂE…Ñ—ügµÁ{mPª#нcgˆ‚5á²Ì!rƒñµ j{Ý]_o[S±ô|2‘æÆÌe‰˜Òù]9™fŽø×àŒŠþ^Í÷H¦ˆ<~ÔÓæé\Zü¿ª‘E4¬AëÀ25GÇf¿RÓ•"&kš}Âió@tM¨dføÚv7*š*ƒ?w(B‰Pà hÙ÷íy¼¹Êԉט®¬^[Ž;£¨b•<¶¢Ç¬^ òbÎÅÐ?Ï°Çæü,üÖOEéc@é‚c £×•°£ÀjË~œaiœ)¯Œ¦ Œ8Å䛵=æ'Evzm°ã’l óÝÓ\t|wy}“ènbÛg¬Ý[ïJ `ÈÃŒ^I°3¿ïµ£"«ÇCœËQ¤´…mcî 'ü6%gûŽˆ$ÌÞ_%¨P¡¹Êsºä2*é4hSSÿ)ÚJOd½Cïj©ÖÜmÍX÷Áe’,x’a÷†ûïgHÊ Ó»×dÃÇšî®ü|hä¸{·'"Pé(ryŒûÇì¬Z¹ï¸J·±‹oŠÑ8Üjÿ×@ûY Uã /;]ËDòâýCðŸþAc/´íôÏöÄeEXq˜ât&»4„n"u !x~ÆKòó·Œ‹Ó .¡Ý@üÎÑ •‘Ðü §8†Èå}Wzûݱ«ú´ ôß!E_yñcÄòòË7ÀP†«+åÝžK5i˜ï¶×Ó¤ÿ;cWõ{D‚´ÞaÚ»{ <¹T³w°ùCŒRÏÁUs<6’Y£*Jp„,  QŒ&÷ð’¸Å…Û(ë² ºè/qˆ~!ßó3é$ã2ø‡B¯ˆ—g1½tÞTæDUí;ÿ‚¦ÝQÿgQ)J¢ÊúlúÃä.]HNÅsá-Ú–ª¤:@¹H5 ¶ r” w†ŠÄ¨|á²^:=J…r j{¤ÛÈÔõc=iõvftkÚý83©‘”娹6kŸWd/ |ÚzÂhX¬v+O«¿ô„f_ù.?͇è}ÇÍÙZ/º5±:¼€qÄv.VÑ» !ÊúÐfÖ7¾hMUxbÑtŸ¢pø·XIÉÌ¡‰åT‡Z½L"\ÿzQ†çt6`Ï^”œö šcKýQ¶èQ}„”WòÙ¡a¢Qè?™€ç€\pNOŸ0 Ð4m»3\Ÿ?X•P=ѶêD:AïZƒ?ãQ½&H$5î,DUõ¼G¨—ãþüðØñý¾n^ñäƒ{ë–ïÆTÇĨ¨ :ÊóGòÅ[¿Eˆøô*«V®UuyZs'ÊI›y`XA øŠí·®'Å®ænì’÷(’Ó4 ûÂó'´:’ÿ ÿÿ/§µ˜8Ô¨ô‰ÏðËÕ¬¯X°½âBà!¦H‹§ÔÞÈÿ²§ÿ~ËH¡Ih´çPdza=‹Ô]%A Q†7;ɲßɯRûðø£ÔÍJ$GrF?$'õlÜDiÿiÿfü6ÀõV Ôlû®%IÂÌïsÄ5e›ÈôÔ—pd*ŸÛZ Rk¢‹çãi¯³Kú¹lÕ<µ6ÙÔ|üÖã ¯ÅD%lý.>‘\ÎoTŸdX£W³Ì@þ•dáÁŸ…©·Ë|İñðe¼Ëw @MxÈÎO¯ì‹$äOÑÒîΪdÿt¤1'o¯Ë‰n2ÏêDà ¸‚ÎoñŒˆI µóÊÔÙþË4,…žY1vwfø9C”Œ˜Î“.ÏÄ$ÖŒ„QÕ"¬êÿ'o7wî_½_[y,š*~Ä„;Ê6z–!‡ÚÞ¦/÷ÃÚà*&m<duL“Õn/\ˆ~ˆÀÄÖVå–n®~×by‹Œ­À ™Q¨m’;¶è¤Ü«9.îÂ7Oyå<ÈLHá¥*´mMn–h7?°ËúÁÚ¬ÙÅ6̱£zl/L1ülðfX*sÙlî™Ð)äb²œT<Ó¡&a¥#uB—IQ‡•ÂjÞ3¤ý|ìëËBMð4ÅfÓñWO/i„&×ñß Ue,%¶xÿ+etÂó¢.ïžÌ0XÝÁižÁ+Þ†8‹lH+d4¬ÏÁI¨íàÌò¼-„ÃíÕÒ„hZÿu%#h1îYƒׯÊo×à(K”Ù`×+9.ˆûŽŽÅmhlÿ\a^§óŠ_ûë¥ßjî+ù¬²‘Å· ŸYóÛ§¦ùżJ[D‹ñ†¾4v nãíË<€ë|˜j¾¤äY2Qóíéµ2û‹Ï¨9­JÆh±É}JÌ_Ôš¿´•G}òpM‚ŽRô¿¬ü¹™Â/[;ÅQ‹ë”F ʉ:09'aEwëÙåÛñ*æÖ;þ1iLQ8r× ‘EY¨»Ÿ¿ŒRµI¢IВФâÊXå0»Þ6|öÌvmM6rÅ¥×Ñ÷î/tP¯×±¦áƒžñRÿ^sõÝ{dŸq+"(&ÎF¹‡X;u-D¿ª9/U":Aûˇ.Ìã7Ã妩ñ¡úµq_ÞÞ¯ªâÑň ÞܪŸ…0ÁJ }Áqž2Ô­ž:}ZÁ$YÃàWΛïÂg¬üÿTà›;ÄÆY“vÒhë£0â½÷Ľ̛nè¤r)(9šËØÁi֣݌Õ×7†S¢‚{±LtQXÑÊX,–7Þf‹oiõ£`;œíJwßägé§"ë9áïô]¦’äæþrÑ&¼>RímžÄmŒ±Ë•jCóÁo#â4h5œ:Ái8´™ƒª×êXA¶Ñ®Wl¦œ·¥#l twt[CMû+6pã¾ïùÿ ⽨‰ê’‹;‚ÛPÊг•˜3Á,ô‘ Êq5°5 œîn%Nðs¸zéÃ>†Rˆ*~…åÕ{¯Ãô3Çf£ ‹¯Í·”%ïn§ºßÀÿãÌ*°q)–Ÿz™5‰ç¢v›˜$H*U¹F¹Ôy± SR§«(~“[q»…Yk»½r-ÛvIÙ93m~ ‘-øpßéüÅrl:ÐI¿°ª½èÄnà.ô÷÷€&Gß%ûL”Aó)m? ûí~ïËóØb"”:[ÚZïgÆdhàvF÷¾¥Ó)#%ØØÛ™ =;ð Åg(G-TYlI¾‰÷XÏém¢“î“¢à=1—"‚í§D˜Þî80Vl :?í^VÃÔÀ‰¶;`3[{ËéÎŒRü}ÚdøxøÀ°Îõ ™>ðg–ûÔïÅE™Ñª©‘É0µsrâÁÀ ZÛst’ª f)ò.gŽrÁ.Dô%ž­ÞA> _µ4ìõ5ªƒxø‚žÞNÜõ+tú¥ÔOQAè›QG= îŽÌ.û&È–[’øGÎv ’º®L‡”>1ÉcXËR9}C´¥¦‘ñ/ÿ.4¦ œÉ­Vj<Ãöu—¾ÅâÂqVš½ Ïe<ŽŸ²é%8Õ_¦<¡×nË]–Íqº_‰Æ®g(æãÈq‹•š›TÜÙNÏõ›pc&¦*Áª–Sq Aˆ}ÛòêÁÅ0§X ;AÓÿ!·ÜZ¶ gJ²Þ5*ºÄ!ÐF³«Ï´ªÁ¯Ð¤ ?c„ýϱæåÍãlɹŸQ‹Ê9ßXÙ› ±³®€R}fh°›‘-^ˆûW*-¤t‡Ã$ˆ=¿a¹¤í“¨[i;†8t°S{6¦ôqá­Âñj²WE³dÒ™]ÙÆ¾›>YÊ4½DÑÜꢆx@uÐx>ù/N߯€gäW°_^+ªøÿyF£–e²a‡€s !ëÓ·©*[ó 7ö-åØ"›ÿò¦—£WšñÅð8ô½ í:?ŽªÃH»9S‰þ#Ó{y|pJÖ†åÀ 2! ~u±ó'Ù÷PèCy[—+EÑj]¸l/%*Ôñé0œ˜½d¹Å¡;á:ím_‡ %rwéWlCæã5»'çZ -/¿óô—̬y0Ï*L^±Tüª ê7cúžñ÷E ùƒ?²Wä ˜•Í´Ó¹0a:©°ëMSÿƒ”ؤ–ªNíCbG@¤É±W®¸‡ øê2»”Ið™K0ÑõÌÃp3 ÞéO.d0•RMGôÙ'oúåºõ™lßËOwÙ]…›Êx\dü.F¡™Ót8 ·4c¼}CB'Ò+a2°8“‡wdÚdÞÓ‚ë÷2R^çú‰FŒz¶/n~*¼_à(2NìaÇ"&Ì]§jxí\ÂV5—k‘wÎt+¤”Û–œ'4Óö$Î}^ñOQš¨#c?y°ÿzӔآʎ“«JþL°¼ág‘Àe7›¯,|‚…gE4~hÊ´7(ô½sÊlÉT}‹ UÆ—÷àËr·ï¯'fð4€6[æW²œ¤"âO°¦5ª„’7˜Î2¿*_ϲ¨\à!rèãŽv¹ ea'X˜gæ4¾÷»±W¨ª&X>ò­±EÿéACÝÜдS¸;ŒÈ< .^ô¹èž¢Û;~EÏM’÷ß¡µ×[°¡²¢ëûع/øÄƱ½4Fz^˜jª”z™S¯Pœ©zo#ò^›'m¾™@>#Wÿ4ÿ*‚áR5MQsšÙsIb¸Ôtsî{û¾-+ÂX¼B VÆåäT~7¤p"Fˈ 0ÿn÷˜¨37Ol+¡¸1ãgW!=ß.G->šö‡ÓnžhOzÅùIŒSîÅ©,‘\Ze«vüÍ]´±šIÃO:MÍ«¸õ‹¥’ðÉ ¢ÛG¤sF1Ú꙳JõÖšÖ$eLærS³€‡»Á{^2 URx1ݼ{ζÜ×\!¢`xY€Á^ ¤šèãé1WÃôžÉÁ¹q†º›=ËŠ‘3sþ»TƦ8M`õtó³ÆCBJCŸ{ÇYºßøw¯ 4ß‹†¤"È£ù £aið™Bæ#<ÐR„»&„­A5_[â¤W|Ñ"è¦ê¯b­N$%GDðl\ù˜˜UãYç}ï©iúUdŒ7 ¸Àåw±êY2„?5=Kš<*«t‘€Ñ‚óOs+ü¨=h©;£]o°õ<RDM8ä£À5ɵް — ™#ï§®5ëï6È‘{š…ÜM‰J)Ñb¨tâ¹zj©‡Œ s_ú «(òÛñÿy,z‹*²á˜ò£„ldøûÈ@‰¥üÕiÑ?è½ÖS'åHµ•ï._ÅlØvÿ0ëÓŸOdÊD‘ýRØfzåIó±2Á±ûMLò»}9|nl²cº Êè.g†ws¼5ÐrI¿" ©8çµPŸÃŸk2zT8Œ ðGwfŽ÷»}M¶´Õ™á~þx˜7ø‘‚?Q;ù©Ï‹°”$FM¥hóªÅ-ZpÁ‚2 `˜¦¦Ì}Ó -`Ôˆ÷š³#1³Ù*g5¦«ÖÀˆŒmÏêu$p Ö±/ç åFlY!nÀ…¢îÝM³³|d¯5÷{U î^DJe|ÕǼâ‘“-/3¼ä ¡B$÷±û›èŽ «¸žlºè¤æDć(t{®ñ!ePܘ£¥ëC9®†þdÛ¦ÙÒ(D¯†·2oÕÑÈÊ .)Ó]/=È>› ¢&‚!-ö1¨GÔ†ù²q°ÿ´ôÏŽH8kåuX77(óÏ×f©‰ˆ¿¼wb9¥ÂyŽñÙdŠ7TÊ<d1ò‡?‹pFÃC¹nÿ>–¡y_á ›Í†Ò0Þ«QW*³™Nß6á)'®£©nàCBȨÌ.TH ”|axi9–ð§ E9/ E*”ÄX D9·ãLÉÍ;ã¨J(Ü›_¦Ln¡êx° ·¿’¦ð! ²ÕS€tžÅUÚ]äe6!(ºr`òvæø•Èº° T%õsí¥÷zÅO íÌjñ·ào©Œ& Lh™³=Ô—î‡ð§ó®MÐX‡Ìk‡íf˜èû°’TŠ®ðš"–1)£ÛüƒÎˆ¼¥œ3Õ‚‡%XÕ!¦è4žÖ“øøËt¸A½C¶û†ÜQ߀"’VFý•³ß@‘A:‘)às•7ñ1òXLŸ_ü¼†qÒq9| žãbæ·¤¹M U‡„fÞ‡Yïòù sžèŒÏ<à¬Y¦'jémtucs¢´Ó|[álÖðïr=ÍÆŒ%èíÈd̆”ñ²¤”¹bf#FWO¾.æàn˜áû6Urò4Ác‚ð;¸™•…× æ×éï@o/¤à$²HD‡æ‚}CSÕ °…ìè·Ôvˆy5áÊO±Ø¼9½©îD/Ä-GÖ'äBœÖ6÷SÊƽÊ<œšsšI{,jjérY½U”ˆÄˆ‚¹ÒO‰ôè2.±œR%â=áÄk ÉdR—´\ Ü6â¯0`u~QqE‰r›LÅÆG7»T)#ä,ÛåêT÷ÏI*êóûÛh|ûyÁmdžÎaA» š6p OQ‚MŒ>Ÿ A4QÎÅáØ6BB(déh± 0ix` b޼3‚{´CPŠnâ`£Â>í¯¬‡FbÆ[±Ê¬ŒööYÎÆÃO~¨Þþ¬§M*†ür Ý÷Ì(¡ŠL*[CXyS“=îAµ–‰â‹­ó7{ƒmóû Ž—¤b)ÅezGî<à°Ãt´t{“c.èËc©|Ÿ~ãË%Èéš×'×N‹²#âIÇIeÒï1©ã¶TŒ$•¾r×pf2Á.Öú3Ö<ÿ$¬ý㬊NþZqÁ|ú‘ôGaËãó¿B Ý•-"ïn÷, ¯h 7še|ïs•–Ô mÀä¿Ïx {NSõdê§€‹ž ÿn¢ZWþšÉ˜…Æ?PwÖÁBŸ»{… ›4hö ÿSÂC6Ïæ¤éè ÷3Šwc%R§cVˆ5J|wÂ’B`ZöÊÖ*×fs_À°<ÉfØ 2_]J–.ëže‘~üxI!2¯eU¦›Ö6c§ž i­²üÑ#\E0±Øì$1ÇBC0â( (þ!å[Öð0/6Q‚‡™ÄíO$¨ýêL'ðLcÚEíàç¾Å&#²Iÿ3ê½ó#3IÂúÁè!¯u<Œ){’hѾÕ,ÇQBUžØk>ðnžë´ÞEÕßìm–»CÄ•;8„s¦§€…mH/ „*^e†€íw ù0Þ´†M€-Y!_³­˜èïµúÛ@X¿ÿlÑæMìþiÙ)’>Úº¿q3f¶ö"¦Œ"öª†Á¢ÁÁ¢«Ah2Û ˆC¤-°“¢ûaùå_W!]TéTµÚ+›9ì1ØübXÊFêÆ2aÙåhÜ#ΓWæ)·Aüt@†tþˆcÐóYL¶Aàr‹¥$H²©WUgƒ“Aù1QÚwH?Q¨qK „æm‹<£È¯ŽêéCh{(þÚ8ɹËñéËò£(ª)Üt÷t6ÕÝ`ýÔª¨…ÇÝ“ó÷2|YEóÈ®6üT¹p‹áÌÖô³³úʵ+·"ÛR( tWÏÊúëR³F+úΨ±š: ¾ÿzlæ+ž¬¿iqƤ—ö&W”h¦'û&.×—i±\€0“Â^Á…²—[zÉ;ñ[èh*,oöŽ çÑeµtvßý5¡‡Ô]w=§`8Ю¬ùÕñ4 it(Û¯•¶ªëœ@ÁŠø±ñÚÏ™ÁÌp…©ƒÊMDÍ`M¡¤ÑÒ¦Ÿ‰€-á}®&Q€Ly šfGgU¡^Þ¹S¶äì„­¥hžždÿ/>Má‰t¶‹Th¾4€Ì9Û/¯ôp¨Ó+ÔóTWãiMÖ` šÑÍÔÚ³_Ã¬æµ ² ˤÝov¤å¦¹ K”Ù®¢˜cºð¥9ͶéZÞw-H¹>‚²gó?vá•gÁÄíÊZgYù“‚äÉQ?NãK±ŠéBÿ›®=2$Úõ¿“™w3ÖF°¿ÏiÏû§{¶µñênd YWÃìÑ/òJ0¹2Y5ñU}AB›…÷™ñDJ‘¨ .#®Í út·k’Ê>‚[þÀO"JEæPt³%BXº¡r þÃOÞÕÐBëv`J¶¡kWv0÷넉bw?êY!Ë…´—„®ç±Àmºž<—´ùœÝÔ8%]×nî Ÿ‚FâN \t#‡&Ó…·¶Þ_ÍÓY¹} µ®Ûâ”6&)w¦—°‡6›þÈâ ^븢G²—PŒgï3TµŽû“Ä,Ñ ï™N ¼¬ï“ª~åeúHýÅ[Ì™‚7T‹höY¾ò:XÇ7˜'Õ`ÏÔ-¸‰n¦ÝQ,Œ|!)m;‡Ë÷µÂ’[0Š4X¶?€| °]KûgœØÄŽÝ65ÐLâB¿¤¿ýgA¯‡÷.¼÷3­IÐSmvÂyHSü. 8c/¼v®äžû¨›¢ReJ°Ðc]¤¦s05Ó>&(½S¹‰Q¯ïG~7¥€}w_´ÂØÀÕ_šà.uD±­P² LWT¿„ù²WëˆW'3“c2¶ëƒi'¯!û§-.á·ô†!¢\–„56ãÕJ»à‡A«Y ÍÉÓ[åzv#|Öà™ÚÏR½Ùf>kXÑöÉ=’Ÿ…‡z7Êêd§ÿÖá*o͆¸ ]§}æMí¯ A.(¤_&wõÈ¡ †ÛñáúuÒÝÖuØå ³þ0Åhƒªˆ]k3w€ÀÑìrž]Ý@\³ª÷äfqýLŒI-Ïl ¹±üŽ9Oṙ—i‡9R6¤:vèÊs ÷îzÄ£úc£zB5Þná}Ýq4ùø C&oÝæ މ¢Ææ †áý%÷¿‹P ÄŠV1Æk.ZpPÄp¿MUýC9ut‹s¤€ÃUv=˜á=2–ZÇ;M>éœ?sa(»J²„Ž0öûµÒ›þ±–¹œ8rœh6! A­«º¬&ÁK¼,þ€›”B.%·24?œBD죒ž#Wu‹0Ϩy¸Hù‰`¿ï¥à"´ù¦xÄ9á%ÚbZSÈó¾Ê¥ “å !þ†Ž¹oÿtu>oʬ2uø,¯h »¯¢þQ ›çK(¹É˜¹0ßõ!Uk™ì|5£ßÁ{Ôœ™†„´Wó!ÇvL‘'.WWã¶‘ÃþÜøJC"Æ-úÉ“ÿcÔä}v/nÖ›è‰ûÒ¦|[´B g"?ôï¶—ß·LmIïÛS~Ý+ï¶“ øh³öˆþÑðÒáIÿa©+ü¿á£3ê;¿ÃQ†¥_mÔþYüï·a¯·fÿCRÿ|4þûO7í½ÿ7D½ûF£ä Ãä ü5'øjöÞ?¶þý¢'ðÔŸøT?ÃAíöˆ÷Ú"ÿCE¿…,¾ÚŽûtÏøT¤¾Ý2¾ÚuÓþ×ü5ø\ü/Ïá©ð¦WÛO á£wÛL÷Û¥ª¾¢ûtûQmöé§ð¼¿†’~ÑÛ|ßi'ðÚÿpÜ‹í¿½ûmÏÚ¿n†þÛ{ß´köˆoÚ!ûmïÛ¥/Û}þÛ$~Ý+ï¶œþ'ü4RûiÇð¨?ÃQÿBéÿáü4÷øS®øR?ðѯáA𢿆ŒÿaE?…%ü4?†ÿÿ†+ö‘oÛsþÓ«ü4?ø[7Ûp¿m±ûBn¯ßn½ÿ½ÿa`_i–ý·-õWž~ UþðÐ7í¹ÿ6»ÃBáGÿí'ü4#øQáHÿCE?…þOðÑŸáE€ô„ Ë­ÞæÛÈkëýÍ?Öø5 lçð[ÉØµ)øü6åÑ”*+"C |«(©æÒeTÚ< £x4Åo¼_øÎJ0œïdðÊGh³ŒJ”ñ­Âÿ5µƒœ²º<÷p[NA'ÊSjÕr±{Q:O-1PH))±þèÈÅCóPÀž 7‹Qޱ¬b¡ÌCZ^ÑO¸‰_ãÉzwP%Úý@åÿ/Šâ»n(ý` Ië0•Š®öb2ÛNú—NR§ŸDi~…¯€|>ƒ·»ç Qmš$Miä” ¹ëg‰#){îÃk2†!ˆmÐ5oÆòEÚó†ì¸Ãä.+ç&CDDiUæ›}UøœNw„[½ío°¶^ þÚ¨©(®›"è-† <5:ãƒJÓuÆâ‰ÿÿNI?xT• ©æ"ôògöf;>ôö‘Á#Óm¤°³".@ûwÆÙù­U2.7L5C*¡¡»š&ÐÏ%”†¾*"¸Rh"©ôx³¦¨{¹|Õä£Eà ñ³ãÿbÊ`VqàL£ÇjY‰8ûÿåÝìáq;„Ž Ê©ÿ#ÏĹ-¡Ç¢/„~Ù_!jᎣ7Hñk‘l½ôZ)ç´ )c¸àZ{B¸£§jÊ,Ie;ýëÿ^üàÕp’Ò°;•6Úí@Î.ï˰Øq ÆÚî¥ôqÕT8¤¥al¯ãÄ&ØÀï,lKÒ"7 ¥.Å þØW}ìh¸³kúò;)RйÙBâbwyC8JMôo½¡éa;€ U¼ÎÜœeåãÄH_À=ï—¦:/Úþ|£šX7‡µÖ`æ·àËóy8â’•-"ûœB%è°æ%3?$Êÿðq>ûˇÿ7z~:¯”[¨× ¶Ÿ£ uUyág˜‚/·õ‡ýà€Ð:ûÂS†â 7‘ûQ™p\,¿öç0ÞÇfJU÷[‡LÀÍ.·g¼{‰e|T¤Ž¢Æm†Ëø|PÕÇÞ^ÂWl½ò áÒâÂ¥øŸàØE+§®õå:ÐÅem†oOjð=šŠSB4XAôSq‚ÓÄuU-„-FÛ=³ÔCQ@Suó|û»a6þÃæVH1µËvó'\µë\þ$Ò«•±åz«ò½ñyÏ–“b$°A|Ûœ5ÌöÌ+z@atxO–¡æHѸÂ,µõ‡Ei×È[ZkÿAУèmÇ0wõ±e(\y—[7ûÜlTúë›PHG?”ã¡€Ty­|`2Vu¥.Ódç©+dVÞ°XAû6¢“ÄrSùbò‹]À I7^¹%°ú;¸0%!)ß›a™<2 ç¹OD׋6sìˈºzNžß¦L ê,@›·ÐI¤c£óyTñû¯;×d³„C‡xjµ_X„° ÷x¯ ’æˆbň;¯(÷­µ™Ýº‹7"µý¸.TýЉ žÏ·gôè× m/EL‚5-µì7Nc¤®I¿ õ9þSíð±ÙêÐ6OiuyQîÖZ¯òþûS…èp`œë9®æfTP­(¸ÎMvUE 6.¶Á®IP­˜CøvUx8˜ôûeW‘%B¶`r'mzÐKpüè, ß®WòQô#añc à6¤¦˜Â“2ÆÜ” Tm“í$LÚ{Ñx¼§Ø»ˆî©1SÝ–ÓJkàŠÞNž¶oÙ2¯ïâ­Ïa¾ß¹ÝÉNƒg§†ñÔ¤Þ ¸çØz‚ Ük]`WsQ«©¯WûÉêJòØb$» E‡¯È‡Þý—ЭŦe¡®¬/3¹ÉÈ¿ø.¸XüûwôQóD#å1gõqÛLÌWÅ%Ú×hf–z~›Gí9ÊbPéJ­+É`ÆØ$εX€jHsêE{—Ÿ…°ur)ÇÒÞUœB»´Ä;Î×Xd¾DráÇƒÆÆ{ÃŤm¸­:­ùuÿnõK䯤 k¹5Ë`›­r¿×á,¿P0—ÿ^ú³·ÿ/þ $%ÿçÇrÃfÉ-˜'¬•£Ð_`,hIh÷—WâÒ´rÝ9dvÂÄù¼Psr<õ×YwýIú8€3“- N¯88¨h ¯ÅÎc¸ÙÖeè[gŽt´óôu|5²·ÉO & Ú#ï\¶Ûݦ°^õμ a€==þ˜óü1tsÖ>@Êxé=Gî­ ÷eùÖ–¼.Z°É~€L‰ª GMs>'²(wÜ‚©ËðY‡½ñpÐ’×o™àÙ$QH/¹±Mî†Qy*¶ =võ§F¤$¶G7ù•-L–¸K™óN¬k–dBò¯Gï >=¥—jœ¦ŠŽà&ü]YæÇõÛÇtö:®ˆìõ¤£ÖœåRæ¿Ôø±vÒþZ=6ñAÃXS€\¶üþR3Þ.ºå§YTAÙ¨¡,ÿ4¤méü^eÙ"bn-D)¤íæ)OU5JšcÙÃGÚ£åßôH€½*š¹Ç7à…D338sÜÞÆƒ¬ò)F¢¹a6 ±ÝQ§-…]áÌpàCÉÑÒc®µ–&Îvüb¬öA#ë1¼[ó¦#¦ Ì‘ö­¾+9t •³gÈ\ñüAÊ[k'·ÙÌG£;7¥/ñËúÐãè ¾¥ãf Ÿ¢ÚJ¡»œ <¬¡*–â±õ ò‰È8ð'ù)Ì_UÊnïƒkC<®“5­3Rµˆ¥gní(„R‹H݈ZeñLªäZÄ— а~÷„Ûr­ñ¯¾Å#‘= Ðí‹~jCõk9ÊÖÁ!íö#NˆƒÅèkÔ-CÛTð‘9¸zÉ ñoe«(Á¿œ&=À IÝVªPë è3•°I°VeÝ$™ARšï3gä£MÖX¥Ößò#™:ÉnH'Q3^™Kƒ€›s*ÆSÝJ©ŽXÀ½oÓŸ §b-³Î:¼Ñ­aé#D›é Ogh‚9€P´ç3-Û¹ñm†¬’Àï§ü¡é=%¯>V¶!/‰P•Aâ÷¡ÙÜOøKa¯N¬þ§Ä/5“P•àeSG„4">ùH•?`¿™òcÔV–°f—H¨ù"¦˜â6Š OòtJ’QÝßøFÌ{@ EÍDÿG"´¦Š6©aÞb…(½yÞ"j=„'â×âš|VÊÜ]!Ts¿2¤G¨å¬qüÑÛ(O3ìOU³º <ƒJOÖfåÓj#(FÃÈ¡²aм™ÀégÒ°µ5H ºë[¼ðò—c€qzà~qÖ*CÉn³›@Y³÷X2[{[©+£/¿4"wÒCÀøìú>Hókãª|6˜(¢Œ€²j¨žµüTrOÿîà<ÆBгwsb%l5gŒ†m“Iuª>L/K»ã²§4nšHoªCËQ‚!! X‹FÊ;Á3ÎJkMô/s]Óˆ‰÷*ûî Ûi(Ç´• ï[:¿œ¼:ÇxÚÈ­ÙrÏõʸNÖîÝNœƒïÌj(‡HO2FµÀtÉlæÈnžlœi§ÔØøß+àoØÌbgõšTó§xxç‚äßÀØã¥Íñ.Õ×ñ©ͿÌ\R4Zÿ y$)Ìjš8Ѩ•£Ü .» Œäcƒ{L ÕÊkâ8_Æ;¥í- Þ/›ÀZY«åÌÿVÙh+ÕŸŒ[ꦕB¤ò¦´k™÷|«_Ü•viuÙªFh«}Ý ò*ùÚàÐÚ>·ø 4ÖÎ3CoÆêf ¸7OZ ëãìTØÆçbËÆÔƒQÉþƒiX¡åŸ»ÐSx¥í‹ØaÿW}ÕZËrC‘|<ÌLÿx0ä)vŸ5ªüïïïÚÆ 4ÖОÆÇÇødÿ3ëàcp1…s1ƒ‰ííýrýtš¾¤×y?ý{eõ`—0wÌî§ëóŠ÷ÈBIæFfž‚®Žîy±š‘7y[¼œLk˱¦—mGû¿Õ‚TkiÖå&…¿Fr§³Ñ·û¸ÿPvsˆO'Αé9^SR(ÇPìZ´Ô"å ÔbE¸[@g>ׇïŽr>}ñv‘fZ‹ Jßl/ß-²³Ù‚±ù_6ðÇãm›oCáC[ØÄOÝ)ýnppŠÏ“Cã3[Žœw½©,¹ÆMÿÒ]î³ç»šB'èÖ,,mYÛPßYF”÷0¥ý¯ù³Ë`íňe X|U©u3ð-Ð}õŠþª½Z˜‡r$…öØ‹QB]n¯w~ñ£/mùcÑ÷“Ù¸3 r0ÕoØuÏ2îm Ïtà!F)/ÿ^¤Â=Íü®×°‹Í9b›%ñ¿Ãˆ<·„vG¿àŸãN¡¨£GŒ [$É ö"¸¢ÇYh ?¼a¸í"Õ‡r/oÁKüÅ0-’YÅi“äàçw¸t·Û{¡»ÑÇ¡¹œ]à.İ´¤'±_˜a~wª¾^d.õaxSºPÊô`…ož¢,…_Zû«b@í{ÉW•ÝŠ‘•\£Lž‚¤áç ÞÂïMEˆH¸DÉP‰øþÄjÒƒéyøa‡ãC>÷‡w»7Æ4˼^›Ò`‘}‹"{HÁ6nÈrdÐÁ¦5Lp`aZLc)Õ×ò3¢‰7Ëõ(¯?0‰“²~m†¿ìhµ_Ù7<Ü¡¥¼ußnÚ WrüZ>ÕL”Íõ^üƒ;x¿ä-Ñ""J” Ì˵»ºs®x¨Å†f#²Æ'm¢J®GØÏµk ÕÙùZü!¥Þ묵*8¿Lê±y÷†'Iê"J0Æ4­ž|ä:%mº" t3yiÜ9Õþµë*ØÀ1B%_Ô•~nëÑ®ÒšŠº`uƒ5ñ%üû<®®…-hfAç€Ív‚‹l³áæ§JýnéÄ…-û$+z@‘8¬B®ÙmôPµõJ2=…u!'_žYT4 :s Y|…uKŽpšÖ²ÇÄâ§îëÆôÂØñÎA0åÕb`tëj„-–e7"š ÒÉe0×È^é{$Iq$È–Ž7è‘ç&ë|éš(äVéfä'a¬úS¢.9oÆpÉË»qÛoBnˆ ÀAe&á.Å"œ¬ñsæp’ŽÆ•s¦t ÌítŸ¦j5V·_ÐHF—ü³ è·*o™ÍW`ø4ÿªØÊï4ãSŒο»ƒ·@ã2LSØ }‚÷¨ŽZýέùN¥¸–¯3œ'VPõ†UNýq'ë5œBHÑ+ú3Ô©Þõa%Ê-UAË%*.»•ý3*]yN½Ã»«rÊ"ÝD”‰‡öºF5©MA@š‰@ŒJsȨÅ#IÌ-Ñ0µò€½mã0ÁÉM#®½f>7›xÃG/ù\‡".P+TÕk8ÓÂFýÓkº5=W”Ö3õuK ÛÍú~‡”B€\˜¢ddG£pÆV¾æt®)ЃŒ×ºÆ•Ee0mdŽzú5ÙÖ^‚§o8twsŒ«ÓGç˜ùjäáí}ˆ´1»±†YZÏ— ›ùÍ›W-7lÛ ¥-⢽“¼y%§%H…¿Ó¦, Ë_LèDqTn‚»Yn*ƒŠ7{E'jNæÙ’¶¨œb6"ìå2ÓHDnx¾ÿ—¼RxÛlg#Ü/¥q½V~lˆWÀŸE«p£É¨!ŸfÌ<¡ïòŽogŽºMLõP’¢’c°b„º )3›¡¹fóAU䞢XVTѰuÝ“…z] bùkKÊaC£ÆX›$©W„ô–3nç|ˆ2¢ ‹Òö“ؘF†«vjXþ†`vïú0š‡ø Z—œz‰þ—œ3õÂ…>p1PT,ñ-ÐSC¶tgÜ6"¨IÐ> ÿÊ•`b0R ¤ÃhçVñkE{RQ¶~„ˆEËvšø¼M„Ž$~oÇë³è°µˆ­wÉçp ×1ü84@ˆ…^Å¢ZÇ®fÜÅ-_æ €™¥Mýg9®N$¶s[ÊIû „Öq±ƒÒf™]ÀKMbF;éÓwŒÝm‰ÈÜ^ÒzŸýšHÄý|ñ’õjk/=ýïÃ ÛØÁ`h—½ÞzàÉÄpø]±÷ÿ';µ®–”'·Ýû6``¼õ±â)Ï$Þ¡'—.7%í®-¬jb«<"ðŒwoÌ,ã›äKÀ7ÿcª¢~&;wÚSÀ“Å4å½ã¿#-´„š×e)&W²iÇÐ%˜lmmþ?šž³OL6¸-ŒT7Y ]gèúð\›aG[®rseT–ÁV_ú5€ãåŸ@‰ŒXa}>Ôˆ×ÎÁiwÎ\¦…ä\- ¯l¬&Ó}­Õ™áÊÈ´™Ô#dï˜î€Ñÿ0'ææ¡aÇŸŽ}¨…Ä8™ã>gÞúâ–DL°0¯w”Vñ=oÄ]>â‹c¸þðåÀ€œ|Õ¯›Å¢œì©ž’E!wé­Å#¿BÖ`ûx+*«]gFRêÀC¨å…fª1 ²ü‡ýN[¿(’Ñ&¯ç'qò½º8™Ê•þ‹ƒrÙvh` v'1cãO´S„žÊZ?í LýJ°¡WÚÏêÉ•½¾‚ €AàZÖ䨆¶J¾X°½ùªÝÕàH§.ù*öåÎ\¦?¥Êˆ n^[•«^IeØk̯ÞíÜuÊB¢ôª}-ëUG\#r§|˜SYà…á^»´æXV|[¬ôA”v§ŽýÒFiåŸ÷Á‚ŸÍGjì=æ5*à)ä-úÙGçdl¨æRì•yëÍNê#^s RÌú«²]h:5û«ŸJEäwó5ïUlIx$ÿ¥lsîn“¦Á:KÏǸu‚•ºÝA »œð±bú   9+µÏJÇj¡e¶X ‘‹ÏMLo{'§d*N@â¹,NŽ$g9mqy¤Ãir‘å–ôƒpçŽÐ̧èú¢IqM×ê”ë=ƒ~øªë¡e½ÕOaâló@V¾€ ÚÕ¦ˆT]¯RÖ-qüÜ3MÔ~ϰ’‰såDÿsg 6¦†ŠuŸŠ^¨ ä‹Þk«$»‡ÖXeÀ+ß·æùü ô´wZ±=0ÀáRÌV9û7¢þü>¹žºkä´¤mŠ…ƒ}#ךSç3â 0hc޼,`ɧ´S¯/ï_R®«Ûó;ðÐ'ÇíìAáUš8LÉ(A«? pûÄL_[!Ê®N—#Uè‚ÿŠH =ú¦OïêA±·×€|kbNÓ ýhÑyhèr-öì³yÉ)%*¨ÎÍ›î]äÞÛZ>7yHhä”ç¼ÈÌ 5Ř¡z9¼7„0l:Ã`ûªL‡"SùA(p­¨±v»×j.%I¡ ¶[ÍÈñª+åÛåœ7 õ¥ì’¶åƒÉ¬Ñù#BžHÉ̘\’ `Ù‰/‚H}붦ËudA…A„q°Çþã—ÔûarZçØk4fpíÌÁv~¼’<‡Ûµ¹_&Ú?fÈnnæÎ‚ò²šW±¿¹‰WµMH=‡¾;̒莰y®k,òÈ • ó<3H‘þm2#yÍȹ<ÛP¨ÕÌ©•9ºTÍ‚¨”sÅd›ßl¶fÜÛ8xI?M=D}YQ"e­(/¯?GgåÜÏ6Bõœw:°VÖÁÏÁºÔ[½*ÛÒ;,!äÓu!ZvíÈM¹–鎔çÖåì×á6yöc®B)tƉuÅ®÷èKvþ8-£€·0Šz)¢@åY‚ºíç±úÇ…89[×ÿ ‡^“ÝÏðŒ]®é;ËŒ[]ÀYß7PaÛ±4¥H1]Êx9FÄQð#w»Õø¦ ¢U¡Íïb±dÄaÚûE0ž&Å™>ÐÞt}ö!%'¿ÞnØL]ÔþšRÿD©9ûèÎ ‹'ìùfd«"¬HÛ ß–Tg>]›.*4#ËÆê É ›dz倨nŸ“º•» ë=g]àT ƒ:Òý>¶ÑÇ3”Kuts³ÜE·ù˜8ð—ë ’µ@¯-Çwÿ:Zˆ#á0Á.<ÅGôdçÅÓ..”¾úfE‰d´¸,ç~5"Wÿ!8¤Ø17} r/ºôð\ºV}¤¼™ö¯f,È-ÈR}”U-Œì«²!´u(Ät÷†wˆndDšn—?yúH!*âÙmBÈO\x‹wÈ4<ºÝÜõœlm|˜ƒBÿ,5 –™¶\Ò}È.¦&(…Î09Y~i’ÛWC~‚áÔ­ð̱§ÖV!æ>Wõ#¸i|䉈ó\- &¯ZƒÜBC„RâÈö·Y£OW¨Œ,êSÃüÞÿz—éŠèøßóùæi[Ѽ  m g´øëFƒšu o±œ´Œè¤ƒx©ù+¢6àKÀL#®ß²Åû>ɰM&˜Ë!¤“•®Çèü˜Qî—AÖr)ì¢o ‚ù‡+5VISZr—ÄŽOÛ]ÎÁò¾q’F¯UìÆˆ‚>y†™"ô;ÆZ¼ æËo‹>̥ńsƧ¿› ”ª}Q÷)åìå~Óß®3 ðï[¦IÄÞÞØ¯Œ`!šÚ:¥ Sõè>›‚U]@~ØbÒù«kO.U”-ëÿ|òúÑOrºÍ7èvŒ5™°ö ö>bÞT³%»ò­S¤ù¼CPð’ ÛR¼‹iô…Sð†3þSC^ÝyÓ8ÒŒ©©ÌN\¢Ù¢HdÎîwÂ$•k$W5qi¡•Pá¶žá˶¡Õ„ë6Ê;óx•˜„)Ɔ;Ô›*ÏsÊh—ïµò=‡˜c¬ï¥UÕ:Ûšð„? ¦:¢œN–Iz¯ "!¥’ÝBÛÍ]:ûh*ªì˘O^ú³·ÿ/þ $%ÿž¶Š.¸v§C‡$ª§0& wôzüè÷ÕyjNëŸ3dõUj-ÏÕVLg%ò7ÑM …_ø_æRF¼CKù’¸6í C…C¹$jgm,âbDù‡!î}M‰¶gÄž¨´Z2D¨ÍÿHùX#Éf1²ƒk¬púH ‡4xâÕQ¹ƒº®oõ¬“Š jÎy»Ù•7Ñ{ˆ›7½c­6‚ãqàYómgÚ•ûùñ>vÏåÂ.“w©‘ÔMÕéXàQA^Š$0L kÿeãeòÙ`pxÄôà˜Ÿ7Ä|œ;´fY,6𨉚§RžP ®ÞŸRrLŽ4¥p¼-&$SFg¬8 2Aç (X(}²>&âÇšI­%“\h¶£ú¹žm¨h¦órf\Ùˆ!ÒN ¼o•›ÖæS‘žµFñ”€e[ o6¨åŸƒZ´¢T V7œ18Õ=Sh ]ïéíº$Z„{©¢çÏŒ´—ÙÏQMmº(ÚR3xø5õÖÞ…Üm‘ní*^ËmÓí>ÇèUhvùܪR«á¾ºyópŽºq¥¢³¿Y,ÛrIPr O´å¬L¼“‘ èešÝà«þ¦Öª&Ch ‚·ŸzNç.bÆZòeÅJAÍš·'àŠ™ô…º =ùkÍK³¸aÉL×Ð྽öq›þÑKD™ •­Oʉê1”o4pe…ö“hž†tÃʵÿ<Ç¥îPé`¥¤>úûÏXß9BD(ijL¼„E^7ÕïXi‚Íd)ZP¦hB“+bÓ¬|Ëßô ^ Âæ˜b] [7¶‡ì¸Ðj  ƒWú£pTFF0év+ÙÿÜ…u³î»[P0üŒ‚~ ¡LÊ(?eK$÷0VŽŠ$O¾'ÍìŠ ìÃËe i1^á©bÍ[ió¾Üм)> .Åå/» gmì<|=\éñü¸f´ƒföÚxøôç›ìˆ ¢r8DÄ#}[ÎmHvÓÚ‘¹ñ^áYÅ콡‹è€lÏZ6N"6U°K®»‹A–=©ð$*Úkð×ö¢¢oì¶Ík†X{J“ÀX3nÜFÉò»¤å†­Çz'G×ì.ÿ¤fâ‚^—Jóä·°¹|1  Ø3+œªÁSç…@±¬¢Yur¦ŸQÅõÚrÉ·Á™ÏF4eÿx —BCnÀ@o×MÊ ¢Y[ê((úæcZŸVþ¥è—ÉÀÏ]ÀgMŒãb 3^á=ë¥| XŸw]utÓUlÒ•ÞíÍêæ>vãxÝÿ%ËÃÕRò·PÛ’Ž¬”Ì(>:Á²…Ht«I•…©*.‚Ù“†å2+ëc‚¶á;ÞPE’x@L¿æFø¨&ÃÔ(Q V]·¿×ƒ:àVyÀó½¿ú¾Moù‘‡‰E4TøFØ&Y ¹¨Ecé”E¢Ÿze*IU ÈV('z§ÆÛX|QM¦ë{‘-Õtðwb‰A*ë–Ô!9|í,޵ ÖÉ{äuI©HXU¸æöåâ®1“Þ›Ð*UØæNYÐ1‚´P8N†—èÕLH’Qƒ† æ¢1\¸pÁvÖ›ÞáÞ«çY¯£5YÃþÀqËá´3|žºiFø"™¬b”+쿃»¦ºÄ2p„î…|8¦ì`×éµ_þ»#cŒÉ =¢á„Ἣ~0üÂ…‘àýò{'ãkãÅE£úØbûÒõtŽúÈ4uæ<®LÌ;xÓ‚•y`Cªi:E…3BÛ·øßÀbÌúƒ#Æð²‰{Û"®¾z êe°ý­Ö ·q¤Ù ¹wP¯o“{ES5âév$%K[¯±Iƒ°g$ÍÀ9€hþšZÎ,Ó'ç,8ùS ˜³"eSRv]ä‚/¡É•[î×µNtvºJT’ÙKÑ·ksçGmöšîR®w™~”ÂYµ#D’°ÁOôOÑŠ~ö£ähM \û`uòü^‰~Â{ÞVã²ÉEÂd¾QuX‡¥3ñ/˜N¬çqwm9C‡q_w˜Ä5óAT®*’›]Ò î¯Å¬KÅym}(a…e¢ÒÒ"‹ž7Løùhåuë|–Ü1ãtÌ1ÁlæWjÑ^DÊø…ýa~Ÿ0–F.Üo//”òv¿’³`@otô?Ô ÷Âú®ÜNªŠ£‰«ÁÃkŒ7`#¶|K5ÿ~=–Î9‡i)·x SëWÆîœ BlÎ.ðT/ ¯û'oÍ&'¾\#ÃjU°/ñϪëR…_V ^ôš'îSዲ&Â…¤6„E>$…}€GD˜„oŸiå‘ÞÜè@ø]ùøø¶[ÑÞÕ8Ë–Jœº$"4u‰%c‡«ÛÊ ]Š þnO¬Ë:Ÿrê±Z7žö¡A“òãkŸþ•üQ´ú•È’µ»ƒzB:H‹iî~bïµ£Áb>”åÔCˆjgi`ÆÚ¯4ÈÔ”p §„Á“›PØ •ü¾°à™xêÒ3DI‹Ñ«¤²¶*‹ÈAåÄF~ë;G¦Ã½¬9É井¾½}û5ð{¿»ºº§’ѳ0€pDYÿ‚ EÝ \™Þœõ'»(Ç»ƒP ‹©BüŠÅ«ÿ9;ió<¢Œ hÿLÁ4?`6Èó™'1ØtG=`ÿe&¸ÊÀöÿ-jSO‚Hâ·T"ÿ'¤!vF_bȪyõèÛÁ.# ¦"´º% +¡ŒòâŒ%èÉ´Ü`ŠGþØ •ì©SÓ@ªrc—½ æÚè=ˆƒÝ•KcëðdPä„›œPUÚ/¿“Î}8ÄÇÇøãw ‘ÜQH Ñó‚¹YA÷˜*W‰]T䈕€ø™o³MÜ0B8§Q'Ó‹®!³—”ãÿ1„>Þ°çqT°F2ɧâ­sé°Ú£ýë ²³,­OiüÒBFh™/—š#ñaÞsKo0F(DÍÍ@ ob8Å¿õëJ&PçÛóž‚«¾½¼À‹Ûr¤­¼°ï¡‹õY¢ß(8áÈsg4¾÷Ð/ß‹ý˜KÈrhSz½¬ô‰à®!èª_)Wo/ŰߖÙïTK+Õh¡HCí(À-ÐO–}jj…¡y¬„ÒÑ&—,ê´[ʰlR”[lÅ»?‡Š¨/pŽ‹ªZ¢YáDõð¡˜-$g϶{ôÏ¿–\æS­Ö'ÙêšòÁ¨…»—¯í‚xg'Á-ñTÙ㇛“^Q*¼ac÷_ ¤¬øRf›ò)û¯ã+«r SͲݓ’·™0ª …¥Ò¯2ÕuZ›ahX‰3ðÀO$U…‘†‡ÓEddaXör„hO5º‘_1¬æÞ èŠ™Ûç<‹%PŒ Õ4QFkNÆÅ€îì1L±a”hÕ…`nŸqW°T¬44.ìÛÐWÌÛ°uišÈ‰}âTUèzcÂU5P?ɼ,'¤3jjÕég%öMäuR‚̱Üá•)•]7#ƒuDâ¶·Vò¦:µ@4Ý›eW ¼Óá ´bÛQEév“È Òµ–°t¹xoÐ=Žç%¯a"×+èEFܪÇssr_Ý*ÏoËcÀBù¦—m0Tç§ð¨L ¡×+è1|áP˜qnÖ{0ºqâ9\¬˜H„–sÃÝJÚ¨½TFCå&¤÷ófsk‹{ݪjUd¬g÷ÙáŸÂàÙŒ‘N3¹W0­\È|ðÕ Æ@3C?𭶆‘Yúg°ÇG¤ÙÇn{Tbìï/v¥Þ«ãtý㼜b}ªS²˜¤Öpʆ¯-1ÈSü¶SøÜ Ž"Т‰OáqB·7ØzŽòÁ{bÃ>K$4Œodaæå½Q};TÙåû³(=V‡ü¡•ñyÕ¤kKF² |ª)yΚ¨IžÅ~—[‹©(z¥î –A2ÿ:ÔVܶ ¡7:.ÚÙ[N,ZF±´`K §ì9 … ¼r|†Î?¸×ÖKÀQΣ¢Ÿvƒ21BÕðxÀø·Ieoú‡¯*KÜ'ÌI¡ú/ îEi¸Ñòä×C6‹÷<Ÿcò;Xü\j–ÜFlS»`1Q¯¢¢öãø<,=in>ë´#îÚù&Œh•Þ®˜‚q yfCê-ëµÞ”ñ¯bE¿Â]S¾Ë)F U,°0´)hÍÎõ̳““+¢–§nX©…ÓÓœ‘Æ‚çÞî."å›fd”C*n¯@@Ù+ ï¿÷ýŒÏ¸Âž‰ó;“ã „£ªfX½©ÚmgO¯ÜFÖlùiFrýb¾Uu… ýr ½A"«<ëIÍSTýC\ë`õcI‹K¤¡‹ÐD¥¦W„Sq`Öý®Þ}ÝèrÈæ çr–p«`ÙXéîG*!M6~íÓJØ‘è?Ñí:Ý5Cz·È›@ýÂðÚίûÝZtƒr£A±e[ˆ+÷¢q G ÿtŸ¨|M 4|5¼)`.G¶ «нÿ7œ'äkïD½Þþ§VÙôyÈT‚3²0aÔ¦ÐuÖ+YKÆ &?ó}å'¹Jä‘#ª"á4|ÎÖë1²“}ƒL!Ù<¥qõí)Ó»¡QÒ² ò&WŽ,+mž³gÜçéÞ$±ƒrÿˆÄ‘J‡u«ýµâŽ–"Ó¹…„C•fG§ÄDªÖ6œ‡º¯&ûÈij®ä¼F‰ý2y€.h°Ò"¤ªtD14﹦léSó–¾”õ}‰bé’ÿ‚€“úÑ<*ž=äcc¾ÄŠ0÷óÙ\–Á5ù”¢ê¬5vªÔ9ò¢²4Á€€m0š0rñI…‡®‚o¦5‚ó㑽ý|¬#ŠYí„û…e»2£ƒŽ­8KníVAäØÇî¨C…),¿4 yÙ.؉ÈTHŸ¸ˆÓ%Ï1°ƒ* ã¿Ù¾‘ÇŒ²‹ î7nª@À% aó\ ¼ò½å½lËŸ¦‰É7úRƒ8Ò‡ —r©…³ö†ŠF‘ÁS^7xùýz߆¿ž'‰mž"»y¦3¢)ÊŠ½³ªN­]o-ßUÇ­c¦bö‰Ut íL˜Ð¤ovH­ùÔ­¿ez׎¨…÷Ž®åݤ£èâOEs««ÜŒÖƒw:ýx$ø|ÔfùÜ ›7sªük$R3OÇàñ|v´œ§d2°Gქ ÈùÇ×Oy£ÄN…wê®]*´Šõ±>@ï+\ 8Œ"âpe‘–ÈO+ŠY¹V0Á«ý]ï~R¸¹5¤ü`¹'Ç]w힘¥Y¾N(×pCƒÝWvx¦ÏKºå\tÙԈǢ¾E¤¥C5}ÇØ›S“pw\ìxÇzñ›–S %RU•¥(ž8Rô§-yrÝ—î,,>"2kä"Îs®RU5,ä2¬9U§I0îrV$ÛÀ©(æˆmYB8™héôt²…í ¨X]{×ûý¦nÖó•ñ7%zo)JºÔÄŽ:õR~‰Ä¢×ƒÈžB}¾9‡ßs¸édÊRnàl OÖºô!gz¾’Þ´khßJûlž»w%-ÿ"C’ŽT÷Ûa®ÇüŸd‡®$HΉúK¡É`Áh'añf•j‡ŠxDiº¼ƒo¾‡/l/#IÔÄ$OÍ0ýjái°†àQÚÈeo¿Á„”îö?“6e)bab/ .ûœÇ!F‘:Y3(ŽòxV`;Ä>ÅTöツ0wÉt®·í!xM^ —[`ÇœŽË¸V(îöã†pa³> âÉ ÿ:n’¶1¿Œ3>¾ñ'i$ÝÂK[_ß0Ôšû¿u.ìÆ0™Š®â8yR@×ëÈéxy ß>IîÖ¢+t£u†³»§áùbuÁy[ãE‹_ÏÚ6û! ßz<Áv¹4Ùw²6©è‹U—Õi@>Òíæ ! èÀcöˆZñ¡€ÀslÕãA#|ºt2úc²“Nß^Ô|"à‡•€sÝõQÛvcW¿ÒˆÆeïƒ;É/þZÙ F±Øì“€/ײ+3µUI>ö‘·äÒ '{ðeJQ˜`x¡ìâ"3í¤cÚ™Y9‡J†‰oè:™Å8È­zBñ=Àö=O±ãÍX5Ø‹ó›HJq;ÍÙ/3¥¸Ä ø¿îáIaCøŒÚU¬sƒå˜ÂèÀ|î9(s]½6º¹·aJŠ˜FÑÿ ,×ó±ÍÁvywd×CqÍÝgrˆqµ\-ŠKáÜ^\ò‘N¸Ä$ëþ:üuSX"‹Ôv11 åJjëÂu›þÜÔÞÛ«ëygõÊr¾˜“aWÆ ±*÷÷A$:܉ؽt?‹‰¦ïJ°Žô·jÆnOO;IVyª¢–€’…*åh`Î_‘D ¥z#mƒx 0e€Zì–«y‹@³¨ßˆBÆá„•Uwxð kÌá™®ËѵøñÂAL|<2Ș?Lºü›vÇÿTQÃZw9±–G¢M”Ãm±qÍ ÝàÄcgñ™öŸ0êé{ZÍ)'!œï2óö.§“è€&»%æ¾í ”´ôiÞm›wŒ%̪N°R]Ñ¡C §|fqíê$‡+agë")œ+X—Àë;™ü?8Œé`QÛ…¹¦®-ö¿Náqª·—߇²ðt¸f¿·dé+ í)úÌXpu³öa͉ÓeÑEŽiÛVEý|;%“N¸Tº£VØ+ƒìž]ž+ÐX[!€fÁ{®Vx5‡GwdÖŽœáiMÀÂÏçžñßkXÙU?ð2-ø”z§‘‡ˆOcÓŠÍ›†ç‰Þ$‰íÔ¸Ž»KV"xFŽ¢•Uˆl–µgæ„ !õÿ©¹çR˜Ë¿>@{N.1Ôƒ|V]kÐI· ú‹Q•x7LòÌ2«±Ç_œ žÊ&àrÿ&úAa:LßjÈÚ)ËNΓù¤êg%o[rÁN‚£üÐ,çyª-`Pž]Ëá'‚Šêùe’Ù¶Ï8övsn$mù0Ò•G”Ÿ*(™Ò­sdèæ²â‚p¼y}?@o›úÔ¹©˜îµg” å98‘‡ËrIH_º°_Ém·„”GÃ#h…Á$F%…‰÷3˜gǰͬš,†\¡Û+"u§­HTûb _ɉOPrkÚ¯V3V‘~tOM¥î…Ÿ‡–nŸÿu4'ô=»îö2ž©}ø z<+DhÄHö¸ µ^š÷Öç|¯ù g‹ »LH7.õ’óU¯ }_tä[‡ä"z«†5åjTСíD]]ò~Æö+ÛªšÀ—|³ lB"?V­ù±)ÉÝg؇&˜è¸ë íôÚß ³,QÃ,DW˜Q:ù„/†{Û eÂylywº¨yje¦ù¢Àží)6ø ¹yS:þ}»·p<Ç—}nžÁ•ä–@Ù¡ž¶ú)ÆXIŽfÀh}ˆÞ­‡ú©%m"æß*©œŒžövÆgœ\®ØÃ2H}B‡øP@*ŽeïÍ@ÂB_øP@*d¯'^\N“<Œ‹w³ltô†þ",¯cS‚Š‹SŠÆËIJgÃoNåþaW îfœ)báOêФP;**„Ü—¾Ã)à‡¦‚׬¾YJ;y‹I¯Éßµ»“je[©çož%"®\ Ù |á ê¬ÁØ »»%B‹m‚yúi €^Ë:ýöâqQ‘£D°Éšf{íÿ*xÈÊUX""! j¡q åßìT(¬ê /wN‘e-ÉêÂÐ_ªÛ6ÏBãÞuÓÿ¿x®óÍl¡Úr A„žÀÝô¹8 2\E ‚F </­& ÿ #øbÀ*€é."Ë ÊæÌÖ‚„3èƒ4ÞÈHD<6p?\4¿ø•¢–<7¼6Õ¦‹+¦ü Rg”—z³$ž×ãC·0°_–ÊÏvê×ÂyN•dÀÝœl’õ”Ÿ\åâÜ\¾'â‡oÃ?x±:(¤{Ë4qY¤P4 ˆVûçÁLå¥5c'ðßDîÿ(WERÅrã ­Þ([ž<ú âA T<±Ž¯onEã .a0fõǽÖhØW õ¶"¼R]¥1œýzÔÊ ¡[ LºªßÓM:mà™vñÿk‡d_S‚Œ0©:³ ø“Êà%†Àœ¸Ló+ùŒ ¸*aìuNÚ}íTVNªÙ/y¹Ú|é'b$tTTŒ®k‡úxQ®«ðWÅ×¾-ýsm5 ™ŒJª4ÉbO%†"téì°G¶Räi”ìCù)ô•Õp”øS<ØW´qÂÆAò‡R4 ¶vKHÍåŽ6Z4>dX„¨óHD‰{­®^ÙÖ=„úå`#XÛzØ£e½ÁÌ5Åz Ñ$âÎi¥*Kz(¸ØÌÎÁâïøZ«z²vITÿPïš HRËÌ34Ýîëe™ÚÃõ·ö6@vŽ´í'tn£áëqS‹Kú˜ÜÉù¸Õl«zâp‘ ¦nÍœu#í¶: ÔˆòSb×îêÔø¤ÛÚ(tFY~Ê¡#K«2Ë=}ç²=ÑiÀÙ³\_R´éLuïÅ%›m‘µæê4ì¨FÝ^-f·°WWÄÒxí,SâX™›\’“õ‹K·¼´&8V³8Iª¢á™Ä—& [:ii¡˜£òÀÅ~ŸÊƒ¼¿øúä†d9Ëâ¦ü¯\ĵ*ØNHär”\àöY|ˆß W——ô˜€À7*('|ÊȯvЧN$5õ˜ª.…¢î!7ߟNŠeàÂÏ÷«Ô©Tø®žO‚âZ²¾×ììŠØ®•.“ÔT‰¹Ç4⓽û0š<|9_Yåßáñàuß4Hܾ}AbŒmoý“qV4Á¿Ï€R ÷BÊ7 ïI¯=ÞÛÖübùþäo.6¼¡ë†Œ¥¸š¤BÞL °0.äy)HÏø4òšçè›Þþ±w&jAänÔå3Œë ÐA£˜2JÊ@N4ñ¸@aê  âß7'2}0p.ÒefSàŠålTðs>jŽ=8 9³·Él½ãî]2E=ž!AÁCKIê(Áõ©`Ð ‡¸—¥†Ñ;mlÙ<c³„þV›—ÿc¬ˆG¼}ÈáT˜˜„Ã3Þó‹GI‹B;)ÒÚöB=©Z@G*‚ñŒür©u{Øȶ[ 8Þm\Ї5‚KÉLýÔÊ•¿DŠÕôÜ&þ%En‚(ùä5$ Õ”Êj<ƒ³’'?N™mr:½™Ô-p&‹q›˜­§1ûf|ßqÊåÅiÅ`+–К¥¼‚žEe²Â"ˆÛƒÈþSÓK·…ù°IÌW2epí™E£ê®sÎ’¨á·ã\*-AóÊ%²'‰ÇpQ¸ímúCº©Úhìù~ë(ˆ‚kL$¤¾³«»lA4ÓÍ£9†ËáÙåAS‰÷°jÐÔð³(Uüóñåm…Ï65ü„Kã7Aš›­lqùÆ»¾öL–?¥y$î…·zÏö2FB„{Í1Ü6Q} 1r3\°Î•;R5 Q%V='s0ežm§ÝÈê‘c9¥ÔýÛØ}Ow3º·—4Èt°ÂkJ -7 㘜ç{°M Ççwm¤"G€$n[øa»$êÒ‰Õ6K*}DÉõ-ßߦª“Vq±iË6,Eê¢6'OŠÞ=Èæë>»°VÏ‹DÀ'?~V­%˜ ¤ FJß ›<¨FéÊ›‰k;‚Vá6M¼5¦¾¦-¾HŽV¢³__{ߣd`Á¼Ð) $…ŒnCºÄð*X ºM•­] s[aµû¦$bÛu`ÖlUU¹8V”;´è€úÞKkŽËe𢠏…£ nf6ì|®e¥Â˜.‹®Á‚è Ø;³ô TÚ•×A@Ç-£èJObíÅ:'óL gÝÈê„ji®F'¦¦{Œœ¦ySkÔÕe>Ñv¼ÚdUw²ÔÃó+‹¢0 bú¨V™˜rOÿ7¤Ýg6,øZºry°Å› ³Ú#=2LðYþÓë¬Ãø‚}cÜû‘¢Ly¸Qª˜*’¹·;XÙõaÎq§$ÏÙü)9bxÝèõô1iF-¸]Ç#ê´€q>HþR&ƒZÙb¶'4Pjż5K˜ˆ­œºâ“:sÿd|×sW÷@`B_j™X3ßg’g§£ß+—®¼¨Oîvž(Tª ã†TÏà‚ ¤ÎŠªœÞÖ›ÆÞ …(^_OÝÈê“¢ßì>„„¿ÝÈê“¢ßì>„„¿ÝÈéñͲáK@ÂþkòQƤªé‹ßHÜ5)ø?Fê½Ç¨m%¼´µâ¹k”E;ÍŠaÛ®Ñ%*ЏÇ&ƒ&³ö"ó}Aí¿ýÔT7¨A/±?»ÍYKr§ñ«žY-*ØvUtÃe•ò&ÝøÑçŽ jw„Ô RŽ+ýÍ/çÛÌï&°_R´¹ªNCºžìÚ¹YÝ …Ÿ¨KM®™}¶û­zÛ_†þÞë7=4cNÄó!â´oÅ\Ýì 2ŸÌ|cŠåì&WÐÝ LÔ¢uŠ3$y«zT=®IÚúnëÿPùÝ"ve®BJ‚#½å-Œì¢ ‰F"îÜE»KA”-‡ Üð퉥/› _)ϸ ›:­m…Û«‚»¯Û=Ê™—Pа@àX/—i –8­%Æöß Ð:K§‘ÐTMf€¨Þ$RiÀÉ7²Øº5ì¦y\j¾I4~Én˜Êe\ÉýV+Ó¢·¸{2«ð~5ºs§JÔE”×ĺï¦áÖ¶ ž;דþ€ ÿH†q†ÀmD:oÂTœa›S1«zvqþ ðk±êÔúã"/v6£ROõy÷ÇCØé]ÑSâ Dw1‚^#kˆì(Þ.­/üNZ#857 Œ©,EîW7A™|v=¢Ø³©(/¥Ø.³ YÏïçBZ|I>‡Kª´šÆrÆ6EÑnA ¬NñaB ³Ô>?Í…|‚vRjÐà’LÔ¬ƒQÊëòœ×dÖ‹L¢×l;Ab¡ß)6­fIžêZºó@±Ôö“Õ%å«/\4¹)L‹Z®÷¤ÿC“\*öSkdñ›©*a¹±ó§hçV !è@œ£åô i“W8¢5©‹ÅÅX”Úy|Ðóbg{¼—¾Þ[Rz½ ¯(¡ÞZAû}ähg+UÇà{$ZR¦¥ÿ1£ÍwS%-Ú¢22¤å°·³×1Òÿ*ùõøõª ¬”AÊÖžz\ƶŷçË9VÑ^Fn7ç°ˆ ™·ó£]õs æ,]S¡Ÿ¤dúGÐsåK&ñ‚6lµ@kèÁ¸LÅA4̰'–ب}– %íõ3=b»-©óÏ´è8½4rqæªßtpÌmøã6>r¶Ž|lRä²Àö¹þ°v®¡œœ ô7`XŒÎÕ$Ò¤pÙ#íÖ²#¤›tyQþFn%g©†§>Úé;c¶Æ[›Ú.É"ÉŠÏËI#Ä&%Sv1ºp,µ^GOuÐ’i~i©åŸ{®ÅþoG¢ˆä5œA½ºä¬dxDÏGAz«®L|¸sXâêv`Ô Æ¸’bjæãP¡ÿCðCI+Ô)™ÃþÑÔ6v&xyÍ~²7Q·œ`À¨U¨‘0Mlȇ8±¿—Ú9&Ø À`ÂLY̆6C¥…1jc,Ö&øÑÆTÖò Èp󵿣~#BnP¹À«óÜáÍøE ZG£*–×^ò “ɤÿI7sGùTÔj ¾`ÿjêoÿ\#®à¯uMòYj™?¸¹Â'ð>ULàéWƒÏÓŽ¢Ob8· Èõ ªúÿŠ ¼ÈAþ„AYì•èhcvˆÝ÷¬¤"$XœÉÂÔôðRéR‡!Z䨲‡uöMÛðoHÕ: ¥¯¸Æ¤ß-v®’üE;Ó¿–W„â?o=“®ˆ™0 '©Óú§Ù½ì×ü©C™‘t ÿ`*2µ€ÍÎmO³¸ežQóvôvxh¼ªpbÀ놓~mnæä\g7ËU=ŒÏ¤TBšäb¡±LÔ÷‹`q·oK^Àû}Åé ócEmïÂWìè(D ]±‹<îP¹#è¼-ãö€‘N•¡@\õéÇ'ˆ‘áø# M~†‡!ú_‘Rcä0µsüT}Ò! =Áœzí]e:iâæÈI‚?Œ§ïO)v²åa…¡m4wìEYr®ºx0²¬5Ó’µG«ÝØÑ ³µM¢!‹Ÿ*‡ÿ>rh°È¢i’Á÷ –óö šÑ²EËŸL°µ.)ÕíÌø«°£ŒMc“ÍÀ<\Ž‹{Ä5SO}ö(â¦Úä+€Ü%JYÅáx}V“¿"# Xjƒ ¾ÉŸÎ(ÝB¶Œ‘@|”Ù†O{òŠÿÛMãË$–˜|¢†éŒü”IF{Us¶ºî,Þø¾5:},kˆåF6ÞΚ¡*_íQøôW'ãh=/¼N‡=ç~žÜø3œ¥Ñ5öêžwGGªì¤šJ€÷¾e.ƒÈÖ8ñ©H#Òmâ—,ÃbÆö’™êõÔ|Kå[8×:Ôbµè÷" #úJàØ~êäüa‹E¿Q9q‘9úÀ.VX l¸0¹ÿãö†`,݇ag r$·[½N_2ÓKÌ–:ÄÒ2ä“1Þ´zçpïÿ#á{¿yU^7–êCöt¤ù(I´d5ð & ï|aððl÷Ñ/eªúüHHüþýÓ@v ´záèðA¡ ;Õ²D³sÕ‡Œ„«t¬“ï)kÐÛ#êÅ1ØmÕªŒ¬æCµcÒýÌ> 'ÜÁ‚¨§^&ÕDt_>µÂgŸŸ8¼ÿ‚$%#Õ}Âu•ôÁ´Ý’‹R‡³oø½Ø¨ì|BS“Y¦þ™Ì´SÉØ¨Y³£ÓuÖªïç)^€ÂÝL—úÓFâøTºA¨÷‚­†ƒ~ˆ2ì¦L!.›zÛÁò†¡4žÑü°1Íå#Ž0éc% U»C†–õ»Úçðfa©ÇQ€áǧg÷©O[È3ññØ6] pSï}ûŒÓG1ܳ2òÖä|ßÂ韥Uè)…Øña˜èhtùùò«hä(£ç5pÿp_áµ}LðÏñ‘±‰`%q¾%NEVÙ½rㄯ‹"€þK[AuiáBŠÒ ‚r–U…Yl¿w6[­Aò&šØQøÅx*ÓÀG#쉦£°¾ÎÑ ýXxdJÌÛ;P©%@(}C¿ÿëü¨Gdz'o9ÂE…Ñ—ügµÁ{mPª#нcgˆ‚5á²Ì!rƒñµ j{Ý]_o[S±ô|2‘æÆÌe‰˜Òù]9™fŽø×àŒŠþ^Í÷H¦ˆ<~ÔÓæé\Zü¿ª‘E4¬AëÀ25GÇf¿RÓ•"&kš}ÂDbì Å$»þrïß)WㆰD¸_ÔÝéª8°Ÿ»”!D¨V\¨¸Î–g@ª©.c¶àF“nT;œ€[Qc‡V?‚¨û–õåÎ2yÙ©–‘²T‚ºoÎi?¯KN%qö²*ÅÅR}… (¹Þ"µñ”Á‘‡¼“`g/ÁòÉyc{ÎcŒÁ}­Oy‰Ñ]ž[l8Åä›<›å#+ê¹ÑB:ÖUyë7ZûÓƒ‚˜20ã’l ÷ïµ£"«ÇCœËQ¤´…mcî 'ü6%gûŽˆ$ÌÞ_%¨P¡¹Êsºä2*é4hSSÿ)ÚJOd½Cïj©ÖÜmÍX÷Áe’,x’a÷†ûïgHÊ Ó»×dÃÇšî®ü|hä¸{·'"Pé(ryŒûÇì¬Z¹ï¸J·±‹oŠÑ8Üjÿ×@ûY Uã /;]ËDòâýCðŸþAc/´íôÏöÄeEXq˜ât&»4„n"u !x~ÆKòó·Œ‹Ó .¡Ý@üÎÑ •‘Ðü §8†Èå}Wzûݱ«ú´ ôß!E_yñcÄòòË7ÀP†«+åÝžK5i˜ï¶×Ó¤ÿ;cWõ{D‚´ÞaÚ»{ <¹T³w°ùCŒRÏÁUs<6’Y£*Jp„,  QŒ&÷ð’¸Å…Û(ë² ºè/qˆ~!ßó3é$ã2ø‡B¯ˆ—g1½tÞTæDUí;ÿ‚¦ÝQÿgQ)J¢ÊúlúÃä.]HNÅsá-Ú–ª¤:@¹H5 ¶ r” w†ŠÄ¨|á²^:=J…r j{¤ÛÈÔõc=iõvftkÚý83©‘”娹6kŸWd/ |ÚzÂhX¬v+O«¿ô„f_ù.?͇è}ÇÍÙZ/º5±:¼€qÄv.VÑ» !ÊúÐfÖ7¾hMUxbÑtŸ¢pø·XIÉÌ¡‰åT‡Z½L"\ÿzQ†çt6`Ï^”œö šcKýQ¶èQ}„”WòÙ¡a¢Qè?™€ç€\pNOŸ0 Ð4m»3\Ÿ?X•P=ѶêD:AïZƒ?ãQ½&H$5î,DUõ¼G¨—ãþüðØñý¾n^ñäƒ{ë–ïÆTÇĨ¨ :ÊóGòÅ[¿Eˆøô*«V®UuyZs'ÊI›y`XA øŠí·®'Å®ænì’÷(’Ó4 ûÂó'´:’ÿ ÿÿ/§µ˜8Ô¨ô‰ÏðËÕ¬¯X°½âBà!¦H‹§ÔÞÈÿ²§ÿ~ËH¡Ih´çPdza=‹Ô]%A Q†7;ɲßɯRûðø£ÔÍJ$GrF?$'õlÜDiÿiÿfü6ÀõTÕþ«æ&¬Õj6žk@0¬ák¤‘ØDÈc#  Moçp{›o‡ÅËEAwÛA5r÷Á26CÒJ¡c÷ ¸¾~«ù]nŒ>Mb-™¦:á¬ó ¤‚–^h>l¸ ·Ë|İñðe¼Ëw @MxÈÎO¯ì‹$äOÑÒîΪdÿeXÀ)Ýw»pKÌ[•‡=Ññi9„š­âo'· }ËyÙÙŸÓַСUr1vvhð7&œ¹p6ÀÓžG;”hꎩL èüsæUZ}n×1¡fŒœÙ;!òž„å-= x?Þ¦/÷ÃÚà*&m<duL“Õn/\ˆ~ˆÀÄÖVå–n®~×by‹Œ­À ™Q¨m’;¶è¤Ü«9.îÂ7Oyå<ÈLHá¥*´mMn–h7?°ËúÁÚ¬ÙÅ6̱£zl/L1ülðfX*sÙlî™Ð)äb²œT<Ó¡&a¥#uB—IQ‡•ÂjÞ3¤ý|ìëËBMð4ÅfÓñWO/i„&×ñß Ue,%¶xÿ+etÂó¢.ïžÌ0XÝÁižÁ+Þ†8‹lH+d4¬ÏÁI¨íàÌò¼-„ÃíÕÒ„hZÿu%#h1îYƒׯÊo×à(K”Ù`×+9.ˆûŽŽÅmhlÿ\a^§óŠ_ûë¥ßjî+ù¬²‘Å· ŸYóÛ§¦ùżJ[D‹ñ†¾4v nãíË<€ë|˜j¾¤äY2Qóíéµ2û‹Ï¨9­JÆh±É}JÌ_Ôš¿´•G}òpM‚ŽRô¿¬ü¹™Â/[;ÅQ‹ë”F ʉ:09'aEwëÙåÛñ*æÖ;þ1iLQ8r× ‘EY¨»Ÿ¿ŒRµI¢IВФâÊXå0»Þ6|öÌvmM6rÅ¥×Ñ÷î/tP¯×±¦áƒžñRÿ^sõÝ{dŸq+"(&ÎF¹‡X;u-D¿ª9/U":Aûˇ.Ìã7Ã妩ñ¡úµq_ÞÞ¯ªâÑň ÞܪŸ…0ÁJ }Áqž2Ô­ž:}ZÁ$YÃàWΛïÂg¬üÿTà›;ÄÆY“vÒhë£0â½÷Ľ̛nè¤r)(9šËØÁi֣݌Õ×7†S¢‚{±LtQXÑÊX,–7Þf‹oiõ£`;œíJwßägé§"ë9áïô]¦’äæþrÑ&¼>RímžÄmŒ±Ë•jCóÁo#â4h5œ:Ái8´™ƒª×êXA¶Ñ®Wl¦œ·¥#l twt[CMû+6pã¾ïùÿ ⽨‰ê’‹;‚ÛPÊг•˜3Á,ô‘ Êq5°5 œîn%Nðs¸zéÃ>†Rˆ*~…åÕ{¯Ãô3Çf£ ‹¯Í·”%ïn§ºßÀÿãÌ*°q)–Ÿz™5‰ç¢v›˜$H*U¹F¹Ôy± SR§«(~“[q»…Yk»½r-ÛvIÙ93m~ ‘-øpßéüÅrl:ÐI¿°ª½èÄnà.ô÷÷€&Gß%ûL”Aó)m? ûí~ïËóØb"”:[ÚZïgÆdhàvF÷¾¥Ó)#%ØØÛ™ =;ð Åg(G-TYlI¾‰÷XÏém¢“î“¢à=1—"‚í§D˜Þî80Vl :?í^VÃÔÀ‰¶;`3[{ËéÎŒRü}ÚdøxøÀ°Îõ ™>ðg–ûÔïÅE™Ñª©‘É0µsrâÁÀ ZÛst’ª f)ò.gŽrÁ.Dô%ž­ÞA> _µ4ìõ5ªƒxø‚žÞNÜõ+tú¥ÔOQAè›QG= îŽÌ.û&È–[’øGÎv ’º®L‡”>1ÉcXËR9}C´¥¦‘ñ/ÿ.4¦ œÉ­Vj<Ãöu—¾ÅâÂqVš½ Ïe<ŽŸ²é%8Õ_¦<¡×nË]–Íqº_‰Æ®g(æãÈq‹•š›TÜÙNÏõ›pc&¦*Áª–Sq Aˆ}ÛòêÁÅ0§X ;AÓÿ!·ÜZ¶ gJ²Þ5*ºÄ!ÐF³«Ï´ªÁ¯Ð¤ ?c„ýϱæåÍãlɹŸQ‹Ê9ßXÙ› ±³®€R}fh°›‘-^ˆûW*-¤t‡Ã$ˆ=¿a¹¤í“¨[i;†8t°S{6¦ôqá­Âñj²WE³dÒ™]ÙÆ¾›>YÊ4½DÑÜꢆx@uÐx>ù/N߯€gäW°_^+ªøÿyF£–e²a‡€s !ëÓ·©*[ó 7ö-åØ"›ÿò¦—£WšñÅð8ô½ í:?ŽªÃH»9S‰þ#Ó{y|pJÖ†åÀ 2! ~u±ó'Ù÷PèCy[—+EÑj]¸l/%*Ôñé0œ˜½d¹Å¡;á:ím_‡ %rwéWlCæã5»'çZ -/¿óô—̬y0Ï*L^±Tüª ê7cúžñ÷E ùƒ?²Wä ˜•Í´Ó¹0a:©°ëMSÿƒ”ؤ–ªNíCbG@¤É±W®¸‡ øê2»”Ið™K0ÑõÌÃp3 ÞéO.d0•RMGôÙ'oúåºõ™lßËOwÙ]…›Êx\dü.F¡™Ót8 ·4c¼}CB'Ò+a2°8“‡wdÚdÞÓ‚ë÷2R^çú‰FŒz¶/n~*¼_à(2NìaÇ"&Ì]§jxí\ÂV5—k‘wÎt+¤”Û–œ'4Óö$Î}^ñOQš¨#c?y°ÿzӔآʎ“«JþL°¼ág‘Àe7›¯,|‚…gE4~hÊ´7(ô½sÊlÉT}‹ UÆ—÷àËr·ï¯'fð4€6[æW²œ¤"âO°¦5ª„’7˜Î2¿*_ϲ¨\à!rèãŽv¹ ea'X˜gæ4¾÷»±W¨ª&X>ò­±EÿéACÝÜдS¸;ŒÈ< .^ô¹èž¢Û;~EÏM’÷ß¡µ×[°¡²¢ëûع/øÄƱ½4Fz^˜jª”z™S¯Pœ©zo#ò^›'m¾™@>#Wÿ4ÿ*‚áR5MQsšÙsIb¸Ôtsî{û¾-+ÂX¼B VÆåäT~7¤p"Fˈ 0ÿn÷˜¨37Ol+¡¸1ãgW!=ß.G->šö‡ÓnžhOzÅùIŒSîÅ©,‘\Ze«vüÍ]´±šIÃO:MÍ«¸õ‹¥’ðÉ ¢ÛG¤sF1Ú꙳JõÖšÖ$eLærS³€‡»Á{^2 URx1ݼ{ζÜ×\!¢`xY€Á^ ¤šèãé1WÃôžÉÁ¹q†º›=ËŠ‘3sþ»TƦ8M`õtó³ÆCBJCŸ{ÇYºßøw¯ 4ß‹†¤"È£ù £aið™Bæ#<ÐR„»&„­A5_[â¤W|Ñ"è¦ê¯b­N$%GDðl\ù˜˜UãYç}ï©iúUdŒ7 ¸Àåw±êY2„?5=Kš<*«t‘€Ñ‚óOs+ü¨=h©;£]o°õ<RDM8ä£À5ɵް — ™#ï§®5ëï6È‘{š…ÜM‰J)Ñb¨tâ¹zj©‡Œ s_ú «(òÛñÿy,z‹*²á˜ò£„ldøûÈ@‰¥üÕiÑ?è½ÖS'åHµ•ï._ÅlØvÿ0ëÓŸOdÊD‘ýRØfzåIó±2Á±ûMLò»}9|nl²cº Êè.g†ws¼5ÐrI¿" ©8çµPŸÃŸk2zT8Œ ðGwfŽ÷»}M¶´Õ™á~þx˜7ø‘‚?Q;ù©Ï‹°”$FM¥hóªÅ-ZpÁ‚2 `˜¦¦Ì}Ó -`Ôˆ÷š³#1³Ù*g5¦«ÖÀˆŒmÏêu$p Ö±/ç åFlY!nÀ…¢îÝM³³|d¯5÷{U î^DJe|ÕǼâ‘“-/3¼ä ¡B$÷±û›èŽ «¸žlºè¤æDć(t{®ñ!ePܘ£¥ëC9®†þdÛ¦ÙÒ(D¯†·2oÕÑÈÊ .)Ó]/=È>› ¢&‚!-ö1¨GÔ†ù²q°ÿ´ôÏŽH8kåuX77(óÏ×f©‰ˆ¿¼wb9¥ÂyŽñÙdŠ7TÊ<d1ò‡?‹pFÃC¹nÿ>–¡y_á ›Í†Ò0Þ«QW*³™Nß6á)'®£©nàCBȨÌ.TH ”|axi9–ð§ E9/ E*”ÄX D9·ãLÉÍ;ã¨J(Ü›_¦Ln¡êx° ·¿’¦ð! ²ÕS€tžÅUÚ]äe6!(ºr`òvæø•Èº° T%õsí¥÷zÅO íÌjñ·ào©Œ& Lh™³=Ô—î‡ð§ó®MÐX‡Ìk‡íf˜èû°’TŠ®ðš"–1)£ÛüƒÎˆ¼¥œ3Õ‚‡%XÕ!¦è4žÖ“øøËt¸A½C¶û†ÜQ߀"’VFý•³ß@‘A:‘)às•7ñ1òXLŸ_ü¼†qÒq9| žãbæ·¤¹M U‡„fÞ‡Yïòù sžèŒÏ<à¬Y¦'jémtucs¢´Ó|[álÖðïr=ÍÆŒ%èíÈd̆”ñ²¤”¹bf#FWO¾.æàn˜áû6Urò4Ác‚ð;¸™•…× æ×éï@o/¤à$²HD‡æ‚}CSÕ °…ìè·Ôvˆy5áÊO±Ø¼9½©îD/Ä-GÖ'äBœÖ6÷SÊƽÊ<œšsšI{,jjérY½U”ˆÄˆ‚¹ÒO‰ôè2.±œR%â=áÄk ÉdR—´\ Ü6â¯0`u~QqE‰r›LÅÆG7»T)#ä,ÛåêT÷ÏI*êóûÛh|ûyÁmdžÎaA» š6p OQ‚MŒ>Ÿ A4QÎÅáØ6BB(déh± 0ix` b޼3‚{´CPŠnâ`£Â>í¯¬‡FbÆ[±Ê¬ŒööYÎÆÃO~¨Þþ¬§M*†ür Ý÷Ì(¡ŠL*[CXyS“=îAµ–‰â‹­ó7{ƒmóû Ž—¤b)ÅezGî<à°Ãt´t{“c.èËc©|Ÿ~ãË%Èéš×'×N‹²#âIÇIeÒï1©ã¶TŒ$•¾r×pf2Á.Öú3Ö<ÿ$¬ý㬊NþZqÁ|ú‘ôGaËãó¿B Ý•-"ïn÷, ¯h 7še|ïs•–Ô mÀä¿Ïx {NSõdê§€‹ž ÿn¢ZWþšÉ˜…Æ?PwÖÁBŸ»{… ›4hö ÿSÂC6Ïæ¤éè ÷3Šwc%R§cVˆ5J|wÂ’B`ZöÊÖ*×fs_À°<ÉfØ 2_]J–.ëže‘~üxI!2¯eU¦›Ö6c§ž i­²üÑ#\E0±Øì$1ÇBC0â( (þ!å[Öð0/6Q‚‡™ÄíO$¨ýêL'ðLcÚEíàç¾Å&#²Iÿ3ê½ó#3IÂúÁè!¯u<Œ){’hѾÕ,ÇQBUžØk>ðnžë´ÞEÕßìm–»CÄ•;8„s¦§€…mH/ „*^e†€íw ù0Þ´†M€-Y!_³­˜èïµúÛ@X¿ÿlÑæMìþiÙ)’>Úº¿q3f¶ö"¦Œ"öª†Á¢ÁÁ¢«Ah2Û ˆC¤-°“¢ûaùå_W!]TéTµÚ+›9ì1ØübXÊFêÆ2aÙåhÜ#ΓWæ)·Aüt@†tþˆcÐóYL¶Aàr‹¥$H²©WUgƒ“Aù1QÚwH?Q¨qK „æm‹<£È¯ŽêéCh{(þÚ8ɹËñéËò£(ª)Üt÷t6ÕÝ`ýÔª¨…ÇÝ“ó÷2|YEóÈ®6üT¹p‹áÌÖô³³úʵ+·"ÛR( tWÏÊúëR³F+úΨ±š: ¾ÿzlæ+ž¬¿iqƤ—ö&W”h¦'û&.×—i±\€0“Â^Á…²—[zÉ;ñ[èh*,oöŽ çÑeµtvßý5¡‡Ô]w=§`8Ю¬ùÕñ4 it(Û¯•¶ªëœ@ÁŠø±ñÚÏ™ÁÌp…©ƒÊMDÍ`M¡¤ÑÒ¦Ÿ‰€-á}®&Q€Ly šfGgU¡^Þ¹S¶äì„­¥hžždÿ/>Má‰t¶‹Th¾4€Ì9Û/¯ôp¨Ó+ÔóTWãiMÖ` šÑÍÔÚ³_Ã¬æµ ² ˤÝov¤å¦¹ K”Ù®¢˜cºð¥9ͶéZÞw-H¹>‚²gó?vá•gÁÄíÊZgYù“‚äÉQ?NãK±ŠéBÿ›®=2$Úõ¿“™w3ÖF°¿ÏiÏû§{¶µñênd YWÃìÑ/òJ0¹2Y5ñU}AB›…÷™ñDJ‘¨ .#®Í út·k’Ê>‚[þÀO"JEæPt³%BXº¡r þÃOÞÕÐBëv`J¶¡kWv0÷넉bw?êY!Ë…´—„®ç±Àmºž<—´ùœÝÔ8%]×nî Ÿ‚FâN \t#‡&Ó…·¶Þ_ÍÓY¹} µ®Ûâ”6&)w¦—°‡6›þÈâ ^븢G²—PŒgï3TµŽû“Ä,Ñ ï™N ¼¬ï“ª~åeúHýÅ[Ì™‚7T‹höY¾ò:XÇ7˜'Õ`ÏÔ-¸‰n¦ÝQ,Œ|!)m;‡Ë÷µÂ’[0Š4X¶?€| °]KûgœØÄŽÝ65ÐLâB¿¤¿ýgA¯‡÷.¼÷3­IÐSmvÂyHSü. 8c/¼v®äžû¨›¢ReJ°Ðc]¤¦s05Ó>&(½S¹‰Q¯ïG~7¥€}w_´ÂØÀÕ_šà.uD±­P² LWT¿„ù²WëˆW'3“c2¶ëƒi'¯!û§-.á·ô†!¢\–„56ãÕJ»à‡A«Y ÍÉÓ[åzv#|Öà™ÚÏR½Ùf>kXÑöÉ=’Ÿ…‡z7Êêd§ÿÖá*o͆¸ ]§}æMí¯ A.(¤_&wõÈ¡ †ÛñáúuÒÝÖuØå ³þ0Åhƒªˆ[NË·X-åc•t0¬ÉØÑÊ\Œ÷5= |µÝ™MghÒhøÛ«÷Ò×Xf6$>09p\DµA„; è‚£OuÝÕ4È7Z„ãš?Œ0ömä+Ó+„?ÚØ÷¿‹P ÄŠV1Æk.ZpPÄp¿MUýC9ut‹s¤½>ëOĉ Yõ ÛŸŽû0wÈNÐ;úæ=GhG¿Ë¹c…}±Ë%DRÓÁ,‚¨‚ %ÕÔêú¾äÓ¸¹Y6 þÆ`?6‹r‡ô@˜ˆP¦Š¥ ¤¾ñ‹0Þp—nµmŧï¥à"´ù¦xÄ9á%ÚbZSÈó¾Ê¥ “å !þ†Ž¹oÿtu>oʬ2uø,¯h »¯¢þQ ›çK(¹É˜¹0ßõ!Uk™ì|5£ßÁ{Ôœ™†„´Wó!ÇvL‘'.WWã¶‘ÃþÜøJC"Æ-úÉ“ÿcÔä}v/nÖ›è‰ûÒ¦|[´B g"?ôï¶—ß·LmIïÛS~Ý+ï¶“ øh³öˆþÑðÒáIÿa©+ü¿á£3ê;¿ÃQ†£ßmØþQ}£—Û°÷Û³¿ÃRølÍöлöèwíÔÿ?hŒùÅpù ÿ¼ÿ¡¿mãûoïÚ" IÿB¡þo´G¾Ñü4[øRËí¨ï·LÿB£þ%öé•öÓ®Ÿð¦¿á¨ÿapð¿?†¤™_m=ü4x?†ßm3ßn–©úˆ7íÐ_Ú‹_·M/¶Üþ¾}·>q?·c¿nØþÛŸß·Lï©ï_Uû>}Å·íß´Köè—íÒ—í¾ÿ6É·Jûí§?†„ÉÿŠ_m8þøj?ðºÂðþ{ü)×Gü)øh×ð ¿øQ_ÃFáE?…%ü4?†ÿÿ†+ö‘oÛsþÓ«ü4?øZ·Ûr?m©ûA¿n±_n¿ÿ·ÿa£·Úé¿mû}WÇçÃäü4#øhöÜÿ[]á¡?ð£ÿBö“þü(‡ð¤ÃE?…þOðÑŸáE€ô„ Ë­ÞæÛÈkëýÍ?Öø5 lçð[ÉØµ)øü6åÑ”*+"C |«(©æÒeTÚ< £x4Åo¼_øÎJ0œïdðÊGh³ŒJ”ñ­Âÿ5µƒœ²º<÷p[NA'ÊSjÕr±{Q:O-1PH))±þèÈÅCóPÀž 7‹Qޱ¬b¡ÌCZ^ÑO¸‰_ãÉzwP%Úý@åÿ/Šâ»n(ý` Ië0•Š®öb2ÛNú—NR§ŸDi~…¯€|>ƒ·»ç Qmš$Miä” ¹ëg‰#){îÃk2†!ˆmÐ5oÆòEÚó†ì¸Ãä.+ç&CDDiUæ›}UøœNw„[½ío°¶^ þÚ¨©(®›"è-† <5:ãƒJÓuÆâ‰ÿÿNI?xT• ©æ"ôògöf;>ôö‘Á#Óm¤°³".@ûwÆÙù­U2.7L5C*¡¡»š&ÐÏ%”†¾*"¸Rh"©ôx³¦¨{¹|Õä£Eà ñ³ãÿbÊ`VqàL£ÇjY‰8ûÿåÝìáq;„Ž Ê©ÿ#ÏĹ-¡Ç¢/„~Ù_!jᎣ7Hñk‘l½ôZ)ç´ )c¸àZ{B¸£§jÊ,Ie;ýëÿ^üàÕp’Ò°;•6Úí@Î.ï˰Øq ÆÚî¥ôqÕT8¤¥al¯ãÄ&ØÀï,lKÒ"7 ¥.Å þØW}ìh¸³kúò;)RйÙBâbwyC8JMôo½¡éa;€ U¼ÎÜœeåãÄH_À=ï—¦:/Úþ|£šX7‡µÖ`æ·àËóy8â’•-"ûœB%è°æ%3?$Êÿðq>ûˇÿ7z~:¯”[¨× ¶Ÿ£ uUyág˜‚/·õ‡ýà€Ð:ûÂS†â 7‘ûQ™p\,¿öç0ÞÇfJU÷[‡LÀÍ.·g¼{‰e|T¤Ž¢Æm†Ëø|PÕÇÞ^ÂWl½ò áÒâÂ¥øŸàØE+§®õå:ÐÅem†oOjð=šŠSB4XAôSq‚ÓÄuU-„-FÛ=³ÔCQ@Suó|û»a6þÃæVH1µËvó'\µë\þ$Ò«•±åz«ò½ñyÏ–“b$°A|Ûœ5ÌöÌ+z@atxO–¡æHѸÂ,µõ‡Ei×È[ZkÿAУèmÇ0wõ±e(\y—[7ûÜlTúë›PHG?”ã¡€Ty­|`2Vu¥.Ódç©+dVÞ°XAû6¢“ÄrSùbò‹]À I7^¹%°ú;¸0%!)ß›a™<2 ç¹OD׋6sìˈºzNžß¦L ê,@›·ÐI¤c£óyTñû¯;×d³„C‡xjµ_X„° ÷x¯ ’æˆbň;¯(÷­µ™Ýº‹7"µý¸.TýЉ žÏ·gôè× m/EL‚5-µì7Nc¤®I¿ õ9þSíð±ÙêÐ6OiuyQîÖZ¯òþûS…èp`œë9®æfTP­(¸ÎMvUE 6.¶Á®IP­˜CøvUx8˜ôûeW‘%B¶`r'mzÐKpüè, ß®WòQô#añc à6¤¦˜Â“2ÆÜ” Tm“í$LÚ{Ñx¼§Ø»ˆî©1SÝ–ÓJkàŠÞNž¶oÙ2¯ïâ­Ïa¾ß¹ÝÉNƒg§†ñÔ¤Þ ¸çØz‚ Ük]`WsQ«©¯WûÉêJòØb$» E‡¯È‡Þý—ЭŦe¡®¬/3¹ÉÈ¿ø.¸XüûwôQóD#å1gõqÛLÌWÅ%Ú×hf–z~›Gí9ÊbPéJ­+É`ÆØ$εX€jHsêE{—Ÿ…°ur)ÇÒÞUœB»´Ä;Î×Xd¾DráÇƒÆÆ{ÃŤm¸­:­ùuÿnõK䯤 k¹5Ë`›­r¿×á,¿P0—ÿ^ú³·ÿ/þ $%ÿçÇrÃfÉ-˜'¬•£Ð_`,hIh÷—WâÒ´rÝ9dvÂÄù¼Psr<õ×YwýIú8€3“- N¯88¨h ¯ÅÎc¸ÙÖeè[gŽt´óôu|5²·ÉO & Ú#ï\¶Ûݦ°^õμ a€==þ˜óü1tsÖ>@Êxé=Gî­ ÷eùÖ–¼.Z°É~€L‰ª GMs>'²(wÜ‚©ËðY‡½ñpÐ’×o™àÙ$QH/¹±Mî†Qy*¶ =võ§F¤$¶G7ù•-L–¸K™óN¬k–dBò¯Gï >=¥—jœ¦ŠŽà&ü]YæÇõÛÇtö:®ˆìõ¤£ÖœåRæ¿Ôø±vÒþZ=6ñAÃXS€\¶üþR3Þ.ºå§YTAÙ¨¡,ÿ4¤méü^eÙ"bn-D)¤íæ)OU5JšcÙÃGÚ£åßôH€½*š¹Ç7à…D338sÜÞÆƒ¬ò)F¢¹a6 ±ÝQ§-…]áÌpàCÉÑÒc®µ–&Îvüb¬öA#ë1¼[ó¦#¦ Ì‘ö­¾+9t •³gÈ\ñüAÊ[k'·ÙÌG£;7¥/ñËúÐãè ¾¥ãf Ÿ¢ÚJ¡»œ <¬¡*–â±õ ò‰È8ð'ù)Ì_UÊnïƒkC<®“5­3Rµˆ¥gní(„R‹H݈ZeñLªäZÄ— а~÷„Ûr­ñ¯¾Å#‘= Ðí‹~jCõk9ÊÖÁ!íö#NˆƒÅèkÔ-CÛTð‘9¸zÉ ñoe«(Á¿œ&=À IÝVªPë è3•°I°VeÝ$™ARšï3gä£MÖX¥Ößò#™:ÉnH'Q3^™Kƒ€›s*ÆSÝJ©ŽXÀ½oÓŸ §b-³Î:¼Ñ­aé#D›é Ogh‚9€P´ç3-Û¹ñm†¬’Àï§ü¡é=%¯>V¶!/‰P•Aâ÷¡ÙÜOøKa¯N¬þ§Ä/5“P•àeSG„4">ùH•?`¿™òcÔV–°f—H¨ù"¦˜â6Š OòtJ’QÝßøFÌ{@ EÍDÿG"´¦Š6©aÞb…(½yÞ"j=„'â×âš|VÊÜ]!Ts¿2¤G¨å¬qüÑÛ(O3ìOU³º <ƒJOÖfåÓj#(FÃÈ¡²aм™ÀégÒ°µ5H ºë[¼ðò—c€qzà~qÖ*CÉn³›@Y³÷X2[{[©+£/¿4"wÒCÀøìú>Hókãª|6˜(¢Œ€²j¨žµüTrOÿîà<ÆBгwsb%l5gŒ†m“Iuª>L/K»ã²§4nšHoªCËQ‚!! X‹FÊ;Á3ÎJkMô/s]Óˆ‰÷*ûî Ûi(Ç´• ï[:¿œ¼:ÇxÚÈ­ÙrÏõʸNÖîÝNœƒïÌj(‡HO2FµÀtÉlæÈnžlœi§ÔØøß+àoØÌbgõšTó§xxç‚äßÀØã¥Íñ.Õ×ñ©ͿÌ\R4Zÿ y$)Ìjš8Ѩ•£Ü .» Œäcƒ{L ÕÊkâ8_Æ;¥í- Þ/›ÀZY«åÌÿVÙh+ÕŸŒ[ꦕB¤ò¦´k™÷|«_Ü•viuÙªFh«}Ý ò*ùÚàÐÚ>·ø 4ÖÎ3CoÆêf ¸7OZ ëãìTØÆçbËÆÔƒQÉþƒiX¡åŸ»ÐSx¥í‹ØaÿW}ÕZËrC‘|<ÌLÿx0ä)vŸ5ªüïïïÚÆ 4ÖОÆÇÇødÿ3ëàcp1…s1ƒ‰ííýrýtš¾¤×y?ý{eõ`—0wÌî§ëóŠ÷ÈBIæFfž‚®Žîy±š‘7y[¼œLk˱¦—mGû¿Õ‚TkiÖå&…¿Fr§³Ñ·û¸ÿPvsˆO'Αé9^SR(ÇPìZ´Ô"å ÔbE¸[@g>ׇïŽr>}ñv‘fZ‹ Jßl/ß-²³Ù‚±ù_yDý•[Óa»\˜[¨0aÑ®8PÈŠ!V“ò¾^Õç!q¡f*)£5[¬ƒwJ#Ì€òž4ϤÊ6¢ê‡)lLZ¹F¢6/¡€ŠŸty%hßÓèþ ñgÙ"ƒ]K|ޏ^)¦*1h(”Ÿ$”I¨èj~ˆ‘/6.ÞÇG.7çÓ(à ºìâ§÷£Ú£7Ó©Þes¼]%OŒ47Þ/ªòÏŸi~x»wNV+„cýª\»·OÈfò–ip‹–Ò_)m'•­}Õrºh(|‡nÚГþ™ç»šs“¬cÝ.T}/dV®Ö,I±PU‰dö ¤ä§N–:S>E›¡ƒ‚÷ËléѹR Œ­|wyÌ꛸*PÊC_¡%[±h¹îœ„ˆ/¦=VC7¾96„‚gº ‚ðfýߘ³/*Ža'ônd[‡,Bsd¾7øq‚öâÐŽÈþ€ùæiÝnr¼‰l¨C$(¢ÌÚŠqc 4?1:†ãÄruô9%½â*t‘nHÎ OOÑ<@×<†ëÈ­èãÐÜ„‰£€….Äk¸Ê–Ïú±ñ!OŠÚõnÁ§<†Yì®/$î‡Tò½![ç…(‹!WÖ¾êØ‚ wLïÓª³éè@…œ"ž‚¤áç ÞÂïMEˆH¸DÉP‰øþÄjÒƒèi^ú³·ÿ.úV¦JӞ0‘Ñ–ŽÁ6nÈrdÐÁ¦5Lp`aZLc)Õ×ò3¢‰7Ëõ(¯?0‰“²~m†¿ìhµ_Ù7<Ü¡¥¼ußnÚ WrüZ>ÕL”Íõ^üƒ;x¿ä-Ñ""J” Ì˵»ºs®x¨Å†f#²Æ'm¢J®GØÏµk ÕÙùZü!¥Þ묵*8¿Lê±y÷†'Iê"J0Æ4­ž|ä:%m¶íáÓ¡›ËNáίõ¯YVÆŠ)*øž¤«ópçûJjˆsÚLɈ\ ÑÕÔ”pq]úGXWD uj€‹ Í\ð4*й3m1ÍP}@ HÆœV!Wl¶ú(Zú¥ .†r‘ƒ'>P"×fAø5Àã’÷“zŸ¥n8laª) ´ï(j•Ÿb³³;˪ÄÀéÖÕ[-ÊnE4¥’Êa¯½ÒöH’âÆÇPÀióÊ»‚E¨W*9’ˆ›ÍJÆNÃXsk¡Ä¸äÏÒn[ŽÛxšpÀt@N (Á7 v)åiñsæp’ŽÆ•s¦t ÌítŸ¦j5V·_ÐHF—ü³ è·*o™ÍW`ø4ÿªØÊï4ãSŒο»ƒ·@ã2LSØ }‚÷¨ŽZýέùN¥¸–¯3œ'VPõ†UNýq'ë5œBHÑ+ú3Ô©Þõa%Ê-UAË%*.»•ý3*]yN½Ã»«rÊ"ÝD”‰‡öºF5©MA@š‰@ŒJsȨÅ#IÌ-Ñ0µò€½mã0ÁÉM#®½f>7›xÃG/ù\‡".P+TÕk8ÓÂFýÓkº5=W”Ö3õuK ÛÍú~‡”B€\˜¢d`zLèJÎ&=Ìé\S¡…¯t *ŠÊ`ÚÉõôoMuƒ7;¥„¬B÷-tØf"ˆ‡¸ùo+ŸÞ¾ÃW%öa0Ë+Yòá39³r å¦í›at¥¼TW²w$´ä©·útÅ9gƒNã',‡„Uia~JÃI3PÖ¡ÌM|ÿÃÖÓ1§¡|É|Vth ÆD‡ÏCè#¸I7æ>í25Þ™J2þãz¬üÙ¯´OŸE«p£É¨!ŸfÌ<¡ïòŽogŽºMLõP’¢’c°b„º )3›¡¹fóAU䞢XVTѰuÝ“…z] bùkKÊaC£ÆX›$©W„ô–3nç|ˆ2¢ ‹Òö“ؘF†«vjXþ†`vïú0š‡ø Z—œz‰þ—œ3õÂ…>p1PT,ñ-ÐSC¶tgÜ6"¨IÐ> þþûG:h0R ›D'HÆåWc*€¸nˆð€]êÓ_‰°ë“"û×ðrCª¥™Â˜ð­sàD€áèUìZ%¬zæmÌRÕþ`T/€9ÓT0vœ\oïÒWFG€4“0$ÊîZk1ßN›¼fëlNGM/ôû³ît“œ­óÕ­ý’Û,¨Åö€äp7àÓ"zàÉÄpø]±÷  2¿';µ®–”'·Ýû6``¼õ±â)Ï$Þ¡'—.7%ëóx[-IŒ*Ê5Ú­ÑÒ®3>·W7—Z[Æ&þ&MpÀEû‘9Žz«™3:ó,zr#¦ é¶¨õïž,}¨¦|éƒ^Œ§/5jRôô9®ºÀ²EŠB¦=–Îöš4Âó×âà!§®“sÓ6}^ÔS¡¬v–?ŠD–ÄHùŽF0œ=m ³¹U3y/"â ßåÓ¹ìp‰å}3pͪèÅJ¾aA §¯°ú;=kPé¹ÇX6~öz;ѹ™ßª ! 3ëÔÄÂhÆÎøëQª3¦%*5(ÊùíkŸ‚à;O/™åõשŸMEÕÙTG§ßr!¾Ä‡éb¬ÿ¢£8‚c¦Ó×¶Ô‰°Ãlái8Qma2èQárް²¶”p(g>×Y®eïùç}«PSœÖ9`l ù\ÍÞR»ÖöÚš‚Îg°[ÌˉìJš•Q%ÌÜtúŸbÁ¡Kœèw{û¼ZërSu®ÉhƒS¨Ž°]Kx&WÛfF­Ì¤RúŽÌ£?š+2éO±h E¸(8â„{s›!²«‚6$Æ(öÿ=Ï/ õØýí‡b™Wzamxåu¢VߣM,ÿ_ 5Wx%™qmÀLè›Yà­$Ìç-ð8¢Ö 4¥‚c©OføŒs÷î÷x™3J¯ªŽg¶>§!ç'üáißÌ×½U±%à“ü +c¯` ¬5ˆº›““Ed`JÒ%ÉÃi’Õš¿½RPœ•Úç¥cµP²‚[,ùôŸÖÞ rXÒÉ[5Úv`„~£)¢“8šÜÀ5ÄŒ£)៚MuAÉOŽ¿;\@ +’{l¬E7ÛQá]VMšƒ•âRæ{~i—q¹*‘}–#’Ö'Sƒ *Ø—MÇù½¥è|¡úHKµÃø@[àÿG[šG>A5ýfbBF T£ª2µoÂ&ësÅè;!-ÃE:ÏÅ/—ÿÄCÿÞ´tnú_Î ³d¢”Qè*åsSˆ6B¤dBÜ=^˜Ž´ODÎËe‘3§ÃÍ13ó®¾KJFبX7Ò=y¥>s> Í@ȲçÈ\fþ7Ž¡«ØDƒlÎCV}áH»Ôb>~ÞÀ4[ã„Ì…¯3x†âR'<Ÿ_žn -Pº-)¢QŽVOåŸ)ˆï ´Z¿„­Ë¢’å+ãË(MêA±·×€ßºv¸{¤zHp»™Úg;8^¶Àæ3âÿ´)X¾@/ÝÄ{/‹²ë&ZO’:I°è+ ?o_ôo­ƒCqlníf…¢ÖkrY6õ&™|Ñ¥„ÜÇ„¦¼GÌ¥äs&y;µ¥^Zèx§¢¹¾úÔ[½*ÛÒ;,!äÓu!Zví}p~IÝ6©›P®'¬%ÓÕÑúB8‚.Óé¨/a5=èe à³ÊßOò€ám¹„SÑKt}*ðŸ¹Ä„Ͱ£¢ãÚ.wn[-≻íJ%Ò5êM&·:éÀ;ŠgûuÁZ¯PaÛ±4¥H1]Êx9FÄQð#w»Õø¦ ¢U¡Íïb±dÄaÚûE0ž&Å™>ÐÞt}ö!%'¿ÞnØL]ÔþšRÿD©9ûèÎ ‹'ìùfd«"¬HÛ ß–Tg>]›.*4#ËÆê É ›dz倨nŸ“º•» ë=g]àT ƒ:Òý>¶ÑÇ3”Kuts³ÜE·ù˜8ð—ë ’µ@¯-Çwÿ:Zˆ#á0Á.<ÅGôdçÅÓ..”¾úfE‰d´¸,ç~5"Wÿ!8¤Ø17} r/ºôð\ºV}¤¼™ö¯f,È-ÈR}”U-Œì«²!´u(Ät÷†wˆndDšn—?yúH!*âÙmBÈO\x‹wÈ4<ºÝÜõœlm|˜ƒBÿ,5 –™¶\Ò}È.¦&(…Î09Y~i’ÛWC~‚áÔ­ð̱§ÖV!æ>Wõ#¸i|䉈ó\- &¯ZƒÜBC„RâÈö·Y£OW¨Œ,êSÃüÞÿz—éŠèøßóùæi[Ѽ  m g´øëFƒšu o±œ´Œè¤ƒx©ù+¢6àKÀL#®ß²Åû>ɰM&˜Ë!¤“•®Çèü˜Qî—AÖr)ì¢o ‚ù‡+5VISZr—ÄŽOÛ]ÎÁò¾q’F¯UìÆˆ‚>y†™"ô;ÆZ¼ æËo‹>̥ńsƧ¿› ”ª}Q÷)åìå~Óß®3 ðï[¦IÄÞÞØ¯Œ`!šÚ:¥ Sõè>›‚U]@~ØbÒù«kO.U”-ëÿ|òúÑOrºÍ7èvŒ5™°ö ö>bÞT³%»ò­S¤ù¼CPð’ ÛR¼‹iô…Sð†3þSC^ÝyÓ8ÒŒ©©ÌN\¢Ù¢HdÎîwÂ$•k$W5qi¡•Pá¶žá˶¡Õ„ë6Ê;óx•˜„)Ɔ;Ô›*ÏsÊh—ïµò=‡˜c¬ï¥UÕ:Ûšð„? ¦:¢œN–Iz¯ "!¥’ÝBÛÍ]:ûh*ªì˘O^ú³·ÿ/þ $%ÿž¶Š.¸v§C‡$ª§0& wôzüè÷ÕyjNëŸ3dõUj-ÏÕVLg%ò7ÑM …_ø_æRF¼CKù’¸6í C…C¹$jgm,âbDù‡!î}M‰¶gÄž¨´Z2D¨ÍÿHùX#Éf1²ƒk¬púH ‡4xâÕQ¹ƒº®oõ¬“Š jÎy»Ù•7Ñ{ˆ›7½c­6‚ãqàYómgÚ•ûùñ>vÏåÂ.“w©‘ÔMÕéXàQA^Š$0L kÿeãeòÙ`pxÄôà˜Ÿ7Ä|œ;´fY,6𨉚§RžP ®ÞŸRrLŽ4¥p¼-&$SFg¬8 2Aç (X(}²>&âÇšI­%“\h¶£ú¹žm¨h¦órf\Ùˆ!ÒN ¼o•›ÖæS‘žµFñ”€e[ o6¨åŸƒZ´¢T V7œ18Õ=Sh ]ïéíº$Z„{©¢çÏŒ´—ÙÏQMmº(ÚR3xø5õÖÞ…Üm‘ní*^ËmÓí>ÇèUhvùܪR«á¾ºyópŽºq¥¢³¿Y,ÛrIPr O´å¬L¼“‘ èešÝà«þ¦Öª&Ch ‚·ŸzNç.bÆZòeÅJAÍš·'àŠ™ô…º =ùkÍK³¸aÉL×Ð྽öq›þÑKD™ •­Oʉê1”o4pe…ö“hž†tÃʵÿ<Ç¥îPé`¥¤>úûÏXß9BD(ijL¼„E^7ÕïXi‚Íd)ZP¦hB“+bÓ¬|Ëßô ^ Âæ˜b] [7¶‡ì¸Ðj  ƒWú£pTFF0év+ÙÿÜ…u³î»[P0üŒ‚~ ¡LÊ(?eK$÷0VŽŠ$O¾'ÍìŠ ìÃËe i1^á©bÍ[ió¾Üм)> .Åå/» gmì<|=\éñü¸f´ƒföÚxøôç›ìˆ ¢r8DÄ#}[ÎmHvÓÚ‘¹ñ^áYÅ콡‹è€lÏZ6N"6U°K®»‹A–=©ð$*Úkð×ö¢¢oì¶Ík†X{J“ÀX3nÜFÉò»¤å†­Çz'G×ì.ÿ¤fâ‚^—Jóä·°¹|1  Ø3+œªÁSç…@±¬¢Yur¦ŸQÅõÚrÉ·Á™ÏF4eÿx —BCnÀ@o×MÊ ¢Y[ê((úæcZŸVþ¥è—ÉÀÏ]ÀgMŒãb 3^á=ë¥| XŸw]utÓUlÒ•ÞíÍêæ>vãxÝÿ%ËÃÕRò·PÛ’Ž¬”Ì(>:Á²…Ht«I•…©*.‚Ù“†å2+ëc‚¶á;ÞPE’x@L¿æFø¨&ÃÔ(Q V]·¿×ƒ:àVyÀó½¿ú¾Moù‘‡‰E4TøFØ&Y ¹¨Ecé”E¢Ÿze*IU ÈV('z§ÆÛX|QM¦ë{‘-Õtðwb‰A*ë–Ô!9|í,޵ ÖÉ{äuI©HXU¸æöåâ®1“Þ›Ð*UØæNYÐ1‚´P8N†—èÕLH’Qƒ† æ¢1\¸pÁvÖ›ÞáÞ«çY¯£5YÃþÀqËá´3|žºiFø"™¬b”+쿃»¦ºÄ2p„î…|8¦ì`×éµ_þ»#cŒÉ =¢á„Ἣ~0üÂ…‘àýò{'ãkãÅE£úØbûÒõtŽúÈ4uæ<®LÌ;xÓ‚•y`Cªi:E…3BÛ·øßÀbÌúƒ#Æð²‰{Û"®¾z êe°ý­Ö ·q¤Ù ¹wP¯o“{ES5âév$%K[¯±Iƒ°g$ÍÀ9€hþšZÎ,Ó'ç,8ùS ˜³"eSRv]ä‚/¡É•[î×µNtvºJT’ÙKÑ·ksçGmöšîR®w™~”ÂYµ#D’°ÁOôOÑŠ~ö£ähM \û`uòü^‰~Â{ÞVã²ÉEÂd¾QuX‡¥3ñ/˜N¬çqwm9C‡q_w˜Ä5óAT®*’›]Ò î¯Å¬KÅym}(a…e¢ÒÒ"‹ž7Løùhåuë|–Ü1ãtÌ1ÁlæWjÑ^DÊø…ýa~Ÿ0–F.Üo//”òv¿’³`@otô?Ô ÷Âú®ÜNªŠ£‰«ÁÃkŒ7`#¶|K5ÿ~=–Î9‡i)·x SëWÆîœ BlÎ.ðT/ ¯û'oÍ&'¾\#ÃjU°/ñϪëR…_V ^ôš'îSዲ&Â…¤6„E>$…}€GD˜„oŸiå‘ÞÜè@ø]ùøø¶[ÑÞÕ8Ë–Jœº$"4u‰%c‡«ÛÊ ]Š þnO¬Ë:Ÿrê±Z7žö¡A“òãkŸþ•üQ´ú•È’µ»ƒzB:H‹iî~bïµ£Áb>”åÔCˆjgi`ÆÚ¯4ÈÔ”p §„Á“›PØ •ü¾°à™xêÒ3DI‹Ñ«¤²¶*‹ÈAåÄF~ë;G¦Ã½¬9É井¾½}û5ð{¿»ºº§’ѳ0€pDYÿ‚ EÝ \™Þœõ'»(Ç»ƒP ‹©BüŠÅ«ÿ9;ió<¢Œ hÿLÁ4?`6Èó™'1ØtG=`ÿe&¸ÊÀöÿ-jSO‚Hâ·T"ÿ'¤!vF_bȪyõèÛÁ.# ¦"´º% +¡ŒòâŒ%èÉ´Ü`ŠGþØ •ì©SÓ@ªrc—½ æÚè=ˆƒÝ•KcëðdPä„›œPUÚ/¿“Î}8ÄÇÇøãw ‘ÜQH Ñó‚¹YA÷˜*W‰]T䈕€ø™o³MÜ0B8§Q'Ó‹®!³—”ãÿ1„>Þ°çqT°F2ɧâ­sé°Ú£ýë ²³,­OiüÒBFh™/—š#ñaÞsKo0F(DÍÍ@ ob8Å¿õëJ&PçÛóž‚«¾½¼À‹Ûr¤­¼°ï¡‹õY¢ß(8áÈsg4¾÷Ð/ß‹ý˜KÈrhSz½¬ô‰à®!èª_)Wo/ŰߖÙïTK+Õh¡HCí(À-ÐO–}jj…¡y¬„ÒÑ&—,ê´[ʰlR”[lÅ»?‡Š¨/pŽ‹ªZ¢YáDõð¡˜-$g϶{ôÏ¿–\æS­Ö'ÙêšòÁ¨…»—¯í‚xg'Á-ñTÙ㇛“^Q*¼ac÷_ ¤¬øRf›ò)û¯ã+«r SͲݓ’·™0ª …¥Ò¯2ÕuZ›ahX‰3ðÀO$U…‘†‡ÓEddaXör„hO5º‘_1¬æÞ èŠ™Ûç<‹%PŒ Õ4QFkNÆÅ€îì1L±a”hÕ…`nŸqW°T¬44.ìÛÐWÌÛ°uišÈ‰}âTUèzcÂU5P?ɼ,'¤3jjÕég%öMäuR‚̱Üá•)•]7#ƒuDâ¶·Vò¦:µ@4Ý›eW ¼Óá ´bÛQEév“È Òµ–°t¹xoÐ=Žç%¯a"×+èEFܪÇssr_Ý*ÏoËcÀBù¦—m0Tç§ð¨L ¡×+è1|áP˜qnÖ{0ºqâ9\¬˜H„–sÃÝJÚ¨½TFCå&¤÷ófsk‹{ݪjUd¬g÷ÙáŸÂàÙŒ‘N3¹W0­\È|ðÕ Æ@3C?𭶆‘Yúg°ÇG¤ÙÇn{Tbìï/v¥Þ«ãtý㼜b}ªS²˜¤Öpʆ¯-1ÈSü¶SøÜ Ž"Т‰OáqB·7ØzŽòÁ{bÃ>K$4Œodaæå½Q};TÙåû³(=V‡ü¡•ñyÕ¤kKF² |ª)yΚ¨IžÅ~—[‹©(z¥î –A2ÿ:ÔVܶ ¡7:.ÚÙ[N,ZF±´`K §ì9 … ¼r|†Î?¸×ÖKÀQΣ¢Ÿvƒ21BÕðxÀø·Ieoú‡¯*KÜ'ÌI¡ú/ îEi¸Ñòä×C6‹÷<Ÿcò;Xü\j–ÜFlS»`1Q¯¢¢öãø<,=in>ë´#îÚù&Œh•Þ®˜‚q yfCê-ëµÞ”ñ¯bE¿Â]S¾Ë)F U,°0´)hÍÎõ̳““+¢–§nX©…ÓÓœ‘Æ‚çÞî."å›fd”C*n¯@@Ù+ ï¿÷ýŒÏ¸Âž‰ó;“ã „£ªfX½©ÚmgO¯ÜFÖlùiFrýb¾Uu… ýr ½A"«<ëIÍSTýC\ë`õcI‹K¤¡‹ÐD¥¦W„Sq`Öý®Þ}ÝèrÈæ çr–p«`ÙXéîG*!M6~íÓJØ‘è?Ñí:Ý5Cz·È›@ýÂðÚίûÝZtƒr£A±e[ˆ+÷¢q G ÿtŸ¨|M 4|5¼)`.G¶ «нÿ7œ'äkïD½Þþ§VÙôyÈT‚3²0aÔ¦ÐuÖ+YKÆ &?ó}å'¹Jä‘#ª"á4|ÎÖë1²“}ƒL!Ù<¥qõí)Ó»¡QÒ² ò&WŽ,+mž³gÜçéÞ$±ƒrÿˆÄ‘J‡u«ýµâŽ–"Ó¹…„C•fG§ÄDªÖ6œ‡º¯&ûÈij®ä¼F‰ý2y€.h°Ò"¤ªtD14﹦léSó–¾”õ}‰bé’ÿ‚€“úÑ<*ž=äcc¾ÄŠ0÷óÙ\–Á5ù”¢ê¬5vªÔ9ò¢²4Á€€m0š0rñI…‡®‚o¦5‚ó㑽ý|¬#ŠYí„û…e»2£ƒŽ­8KníVAäØÇî¨C…),¿4 yÙ.؉ÈTHŸ¸ˆÓ%Ï1°ƒ* ã¿Ù¾‘ÇŒ²‹ î7nª@À% aó\ ¼ò½å½lËŸ¦‰É7úRƒ8Ò‡ —r©…³ö†ŠF‘ÁS^7xùýz߆¿ž'‰mž"»y¦3¢)ÊŠ½³ªN­]o-ßUÇ­c¦bö‰Ut íL˜Ð¤ovH­ùÔ­¿ez׎¨…÷Ž®åݤ£èâOEs««ÜŒÖƒw:ýx$ø|ÔfùÜ ›7sªük$R3OÇàñ|v´œ§d2°Gქ ÈùÇ×Oy£ÄN…wê®]*´Šõ±>@ï+\ 8Œ"âpe‘–ÈO+ŠY¹V0Á«ý]ï~R¸¹5¤ü`¹'Ç]w힘¥Y¾N(×pCƒÝWvx¦ÏKºå\tÙԈǢ¾E¤¥C5}ÇØ›S“pw\ìxÇzñ›–S %RU•¥(ž8Rô§-yrÝ—î,,>"2kä"Îs®RU5,ä2¬9U§I0îrV$ÛÀ©(æˆmYB8™héôt²…í ¨X]{×ûý¦nÖó•ñ7%zo)JºÔÄŽ:õR~‰Ä¢×ƒÈžB}¾9‡ßs¸édÊRnàl OÖºô!gz¾’Þ´khßJûlž»w%-ÿ"C’ŽT÷Ûa®ÇüŸd‡®$HΉúK¡É`Áh'añf•j‡ŠxDiº¼ƒo¾‡/l/#IÔÄ$OÍ0ýjái°†àQÚÈeo¿Á„”îö?“6e)bab/ .ûœÇ!F‘:Y3(ŽòxV`;Ä>ÅTöツ0wÉt®·í!xM^ —[`ÇœŽË¸V(îöã†pa³> âÉ ÿ:n’¶1¿Œ3>¾ñ'i$ÝÂK[_ß0Ôšû¿u.ìÆ0™Š®â8yR@×ëÈéxy ß>IîÖ¢+t£u†³»§áùbuÁy[ãE‹_ÏÚ6û! ßz<Áv¹4Ùw²6©è‹U—Õi@>Òíæ ! èÀcöˆZñ¡€ÀslÕãA#|ºt2úc²“Nß^Ô|"à‡•€sÝõQÛvcW¿ÒˆÆeïƒ;É/þZÙ F±Øì“€/ײ+3µUI>ö‘·äÒ '{ðeJQ˜`x¡ìâ"3í¤cÚ™Y9‡J†‰oè:™Å8È­zBñ=Àö=O±ãÍX5Ø‹ó›HJq;ÍÙ/3¥¸Ä ø¿îáIaCøŒÚU¬sƒå˜ÂèÀ|î9(s]½6º¹·aJŠ˜FÑÿ ,×ó±ÍÁvywd×CqÍÝgrˆqµ\-ŠKáÜ^\ò‘N¸Ä$ëþ:üuSX"‹Ôv11 åJjëÂu›þÜÔÞÛ«ëygõÊr¾˜“aWÆ ±*÷÷A$:܉ؽt?‹‰¦ïJ°Žô·jÆnOO;IVyª¢–€’…*åh`Î_‘D ¥z#mƒx 0e€Zì–«y‹@³¨ßˆBÆá„•Uwxð kÌá™®ËѵøñÂAL|<2Ș?Lºü›vÇÿTQÃZw9±–G¢M”Ãm±qÍ ÝàÄcgñ™öŸ0êé{ZÍ)'!œï2óö.§“è€&»%æ¾í ”´ôiÞm›wŒ%̪N°R]Ñ¡C §|fqíê$‡+agë")œ+X—Àë;™ü?8Œé`QÛ…¹¦®-ö¿Náqª·—߇²ðt¸f¿·dé+ í)úÌXpu³öa͉ÓeÑEŽiÛVEý|;%“N¸Tº£VØ+ƒìž]ž+ÐX[!€fÁ{®Vx5‡GwdÖŽœáiMÀÂÏçžñßkXÙU?ð2-S ¯2°x×ëã ÏÏôó\1úž¤´äIÈ!Ø“T¸…Y|Q•ù²š Ib„wû§ûᶆ¨nãc~TdY!wÂ27ˆ÷Ë:8º6ûùìãƒÿr¬`Wí§tJ$p ‹Ivœk8µnžKªBØ£ö,£üºÅ‹ëÓýÿ)ËÄOMŒ™Å¹Ë°Ö,ùL=ã îa!ö~Å™"EVß ¬-怨J`Ý‚úñwEnÅýj‰K”¶¤$îÅþð¡T(ÒNB9Œ–´ q` q£îxÈ/S÷3›' fØ›dƒîæÑ—«ûʼ`lz„Ò“ {H(¸@l µƒ%Kï CŠîP•Ò€ éß`Øa:ßPýR4 ß³|×Iˆ}åï­Îô:|a_HƒSq®K.اm©I}¨t–¨¥¸ÔPDu@ ª ¼W:÷x_¶œýÓz媘½‹ÇL¼'›œÖ}ˆu"b0™¼mZE#Ø¥îǽ'… ŠC!’vC‡œù,”pˆïø?¾ž!ÝÃyâ*>J7> …Ýîc2Ö—…W\ØOcøªÑä˜å‹ÕÊ™•Ò~ÐmcàQcÊÎÂT ×Q£k¥„ÎVK{<£{ļyl²Ó)§YL*F,¶² RÁ uo“…¨†0ôʹºåSR>ò›ì!ƒx#àˆ?ý]èIÚ$¨åZB‹D)].ˆ¢”ñb·ÒƒÞuSGPE2A« —±Ð•?\+Ý‘rB``"7f ô%ÄU+œ®¿þyóË‘¤Ä¸Òóh¤ìÊ‹B°0ó¶¹gãx¿„RnV2È2a1sØzª*Võ »§H²VùQÆÕøq”Ë–¿üh„—„HôŠ…PŸC)Jœ¡-A(0“ؾ—'¦Kˆ¡°HѤ€%õ¤ÑÈ­‡m»á¨í-£õ¬ÊiÁ—ºMºÒÞæFi‰‰‰˜`Í‚Ó)'5ÛÛ¢«Xý Ðbô‡íêupr:gçfïuÊeþüg&º±œ©6_þÅØ0k†Ö=‰–嬊`7Ám›<—Æí?ò.êï{›ä c ó„(jE+“ž‚Ò¤³êš{©(,Î×ï(Àú¬“ݰ2Qp‚Ö\„‹–GþËq‚qlXÄfzyЮ߰ü+?¥Ä(jPê"±rYÔ࣠*N¬È>$ñ©3mm$kg¨‹x>›…&—i ®ðýNàðoe>Áð]4W4¹ ÉÐòb,–¾ a•Iîð#·ò””X"Ù„ž$ʪ¶Ÿ:IÙÙÜš?52­D:CDæ¸Ê§ù´‰/ÖæÖTúé5§ ~v X°ÄN=–ˆöÊ\2ˆ%>’¡ú®Ÿ g› öŽ"øXÈ7̼³•*æÃØiÿ)Ö×´!GšB$KûÝhEröαì'×+rÆÛÐÅ(îa®+Ðf‰'sM)R[ÑEÆÆ•óåçC-{6ÀzJ“…/Ô³CëU†ßü¸Ž0¡ª°Á w–¤qv~Í6ˆA$<¬¢?•~íîWÅtuõX:`:|}q5ûliƒ ½‚{Æ·û5 »\( ›9Lá[:8è¹@ ŽGöjñ{AËÀÙ¨’hü‰9ÐiÊV˜ȾöÖ2³¬Êvl(í1mÛQ˱ætuõ%JlÉ: rTLaJ©ëÆ5Öf°dj¤Ë'²ÀÚüU:T\œ©W™(Œd_Ç~‚ ð–¬$öއ)EÎe17Èñ Åp› 2ö‚¾þ`Ùzî~ïq¤:†Ç%+ëj~8õ÷Ñ(΢J}ˆÌLâ[t eû*:ªòý"~êÊ ®•.“ÔT‰¹Ç<'Øå»‘ƒÂdÅ7¯RSLûÂ.Ö3Ób¥’ÍöTdwãXícnŸ©°ŒÿHäkå‘jãš=5yîöÞ·ãÏ÷#xàÐãtšÃro×YøC¦B(æ63ó°Ð â{Ôœ)¤øâ›Þþ±w&jAänÔå3Œë ÐA£˜2JÊ@N4ñ¸@wÝ,Ò âß7'2}0p.Òefa\h}ï`-­½vµ./g ݹI¦-Öt`íå+Èß É¥7‰¯p+vT)ð9O8•K|f[ùXòWÑ 1µH 0sh ^íêá%”×¢AÀ#‚ckmþ$tJ¬Dæ‡*k¸lñ¨¨È[’V¢)ºhs ÿ a=—±u 5›Õû²8Dp3!–LJö™ï?åý¢Ë‡€nú• \ ¢Üfæ+i²î³#/BI޹‰ˆSn~¯¯u.(kô¸¨@#×K„ÿX¢ÒüILÍ´ ÒCÓ*}HéÂІß%ë?x§HΚG|¨ °mN Ÿ!œµÜê€{;â‡q|O‰‘Y`ßV¨]2øpw#þþÈâ7[·â¸0b&ú"y‘”æ½.b5Z¨Úœ¢ªP»Yÿ{4Á1}r«g•¹€ç"ª2ÿFÞj÷  ÄÎ\™SJ†N2?ê oîEq¼q¼5ÒõžN›ªI¥YÐÑTBéÔ3#0–óñ.R¿èæ!Bú9=;tcµ2÷°jÐÔû&þ®ù¡>Hì"Ћ¤Ž?n¯y"Q–„QÅ?3õî3’7ì¼nézUBÄ_©œ•ç<ƒk“WÁ¿šs(õS /õ°Ó%ëù )¹ ±ÓžF ÙU¯\c"{ÄöfžmÁÌѬ ‹MàûK?ßWÔÀcßL.ÉÕ÷b¸¥ˆ»Ë‘n~"ù2S˜P¯ŽŒRÕÔhÏ]€«Æþéã_GüçW8“ÝÌO? "˜Wñ|O5¢;œºáyV Œ_µGAååÿ|ãr0'Y•i³ ÝÝJyOÔt^XçQ+¬ê™7#iš²¾ËÂ$ÖB DÄÉ­‡uÍ&ïs×Ç…‘µ¥)»*µÐcâ«ã5¬O°öj®óØUL×\M y}ö%;= õÃ’ž*B4™X=zûcé: šP©ì{µ‹‚­Î2$A|wiÏ)0JÅ”zç¼Rl¢lLóòLö€.L噘-Õ_T Ó™øÿs¿ˆí¼‰NRР𧱫h$KYAlŠà8L³L‰6ØŠ`KfÔ›vêl¤Í-o¿ˆL¡7”E{¤¼^\)dV_]OJÑ„~³B}øk¨Ùµ"¹£ù¶0 ÎN%¼Ž 꽃¯æ rŽ(7÷Ù™Ë5Á¹9†‰qIú÷E[°“™'¿¶âÈâ¹{I•ô÷BS5,t{}ié«OT=®IÚúnëÿPùÝ"ve®BJ‚#½å-Œì¢ ‰F"îÜE»KA”-‡ Üð퉥/› _)ϸ ›:­m…Û«‚»¯Û=Ê™—Pа@àX/—i –8­%Æöß Ð:K§‘ÐTMf€¨Þ$RiÀÉ7²Øº5ì¦y\j¾I4~Én˜Êe\ÉýV+Ó¢·¸{2«ð~5ºs§JÔE”×ĺï¦áÖ¶ ž;דþ€ ÿH†q†ÀmD:oÂTœa›S1«zvqþ ðk±êÔúã"/v6£ROõy÷ÇCØé]ÑSâ Dw1‚^#kˆì(Þ.­/üNZ#857 Œ©,EîW7A™|v=¢Ø³©(/¥Ø.³ YÏïçBZ|I>‡Kª´šÆrÆ6EÑnA ¬NñaB ³Ô>?Í…|‚vRjÐà’LÔ¬ƒQÊëòœ×dÖ‹L¢×l;Ab¡ß)6­fIžêZºó@±Ôö“Õ%å«/\4¹)L‹Z®÷¤ÿC“\*öSkdñ›©*a¹±ó§hçV !è@œ£åô i“W8¢5©‹ÅÅX”Úy|Ðóbg{¼—¾Þ[Rz½ ¯(¡ÞZAû}ähg+UÇà{$ZR¦¥ÿ1£ÍwS%-Ú¢22¤å°·³×1Òÿ*ùõøõª ¬”AÊÖžz\ƶŷçË9VÑ^Fn7ç°ˆ ™·ó£]õs æ,]S¡Ÿ¤dúGÐsåK&ñ‚6lµ@kèÁ¸LÅA4̰'–ب}– %íõ3=b»-©óÏ´è8½4rqæªßtpÌmøã6>r¶Ž|lRä²Àö¹þ°v®¡œœ ô7`XŒÎÕ$Ò¤pÙ#íÖ²#¤›tyQþFn%g©†§>Úé;c¶Æ[›Ú.É"ÉŠÏËI#Ä&%Sv1ºp,µ^GOuÐ’i~i©åŸ{®ÅþoG¢ˆä5œA½ºä¬dxDÏGAz«®L|¸sXâêv`Ô Æ¸’bjæãP¡ÿCðCI+Ô)™ÃþÑÔ6v&xyÍ~²7Q·œ`À¨U¨‘0Mlȇ8±¿—Ú9&Ø À`ÂLY̆6C¥…1jc,Ö&øÑÆTÖò Èp󵿣~#BnP¹À«óÜáÍøE ZG£*–×^ò “ɤÿI7sGùTÔj ¾`ÿjêoÿ\#®à¯uMòYj™?¸¹Â'ð>ULàéWƒÏÓŽ¢Ob8· Èõ ªúÿŠ ¼ÈAþ„AYì•èhcvˆÝ÷¬¤"$XœÉÂÔôðRéR‡!Z䨲‡uöMÛðoHÕ: ¥¯¸Æ¤ß-v®’üE;Ó¿–W„â?o=“®ˆ™0 '©Óú§Ù½ì×ü©C™‘t ÿ`*2µ€ÍÎmO³¸ežQóvôvxh¼ªpbÀ놓~mnæä\g7ËU=ŒÏ¤TBšäb¡±LÔ÷‹`q·oK^Àû}Åé ócEmïÂWìè(D ]±‹<îP¹#è¼-ãö€‘N•¡@\õéÇ'ˆ‘áø# M~†‡!ú_‘Rcä0µsüT}Ò! =Áœzí]e:iâæÈI‚?Œ§ïO)v²åa…¡m4wìEYr®ºx0²¬5Ó’µG«ÝØÑ ³µM¢!‹Ÿ*‡ÿ>rh°È¢i’Á÷ –óö šÑ²EËŸL°µ.)ÕíÌø«°£ŒMc“ÍÀ<\Ž‹{Ä5SO}ö(â¦Úä+€Ü%JYÅáx}V“¿"# Xjƒ ¾ÉŸÎ(ÝB¶Œ‘@|”Ù†O{òŠÿÛMãË$–˜|¢†éŒü”IF{Us¶ºî,Þø¾5:},kˆåF6ÞΚ¡*_íQøôW'ãh=/¼N‡=ç~žÜø3œ¥Ñ5öêžwGGªì¤šJ€÷¾e.ƒÈÖ8ñ©H#Òmâ—,ÃbÆö’™êõÔ|Kå[8×:Ôbµè÷" #úJàØ~êäüa‹E¿Q9q‘9úÀ.VX l¸0¹ÿãö†`,݇ag r$·[½N_2ÓKÌ–:ÄÒ2ä“1Þ´zçpïÿ#á{¿yU^7–êCöt¤ù(I´d5ð & ï|aððl÷Ñ/eªúüHHüþýÓ@v ´záèðA¡ ;Õ²D³sÕ‡Œ„«t¬“ï)kÐÛ#êÅ1ØmÕªŒ¬æCµcÒýÌ> 'ÜÁ‚¨§^&ÕDt_>µÂgŸŸ8¼ÿ‚$%#Õ}Âu•ôÁ´Ý’‹R‡³oø½Ø¨ì|BS“Y¦þ™Ì´SÉØ¨Y³£ÓuÖªïç)^€ÂÝL—úÓFâøTºA¨÷‚­†ƒ~ˆ2ì¦L!.›zÛÁò†¡4žÑü°1Íå#Ž0éc% U»C†–õ»Úçðfa©ÇQ€áǧg÷©O[È3ññØ6] pSï}ûŒÓG1ܳ2òÖä|ßÂ韥Uè)…Øña˜èhtùùò«hä(£ç5pÿp_áµ}LðÏñ‘±‰`%q¾%NEVÙ½rㄯ‹"€þK[AuiáBŠÒ ‚r–U…Yl¿w6[­Aò&šØQøÅx*ÓÀG#쉦£°¾ÎÑ ýXxdJÌÛ;P©%@(}C¿ÿëü¨Gdz'o9ÂE…Ñ—ügµÁ{mPª#нcgˆ‚5á²Ì!rƒñµ j{Ý]_o[S±ô|2‘æÆÌe‰˜Òù]9™fŽø×àŒŠþ^Í÷H¦ˆ<~ÔÓæé\Zü¿ª‘E4¬AëÀ25GÇf¿RÓ•"&kš}ÂDbì Å$»þrïß)WㆰD¸_ÔÝéª8°Ÿ»”!D¨V\¨¸Î–g@ª©.c¶àF“nT;œ€[Qc‡V?‚¨û–õåÎ2yÙ©–‘²T‚ºoÎi?¯KN%qö²*ÅÅR}… (¹Þ"µñ”Á‘‡¼“`g/ÁòÉyc{ÎcŒÁ}­Oy‰Ñ]ž[l8Åä›<›å#+ê¹ÑB:ÖUyë7ZûÓƒ‚˜20ã’l ÷ïµ£"«ÇCœËQ¤´…mcî 'ü6%gûŽˆ$ÌÞ_%¨P¡¹Êsºä2*é4hSSÿ)ÚJOd½Cïj©ÖÜmÍX÷Áe’,x’a÷†ûïgHÊ Ó»×dÃÇšî®ü|hä¸{·'"Pé(ryŒûÇì¬Z¹ï¸J·±‹oŠÑ8Üjÿ×@ûY Uã /;]ËDòâýCðŸþAc/´íôÏöÄeEXq˜ât&»4„n"u !x~ÆKòó·Œ‹Ó .¡Ý@üÎÑ •‘Ðü §8†Èå}Wzûݱ«ú´ ôß!E_yñcÄòòË7ÀP†«+åÝžK5i˜ï¶×Ó¤ÿ;cWõ{D‚´ÞaÚ»{ <¹T³w°ùCŒRÏÁUs<6’Y£*Jp„,  QŒ&÷ð’¸Å…Û(ë² ºè/qˆ~!ßó3é$ã2ø‡B¯ˆ—g1½tÞTæDUí;ÿ‚¦ÝQÿgQ)J¢ÊúlúÃä.]HNÅsá-Ú–ª¤:@¹H5 ¶ r” w†ŠÄ¨|á²^:=J…r j{¤ÛÈÔõc=iõvftkÚý83©‘”娹6kŸWd/ |ÚzÂhX¬v+O«¿ô„f_ù.?͇è}ÇÍÙZ/º5±:¼€qÄv.VÑ» !ÊúÐfÖ7¾hMUxbÑtŸ¢pø·XIÉÌ¡‰åT‡Z½L"\ÿzQ†çt6`Ï^”œö šcKýQ¶èQ}„”WòÙ¡a¢Qè?™€ç€\pNOŸ0 Ð4m»3\Ÿ?X•P=ѶêD:AïZƒ?ãQ½&H$5î,DUõ¼G¨—ãþüðØñý¾n^ñäƒ{ë–ïÆTÇĨ¨ :ÊóGòÅ[¿Eˆøô*«V®UuyZs'ÊI›y`XA øŠí·®'Å®ænì’÷(’Ó4 ûÂó'´:’ÿ ÿÿ/§µ˜8Ô¨ô‰ÏðËÕ¬¯X°½âBà!¦H‹§ÔÞÈÿ²§ÿ~ËH¡Ih´çPdza=‹Ô]%A Q†7;ɲßɯRûðø£ÔÍJ$GrF?$'õlÜDiÿiÿfü6ÀõTÕþ«æ&¬Õj6žk@0¬ák¤‘ØDÈc#  Moçp{›o‡ÅËEAwÛA5r÷Á26CÒJ¡c÷ ¸¾~«ù]nŒ>Mb-™¦:á¬ó ¤‚–^h>l¸ ·Ë|İñðe¼Ëw @MxÈÎO¯ì‹$äOÑÒîΪdÿeXÀ)Ýw»pKÌ[•‡=Ññi9„š­âo'· }ËyÙÙŸÓַСUr1vvhð7&œ¹p6ÀÓžG;”hꎩL èüsæUZ}n×1¡fŒœÙ;!òž„å-= x?Þ¦/÷ÃÚà*&m<duL“Õn/\ˆ~ˆÀÄÖVå–n®~×by‹Œ­À ™Q¨m’;¶è¤Ü«9.îÂ7Oyå<ÈLHá¥*´mMn–h7?°ËúÁÚ¬ÙÅ6̱£zl/L1ülðfX*sÙlî™Ð)äb²œT<Ó¡&a¥#uB—IQ‡•ÂjÞ3¤ý|ìëËBMð4ÅfÓñWO/i„&×ñß Ue,%¶xÿ+etÂó¢.ïžÌ0XÝÁižÁ+Þ†8‹lH+d4¬ÏÁI¨íàÌò¼-„ÃíÕÒ„hZÿu%#h1îYƒׯÊo×à(K”Ù`×+9.ˆûŽŽÅmhlÿ\a^§óŠ_ûë¥ßjî+ù¬²‘Å· ŸYóÛ§¦ùżJ[D‹ñ†¾4v nãíË<€ë|˜j¾¤äY2Qóíéµ2û‹Ï¨9­JÆh±É}JÌ_Ôš¿´•G}òpM‚ŽRô¿¬ü¹™Â/[;ÅQ‹ë”F ʉ:09'aEwëÙåÛñ*æÖ;þ1iLQ8r× ‘EY¨»Ÿ¿ŒRµI¢IВФâÊXå0»Þ6|öÌvmM6rÅ¥×Ñ÷î/tP¯×±¦áƒžñRÿ^sõÝ{dŸq+"(&ÎF¹‡X;u-D¿ª9/U":Aûˇ.Ìã7Ã妩ñ¡úµq_ÞÞ¯ªâÑň ÞܪŸ…0ÁJ }Áqž2Ô­ž:}ZÁ$YÃàWΛïÂg¬üÿTà›;ÄÆY“vÒhë£0â½÷Ľ̛nè¤r)(9šËØÁi֣݌Õ×7†S¢‚{±LtQXÑÊX,–7Þf‹oiõ£`;œíJwßägé§"ë9áïô]¦’äæþrÑ&¼>RímžÄmŒ±Ë•jCóÁo#â4h5œ:Ái8´™ƒª×êXA¶Ñ®Wl¦œ·¥#l twt[CMû+6pã¾ïùÿ ⽨‰ê’‹;‚ÛPÊг•˜3Á,ô‘ Êq5°5 œîn%Nðs¸zéÃ>†Rˆ*~…åÕ{¯Ãô3Çf£ ‹¯Í·”%ïn§ºßÀÿãÌ*°q)–Ÿz™5‰ç¢v›˜$H*U¹F¹Ôy± SR§«(~“[q»…Yk»½r-ÛvIÙ93m~ ‘-øpßéüÅrl:ÐI¿°ª½èÄnà.ô÷÷€&Gß%ûL”Aó)m? ûí~ïËóØb"”:[ÚZïgÆdhàvF÷¾¥Ó)#%ØØÛ™ =;ð Åg(G-TYlI¾‰÷XÏém¢“î“¢à=1—"‚í§D˜Þî80Vl :?í^VÃÔÀ‰¶;`3[{ËéÎŒRü}ÚdøxøÀ°Îõ ™>ðg–ûÔïÅE™Ñª©‘É0µsrâÁÀ ZÛst’ª f)ò.gŽrÁ.Dô%ž­ÞA> _µ4ìõ5ªƒxø‚žÞNÜõ+tú¥ÔOQAè›QG= îŽÌ.û&È–[’øGÎv ’º®L‡”>1ÉcXËR9}C´¥¦‘ñ/ÿ.4¦ œÉ­Vj<Ãöu—¾ÅâÂqVš½ Ïe<ŽŸ²é%8Õ_¦<¡×nË]–Íqº_‰Æ®g(æãÈq‹•š›TÜÙNÏõ›pc&¦*Áª–Sq Aˆ}ÛòêÁÅ0§X ;AÓÿ!·ÜZ¶ gJ²Þ5*ºÄ!ÐF³«Ï´ªÁ¯Ð¤ ?c„ýϱæåÍãlɹŸQ‹Ê9ßXÙ› ±³®€R}fh°›‘-^ˆûW*-¤t‡Ã$ˆ=¿a¹¤í“¨[i;†8t°S{6¦ôqá­Âñj²WE³dÒ™]ÙÆ¾›>YÊ4½DÑÜꢆx@uÐx>ù/N߯€gäW°_^+ªøÿyF£–e²a‡€s !ëÓ·©*[ó 7ö-åØ"›ÿò¦—£WšñÅð8ô½ í:?ŽªÃH»9S‰þ#Ó{y|pJÖ†åÀ 2! ~u±ó'Ù÷PèCy[—+EÑj]¸l/%*Ôñé0œ˜½d¹Å¡;á:ím_‡ %rwéWlCæã5»'çZ -/¿óô—̬y0Ï*L^±Tüª ê7cúžñ÷E ùƒ?²Wä ˜•Í´Ó¹0a:©°ëMSÿƒ”ؤ–ªNíCbG@¤É±W®¸‡ øê2»”Ið™K0ÑõÌÃp3 ÞéO.d0•RMGôÙ'oúåºõ™lßËOwÙ]…›Êx\dü.F¡™Ót8 ·4c¼}CB'Ò+a2°8“‡wdÚdÞÓ‚ë÷2R^çú‰FŒz¶/n~*¼_à(2NìaÇ"&Ì]§jxí\ÂV5—k‘wÎt+¤”Û–œ'4Óö$Î}^ñOQš¨#c?y°ÿzӔآʎ“«JþL°¼ág‘Àe7›¯,|‚…gE4~hÊ´7(ô½sÊlÉT}‹ UÆ—÷àËr·ï¯'fð4€6[æW²œ¤"âO°¦5ª„’7˜Î2¿*_ϲ¨\à!rèãŽv¹ ea'X˜gæ4¾÷»±W¨ª&X>ò­±EÿéACÝÜдS¸;ŒÈ< .^ô¹èž¢Û;~EÏM’÷ß¡µ×[°¡²¢ëûع/øÄƱ½4Fz^˜jª”z™S¯Pœ©zo#ò^›'m¾™@>#Wÿ4ÿ*‚áR5MQsšÙsIb¸Ôtsî{û¾-+ÂX¼B VÆåäT~7¤p"Fˈ 0ÿn÷˜¨37Om,‰ŠOxÙÕÈOwË‘äâëì©[qŒ©¡ÎÑV6ÐÝ‹RY!ÙÀ²ÕäŠÕ­9mòè<'KfTš»˜Ÿ:NÜáØQØ@œ+1ê|3*Xglz­Ø‘•3™ÈNάŀ÷Œd†– ’^$€ê/Pªè{‰¢[±[®„jÙcsï¤n·ôžÉÁ¹q†º›=ËŠ‘3sþ»TƦ8M`õtó³ÆCBJC°qÀ·u»ð´¬Ö.•÷»¼#¹I)Áq¹Ó`dò¡Àš P—g(ý¡R_Ð|ë# ÃLà')»õQ÷ì1Œ°N¶.|ÌL*ñ¬,mÑž«fxÒ^‡Z…ôàgcÀIjêS^ÂŽ¢ó7ÙG„|›Í=̯îýðK?]ª×ç¤%z{4m!ƒü‰GÚ.‹¢¥´níÊ(OqÀ ‘ýóü*—Ô×Åí¢Îa<—îa\.Òubåɯ>Îkö– ¦üªµÞBÚW‹hFïܬ†« –‹nÚM^‘¼0™,žö1ÁÛ³ü5xnšë‘±w.ÝN/~LDá€_wT!š¼éónº¬J±upUÀ—-½¨xÖAMuëðBÓ‡ñžKÞæ¦.dÝ•›#ÞØ)¡™lØÄdVŸH|/KgÑÅf´yÉQ¨¤²˜†ìº2äŽÇ^œ+\ “.‚TÖ´n µ_S+ÊIYxW„ Scå dßÇ=“ …º/*x‰Çß$´Í)9\B/ ̦ßÜ SOx.ð°×ë­‡ÔJ[x°ÕÝ0½¦™ˆgˆ÷¬Ðõ˜»u‡ñ·¿å£74J{P»Ë¸Ý÷‰CZ„ê™ÂëüÍiyÓßj†gÅë+ÓŸp\ξ')hð€»™9¼EgÓH¡=Rq-‡´È€eò7ù›+¿”?˜ŒRwqÌEŽâžæo@ ^ٌʖµÑ’ó¶ˆ ¶ž”ÿ Üäûª9öo­†—ÜhUª½¤Þ%IÃÙÔ HzÝ9xë©=Úyá© Ãù¬¦È—OW(R²©§˜ÈÅráÂnDúD|“u¼À;t*à)tЧžïéx¿-YæNrÑDê"œ¨“mˆ¸m|Oí!Íßì{˜s6$[–±HŒÑ:…5PÕNTÛ»¸'æ€áv¦Õ"'䪟@Ô[ؾt[§/úEÉ”o:’ôÊÚcœç¥sö¢„L<‚…?™SE£uµÌu¼A0NU!RÚÿéy°{8ÌÍ.˜Ñ ‰¶ ó4<沱ˡù¬@N6~kpóÉÀQý/(¤æøHháþÞé¡ÓnZmýY 6¸Ww,G+‚í¹°ªïó ÖæP…åÀ²*&Ü'åTòî›!k !¢Í•`n-„ì¸ã¦-Çžõ;„øàqO£íCËweG4Õzœó¨„4¶úºMÌ$«ÛÛU?Â@ÍÍ(Ð Bc߆ÃNTŸZ™³«c¶xÛê2¬• £OnH©ßÇ×Fû#é_ñÂ[ÿ _"¡uŒÑêšæuqàúIÚNQ'ØñhM°ô¸¿KÆäŸõÌ/š]1JQhˆ)!Bâ®™¢d„ kMÑ8c.D[wGUu'©Öù‰Xßß„çËe?•Ü!Ñb¨tâ¹zj©‡Œ s_ú «(òÛñÿy ¨ó”ÅW?1½×ÿ#…DÍNŽæâgi5gDšG4Oú/u”ÉùR-e{Ë—ñEÛö¿Ø‰ŸOdÊD‘ýRØfzåIó±2Á±ûMLò»}9|nl²cº Êè.h¯Â&¦wRŽºY©Ëñ^bëרÓªA{·ì` o;“3° äþ±hÑü€­ñ…Òvîi¸žcÑ ùn7Ûó9ë Xeõ¦ÔW¯qÕ¼äœ>ÃÀÍ¥ÕóªTk }öErž6øRˆR 5ÐfbïÖ)Ü©;]´ãÏì5ñ´Ñm(X*„òþ‘@:gÉåû Ïr¶?v}ƒ¼é$¾#ùúXLM/fuϨ÷QVȾ“+å|s1¸bFá 6S°zs¹4ÅÌt=ùè€â ÑŬ®~:*û†Ž±RÎWØD—Øâ] ídUèô[ê,›x€ZJ>*&4fUO;O÷ÌoßVš«eCs,ëæ½Ê<œšsšI{,jjérY½U”ˆÄˆ‚¹ÒO‰ôè2.±œR%â=áÄk ÉdR—´\ Ü6â¯0`u~QqE‰r›LÅÆG7»T)#ä,ÛåêT÷ÏI*êóûÛh|ûyÁmdžÎaA» š6p OQ‚MŒ>Ÿ A4QÎÅáØ6BB(déh± 0ix` b޼3‚{´CPŠnâ`£Â>í¯¬‡FbÆ[±Ê¬ŒööYÎÆÃO~¨Þþ¬§M*†ür Ý÷Ì(¡ŠL*[CXyS“=îAµ–‰â‹­ó7{ƒmóû Ž—¤b)ÅezGî<à°Ãt´t{“c.èËc©|Ÿ~ãË%Èéš×'×N‹²#âIÇIeÒï1©ã¶TŒ$•¾r×pf2Á.Öú3Ö<ÿ$¬ý㬊NþZqÁ|ú‘ôGaËãó¿B Ý•-"ïn÷, ¯h 7še|ïs•–Ô mÀä¿Ïx {NSõdê§€‹ž ÿn¢ZWþšÉ˜…Æ?PwÖÁBŸ»{… ›4hö ÿSÂC6Ïæ¤éè ÷3Šwc%R§cVˆ5J|wÂ’B`ZöÊÖ*×fs_À°<ÉfØ 2_]J–.ëže‘~üxI!2¯eU¦›Ö6c§ž i­²üÑ#\E0±Øì$1ÇBC0â( (þ!å[Öð0/6Q‚‡™ÄíO$¨ýêL'ðLcÚEíàç¾Å&#²Iÿ3ê½ó#3IÂúÁè!¯u<Œ){’hѾÕ,ÇQBUžØk>ðnžë´ÞEÕßìm–»CÄ•;8„s¦§€…mH/ „*^e†€íw ù0Þ´†M€-Y!_³­˜èïµúÛ@X¿ÿlÑæMìþiÙ)’>Úº¿q3f¶ö"¦Œ"öª†Á¢ÁÁ¢«Ah2Û ˆC¤-°“¢ûaùå_W!]TéTµÚ+›9ì1ØübXÊFêÆ2aÙåhÜ#ΓWæ)·Aüt@†tþˆcÐóYL¶Aàr‹¥$H²©WUgƒ“Aù1QÚwH?Q¨qK „æm‹<£È¯ŽêéCh{(þÚ8ɹËñéËò£(ª)Üt÷t6ÕÝ`ýÔª¨…ÇÝ“ó÷2|YEóÈ®6üT¹p‹áÌÖô³³úʵ+·"ÛR( tWÏÊúëR³F+úΨ±š: ¾ÿzlæ+ž¬¿iqƤ—ö&W”h¦'û&.×—i±\€0“Â^Á…²—[zÉ;ñ[èh*,oöŽ çÑeµtvßý5¡‡Ô]w=§`8Ю¬ùÕñ4 it(Û¯•¶ªëœ@ÁŠø±ñÚÏ™ÁÌp…©ƒÊMDÍ`M¡¤ÑÒ¦Ÿ‰€-á}®&Q€Ly šfGgU¡^Þ¹S¶äì„­¥hžždÿ/>Má‰t¶‹Th¾4€Ì9Û/¯ôp¨Ó+ÔóTWãiMÖ` šÑÍÔÚ³_Ã¬æµ ² ˤÝov¤å¦¹ K”Ù®¢˜cºð¥9ͶéZÞw-H¹>‚²gó?vá•gÁÄíÊZgYù“‚äÉQ?NãK±ŠéBÿ›®=2$Úõ¿“™w3ÖF°¿ÏiÏû§{¶µñênd YWÃìÑ/òJ0¹2Y5ñU}AB›…÷™ñDJ‘¨ .#®Í út·k’Ê>‚[þÀO"JEæPt³%BXº¡r þÃOÞÕÐBëv`J¶¡kWv0÷넉bw?êY!Ë…´—„®ç±Àmºž<—´ùœÝÔ8%]×nî Ÿ‚FâN \t#‡&Ó…·¶Þ_ÍÓY¹} µ®Ûâ”6&)w¦—°‡6›þÈâ ^븢G²—PŒgï3TµŽû“Ä,Ñ ï™N ¼¬ï“ª~åeúHýÅ[Ì™‚7T‹höY¾ò:XÇ7˜'Õ`ÏÔ-¸‰n¦ÝQ,Œ|!)m;‡Ë÷µÂ’[0Š4X¶?€| °]KûgœØÄŽÝ65ÐLâB¿¤¿ýgA¯‡÷.¼÷3­IÐSmvÂyHSü. 8c/¼v®äžû¨›¢ReJ°Ðc]¤¦s05Ó>&(½S¹‰Q¯ïG~7¥€}w_´ÂØÀÕ_šà.uD±­P² LWT¿„ù²WëˆW'3“c2¶ëƒi'¯!û§-.á·ô†!¢\–„56ãÕJ»à‡A«Y ÍÉÓ[åzv#|Öà™ÚÏR½Ùf>kXÑöÉ=’Ÿ…‡z7Êêd§ÿÖá*o͆¸ ]§}æMí¯ A.(¤_&wõÈ¡ †ÛñáúuÒÝÖuØå ³þ0Åhƒªˆ[NË·X-åc•t0¬ÉØÑÊ\Œ÷5= |µÝ™MghÒhøÛ«÷Ò×Xf6$>09p\DµA„; è‚£OuÝÕ4È7Z„ãš?Œ0ömä+Ó+„?ÚØ÷¿‹P ÄŠV1Æk.ZpPÄp¿MUýC9ut‹s¤½>ëOĉ Yõ ÛŸŽû0wÈNÐ;úæ=GhG¿Ë¹c…}±Ë%DRÓÁ,‚¨‚ %ÕÔêú¾äÓ¸¹Y6 þÆ`?6‹r‡ô@˜ˆP¦Š¥ ¤¾ñ‹0Þp—nµmŧï¥à"´ù¦xÄ9á%ÚbZSÈó¾Ê¥ “å !þ†Ž¹oÿtu>oʬ2uø,¯h »¯¢þQ ›çK(¹É˜¹0ßõ!Uk™ì|5£ßÁ{Ôœ™†„´Wó!ÇvL‘'.WWã¶‘ÃþÜøJC"Æ-úÉ“ÿcÔä}v/nÖ›è‰ûÒ¦|[´B g"?ôwÔÙŸŸHß%/Ëä¦~})ßSCö¹~×€ý¯µ¯ýµP¿¶«ý¯§í~ÿm~+ý¯?¶¨?mIþ×/ÚÙ'û_?k‚úœ'çÒwÉO—ÉPüúRú›Ý/íoÿ6­ý®=ý®ÿ[Uµ¹}Nµà?kµõ6ççÓ"ŸŸIß#Òùø¾G…Rù~}~}¯©«ö¹Iþ×;êo~ÖíöÕÁÛû\ÿ6ªý­î‡ûZÛIßRwßRoí¥?ÚÌý­µ¤?kOíhÿ6—öÒ×Ôx_QïßQù]õ~ÚHý´—ûYÿ5¶Oö¸~ÖWíkþÚjú’wÔ™ûioÚÐö  Sšôi·¥hlÎCãñâÇ‘±A‘bÑØÄí|Æ/7*ŽÛñ©žsÇYü:ru+,Õ…n · OfêsI¥Cq3ß6ïüm)GD*.À^¸Ž…c¤çÇgµÏ¹û! “( É~æŒ+¿=û ÛÞÁ:™« º:[kA¬ç}Ò¾ýŠ17À‘_›;× ”‰?†IÖÿ !mî ¼ßŠ"h$ŒQw§<_¼'Y°ï üÕßÿSÿ#ÃŒáB Q&ý>û'⬃bȧrâ¡Eeû¨Õkt(= ×þßó†%ÝáQ]¤ÅÞÅO.z×x}wÒóÑQë´ˆbDª°wr]A¼³•œTø<À\f_8Ib:êˆ&7fïvLk»d/KöÎiïåa¯â½I1²(e¥î‚™Õ[ÐH?× b«ÐsL xRâ,Î/Bé°|ô.–x»›:ý °ï® qΚª~ˆ!­zâ3Í•ftÓ‰–¿!?Ó‰Y¹8LùÔ [òé„hyÓøäÌ,Ý,ký>4²²‚3Ï.xõƒ¨Ðf–d%TñÊŽK‹Z¨)  @É CÏG8ÊÕI÷dŒŠÂa7•‚–†oì;Ö‹F¥gÎÍâ×IM¿ôpt•4_ííVËL=¸åz¤˜”?Æñ—L’Ð<® Þ˜òªA6„A™û4¦!X„„±C[¸G™¯õÿ‚‰ûÚ,®ö#åƒ:u60ÓÒk:ÃýÛ`¬ÇßDëFÜÂ."Ÿx™ð an°–ëmóg'aÖ* ðùBz³A-¼E"ꯂ/Éœm£ 5Ülw?f¥N $¯oòG À×YWe$?-¹˜äåN»}åÆLR4F…ôWaÌzÒhÉ=“E­ýeAºE²2¬ %˜uÂò <¬ÉÃÈÈØ ÈÐqb¯ØÉý ü«¸¬ÐÅÖ^–Âÿ,ø€,Ô ^2>9>‹ò6n¸a‰?ì ýy×™L´.¡28ç.ÁkñÃoØâ½–ÍOlÑœõã Ѥðɸ¡5î™jrúû™ã>;K~ …Â>ð:=Cç ´›i¹§õ`ÚL[°É?“;“GËiÔ™üþ1pdIÔTL#6tð{%4wN.iðGQ?ï©Q@=?Ö'!ÅÖ%YON"qKÖûW$~K¼îÈn£5Uhœm†-uÀ‘ÃU; ^!DQ÷&Q‚VèÄG“)bª¸×ÑÛó¯Âö gc?ˆ€ èGm’mµ6¢ÉM0Ëñ€:‰‰‘¯NRƒ¶—†¿üÈWñ5yk@Ñû?Pó‰ÿI­4§€—nŽ\šÔãl±0é(®$Ÿ·uìüèËÌJ L˜ðÑôcñ,øWýùQÙÏoÞ4´ÀçžšX¦½‰9—LuX—c‘¾2Cz‡G¤¡zÌ‚Û%D䜋Ääfϓɷ¸‹Ð€èæc=¯%2†:EZHsº–ÕÓThúÞÆ„Uºé¿DŒ±·@0æ}éþN@ÖŠäQ’E)yPŸº±,x|·ãØÿ§ùyg* ïw>V˜z##ÿ€‚صŠŒîAž2Ù »ImÒW”aâ†g»?ÊBn†_H‡XŒÿ¹‰i³Fàc|¦L˜ÿ]ÏÔQ©Ï®~ž¬ÄM€LðÉ8ä‹ÔGEkXªM“· â.ÓèÇàå›.¤³@­j¨Õìz/C/|ª—ÓŒVÆ+Œ ífO†à§/ 'Ÿöwç@ÈÍCÎf½Mð¤tq…AöžHG¡šý¯¶á(¤,UšÛítи3³ß5!7ÇxÏý½‹É8m5ùð𠉧”«Y¸>9^~³† ^ÇH”}¾à‘&98UžB§÷"¼ÆÃŠÁ/P ÿßNC) ªÝŠ!‡ÿk³€¼|à’ò;9›âTå(ÝãŒûÈ7òõ ßäïÖŒÃl®_ޢܫ%ŒXeÁGÀ_ºÄl6ÙàÛÃÉÝðâUWÔÎA(<&T/f¯ÃÄ á 7ßXlu îGÒc.ÉMQ¦dÝ!…m|¤žá„ej¿žŒ’öIÕIZ›¶;›E®ß†ó®cýH,áÈ£òж&DSÊô4ˆÇÛPh1ðH9¸=G›’®¹7ß_"Ѻ»µ…"kú¥/+CŽäŸì$Ûÿ2ÂÝ%9ÐL8 V¨æv- mõpR¨Wh·”z– 9ìÁÌ‘§û °i&²ùÌ}øòÖÜYCw”YØ_Å¥Pú‡W95û•FÎT]îkUg2žA@6°{Í:]æ¡ã@©Ö]#’¤ÜЀð†CGÀeÞåõ¯-:CÐàQz¤*'Ò €«uÊ´„÷7pEÀÎ¥~eükhÐMZ¸Ýçìáî„D¹¤§ó‚E­¹l3Œ; 91¦üb§­êº&tfA‡d‘!‡}@9‘Ïw3ŽŠh²_[ŽAò¨–7ŸÞÏ =ÖÁȽ,âpºNLµ"ƒ¿¨Ij†¨v b+÷Põʺz[¶ÊâfbTï÷”Ê7»ƒ¶àÆû´@ü¼™¦Œô?O¡ÊW–xÑT˜3¡=¥_ý¤Be0C"½Dú_#ÒGÃî³»¢¾vu6áJÙ¸°Ð¤u¹ž:ˆ'Ør:z©ïîg E+Gu„ËíïS£IKˆ·øÕÙaNèFÇÔ‰±RõJx¼ü 9‰TdwÓóïçËEs 6•‡«\Þ!]Ï®M±¬fX™ÌL£G>ó< go‹çRªúAœ´Òí¡ëo¦ ç´*Óé’¼QÓ[Ô•åãzpßÿ_.E;4ýtI¹T_R3¿ïµ5·Æ´‡e™oáÂmª–€NWÙ„™5Tùgi[t¢w«.E" G6µ»ÐU~ýDöï¬ôßÅð—}hÀäì\Éa(*Y-߈AëM®5—­$ìT:"ñŸûð¾5ÝFÖïfK6|¿+]í÷dÁw¤¾‰°i æt3•¬YH¨“ÁÆÅk[XTz+›¤Š²ô}HòJi>z<4Uu»]B®¢ 3Ó¶¥=k]oüd®áViüþÉ ùŸ(,‘!Xi_ðƒ+4išq÷5±t4v·>*0ÚÆžuÌ¥²ÐEâ›rد:<^$ƒYŒ!"û5ñ4NÒ/]w]?VŠ|?S­æ\QKštXˆ€Œ‘j¹94ù®…1G¼ohµÕ÷À|½{îä•Jæ˜æâãú§ ÷ÀÂrâ*ñ}Æ^,YÏ>ü[Þk[×ﯸ±ÁŸðÿXIw%éä òJZ/é1ö¿ªL¿nM§òQˆÂ©™ÄéŸê…˜Srû/ʉQÍ HºÊ^Ïü0¶¦/^ÚB7GÅ­§ä–£óµì÷D±KÔ“äÃvò]´ù Ö ¹óß»;‚èïLW²ø2?0 îÁÂøoŠ ·&7c¦;2±-¿räa °–l®ËÂÒ…lÈøÐž"°jìÉÌ[D&1+g {‹4;]!@ý‚½ü|h™I_Çï¡ìLÔj¬nõI1,§†X¯Æ©ÙÛÖ»¼SÜ_ŠtU—ÿ·Ü"6Ë®çÒù;òMf*ßÛ½¼ B»ªâ‚?‰*_ï.9ÌH€Q _ûªXsü'š> y! ЫcB¥³>J«·7l%ÓnFì[õv C·àP‚ú½Õו÷!ÛŠyÉ|FŽ%ŸZò ±›Áµ¯½Œ­Ø'³1Dû 8‹SOÐçmÜ|¼ ßëí àÆˆ%'wx÷ô*]NU˜rO*ìw6—$%UuYá1ÿjØÉÿHˤQµóÂ-,äú|Ç~dÍmx!òS¤(¨8äóY,XEV=÷È#¸ê¢ý“û/dªi%k‚Ü{¬~-6ûﳪ;¯ÍÇîÂÞúªÑøê&ÖwLšBÁ}-P ô8–ˆ]ÇVò0‹¥ï (tJKvèJTüï(D­ñ¥Å¯í/ -—ŽMºÿT§‡L}šäÃCF4nuÍxþ|Q#™i“iÌúéÈVã (ÒÆ$îú¬fcõÀÀ¹#›:ÅS|}î¾Õ¦±;vÝv¶–»QràGîU„ö0ÞõLg®~_â裮–èª%KxÁŒ7ó¼qJvj€ÈË…hŸ–éÞMª‘a í»r$]– ‚f.÷›¾jH&þªb Ë_랸NµG ˜_`½—T[û³;ŒÓŸ¼e¸e÷ÛEgWs1‹ýë·J,g!Ùˆ@ã)Ø/ÃcùŸµÚí)<ÊÄß6æÚ˜ôËë^ ÊQOÝÇB˜H\ ÉÑ÷n ÷³ÎÉë9¶Ý•Ò‹âÜT@áÎçP1öùóN¡—Õ2‰Qu;$ŸŸä iÃÎFÝÙ’æ&Øš{÷Îiõ #ƒ¶@ØþxÁS"W³Z!µL†©w««%#šK@œ5úb9ÜjLÜËÑ>F‰H)spš €"÷Š9tV>§Œ$fðmÙÈMNgÀPpsFKn  ÆF\Q]ŒŒu´5÷)œÇùJò¦[ó¶Í°UZ±Èñ3»¿©wáx_Ý£.0óžT:?rï¢Ð!$¸03NŸ™ÎÜaŠßU´;É*O3ÊêeÍf+‡U’Z„&2î»æ5È2E¶D¦ÚBBT$A²÷£êÛV› ƒ7×Î"øqø¤þ ìL•µ)Ÿ»fyïÓÕáËÉ[ñÇ–G+Rñ=º²—wX\áŠkò @å±üªIoð …ŽPUYOÀÅ8ŸPh–³!–‚ç'ï*eû]ŽXñ ã@ªƒÄ §ºö6glš©³<_«òt6+ãù:ÕÁ)«97©­ë¼P ˜);Ûð±-D)pB‘CÇMïyè±Ìì¼c‰‹jtû|<¼ËxbäÝu1FâSf•eV'ÅØ–Ì!’Ò™:+T LÃMü*\Ì ìÄ¡enã¡`”½·âýÈȧ@¼ÚLðˆ2þ;Õ·ròrUTdahZÕYtßÙñ=_oRäOìÕ8v‰NOþü2W7-ZŒ;g371þ³·Hn tÓž¹iå'/‹4m jõ0Láÿ#]õQPh…Ó”3ù;\#c燞,’x˜¶¨¥ß‰I9kîÑ¢¸o3 G™Üs~åG=bËF]ùt«ÿ)Ñö•êî²jÁ«-_µa•–2³C'l"…Ârâ”ÒÕ¦´üd W€ø‡ílÔ—ár¾<»KªªT²}3©ÊíÒ½êxÍÀƒ göázç¤<£‚¯DñiBÈ\Vp´]éHæÇÌÏ!ð.ªZ½â;ıґFÿ8týe1UŒæÞ)nd3 ¯øpÚôˆÂêXÁ‘XRãb&©¼Ü(zœç¹¢¨:F½+d„Æ.”ªoëé9Ìr‡$¼Û"v©h©lY]Ú’1î˱¢[6†K Nf<ï%Žý¤®Wຠí¾äUÀêä!šþ'êtQ‡øwÃ]ûTô‚9! =Å £Xë²&¿‘²µ4£ ðòï¤Fœåìz„ÙλÅL' ïQ†T­§HØc³wÛµdô±U«OÞM/¼õÉ}–Êz­{d¤nj •x©w>“oc®`€•Y†ÆÃT ¨©ˆ½È-/µôß:æÈ¥¸l1Ú·Äꤽ8øKÍßïmûtæ vó-ƒ°ÔrÛ¶{–­õF­Bl`Ý’4džÒEWßÛ©÷5µpæ¦QS®ÀB‰f™}õ¢&á¬à=Ü“ ±i¾$)í_¿„³¿i£8çû`ûc3.ѽH+b£ pj0Þ(P½îªö̙Ϭ hW¦÷?jClôû§~ì­øŠëÛÊ¿Bb<új _– RH@ÝLéIM—çlp—qoZåœùÆü=£ÁZÁû &IÄ—üBí§A%0Ÿ ‡ú-x- ÕÏ}k¥á£fÐãR9Ñ!aIJ›ÇëàÈ…*{°Ò‚Sš>”–G;¬¢Á49&±ØîÀ“/‰¡N‰ß¡v7âƒe³o•ôù¥,ß_ÛÑ×v†¯ªhšˆQ'õ» âÌÕà4nmõî+î׃~›Cä%òÜ÷jMۭˡř až!ÝJs@àø‘"d“é!+qòÞ{)dD#uçMOÝÓž=ÄOI |­ZI¤ ÖzÈ+À6–_Óv¨ÕØ" hÅC|׈k/æ´q|¨“ð$ ùl¾ÿi–[>æpT°¦JÖhâ`•º–D†oJÁØ)Ÿ´ô•ó±YO«¾~Ükì•Øúg­žN>@É­®<²Èœ¸x6µò§]Zdqàdzîe7B>wr­ßï»÷×óô„JÒ¥vø’»¬_G~"vã*äê´b— ïé.­À¹§ˆÌ¨Ò0èóÁîxÅòí:ƒ¤· fœó%ÿDÐÚáÍÌPˆCwµébg×'º¢¼×¡ ,¨{TÍ90ß%j#í©I+ ?í£K^S×:×úý¹!d@´“`7óu"ê§³¸6©ËÒ[=¦p°'õFªí–ÿU{xä£ÔFÊþÁ'ÆÝhW’é=*ú~TºùëDŸ ýË^¡:…&sww„ rês(8¸—a0¡áäƒO ñìË—8 M7~s[؈J ô+~È+~yh¨ÄÁ±ö¡‚Ø£C`«—Þ‰4¦¹‘I.k)»OÄ©Fc7˜¾=zb m˜/iàkCy8Ô/n±Šr¨=Þ/=›î£3âÜìÉÎ2ÑšqÆÛþ† wóâÂ3(÷-?Ú:ˆÀ§ñXÄL"fSÃÄK}æïİ2¡«ÔY¹/5ÁÑdž³ÅæÓÊ,î©;èŽÑ¢ë³±Zì«û¹n2„u³°ÙíJø=ù#º=?îIž]VOÕ„`3a:ýjÒÐgq 3 Úúc}5‰A ÖQ… Ï 3C;í @¹o)Ë ûÁQô×ûn>²†YøƒkÙÍšXü‰„|düýÓÒA÷ ;_¦Å¶bI´zÿJ¹8ЋߛÑðM˜ÏÙƒÒ:#×lM½œß4¸Ì=qqp[;p0¿Áì«©É¿‘/Â䈂m¾Ü%Í4óyé öè O×%$쀪Fx¸A¥P8„evK24Çü´”Dé„Å´ e°¨2¾ÀVÐŒÍ;LOV °Î2I¨+Òw‘xÝR¦%sF=Ÿÿ8ÆöÝé¾BŒ€PWÿhðƒÌáVÕ,¦uABBϪõIóläå`Uf!•.踅 5a‚ì•X¶¡ PÎã?›LqjsÌÏå$ƒuMÃôœô‚3û[7å”´AÑFësÇmè‹Vøã‚le¿dáäÐñ3qU…HýÚS™£Ù4¹g£p>LVo¾æñ–3$rÖ»Y¤[y½¨‘©`q%ú¨ùìÑI¤’òåÅW2ÑPš"ÅÔÛçä/ÞFX+xÉúG!-âoÍ•†„)߈¯.tÝÞ³“¨¢›’º×àÆ Š·ˆãBó§ÀY^Æ­Šf3FÃÂ}¡Ï5¯Ú€w&W©’OgV‰Îaìe0(ÄÒ3±[òÑè÷áç ¨;Œ/ Æ€°ôv,`éè.ØTÄM-ØNÍ,·ž ˜7ò©np„[0G¶:å Èp þ|Óé£H*Ùß"[0§K±Ä~ÆW7»ªþ;jW‚‹ç¹«ôSÿHÙz€\Ú8Z'wÞeJ|¯¤›1×oœÒïUpÿE#ÿ^YÐåÑÇòb£é¶“Ðx­uónÃC¬EO5W¶8ç”Óè)éÍ5 «F¨LVUÞÝâ 黩Ÿt;=(è„‹l¢ÑÚ²NG5–â¹´™4Ôû/Ý/1FJѶ·d‚8ÖWxb€ ºo >ñ¯J öÑPÃÑ·~d„°»ÇšÇÐ÷ÝžJµ?¬JL 2†Á¬„¨o0™¸ì‹è‚ç4zt?ìS„Ú¢³Ôiz»ÃY*Jò=òSçæÖ¹x'a^?ëß©Cõ)Ö&‹õ÷(ô I<D^~!‹Œåÿ÷.Ç}äÌ‹ž&qÓ‹ч‰È´J޾ӏ±ù—Œ–¤bsB°g f½Ëjz`½«éaU¼å#ÈdE—Q¨ºø‰Þ³×—[/i¾ç2y~ ‹±˜4ØúãU×8$q©ÊÅ´ »Ë =´ìh–]“ìß7Œ¿Úñ¦"j€Y+>U›þT/f‰ Hä6UÑçvH¦¸ÍzŠ%‚D£ádÃðèžÔ°+”x‘l=$ˆÙ§“XžU€wGåì"¿ç²T¥õ=”iÞŠc«¡b rò#ßá‘YÄž'ñòþD©s¢Ä•+}ÐRy×dÖôû`‹BÿSªÅ”¾‹³à«²;¬ßíÐùt¾˜òýM²92Rvö²Ïƒµµ•NK#{›-¸­wù’Ïüšg=~S(Ïö2K»lJèWÖ–ˆ!ÑR÷"éMVq ~Oã'úÌÓÒü d›«é‡¼nS·,"\C:ÛÝ/øÜÎâúš1—–ÀAQz%ù”¦¿+$U£è/Xêé{Rú¢dX,-áÂ]ŒFå[û{u?aø§”y³?Pv+)lëyÇTçivÚ—o« ÕŽ™k‘N‘ Ñ@øFCúï…q·VÜB¦S@Ãf¨Ê ]~ÅÝÊÒæ‘I¦hž§¾eâŠ&ÂŒF­{Ìuž…ÿ-ØC2¨Á|“‘j¯°ß6ññ8Ÿª‘‹³‹Ffeðö+°sAL’bðü¡šk7ÇC­û›ÇƒÐ¶c#ûÀ™eôÙzB<çbyQ}ù3ìk› ëôR‡üb<,[Ëíi#:¨ö¼’²;%`œŸæ%ˆ¯jE—+(§£½®³òPRý??XõŽ#øêµß¶ Ì.¨}´ˆÇ…B¿ÐÌ7p¼ÞwYÞd*+úçcCox¶×™c$ƒ/\i‡^­kЮ)’R\t=Õž|î¢m<giM!íwß}ô3m§‰á”Ç×Kßmç»!ñÎl±éõyNJAÚ)¨"AñMB!tï~d§ó¬UT¿ÕcoU˜àí®½¹”‚ïÞI{ú-"úÇѶ˜µÀ•5aHö*¢ðQ{»P]RŽFÕ·TÜ}Å#°[ÊÕ¶¡³Š0z#KTérÉœoV±ØDY'þ$-áÇÿ Z¹¶G^Áø g«n"7ÄÙÌUYq3}àɦ5Ìw .¬7O„-=žÞ7òGÞ LÐ[ÿ\4`Ï@ˆ…¿;ìsc{듾¬<‘,zÓ„32?ëìwQݽî @çÒbB|û:I¨ Âþ›¼éŽM{þÑX•ÞšH€Æ‰Ôúâ§|â5éDïõÄNâŒÇ³( žÜ﨣~ÙÅDÕäÃÿij£j«Õ¤›ýh›Þ+…[³Œ(³]Üùð«¢_KœÊ°¿P“YÊÌZ{6,oŠ|Ç?*>$.B~q¬…ØÕÔ/C5 ò_÷%D#RõYÎ!ÏîÍí<Š"¡eýYr{ÈüŠú17¯(ìlã‚uç¼+¹¿Š™Kš¡¼èËä¹[Í™Pë& Cz^>—Sñö̦Üc¨k1áJìl ½BòÂÔÏ¥Bõt¦¯vï #include "gwc.h" #define BUFSIZE 10000 static gfloat amount_pink = .01 ; static gfloat amount_white = .01 ; static int n_pn_rows = 32 ; static int feather_width = 0 ; /* patest_pink.c Generate Pink Noise using Gardner method. Optimization suggested by James McCartney uses a tree to select which random value to replace. 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 Tree is generated by counting trailing zeros in an increasing index. When the index is zero, no random number is selected. This program uses the Portable Audio library which is under development. For more information see: http://www.audiomulch.com/portaudio/ Author: Phil Burk, http://www.softsynth.com Revision History: Copyleft 1999 Phil Burk - No rights reserved. */ #include #include #ifdef WIN32 #include #endif /************************************************************/ /* Calculate pseudo-random 32 bit number based on linear congruential method. */ static unsigned long GenerateRandomNumber( void ) { static unsigned long randSeed = 22222; /* Change this for different random sequences. */ randSeed = (randSeed * 196314165) + 907633515; return randSeed; } #define PINK_MAX_RANDOM_ROWS (60) #define PINK_RANDOM_BITS (24) #define PINK_RANDOM_SHIFT ((sizeof(long)*8)-PINK_RANDOM_BITS) typedef struct { long pink_Rows[PINK_MAX_RANDOM_ROWS]; long pink_RunningSum; /* Used to optimize summing of generators. */ int pink_Index; /* Incremented each sample. */ int pink_IndexMask; /* Index wrapped by ANDing with this mask. */ float pink_Scalar; /* Used to scale within range of -1.0 to +1.0 */ } PinkNoise; /* Setup PinkNoise structure for N rows of generators. */ void InitializePinkNoise( PinkNoise *pink, int numRows ) { int i; long pmax; if(numRows > PINK_MAX_RANDOM_ROWS) numRows = PINK_MAX_RANDOM_ROWS ; pink->pink_Index = 0; pink->pink_IndexMask = (1<pink_Scalar = 1.0f / pmax; /* Initialize rows. */ for( i=0; ipink_Rows[i] = 0; pink->pink_RunningSum = 0; } #define PINK_MEASURE #ifdef PINK_MEASURE float pinkMax = -999.0; float pinkMin = 999.0; #endif /* Generate white noise values between -1.0 and +1.0 */ float GenerateWhiteNoise( PinkNoise *pink ) { long newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT; return (float) newRandom / (float) (1<<(PINK_RANDOM_BITS-1)) ; } /* Generate Pink noise values between -1.0 and +1.0 */ float GeneratePinkNoise( PinkNoise *pink ) { long newRandom; long sum; float output; /* Increment and mask index. */ pink->pink_Index = (pink->pink_Index + 1) & pink->pink_IndexMask; /* If index is zero, don't update any random values. */ if( pink->pink_Index != 0 ) { /* Determine how many trailing zeros in PinkIndex. */ /* This algorithm will hang if n==0 so test first. */ int numZeros = 0; int n = pink->pink_Index; while( (n & 1) == 0 ) { n = n >> 1; numZeros++; } /* Replace the indexed ROWS random value. * Subtract and add back to RunningSum instead of adding all the random * values together. Only one changes each time. */ pink->pink_RunningSum -= pink->pink_Rows[numZeros]; newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT; pink->pink_RunningSum += newRandom; pink->pink_Rows[numZeros] = newRandom; } /* Add extra white noise value. */ newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT; sum = pink->pink_RunningSum + newRandom; /* Scale to range of -1.0 to 0.9999. */ output = pink->pink_Scalar * sum; #ifdef PINK_MEASURE /* Check Min/Max */ if( output > pinkMax ) pinkMax = output; else if( output < pinkMin ) pinkMin = output; #endif return output; } void pinknoise(struct sound_prefs *p, long first, long last, int channel_mask) { long left[BUFSIZE], right[BUFSIZE] ; long current, i ; int loops = 0 ; PinkNoise leftPink; PinkNoise rightPink; /* Initialize two pink noise signals with different numbers of rows. */ InitializePinkNoise( &leftPink, n_pn_rows ); InitializePinkNoise( &rightPink, n_pn_rows ); /* Look at a few values. */ /* { */ /* int i; */ /* float pink; */ /* for( i=0; i<20; i++ ) */ /* { */ /* pink = GeneratePinkNoise( &leftPink ); */ /* printf("Pink = %f\n", pink ); */ /* } */ /* } */ current = first ; push_status_text("Generating Pink Noise") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; { long max_allowed = INT_MAX-1 ; g_print("max_allowed=%ld\n", max_allowed) ; while(current <= last) { long n = MIN(last - current + 1, BUFSIZE) ; long tmplast = current + n - 1 ; gfloat prog = (gfloat)(current-first)/(last-first+1) ; n = read_wavefile_data(left, right, current, tmplast) ; update_progress_bar(prog,PROGRESS_UPDATE_INTERVAL,FALSE) ; for(i = 0 ; i < n ; i++) { long icurrent = current + i ; double feather_p = 1.0 ; double wet_left, wet_right ; if(icurrent - first < feather_width) feather_p = (double)(icurrent-first)/(feather_width) ; if(last - icurrent < feather_width) feather_p = (double)(last - icurrent)/(feather_width) ; if(channel_mask & 0x01) { wet_left = amount_pink*GeneratePinkNoise( &leftPink ) * (double)max_allowed ; wet_left += amount_white*GenerateWhiteNoise( &leftPink ) * (double)max_allowed ; left[i] = lrint(left[i]*(1.0-feather_p) + wet_left*feather_p) ; } if(channel_mask & 0x02) { wet_right = amount_pink*GeneratePinkNoise( &rightPink ) * (double)max_allowed ; wet_right += amount_white*GenerateWhiteNoise( &rightPink ) * (double)max_allowed ; right[i] = lrint(right[i]*(1.0-feather_p) + wet_right*feather_p) ; } } write_wavefile_data(left, right, current, tmplast) ; current += n ; if(last - current < 10) loops++ ; if(loops > 5) { warning("infinite loop in pinknoise, programming error\n") ; } } resample_audio_data(p, first, last) ; save_sample_block_data(p) ; } update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; main_redraw(FALSE, TRUE) ; } int pinknoise_dialog(struct sound_prefs current, struct view *v) { GtkWidget *dlg, *dialog_table, *n_rows_entry ; GtkWidget *amount_pink_entry ; GtkWidget *amount_white_entry ; GtkWidget *feather_width_entry ; int dclose = 0 ; int row = 0 ; int dres ; dialog_table = gtk_table_new(5,2,0) ; gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 4) ; gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6) ; gtk_widget_show (dialog_table); dlg = gtk_dialog_new_with_buttons("Pink Noise", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); amount_pink_entry = add_number_entry_with_label_double(amount_pink, "Amount Pink Noise(0-1)", dialog_table, row++) ; amount_white_entry = add_number_entry_with_label_double(amount_white, "Amount White Noise(0-1)", dialog_table, row++) ; feather_width_entry = add_number_entry_with_label_int(feather_width, "Feather width", dialog_table, row++) ; n_rows_entry = add_number_entry_with_label_int(n_pn_rows, "# rows in noise generator (1-60)", dialog_table, row++) ; gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)) ; if(dres == 0) { amount_pink = atof(gtk_entry_get_text((GtkEntry *)amount_pink_entry)) ; amount_white = atof(gtk_entry_get_text((GtkEntry *)amount_white_entry)) ; feather_width = atoi(gtk_entry_get_text((GtkEntry *)feather_width_entry)) ; n_pn_rows = atoi(gtk_entry_get_text((GtkEntry *)n_rows_entry)) ; dclose = 1 ; } gtk_widget_destroy(dlg) ; if(dres == 0) return 1 ; return 0 ; } gtk-wave-cleaner-0.22-04/preferences.c0000777000175000017500000015334113120075107020661 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* preferences.c */ /* preference settings for GWC */ #include #include #include #include "gwc.h" #include "encoding.h" extern struct encoding_prefs encoding_prefs; static int svbr_mode, encpresets, oggencopt; void vbr_mode_window_select(GtkWidget * clist, gint row, gint column, GdkEventButton * event, gpointer data) { svbr_mode = row; } void presets_window_select(GtkWidget * clist, gint row, gint column, GdkEventButton * event, gpointer data) { encpresets = row; } void ogg_enc_window_select(GtkWidget * clist, gint row, gint column, GdkEventButton * event, gpointer data) { oggencopt = row; } void set_ogg_encoding_preferences(GtkWidget * widget, gpointer data) { GtkWidget *dlg; GtkWidget *dialog_table; GtkWidget *oggquality_entry; GtkWidget *oggloc_entry; GtkWidget *oggloclabel_entry; GtkWidget *oggmaxbitrate_entry; GtkWidget *oggminbitrate_entry; GtkWidget *oggbitrate_entry; GtkWidget *useAdvBitrateAvgWindow_entry; GtkWidget *useAdvlowpass_entry; GtkWidget *useResample_entry; GtkWidget *downmix_entry; GtkWidget *AdvBitrateAvgWindow_entry; GtkWidget *Advlowpass_entry; GtkWidget *Resample_entry; GtkWidget *enc_opt_window_list; GtkWidget *oggoptlabel_entry; int dres; int row = 0; gchar *enc_opt_window_titles[] = { "Ogg Encoding Mode" }; gchar *enc_opt_window_parms[4][1] = { {"Default"}, {"Managed"}, {"Nominal Bitrate"}, {"Quality Level"} }; load_ogg_encoding_preferences(); dlg = gtk_dialog_new_with_buttons("Ogg Encoding preferences", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); dialog_table = gtk_table_new(14, 3, 0); gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 4); gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6); gtk_widget_show(dialog_table); enc_opt_window_list = gtk_clist_new_with_titles(1, enc_opt_window_titles); gtk_clist_set_selection_mode(GTK_CLIST(enc_opt_window_list), GTK_SELECTION_SINGLE); gtk_clist_append(GTK_CLIST(enc_opt_window_list), enc_opt_window_parms[0]); gtk_clist_append(GTK_CLIST(enc_opt_window_list), enc_opt_window_parms[1]); gtk_clist_append(GTK_CLIST(enc_opt_window_list), enc_opt_window_parms[2]); gtk_clist_append(GTK_CLIST(enc_opt_window_list), enc_opt_window_parms[3]); gtk_clist_select_row(GTK_CLIST(enc_opt_window_list), encoding_prefs.ogg_encopt, 0); gtk_signal_connect(GTK_OBJECT(enc_opt_window_list), "select_row", GTK_SIGNAL_FUNC(ogg_enc_window_select), NULL); oggencopt = encoding_prefs.ogg_encopt; oggloc_entry = gtk_entry_new_with_max_length(255); oggloclabel_entry = gtk_label_new("Oggenc Location (full path):"); oggoptlabel_entry = gtk_label_new("Enable Options"); /* set the text */ if ((encoding_prefs.oggloc != NULL) && (strlen(encoding_prefs.oggloc) > 0)) { gtk_entry_set_text(GTK_ENTRY(oggloc_entry), encoding_prefs.oggloc); } downmix_entry = gtk_check_button_new_with_label("Downmix"); if (encoding_prefs.ogg_downmix == 1) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(downmix_entry), TRUE); } useResample_entry = gtk_check_button_new_with_label("Resample"); if (encoding_prefs.ogg_useresample == 1) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useResample_entry), TRUE); } useAdvlowpass_entry = gtk_check_button_new_with_label("Adv Low Pass"); if (encoding_prefs.ogg_useadvlowpass == 1) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (useAdvlowpass_entry), TRUE); } useAdvBitrateAvgWindow_entry = gtk_check_button_new_with_label("Adv Bitrate Avg Window"); if (encoding_prefs.ogg_useadvbravgwindow == 1) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (useAdvBitrateAvgWindow_entry), TRUE); } oggquality_entry = add_number_entry_with_label_double(atof (encoding_prefs. ogg_quality_level), "OGG Vorbis Quality Value (0.0-10.0)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(oggquality_entry), 5); /* 5 digits */ oggbitrate_entry = add_number_entry_with_label_int(atoi(encoding_prefs.ogg_bitrate), "Nominal Bitrate (kb/s)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(oggbitrate_entry), 5); /* 5 digits */ oggminbitrate_entry = add_number_entry_with_label_int(atoi (encoding_prefs.ogg_minbitrate), "Managed Min Bitrate (kb/s)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(oggminbitrate_entry), 5); /* 5 digits */ oggmaxbitrate_entry = add_number_entry_with_label_int(atoi (encoding_prefs.ogg_maxbitrate), "Managed Max Bitrate (kb/s)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(oggmaxbitrate_entry), 5); /* 5 digits */ Resample_entry = add_number_entry_with_label_int(atoi(encoding_prefs.ogg_resample), "Resample Rate (Hz)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(Resample_entry), 5); /* 5 digits */ Advlowpass_entry = add_number_entry_with_label_int(atoi (encoding_prefs. ogg_lowpass_frequency), "Adv Low Pass (kHz)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(Advlowpass_entry), 5); /* 5 digits */ AdvBitrateAvgWindow_entry = add_number_entry_with_label_int(atoi (encoding_prefs. ogg_bitrate_average_window), "Adv Bitrate Avg Window (s)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(AdvBitrateAvgWindow_entry), 5); /* 5 digits */ gtk_widget_show(oggloclabel_entry); gtk_widget_show(oggloc_entry); gtk_widget_show(oggquality_entry); gtk_widget_show(oggoptlabel_entry); gtk_widget_show(downmix_entry); gtk_widget_show(Resample_entry); gtk_widget_show(useResample_entry); gtk_widget_show(Advlowpass_entry); gtk_widget_show(useAdvlowpass_entry); gtk_widget_show(AdvBitrateAvgWindow_entry); gtk_widget_show(useAdvBitrateAvgWindow_entry); gtk_widget_show(enc_opt_window_list); gtk_table_attach_defaults(GTK_TABLE(dialog_table), oggloclabel_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), oggloc_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), oggoptlabel_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), downmix_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), useResample_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), useAdvlowpass_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), useAdvBitrateAvgWindow_entry, 0, 1, row, row + 1); row++; gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), enc_opt_window_list, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)); if (dres == 0) { encoding_prefs.ogg_encopt = oggencopt; strcpy(encoding_prefs.ogg_quality_level, gtk_entry_get_text((GtkEntry *) oggquality_entry)); strcpy(encoding_prefs.ogg_minbitrate, gtk_entry_get_text((GtkEntry *) oggminbitrate_entry)); strcpy(encoding_prefs.ogg_maxbitrate, gtk_entry_get_text((GtkEntry *) oggmaxbitrate_entry)); strcpy(encoding_prefs.ogg_bitrate, gtk_entry_get_text((GtkEntry *) oggbitrate_entry)); encoding_prefs.ogg_downmix = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (downmix_entry)); strcpy(encoding_prefs.ogg_resample, gtk_entry_get_text((GtkEntry *) Resample_entry)); strcpy(encoding_prefs.ogg_lowpass_frequency, gtk_entry_get_text((GtkEntry *) Advlowpass_entry)); strcpy(encoding_prefs.ogg_bitrate_average_window, gtk_entry_get_text((GtkEntry *) AdvBitrateAvgWindow_entry)); encoding_prefs.ogg_useresample = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (useResample_entry)); encoding_prefs.ogg_useadvlowpass = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (useAdvlowpass_entry)); encoding_prefs.ogg_useadvbravgwindow = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (useAdvBitrateAvgWindow_entry)); strcpy(encoding_prefs.oggloc, gtk_entry_get_text(GTK_ENTRY(oggloc_entry))); main_redraw(FALSE, TRUE); save_ogg_encoding_preferences(); } gtk_widget_destroy(dlg); } void set_mp3_simple_encoding_preferences(GtkWidget * widget, gpointer data) { /* new encoding preferences settings GTK window code */ GtkWidget *dlg; GtkWidget *dialog_table; GtkWidget *quality_entry; GtkWidget *mp3loc_entry; GtkWidget *mp3loclabel_entry; GtkWidget *artist_entry; GtkWidget *artistlabel_entry; GtkWidget *album_entry; GtkWidget *albumlabel_entry; int dres; int row = 0; load_mp3_simple_encoding_preferences(); mp3loc_entry = gtk_entry_new(); encpresets = encoding_prefs.mp3presets; dlg = gtk_dialog_new_with_buttons("MP3 Simple Encoding preferences", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); dialog_table = gtk_table_new(15, 3, 0); gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 4); gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6); mp3loc_entry = gtk_entry_new_with_max_length(255); mp3loclabel_entry = gtk_label_new("Lame Location (full path):"); /* set the text */ if ((encoding_prefs.mp3loc != NULL) && (strlen(encoding_prefs.mp3loc) > 0)) { gtk_entry_set_text(GTK_ENTRY(mp3loc_entry), encoding_prefs.mp3loc); } artist_entry = gtk_entry_new_with_max_length(255); artistlabel_entry = gtk_label_new("Artist:"); /* set the text */ if ((encoding_prefs.artist != NULL) && (strlen(encoding_prefs.artist) > 0)) { gtk_entry_set_text(GTK_ENTRY(artist_entry), encoding_prefs.artist); } album_entry = gtk_entry_new_with_max_length(255); albumlabel_entry = gtk_label_new("Album:"); /* set the text */ if ((encoding_prefs.album != NULL) && (strlen(encoding_prefs.album) > 0)) { gtk_entry_set_text(GTK_ENTRY(album_entry), encoding_prefs.album); } quality_entry = add_number_entry_with_label_int(atoi (encoding_prefs.mp3_quality_level), "MP3 VBR Quality Value (0-9) (i.e. -V ...)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(quality_entry), 1); /* 1 digit */ gtk_widget_show(dialog_table); gtk_widget_show(mp3loclabel_entry); gtk_widget_show(mp3loc_entry); gtk_widget_show(artistlabel_entry); gtk_widget_show(artist_entry); gtk_widget_show(albumlabel_entry); gtk_widget_show(album_entry); gtk_table_attach_defaults(GTK_TABLE(dialog_table), mp3loclabel_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), mp3loc_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), artistlabel_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), artist_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), albumlabel_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), album_entry, 0, 1, row, row + 1); row++; gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)); if (dres == 0) { /* save setting changes */ strcpy(encoding_prefs.mp3_quality_level, gtk_entry_get_text(GTK_ENTRY(quality_entry))); strcpy(encoding_prefs.mp3loc, gtk_entry_get_text(GTK_ENTRY(mp3loc_entry))); strcpy(encoding_prefs.artist, gtk_entry_get_text(GTK_ENTRY(artist_entry))); strcpy(encoding_prefs.album, gtk_entry_get_text(GTK_ENTRY(album_entry))); main_redraw(FALSE, TRUE); save_mp3_simple_encoding_preferences(); } gtk_widget_destroy(dlg) ; } void set_mp3_encoding_preferences(GtkWidget * widget, gpointer data) { /* new encoding preferences settings GTK window code */ GtkWidget *dlg; GtkWidget *dialog_table; GtkWidget *quality_entry; GtkWidget *bitrate_entry; GtkWidget *vbr_mode_window_list; GtkWidget *presets_window_list; GtkWidget *lame_mmx_enabled_entry; GtkWidget *mmx_entry; GtkWidget *sse_entry; GtkWidget *threednow_entry; GtkWidget *asmlabel_entry; GtkWidget *mp3loc_entry; GtkWidget *mp3loclabel_entry; GtkWidget *allfilter_entry; GtkWidget *strictiso_entry; GtkWidget *copyrighted_entry; GtkWidget *protected_entry; GtkWidget *uselowpass_entry; GtkWidget *usehighpass_entry; GtkWidget *highpassfreq_entry; GtkWidget *lowpassfreq_entry; GtkWidget *otheropt_entry; gchar *vbr_mode_window_titles[] = { "MP3 Bitrate Mode" }; gchar *vbr_mode_window_parms[4][1] = { {"Default"}, {"Average Bit Rate"}, {"Constant Bit Rate"}, {"Variable Bit Rate"} }; gchar *presets_window_titles[] = { "MP3 Presets" }; gchar *presets_window_parms[9][1] = { {"UNSELECTED"}, {"R3MIX"}, {"STANDARD"}, {"MEDIUM"}, {"EXTREME"}, {"INSANE"}, {"FAST STANDARD"}, {"FAST MEDIUM"}, {"FAST EXTREME"} }; int dres; int row = 0; load_mp3_encoding_preferences(); lame_mmx_enabled_entry = gtk_check_button_new_with_label("Lame MMX enabled?"); asmlabel_entry = gtk_label_new("Use MP3 Assembly Optimizations:"); mmx_entry = gtk_check_button_new_with_label("MMX"); sse_entry = gtk_check_button_new_with_label("SSE"); threednow_entry = gtk_check_button_new_with_label("3DNOW"); otheropt_entry = gtk_label_new("Advanced Options"); allfilter_entry = gtk_check_button_new_with_label("No Filters"); strictiso_entry = gtk_check_button_new_with_label("Enforce Strict ISO"); copyrighted_entry = gtk_check_button_new_with_label("Mark Copyrighted"); protected_entry = gtk_check_button_new_with_label("Add CRC"); uselowpass_entry = gtk_check_button_new_with_label("Use Lowpass Filter"); usehighpass_entry = gtk_check_button_new_with_label("Use Highpass Filter"); mp3loc_entry = gtk_entry_new(); vbr_mode_window_list = gtk_clist_new_with_titles(1, vbr_mode_window_titles); gtk_clist_set_selection_mode(GTK_CLIST(vbr_mode_window_list), GTK_SELECTION_SINGLE); gtk_clist_append(GTK_CLIST(vbr_mode_window_list), vbr_mode_window_parms[0]); gtk_clist_append(GTK_CLIST(vbr_mode_window_list), vbr_mode_window_parms[1]); gtk_clist_append(GTK_CLIST(vbr_mode_window_list), vbr_mode_window_parms[2]); gtk_clist_append(GTK_CLIST(vbr_mode_window_list), vbr_mode_window_parms[3]); presets_window_list = gtk_clist_new_with_titles(1, presets_window_titles); gtk_clist_set_selection_mode(GTK_CLIST(presets_window_list), GTK_SELECTION_SINGLE); gtk_clist_append(GTK_CLIST(presets_window_list), presets_window_parms[0]); gtk_clist_append(GTK_CLIST(presets_window_list), presets_window_parms[1]); gtk_clist_append(GTK_CLIST(presets_window_list), presets_window_parms[2]); gtk_clist_append(GTK_CLIST(presets_window_list), presets_window_parms[3]); gtk_clist_append(GTK_CLIST(presets_window_list), presets_window_parms[4]); gtk_clist_append(GTK_CLIST(presets_window_list), presets_window_parms[5]); gtk_clist_append(GTK_CLIST(presets_window_list), presets_window_parms[6]); gtk_clist_append(GTK_CLIST(presets_window_list), presets_window_parms[7]); gtk_clist_append(GTK_CLIST(presets_window_list), presets_window_parms[8]); gtk_clist_select_row(GTK_CLIST(vbr_mode_window_list), encoding_prefs.mp3_br_mode, 0); gtk_clist_select_row(GTK_CLIST(presets_window_list), encoding_prefs.mp3presets, 0); if (encoding_prefs.mp3_lame_mmx_enabled == 1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (lame_mmx_enabled_entry), TRUE); if (encoding_prefs.mp3_mmx == 1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mmx_entry), TRUE); if (encoding_prefs.mp3_sse == 1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sse_entry), TRUE); if (encoding_prefs.mp3_threednow == 1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(threednow_entry), TRUE); if (encoding_prefs.mp3_copyrighted == 1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(copyrighted_entry), TRUE); if (encoding_prefs.mp3_add_crc == 1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(protected_entry), TRUE); if (encoding_prefs.mp3_strict_iso == 1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(strictiso_entry), TRUE); if (encoding_prefs.mp3_nofilters == 1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(allfilter_entry), TRUE); if (encoding_prefs.mp3_use_lowpass == 1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(uselowpass_entry), TRUE); if (encoding_prefs.mp3_use_highpass == 1) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(usehighpass_entry), TRUE); gtk_signal_connect(GTK_OBJECT(vbr_mode_window_list), "select_row", GTK_SIGNAL_FUNC(vbr_mode_window_select), NULL); gtk_signal_connect(GTK_OBJECT(presets_window_list), "select_row", GTK_SIGNAL_FUNC(presets_window_select), NULL); encpresets = encoding_prefs.mp3presets; svbr_mode = encoding_prefs.mp3_br_mode; gtk_widget_show(vbr_mode_window_list); gtk_widget_show(presets_window_list); dlg = gtk_dialog_new_with_buttons("MP3 Encoding preferences", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); dialog_table = gtk_table_new(15, 3, 0); gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 4); gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6); mp3loc_entry = gtk_entry_new_with_max_length(255); mp3loclabel_entry = gtk_label_new("Lame Location (full path):"); /* set the text */ if ((encoding_prefs.mp3loc != NULL) && (strlen(encoding_prefs.mp3loc) > 0)) { gtk_entry_set_text(GTK_ENTRY(mp3loc_entry), encoding_prefs.mp3loc); } bitrate_entry = add_number_entry_with_label_int(atoi(encoding_prefs.mp3_bitrate), "MP3 Encoding Bitrate (kbps)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(bitrate_entry), 5); /* 5 digits */ quality_entry = add_number_entry_with_label_int(atoi (encoding_prefs.mp3_quality_level), "MP3 Quality Value (0-9)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(quality_entry), 1); /* 1 digit */ lowpassfreq_entry = add_number_entry_with_label(encoding_prefs.mp3_lowpass_freq, "Lowpass Filter (kHz)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(lowpassfreq_entry), 5); /* 5 digits */ highpassfreq_entry = add_number_entry_with_label(encoding_prefs.mp3_highpass_freq, "Highpass Filter (kHz)", dialog_table, row++); gtk_entry_set_max_length(GTK_ENTRY(highpassfreq_entry), 5); /* 5 digits */ gtk_widget_show(dialog_table); gtk_widget_show(mp3loclabel_entry); gtk_widget_show(mp3loc_entry); gtk_widget_show(lame_mmx_enabled_entry); gtk_widget_show(asmlabel_entry); gtk_widget_show(sse_entry); gtk_widget_show(mmx_entry); gtk_widget_show(threednow_entry); gtk_widget_show(otheropt_entry); gtk_widget_show(allfilter_entry); gtk_widget_show(uselowpass_entry); gtk_widget_show(usehighpass_entry); gtk_widget_show(protected_entry); gtk_widget_show(copyrighted_entry); gtk_widget_show(strictiso_entry); gtk_widget_show(bitrate_entry); gtk_widget_show(lowpassfreq_entry); gtk_widget_show(highpassfreq_entry); gtk_table_attach_defaults(GTK_TABLE(dialog_table), mp3loclabel_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), mp3loc_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), lame_mmx_enabled_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), asmlabel_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), mmx_entry, 0, 1, row, row + 1); gtk_table_attach_defaults(GTK_TABLE(dialog_table), sse_entry, 1, 2, row, row + 1); gtk_table_attach_defaults(GTK_TABLE(dialog_table), threednow_entry, 2, 3, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), otheropt_entry, 0, 1, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), allfilter_entry, 0, 1, row, row + 1); gtk_table_attach_defaults(GTK_TABLE(dialog_table), uselowpass_entry, 1, 2, row, row + 1); gtk_table_attach_defaults(GTK_TABLE(dialog_table), usehighpass_entry, 2, 3, row, row + 1); row++; gtk_table_attach_defaults(GTK_TABLE(dialog_table), copyrighted_entry, 0, 1, row, row + 1); gtk_table_attach_defaults(GTK_TABLE(dialog_table), protected_entry, 1, 2, row, row + 1); gtk_table_attach_defaults(GTK_TABLE(dialog_table), strictiso_entry, 2, 3, row, row + 1); row++; gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), presets_window_list, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), vbr_mode_window_list, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)); if (dres == 0) { /* save setting changes */ encoding_prefs.mp3_br_mode = svbr_mode; encoding_prefs.mp3presets = encpresets; strcpy(encoding_prefs.mp3_bitrate, gtk_entry_get_text(GTK_ENTRY(bitrate_entry))); strcpy(encoding_prefs.mp3_quality_level, gtk_entry_get_text(GTK_ENTRY(quality_entry))); encoding_prefs.mp3_lame_mmx_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (lame_mmx_enabled_entry)); encoding_prefs.mp3_sse = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sse_entry)); encoding_prefs.mp3_mmx = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mmx_entry)); encoding_prefs.mp3_threednow = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (threednow_entry)); encoding_prefs.mp3_copyrighted = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (copyrighted_entry)); encoding_prefs.mp3_add_crc = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (protected_entry)); encoding_prefs.mp3_strict_iso = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (strictiso_entry)); encoding_prefs.mp3_nofilters = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (allfilter_entry)); encoding_prefs.mp3_use_lowpass = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (uselowpass_entry)); encoding_prefs.mp3_use_highpass = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (usehighpass_entry)); strcpy(encoding_prefs.mp3loc, gtk_entry_get_text(GTK_ENTRY(mp3loc_entry))); strcpy(encoding_prefs.mp3_lowpass_freq, gtk_entry_get_text(GTK_ENTRY(lowpassfreq_entry))); strcpy(encoding_prefs.mp3_highpass_freq, gtk_entry_get_text(GTK_ENTRY(highpassfreq_entry))); main_redraw(FALSE, TRUE); save_mp3_encoding_preferences(); } gtk_widget_destroy(dlg) ; } /* int preferences_dialog(void) */ void set_misc_preferences(GtkWidget * widget, gpointer data) { extern double stop_key_highlight_interval; extern double song_key_highlight_interval; extern double song_mark_silence; extern int sonogram_log; GtkWidget *dlg; GtkWidget *stop_interval_entry; GtkWidget *song_interval_entry; GtkWidget *dialog_table; GtkWidget *normalize_entry; GtkWidget *silence_entry; GtkWidget *sonogram_log_entry; GtkWidget *audio_device_entry; extern char audio_device[]; extern int denoise_normalize; int dres; int row = 0; dlg = gtk_dialog_new_with_buttons("Miscellaneous preferences", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); dialog_table = gtk_table_new(6, 2, 0); gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 5); gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6); gtk_widget_show(dialog_table); stop_interval_entry = add_number_entry_with_label_double(stop_key_highlight_interval, "Seconds of audio pre-selected when \"s\" key is pressed", dialog_table, row++); song_interval_entry = add_number_entry_with_label_double(song_key_highlight_interval, "Seconds of audio highlighted around song marker when markers are \"shown\"", dialog_table, row++); normalize_entry = add_number_entry_with_label_int(denoise_normalize, "Normalize values for declick, denoise?", dialog_table, row++); silence_entry = add_number_entry_with_label_double(song_mark_silence, "Silence estimate in seconds for marking songs", dialog_table, row++); sonogram_log_entry = gtk_check_button_new_with_label("Log frequency in sonogram"); if (sonogram_log) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sonogram_log_entry), TRUE); gtk_widget_show(sonogram_log_entry); gtk_table_attach_defaults(GTK_TABLE(dialog_table), sonogram_log_entry, 0, 1, row, row + 1); row++; audio_device_entry = add_number_entry_with_label(audio_device, "Audio device try (/dev/dsp for OSS) (default, plughw:0,0, hw:0,0 or hw:1,0 ... for ALSA)", dialog_table, row++); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)); if (dres == 0) { stop_key_highlight_interval = atof(gtk_entry_get_text((GtkEntry *) stop_interval_entry)); song_key_highlight_interval = atof(gtk_entry_get_text((GtkEntry *) song_interval_entry)); song_mark_silence = atof(gtk_entry_get_text((GtkEntry *) silence_entry)); denoise_normalize = atoi(gtk_entry_get_text((GtkEntry *) normalize_entry)); sonogram_log = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (sonogram_log_entry)); strcpy(audio_device, gtk_entry_get_text(((GtkEntry *) audio_device_entry))); save_preferences(); main_redraw(FALSE, TRUE); } gtk_widget_destroy(dlg) ; } void declick_set_preferences(GtkWidget * widget, gpointer data) { extern double weak_declick_sensitivity; extern double strong_declick_sensitivity; extern double weak_fft_declick_sensitivity; extern double strong_fft_declick_sensitivity; extern int declick_iterate_flag ; extern int declick_detector_type ; GtkWidget *dlg; GtkWidget *dc_weak_entry; GtkWidget *dc_strong_entry; GtkWidget *iterate_widget; GtkWidget *dc_fft_weak_entry; GtkWidget *dc_fft_strong_entry; GtkWidget *method_widget; GtkWidget *dialog_table; int dres; int row = 1 ; dlg = gtk_dialog_new_with_buttons("Declicking preferences", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); dialog_table = gtk_table_new(5, 2, 0); gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 4); gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6); gtk_widget_show(dialog_table); dc_weak_entry = add_number_entry_with_label_double(weak_declick_sensitivity, "Weak Declick Sensitivity (default = 1.0) ", dialog_table, row++); dc_strong_entry = add_number_entry_with_label_double(strong_declick_sensitivity, "Strong Declick Sensitivity (default = 0.75) ", dialog_table, row++); dc_fft_weak_entry = add_number_entry_with_label_double(weak_fft_declick_sensitivity, "FFT Weak Declick Sensitivity (default = 3.0) ", dialog_table, row++); dc_fft_strong_entry = add_number_entry_with_label_double(strong_fft_declick_sensitivity, "FFT Strong Declick Sensitivity (default = 5.0) ", dialog_table, row++); method_widget = gtk_check_button_new_with_label ("Use FFT click detector"); gtk_toggle_button_set_active((GtkToggleButton *) method_widget, declick_detector_type == FFT_DETECT ? TRUE : FALSE); gtk_widget_show(method_widget); gtk_table_attach_defaults(GTK_TABLE(dialog_table), method_widget, 0, 2, row, row+1); row += 2 ; iterate_widget = gtk_check_button_new_with_label ("Iterate in repair clicks until all repaired"); gtk_toggle_button_set_active((GtkToggleButton *) iterate_widget, declick_iterate_flag == 1 ? TRUE : FALSE); gtk_widget_show(iterate_widget); gtk_table_attach_defaults(GTK_TABLE(dialog_table), iterate_widget, 0, 2, row, row+1); row += 2 ; gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)); if (dres == 0) { weak_declick_sensitivity = atof(gtk_entry_get_text((GtkEntry *) dc_weak_entry)); strong_declick_sensitivity = atof(gtk_entry_get_text((GtkEntry *) dc_strong_entry)); weak_fft_declick_sensitivity = atof(gtk_entry_get_text((GtkEntry *) dc_fft_weak_entry)); strong_fft_declick_sensitivity = atof(gtk_entry_get_text((GtkEntry *) dc_fft_strong_entry)); declick_iterate_flag = gtk_toggle_button_get_active((GtkToggleButton *) iterate_widget) == TRUE ? 1 : 0; declick_detector_type = gtk_toggle_button_get_active((GtkToggleButton *) method_widget) == TRUE ? FFT_DETECT : HPF_DETECT ; } gtk_widget_destroy(dlg) ; } void decrackle_set_preferences(GtkWidget * widget, gpointer data) { extern double decrackle_level; extern gint decrackle_window, decrackle_average; GtkWidget *dlg; GtkWidget *dcr_entry, *dcw_entry, *dca_entry; GtkWidget *dialog_table; int dres; dlg = gtk_dialog_new_with_buttons("Decrackling preferences", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); dialog_table = gtk_table_new(3, 2, 0); gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 4); gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6); gtk_widget_show(dialog_table); // No idea if "Decrackle" vs "Decrackling" means anything - maybe "Decrackle level" should be "Decrackling level". dcr_entry = add_number_entry_with_label_double(decrackle_level, "Decrackle level (default = 0.2) ", dialog_table, 1); dcw_entry = add_number_entry_with_label_int(decrackle_window, "Decrackling window (default = 2000)", dialog_table, 2); dca_entry = add_number_entry_with_label_int(decrackle_average, "Decrackling average window (default = 3)", dialog_table, 3); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)); if (dres == 0) { decrackle_level = atof(gtk_entry_get_text((GtkEntry *) dcr_entry)); decrackle_window = atoi(gtk_entry_get_text((GtkEntry *) dcw_entry)); decrackle_average = atoi(gtk_entry_get_text((GtkEntry *) dca_entry)); } gtk_widget_destroy(dlg); } void load_mp3_simple_encoding_preferences(void) { GKeyFile *key_file = read_config(); if (g_key_file_has_group(key_file, "mp3_simple_encoding_params") == TRUE) { /* MP3 */ if (g_key_file_get_string(key_file, "mp3_simple_encoding_params", "enc_quality_level", NULL) != NULL) strcpy(encoding_prefs.mp3_quality_level, g_key_file_get_string(key_file, "mp3_simple_encoding_params", "enc_quality_level", NULL)); if (g_key_file_get_string(key_file, "mp3_simple_encoding_params", "mp3_location", NULL) != NULL) strcpy(encoding_prefs.mp3loc, g_key_file_get_string(key_file, "mp3_simple_encoding_params", "mp3_location", NULL)); if (g_key_file_get_string(key_file, "mp3_simple_encoding_params", "artist", NULL) != NULL) strcpy(encoding_prefs.artist, g_key_file_get_string(key_file, "mp3_simple_encoding_params", "artist", NULL)); if (g_key_file_get_string(key_file, "mp3_simple_encoding_params", "album", NULL) != NULL) strcpy(encoding_prefs.album, g_key_file_get_string(key_file, "mp3_simple_encoding_params", "album", NULL)); } g_key_file_free (key_file); } void load_mp3_encoding_preferences(void) { GKeyFile *key_file = read_config(); if (g_key_file_has_group(key_file, "mp3_encoding_params") == TRUE) { /* MP3 */ if (g_key_file_get_string(key_file, "mp3_encoding_params", "enc_bitrate", NULL) != NULL) strcpy(encoding_prefs.mp3_bitrate, g_key_file_get_string(key_file, "mp3_encoding_params", "enc_bitrate", NULL)); if (g_key_file_get_string(key_file, "mp3_encoding_params", "enc_quality_level", NULL) != NULL) strcpy(encoding_prefs.mp3_quality_level, g_key_file_get_string(key_file, "mp3_encoding_params", "enc_quality_level", NULL)); if (g_key_file_get_string(key_file, "mp3_encoding_params", "lowpass_freq", NULL) != NULL) strcpy(encoding_prefs.mp3_lowpass_freq, g_key_file_get_string(key_file, "mp3_encoding_params", "lowpass_freq", NULL)); if (g_key_file_get_string(key_file, "mp3_encoding_params", "highpass_freq", NULL) != NULL) strcpy(encoding_prefs.mp3_highpass_freq, g_key_file_get_string(key_file, "mp3_encoding_params", "highpass_freq", NULL)); encoding_prefs.mp3_br_mode = g_key_file_get_integer(key_file, "mp3_encoding_params", "br_mode", NULL); encoding_prefs.mp3presets = g_key_file_get_integer(key_file, "mp3_encoding_params", "presets", NULL); encoding_prefs.mp3_sse = g_key_file_get_integer(key_file, "mp3_encoding_params", "sse", NULL); encoding_prefs.mp3_threednow = g_key_file_get_integer(key_file, "mp3_encoding_params", "threednow", NULL); encoding_prefs.mp3_lame_mmx_enabled = g_key_file_get_integer(key_file, "mp3_encoding_params", "lame_mmx_enabled", NULL); encoding_prefs.mp3_mmx = g_key_file_get_integer(key_file, "mp3_encoding_params", "mmx", NULL); encoding_prefs.mp3_copyrighted = g_key_file_get_integer(key_file, "mp3_encoding_params", "copyrighted", NULL); encoding_prefs.mp3_add_crc = g_key_file_get_integer(key_file, "mp3_encoding_params", "protected", NULL); encoding_prefs.mp3_strict_iso = g_key_file_get_integer(key_file, "mp3_encoding_params", "strictiso", NULL); encoding_prefs.mp3_nofilters = g_key_file_get_integer(key_file, "mp3_encoding_params", "nofilters", NULL); encoding_prefs.mp3_use_lowpass = g_key_file_get_integer(key_file, "mp3_encoding_params", "uselowpass", NULL); encoding_prefs.mp3_use_highpass = g_key_file_get_integer(key_file, "mp3_encoding_params", "usehighpass", NULL); if (g_key_file_get_string(key_file, "mp3_encoding_params", "mp3_location", NULL) != NULL) strcpy(encoding_prefs.mp3loc, g_key_file_get_string(key_file, "mp3_encoding_params", "mp3_location", NULL)); } g_key_file_free (key_file); } void load_ogg_encoding_preferences(void) { /* OGG */ GKeyFile *key_file = read_config(); if (g_key_file_has_group(key_file, "ogg_encoding_params") == TRUE) { if (g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_quality_level", NULL) != NULL) strcpy(encoding_prefs.ogg_quality_level, g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_quality_level", NULL)); if (g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_location", NULL) != NULL) strcpy(encoding_prefs.oggloc, g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_location", NULL)); if (g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_bitrate", NULL) != NULL) strcpy(encoding_prefs.ogg_bitrate, g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_bitrate", NULL)); if (g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_maxbitrate", NULL) != NULL) strcpy(encoding_prefs.ogg_maxbitrate, g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_maxbitrate", NULL)); if (g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_minbitrate", NULL) != NULL) strcpy(encoding_prefs.ogg_minbitrate, g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_minbitrate", NULL)); encoding_prefs.ogg_downmix = g_key_file_get_integer(key_file, "ogg_encoding_params", "ogg_downmix", NULL); if (g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_resample", NULL) != NULL) strcpy(encoding_prefs.ogg_resample, g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_resample", NULL)); if (g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_lowpass", NULL) != NULL) strcpy(encoding_prefs.ogg_lowpass_frequency, g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_lowpass", NULL)); if (g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_bitrateavgwindow", NULL) != NULL) strcpy(encoding_prefs.ogg_bitrate_average_window, g_key_file_get_string(key_file, "ogg_encoding_params", "ogg_bitrateavgwindow", NULL)); encoding_prefs.ogg_useadvbravgwindow = g_key_file_get_integer(key_file, "ogg_encoding_params", "ogg_useadvbravgwindow", NULL); encoding_prefs.ogg_useresample = g_key_file_get_integer(key_file, "ogg_encoding_params", "ogg_useresample", NULL); encoding_prefs.ogg_useadvlowpass = g_key_file_get_integer(key_file, "ogg_encoding_params", "ogg_useadvlowpass", NULL); encoding_prefs.ogg_useadvlowpass = g_key_file_get_integer(key_file, "ogg_encoding_params", "ogg_uselowpass", NULL); encoding_prefs.ogg_encopt = g_key_file_get_integer(key_file, "ogg_encoding_params", "ogg_encopt", NULL); } g_key_file_free (key_file); } void save_mp3_simple_encoding_preferences(void) { /* MP3 */ GKeyFile *key_file = read_config(); g_key_file_set_string(key_file, "mp3_simple_encoding_params", "enc_quality_level", encoding_prefs.mp3_quality_level); g_key_file_set_string(key_file, "mp3_simple_encoding_params", "mp3_location", encoding_prefs.mp3loc); g_key_file_set_string(key_file, "mp3_simple_encoding_params", "artist", encoding_prefs.artist); g_key_file_set_string(key_file, "mp3_simple_encoding_params", "album", encoding_prefs.album); write_config(key_file); } void save_mp3_encoding_preferences(void) { /* MP3 */ GKeyFile *key_file = read_config(); g_key_file_set_string(key_file, "mp3_encoding_params", "enc_bitrate", encoding_prefs.mp3_bitrate); g_key_file_set_string(key_file, "mp3_encoding_params", "enc_quality_level", encoding_prefs.mp3_quality_level); g_key_file_set_string(key_file, "mp3_encoding_params", "lowpass_freq", encoding_prefs.mp3_lowpass_freq); g_key_file_set_string(key_file, "mp3_encoding_params", "highpass_freq", encoding_prefs.mp3_highpass_freq); g_key_file_set_integer(key_file, "mp3_encoding_params", "br_mode", encoding_prefs.mp3_br_mode); g_key_file_set_integer(key_file, "mp3_encoding_params", "presets", encoding_prefs.mp3presets); g_key_file_set_integer(key_file, "mp3_encoding_params", "lame_mmx_enabled", encoding_prefs.mp3_lame_mmx_enabled); g_key_file_set_integer(key_file, "mp3_encoding_params", "sse", encoding_prefs.mp3_sse); g_key_file_set_integer(key_file, "mp3_encoding_params", "mmx", encoding_prefs.mp3_mmx); g_key_file_set_integer(key_file, "mp3_encoding_params", "threednow", encoding_prefs.mp3_threednow); g_key_file_set_integer(key_file, "mp3_encoding_params", "nofilters", encoding_prefs.mp3_nofilters); g_key_file_set_integer(key_file, "mp3_encoding_params", "uselowpass", encoding_prefs.mp3_use_lowpass); g_key_file_set_integer(key_file, "mp3_encoding_params", "usehighpass", encoding_prefs.mp3_use_highpass); g_key_file_set_integer(key_file, "mp3_encoding_params", "copyrighted", encoding_prefs.mp3_copyrighted); g_key_file_set_integer(key_file, "mp3_encoding_params", "protected", encoding_prefs.mp3_add_crc); g_key_file_set_integer(key_file, "mp3_encoding_params", "strictiso", encoding_prefs.mp3_strict_iso); g_key_file_set_string(key_file, "mp3_encoding_params", "mp3_location", encoding_prefs.mp3loc); write_config(key_file); } void save_ogg_encoding_preferences(void) { /* OGG */ GKeyFile *key_file = read_config(); g_key_file_set_string(key_file, "ogg_encoding_params", "ogg_quality_level", encoding_prefs.ogg_quality_level); g_key_file_set_string(key_file, "ogg_encoding_params", "ogg_location", encoding_prefs.oggloc); g_key_file_set_string(key_file, "ogg_encoding_params", "ogg_bitrate", encoding_prefs.ogg_bitrate); g_key_file_set_string(key_file, "ogg_encoding_params", "ogg_minbitrate", encoding_prefs.ogg_minbitrate); g_key_file_set_string(key_file, "ogg_encoding_params", "ogg_maxbitrate", encoding_prefs.ogg_maxbitrate); g_key_file_set_integer(key_file, "ogg_encoding_params", "ogg_downmix", encoding_prefs.ogg_downmix); g_key_file_set_string(key_file, "ogg_encoding_params", "ogg_resample", encoding_prefs.ogg_resample); g_key_file_set_string(key_file, "ogg_encoding_params", "ogg_bitrateavgwindow", encoding_prefs.ogg_bitrate_average_window); g_key_file_set_string(key_file, "ogg_encoding_params", "ogg_lowpass", encoding_prefs.ogg_lowpass_frequency); g_key_file_set_integer(key_file, "ogg_encoding_params", "ogg_uselowpass", encoding_prefs.ogg_useadvlowpass); g_key_file_set_integer(key_file, "ogg_encoding_params", "ogg_useresample", encoding_prefs.ogg_useresample); g_key_file_set_integer(key_file, "ogg_encoding_params", "ogg_useadvbravgwindow", encoding_prefs.ogg_useadvbravgwindow); g_key_file_set_integer(key_file, "ogg_encoding_params", "ogg_encopt", encoding_prefs.ogg_encopt); write_config(key_file); } extern struct denoise_prefs denoise_prefs; static int noise_suppression_method, window_type; void load_denoise_preferences(void) { denoise_prefs.noise_suppression_method = 3 ; denoise_prefs.window_type = 2 ; denoise_prefs.smoothness = 11; denoise_prefs.FFT_SIZE = 4096 ; denoise_prefs.n_noise_samples = 16 ; denoise_prefs.amount = 0.5 ; denoise_prefs.dn_gamma = 0.95 ; denoise_prefs.randomness = 0.0 ; denoise_prefs.min_sample_freq = 0.0 ; denoise_prefs.max_sample_freq = 44100.0 ; denoise_prefs.freq_filter = 0 ; denoise_prefs.estimate_power_floor = 0 ; GKeyFile *key_file = read_config(); if (g_key_file_has_group(key_file, "denoise_params") == TRUE) { denoise_prefs.n_noise_samples = g_key_file_get_integer(key_file, "denoise_params", "n_noise_samples", NULL); denoise_prefs.smoothness = g_key_file_get_integer(key_file, "denoise_params", "smoothness", NULL); denoise_prefs.FFT_SIZE = g_key_file_get_integer(key_file, "denoise_params", "FFT_SIZE", NULL); denoise_prefs.amount = g_key_file_get_double(key_file, "denoise_params", "amount", NULL); denoise_prefs.dn_gamma = g_key_file_get_double(key_file, "denoise_params", "dn_gamma", NULL); denoise_prefs.randomness = g_key_file_get_double(key_file, "denoise_params", "randomness", NULL); denoise_prefs.window_type = g_key_file_get_integer(key_file, "denoise_params", "window_type", NULL); denoise_prefs.freq_filter = g_key_file_get_integer(key_file, "denoise_params", "freq_filter", NULL); denoise_prefs.estimate_power_floor = g_key_file_get_integer(key_file, "denoise_params", "estimate_power_floor", NULL); denoise_prefs.min_sample_freq = g_key_file_get_double(key_file, "denoise_params", "min_sample_freq", NULL); denoise_prefs.max_sample_freq = g_key_file_get_double(key_file, "denoise_params", "max_sample_freq", NULL); denoise_prefs.noise_suppression_method = g_key_file_get_integer(key_file, "denoise_params", "noise_suppression_method", NULL); } g_key_file_free (key_file); } void save_denoise_preferences(void) { GKeyFile *key_file = read_config(); g_key_file_set_integer(key_file, "denoise_params", "n_noise_samples", denoise_prefs.n_noise_samples); g_key_file_set_integer(key_file, "denoise_params", "smoothness", denoise_prefs.smoothness); g_key_file_set_integer(key_file, "denoise_params", "FFT_SIZE", denoise_prefs.FFT_SIZE); g_key_file_set_double(key_file, "denoise_params", "amount", denoise_prefs.amount); g_key_file_set_double(key_file, "denoise_params", "dn_gamma", denoise_prefs.dn_gamma); g_key_file_set_double(key_file, "denoise_params", "randomness", denoise_prefs.randomness); g_key_file_set_integer(key_file, "denoise_params", "window_type", denoise_prefs.window_type); g_key_file_set_integer(key_file, "denoise_params", "freq_filter", denoise_prefs.freq_filter); g_key_file_set_integer(key_file, "denoise_params", "estimate_power_floor", denoise_prefs.estimate_power_floor); g_key_file_set_double(key_file, "denoise_params", "min_sample_freq", denoise_prefs.min_sample_freq); g_key_file_set_double(key_file, "denoise_params", "max_sample_freq", denoise_prefs.max_sample_freq); g_key_file_set_integer(key_file, "denoise_params", "noise_suppression_method", denoise_prefs.noise_suppression_method); write_config(key_file); } void fft_window_select(GtkWidget * clist, gint row, gint column, GdkEventButton * event, gpointer data) { if (row == 0) window_type = DENOISE_WINDOW_BLACKMAN; if (row == 1) window_type = DENOISE_WINDOW_BLACKMAN_HYBRID; if (row == 2) window_type = DENOISE_WINDOW_HANNING_OVERLAP_ADD; #ifdef DENOISE_TRY_ONE_SAMPLE if (row == 3) window_type = DENOISE_WINDOW_ONE_SAMPLE; if (row == 4) window_type = DENOISE_WINDOW_WELTY; #else if (row == 3) window_type = DENOISE_WINDOW_WELTY; #endif } void noise_method_window_select(GtkWidget * clist, gint row, gint column, GdkEventButton * event, gpointer data) { if (row == 0) noise_suppression_method = DENOISE_WEINER; if (row == 1) noise_suppression_method = DENOISE_POWER_SPECTRAL_SUBTRACT; if (row == 2) noise_suppression_method = DENOISE_EM; if (row == 3) noise_suppression_method = DENOISE_LORBER; if (row == 4) noise_suppression_method = DENOISE_WOLFE_GODSILL; if (row == 5) noise_suppression_method = DENOISE_EXPERIMENTAL ; } void denoise_set_preferences(GtkWidget * widget, gpointer data) { GtkWidget *dlg; GtkWidget *fft_size_entry; GtkWidget *amount_entry; GtkWidget *gamma_entry; GtkWidget *smoothness_entry; GtkWidget *n_noise_entry; GtkWidget *dialog_table; GtkWidget *freq_filter_entry; GtkWidget *estimate_power_floor_entry; GtkWidget *min_sample_freq_entry; GtkWidget *max_sample_freq_entry; int dres; GtkWidget *fft_window_list; gchar *fft_window_titles[] = { "Windowing Function" }; #ifdef DENOISE_TRY_ONE_SAMPLE gchar *fft_window_parms[4][1] = { {"Blackman"}, {"Hybrid Blackman-Full Pass"}, {"Hanning-overlap-add (Best)"}, {"Hanning-one-sample-shift (Experimental)"} #else gchar *fft_window_parms[3][1] = { {"Blackman"}, {"Hybrid Blackman-Full Pass"}, {"Hanning-overlap-add (Best)"} #endif }; GtkWidget *noise_method_window_list; gchar *noise_method_window_titles[] = { "Noise Suppression Method" }; gchar *noise_method_window_parms[6][1] = { {"Weiner"}, {"Power Spectral Subtraction"}, {"Ephraim-Malah 1984"}, {"Lorber & Hoeldrich (Best)"}, {"Wolfe & Godsill (Experimental)"}, {"Extremely Experimental"} }; load_denoise_preferences(); fft_window_list = gtk_clist_new_with_titles(1, fft_window_titles); gtk_clist_set_selection_mode(GTK_CLIST(fft_window_list), GTK_SELECTION_SINGLE); gtk_clist_append(GTK_CLIST(fft_window_list), fft_window_parms[0]); gtk_clist_append(GTK_CLIST(fft_window_list), fft_window_parms[1]); gtk_clist_append(GTK_CLIST(fft_window_list), fft_window_parms[2]); #ifdef DENOISE_TRY_ONE_SAMPLE gtk_clist_append(GTK_CLIST(fft_window_list), fft_window_parms[3]); #endif gtk_clist_select_row(GTK_CLIST(fft_window_list), denoise_prefs.window_type, 0); gtk_signal_connect(GTK_OBJECT(fft_window_list), "select_row", GTK_SIGNAL_FUNC(fft_window_select), NULL); window_type = denoise_prefs.window_type; gtk_widget_show(fft_window_list); noise_method_window_list = gtk_clist_new_with_titles(1, noise_method_window_titles); gtk_clist_set_selection_mode(GTK_CLIST(noise_method_window_list), GTK_SELECTION_SINGLE); gtk_clist_append(GTK_CLIST(noise_method_window_list), noise_method_window_parms[0]); gtk_clist_append(GTK_CLIST(noise_method_window_list), noise_method_window_parms[1]); gtk_clist_append(GTK_CLIST(noise_method_window_list), noise_method_window_parms[2]); gtk_clist_append(GTK_CLIST(noise_method_window_list), noise_method_window_parms[3]); gtk_clist_append(GTK_CLIST(noise_method_window_list), noise_method_window_parms[4]); gtk_clist_append(GTK_CLIST(noise_method_window_list), noise_method_window_parms[5]); gtk_clist_select_row(GTK_CLIST(noise_method_window_list), denoise_prefs.noise_suppression_method, 0); gtk_signal_connect(GTK_OBJECT(noise_method_window_list), "select_row", GTK_SIGNAL_FUNC(noise_method_window_select), NULL); noise_suppression_method = denoise_prefs.noise_suppression_method; gtk_widget_show(noise_method_window_list); dlg = gtk_dialog_new_with_buttons("Denoise preferences", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); dialog_table = gtk_table_new(9, 2, 0); gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 4); gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6); gtk_widget_show(dialog_table); fft_size_entry = add_number_entry_with_label_int(denoise_prefs.FFT_SIZE, "FFT_SIZE (4096 for 44.1kHz sample rate)", dialog_table, 0); amount_entry = add_number_entry_with_label_double(denoise_prefs.amount, "Reduction (0.0-1.0)", dialog_table, 1); smoothness_entry = add_number_entry_with_label_int(denoise_prefs.smoothness, "Smoothness for Blackman window (2-11)", dialog_table, 2); n_noise_entry = add_number_entry_with_label_int(denoise_prefs.n_noise_samples, "# noise samples (2-16)", dialog_table, 3); gamma_entry = add_number_entry_with_label_double(denoise_prefs.dn_gamma, "gamma -- for Lorber & Hoelrich or Ephraim-Malah, (0.9-1, try 0.98)", dialog_table, 4); freq_filter_entry = add_number_entry_with_label_int(denoise_prefs.freq_filter, "Apply freq filter (0,1)", dialog_table, 5); estimate_power_floor_entry = add_number_entry_with_label_int(denoise_prefs.estimate_power_floor, "Estimate power floor (0,1)", dialog_table, 6); min_sample_freq_entry = add_number_entry_with_label_int(denoise_prefs.min_sample_freq, "Minimum frequency to use in noise sample (Hz)", dialog_table, 7); max_sample_freq_entry = add_number_entry_with_label_int(denoise_prefs.max_sample_freq, "Maximum frequency to use in noise sample (Hz)", dialog_table, 8); /* combo_entry1 = gnome_number_entry_gtk_entry (GNOME_NUMBER_ENTRY (numberentry1)); */ /* gtk_widget_show (combo_entry1); */ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), fft_window_list, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), noise_method_window_list, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)); if (dres == 0) { int i; i = atoi(gtk_entry_get_text((GtkEntry *) fft_size_entry)); for (denoise_prefs.FFT_SIZE = 8; denoise_prefs.FFT_SIZE < i && denoise_prefs.FFT_SIZE < DENOISE_MAX_FFT; denoise_prefs.FFT_SIZE *= 2); denoise_prefs.amount = atof(gtk_entry_get_text((GtkEntry *) amount_entry)); denoise_prefs.smoothness = atoi(gtk_entry_get_text((GtkEntry *) smoothness_entry)); denoise_prefs.n_noise_samples = atoi(gtk_entry_get_text((GtkEntry *) n_noise_entry)); denoise_prefs.dn_gamma = atof(gtk_entry_get_text((GtkEntry *) gamma_entry)); denoise_prefs.noise_suppression_method = noise_suppression_method; denoise_prefs.window_type = window_type; denoise_prefs.freq_filter = atoi(gtk_entry_get_text((GtkEntry *) freq_filter_entry)); denoise_prefs.estimate_power_floor = atoi(gtk_entry_get_text((GtkEntry *) estimate_power_floor_entry)); denoise_prefs.min_sample_freq = atof(gtk_entry_get_text((GtkEntry *) min_sample_freq_entry)); denoise_prefs.max_sample_freq = atof(gtk_entry_get_text((GtkEntry *) max_sample_freq_entry)); save_denoise_preferences(); } gtk_widget_destroy(dlg) ; } gtk-wave-cleaner-0.22-04/reverb.c0000666000175000017500000001737013450764343017660 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* reverb.c */ #include #include #include #include "gwc.h" #include "tap_reverb_common.h" #include "tap_reverb.h" #include "tap_reverb_file_io.h" static char reverb_method_name[128] ; #define BUFSIZE 10000 //looks like confusion in the previous source. Should this default to -40.1? static gfloat wet_level = -10 ; //looks like confusion in the previous source. Should this default to -0.5? static gfloat dry_level = -1.0 ; static gfloat decay = 1500 ; void load_reverb_preferences(void) { GKeyFile *key_file = read_config(); // We should probably have a separate test for each preference... if (g_key_file_has_group(key_file, "reverb_params") == TRUE) { strcpy(reverb_method_name, g_key_file_get_string(key_file, "reverb_params", "reverb_method_name", NULL)); wet_level = g_key_file_get_double(key_file, "reverb_params", "wet_level", NULL); dry_level = g_key_file_get_double(key_file, "reverb_params", "dry_level", NULL); decay = g_key_file_get_double(key_file, "reverb_params", "decay", NULL); } else { // Not sure why this is set here rather than declared above like the other three preferences... strcpy(reverb_method_name, "Ambience (Thick) - HD") ; } g_key_file_free (key_file); } void save_reverb_preferences(void) { GKeyFile *key_file = read_config(); g_key_file_set_string(key_file, "reverb_params", "reverb_method_name", reverb_method_name); g_key_file_set_double(key_file, "reverb_params", "wet_level", wet_level); g_key_file_set_double(key_file, "reverb_params", "dry_level", dry_level); g_key_file_set_double(key_file, "reverb_params", "decay", decay); write_config(key_file); } void reverb_audio(struct sound_prefs *p, long first, long last, int channel_mask) { float left[BUFSIZE], right[BUFSIZE] ; reverb_audio_sample_t left_out[BUFSIZE], right_out[BUFSIZE] ; long current, i ; int loops = 0 ; current = first ; push_status_text("TAP Reverb audio") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; reverb_setup(p->rate, decay, wet_level, dry_level, reverb_method_name) ; { while(current <= last) { long n = MIN(last - current + 1, BUFSIZE) ; long tmplast = current + n - 1 ; gfloat p = (gfloat)(current-first)/(last-first+1) ; n = read_float_wavefile_data(left, right, current, tmplast) ; /* tap reverb is expecting reverb_audio_sample_t, which is a float */ reverb_process(n, left_out, left, right_out, right) ; update_progress_bar(p,PROGRESS_UPDATE_INTERVAL,FALSE) ; if(channel_mask & 0x01) { for(i = 0 ; i < n ; i++) left[i] = left_out[i] ; } if(channel_mask & 0x02) { for(i = 0 ; i < n ; i++) right[i] = right_out[i] ; } write_float_wavefile_data(left, right, current, tmplast) ; current += n ; if(last - current < 10) loops++ ; if(loops > 5) { warning("infinite loop in reverb_audio, programming error\n") ; } } resample_audio_data(p, first, last) ; save_sample_block_data(p) ; } update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; main_redraw(FALSE, TRUE) ; } /* If we come here, then the user has selected a row in the list. */ void reverb_selection_made( GtkWidget *clist, gint row, gint column, GdkEventButton *event, gpointer data ) { gchar *text; /* Get the text that is stored in the selected row and column * which was clicked in. We will receive it as a pointer in the * argument text. */ gtk_clist_get_text(GTK_CLIST(clist), row, column, &text); strcpy(reverb_method_name, text) ; return; } int reverb_dialog(struct sound_prefs current, struct view *v) { GtkWidget *dlg, *maxtext, *dialog_table, *settings_frame ; GtkWidget *wet_entry ; GtkWidget *dry_entry ; GtkWidget *decay_entry ; GtkWidget *reverb_method_window_list ; GtkWidget *scrolled_window ; gchar *reverb_method_window_titles[] = { "TAP Reverb Name" }; int dclose = 0 ; int row = 0 ; int dres ; char buf[200] ; dialog_table = gtk_table_new(5,2,0) ; gtk_table_set_row_spacings(GTK_TABLE(dialog_table), 4) ; gtk_table_set_col_spacings(GTK_TABLE(dialog_table), 6) ; gtk_widget_show (dialog_table); dlg = gtk_dialog_new_with_buttons("Reverb", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL, NULL); gtk_dialog_set_default_response (GTK_DIALOG(dlg), GTK_RESPONSE_OK); row++ ; load_reverb_preferences() ; wet_entry = add_number_entry_with_label_double(wet_level, "Wet (Db) -30 to 3", dialog_table, row++) ; dry_entry = add_number_entry_with_label_double(dry_level, "Dry (Db) -30 to 3", dialog_table, row++) ; decay_entry = add_number_entry_with_label_double(decay, "(ms) 0 to 2500", dialog_table, row++) ; reverb_method_window_list = gtk_clist_new_with_titles(1, reverb_method_window_titles); gtk_clist_set_selection_mode(GTK_CLIST(reverb_method_window_list), GTK_SELECTION_SINGLE); gtk_signal_connect(GTK_OBJECT(reverb_method_window_list), "select_row", GTK_SIGNAL_FUNC(reverb_selection_made), NULL); { REVTYPE *revitem = get_revroot() ; gchar * row_text[1] ; gchar buf[256] ; row_text[0] = buf ; while( (revitem = get_next_revtype(revitem)) != NULL) { int i, new_row ; for(i = 0 ; revitem->name[i] != '\0' ; i++) buf[i] = (gchar) revitem->name[i] ; buf[i] = '\0' ; new_row = gtk_clist_append(GTK_CLIST(reverb_method_window_list), row_text); if(!strcmp(reverb_method_name, revitem->name)) gtk_clist_select_row(GTK_CLIST(reverb_method_window_list), new_row, 0) ; } } gtk_widget_show(reverb_method_window_list); /* Create a scrolled window to pack the CList widget into */ scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); gtk_widget_show (scrolled_window); gtk_container_add(GTK_CONTAINER(scrolled_window), reverb_method_window_list); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dlg)->vbox), scrolled_window, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dlg)->vbox), dialog_table, TRUE, TRUE, 0); dres = gwc_dialog_run(GTK_DIALOG(dlg)) ; if(dres == 0) { int i ; wet_level = atoi(gtk_entry_get_text((GtkEntry *)wet_entry)) ; dry_level = atoi(gtk_entry_get_text((GtkEntry *)dry_entry)) ; decay = atoi(gtk_entry_get_text((GtkEntry *)decay_entry)) ; save_reverb_preferences() ; dclose = 1 ; } gtk_widget_destroy(dlg) ; if(dres == 0) return 1 ; return 0 ; } gtk-wave-cleaner-0.22-04/reverb_settings.h0000777000175000017500000003415213120075107021570 0ustar00alisteralister00000000000000char reverb_default_settings[] = "\ # DO NOT EDIT BY HAND!\n\ # This file is created and used by TAP Reverb Editor.\n\ \n\ REVTYPE\n\ AfterBurn\n\ COMBS\n\ 0.1015f 70.22f 0.4845f\n\ 0.1042f 80.76f 0.4000f\n\ 0.1108f 65.25f 0.4000f\n\ 0.1309f 80.00f 0.5342f\n\ 0.1386f 52.84f 0.4000f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0061f 65.00f\n\ 0.0059f 65.00f\n\ 0.0055f 65.00f\n\ 0.0101f 80.00f\n\ BANDPS_LO\n\ 400.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ AfterBurn (Long)\n\ COMBS\n\ 0.1077f 70.22f 0.4845f\n\ 0.1124f 80.76f 0.4000f\n\ 0.1185f 65.25f 0.4000f\n\ 0.1866f 80.00f 0.5342f\n\ 0.1943f 52.84f 0.4000f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0061f 65.00f\n\ 0.0059f 65.00f\n\ 0.0055f 65.00f\n\ 0.0101f 80.00f\n\ BANDPS_LO\n\ 400.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Ambience\n\ COMBS\n\ 0.0251f 64.80f 0.2026f\n\ 0.0306f 70.48f 0.2731f\n\ 0.0350f 67.40f 0.5727f\n\ 0.0405f 72.69f 0.3128f\n\ 0.0449f 61.23f 0.7225f\n\ 0.0515f 67.84f 0.6167f\n\ ALLPS\n\ 0.0056f 75.00f\n\ 0.0051f 90.00f\n\ 0.0048f 85.00f\n\ 0.0044f 70.00f\n\ BANDPS_LO\n\ 80.0f\n\ BANDPS_HI\n\ 15000.0f\n\ \n\ REVTYPE\n\ Ambience (Thick)\n\ COMBS\n\ 0.0251f 64.80f 0.2026f\n\ 0.0306f 70.48f 0.2731f\n\ 0.0350f 67.40f 0.5727f\n\ 0.0405f 72.69f 0.3128f\n\ 0.0449f 61.23f 0.7225f\n\ 0.0515f 67.84f 0.6167f\n\ ALLPS\n\ 0.0056f 75.00f\n\ 0.0051f 90.00f\n\ 0.0048f 85.00f\n\ 0.0044f 70.00f\n\ 0.0014f 45.51f\n\ 0.0015f 77.95f\n\ 0.0017f 65.47f\n\ 0.0019f 57.57f\n\ BANDPS_LO\n\ 80.0f\n\ BANDPS_HI\n\ 15000.0f\n\ \n\ REVTYPE\n\ Ambience (Thick) - HD\n\ COMBS\n\ 0.0251f 64.80f 0.2026f\n\ 0.0306f 70.48f 0.2731f\n\ 0.0350f 67.40f 0.5727f\n\ 0.0405f 72.69f 0.3128f\n\ 0.0449f 61.23f 0.7225f\n\ 0.0515f 67.84f 0.6167f\n\ 0.0800f 53.77f 0.7048f\n\ 0.0899f 45.48f 0.6960f\n\ ALLPS\n\ 0.0056f 75.00f\n\ 0.0051f 90.00f\n\ 0.0048f 85.00f\n\ 0.0044f 70.00f\n\ 0.0014f 45.51f\n\ 0.0015f 77.95f\n\ 0.0017f 65.47f\n\ 0.0019f 57.57f\n\ 0.0071f 60.00f\n\ 0.0111f 80.00f\n\ 0.0126f 70.00f\n\ BANDPS_LO\n\ 80.0f\n\ BANDPS_HI\n\ 15000.0f\n\ \n\ REVTYPE\n\ Cathedral\n\ COMBS\n\ 0.2236f 62.93f 0.3416f\n\ 0.2329f 75.14f 0.3602f\n\ 0.2390f 70.34f 0.2687f\n\ 0.2438f 82.99f 0.5093f\n\ 0.2499f 89.97f 0.2467f\n\ 0.2282f 60.75f 0.3416f\n\ 0.1392f 55.00f 0.3744f\n\ 0.1348f 75.00f 0.2467f\n\ ALLPS\n\ 0.0167f 75.00f\n\ 0.0163f 65.00f\n\ 0.0158f 85.00f\n\ 0.0155f 80.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 6500.0f\n\ \n\ REVTYPE\n\ Cathedral - HD\n\ COMBS\n\ 0.2236f 62.93f 0.3416f\n\ 0.2329f 75.14f 0.3602f\n\ 0.2390f 70.34f 0.2687f\n\ 0.2438f 82.99f 0.5093f\n\ 0.2499f 89.97f 0.2467f\n\ 0.2282f 60.75f 0.3416f\n\ 0.2352f 52.90f 0.3106f\n\ 0.1392f 55.00f 0.3744f\n\ 0.1469f 68.00f 0.5771f\n\ 0.1348f 75.00f 0.2467f\n\ ALLPS\n\ 0.0167f 75.00f\n\ 0.0163f 65.00f\n\ 0.0158f 85.00f\n\ 0.0155f 80.00f\n\ 0.0064f 85.00f\n\ 0.0068f 75.00f\n\ 0.0072f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 6500.0f\n\ \n\ REVTYPE\n\ Drum Chamber\n\ COMBS\n\ 0.0520f 70.22f 0.4720f\n\ 0.0598f 80.76f 0.4000f\n\ 0.0644f 65.25f 0.4000f\n\ 0.0737f 80.00f 0.6957f\n\ 0.0845f 52.84f 0.7205f\n\ ALLPS\n\ 0.0049f 67.11f\n\ 0.0069f 59.05f\n\ 0.0073f 87.59f\n\ 0.0079f 59.67f\n\ 0.0085f 65.87f\n\ 0.0095f 75.18f\n\ 0.0100f 71.46f\n\ BANDPS_LO\n\ 400.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Garage\n\ COMBS\n\ 0.0280f 82.20f 0.4720f\n\ 0.0303f 80.20f 0.5652f\n\ 0.0325f 77.30f 0.6211f\n\ 0.0389f 75.30f 0.5217f\n\ 0.0415f 59.67f 0.6522f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0061f 65.00f\n\ 0.0059f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Garage (Bright)\n\ COMBS\n\ 0.0280f 82.20f 0.4720f\n\ 0.0303f 80.20f 0.5652f\n\ 0.0325f 77.30f 0.6211f\n\ 0.0389f 75.30f 0.5217f\n\ 0.0415f 59.67f 0.6522f\n\ ALLPS\n\ 0.0067f 75.00f\n\ 0.0061f 65.00f\n\ 0.0059f 65.00f\n\ 0.0055f 65.00f\n\ 0.0071f 75.00f\n\ BANDPS_LO\n\ 200.0f\n\ BANDPS_HI\n\ 15000.0f\n\ \n\ REVTYPE\n\ Gymnasium\n\ COMBS\n\ 0.1015f 70.22f 0.4845f\n\ 0.1042f 80.76f 0.4000f\n\ 0.1108f 65.25f 0.4000f\n\ 0.1309f 80.00f 0.5342f\n\ 0.1386f 52.84f 0.4000f\n\ 0.0520f 72.08f 0.4000f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0061f 65.00f\n\ 0.0059f 65.00f\n\ 0.0055f 65.00f\n\ 0.0101f 80.00f\n\ BANDPS_LO\n\ 400.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Gymnasium (Bright)\n\ COMBS\n\ 0.0536f 82.20f 0.3416f\n\ 0.0629f 52.84f 0.3602f\n\ 0.0690f 77.30f 0.3168f\n\ 0.0738f 75.30f 0.5093f\n\ 0.0799f 59.67f 0.3106f\n\ 0.1634f 80.00f 0.5652f\n\ 0.1680f 80.00f 0.5714f\n\ ALLPS\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ 0.0063f 71.46f\n\ 0.0069f 80.00f\n\ BANDPS_LO\n\ 600.0f\n\ BANDPS_HI\n\ 18000.0f\n\ \n\ REVTYPE\n\ Gymnasium (Bright) - HD\n\ COMBS\n\ 0.0536f 82.20f 0.3416f\n\ 0.0629f 52.84f 0.3602f\n\ 0.0690f 77.30f 0.3168f\n\ 0.0738f 75.30f 0.5093f\n\ 0.0799f 59.67f 0.3106f\n\ 0.1634f 80.00f 0.5652f\n\ 0.1680f 80.00f 0.5714f\n\ ALLPS\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ 0.0063f 71.46f\n\ 0.0069f 80.00f\n\ 0.0121f 80.00f\n\ 0.0127f 66.49f\n\ 0.0137f 88.21f\n\ BANDPS_LO\n\ 600.0f\n\ BANDPS_HI\n\ 18000.0f\n\ \n\ REVTYPE\n\ Hall (Small)\n\ COMBS\n\ 0.0536f 82.20f 0.4783f\n\ 0.0629f 52.84f 0.4348f\n\ 0.0690f 77.30f 0.5000f\n\ 0.0738f 75.30f 0.4500f\n\ 0.0799f 59.67f 0.4500f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 8000.0f\n\ \n\ REVTYPE\n\ Hall (Medium)\n\ COMBS\n\ 0.0536f 82.20f 0.4000f\n\ 0.0629f 52.84f 0.4348f\n\ 0.0690f 77.30f 0.5000f\n\ 0.0738f 75.30f 0.4500f\n\ 0.0799f 59.67f 0.4500f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 8000.0f\n\ \n\ REVTYPE\n\ Hall (Large)\n\ COMBS\n\ 0.0586f 82.20f 0.4000f\n\ 0.0679f 52.84f 0.4348f\n\ 0.0740f 77.30f 0.5000f\n\ 0.0788f 75.30f 0.4500f\n\ 0.0849f 59.67f 0.4500f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 8000.0f\n\ \n\ REVTYPE\n\ Hall (Large) - HD\n\ COMBS\n\ 0.0586f 82.20f 0.4000f\n\ 0.0679f 52.84f 0.4348f\n\ 0.0740f 77.30f 0.5000f\n\ 0.0788f 75.30f 0.4500f\n\ 0.0849f 59.67f 0.4500f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ 0.0141f 80.00f\n\ 0.0133f 57.19f\n\ 0.0151f 65.25f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 8000.0f\n\ \n\ REVTYPE\n\ Plate (Small)\n\ COMBS\n\ 0.0506f 82.20f 0.3416f\n\ 0.0599f 52.84f 0.3602f\n\ 0.0660f 77.30f 0.3168f\n\ 0.0708f 75.30f 0.5093f\n\ 0.0769f 59.67f 0.3106f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 8000.0f\n\ \n\ REVTYPE\n\ Plate (Medium)\n\ COMBS\n\ 0.0536f 82.20f 0.3416f\n\ 0.0629f 52.84f 0.3602f\n\ 0.0690f 77.30f 0.3168f\n\ 0.0738f 75.30f 0.5093f\n\ 0.0799f 59.67f 0.3106f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 8000.0f\n\ \n\ REVTYPE\n\ Plate (Large)\n\ COMBS\n\ 0.0536f 82.20f 0.3416f\n\ 0.0629f 52.84f 0.3602f\n\ 0.0690f 77.30f 0.3168f\n\ 0.0738f 75.30f 0.5093f\n\ 0.0799f 59.67f 0.3106f\n\ 0.0582f 77.66f 0.3416f\n\ 0.0652f 68.35f 0.3106f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 8000.0f\n\ \n\ REVTYPE\n\ Plate (Large) - HD\n\ COMBS\n\ 0.0536f 82.20f 0.3416f\n\ 0.0629f 52.84f 0.3602f\n\ 0.0690f 77.30f 0.3168f\n\ 0.0738f 75.30f 0.5093f\n\ 0.0799f 59.67f 0.3106f\n\ 0.0582f 77.66f 0.3416f\n\ 0.0652f 68.35f 0.3106f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ 0.0126f 70.84f\n\ 0.0138f 86.35f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 8000.0f\n\ \n\ REVTYPE\n\ Pulse Chamber\n\ COMBS\n\ 0.0752f 61.53f 0.4000f\n\ 0.0536f 28.64f 0.4000f\n\ 0.0907f 85.11f 0.4000f\n\ 0.0660f 47.88f 0.4000f\n\ ALLPS\n\ 0.0039f 80.00f\n\ 0.0043f 70.84f\n\ 0.0045f 58.43f\n\ 0.0049f 43.53f\n\ BANDPS_LO\n\ 50.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Pulse Chamber (Reverse)\n\ COMBS\n\ 0.1742f 47.26f 0.4783f\n\ 0.1526f 23.06f 0.1863f\n\ 0.2021f 72.08f 0.4000f\n\ 0.2175f 90.07f 0.4000f\n\ ALLPS\n\ 0.0039f 80.00f\n\ 0.0043f 70.84f\n\ 0.0045f 58.43f\n\ 0.0049f 43.53f\n\ BANDPS_LO\n\ 50.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Resonator (96 ms)\n\ COMBS\n\ 0.0969f 52.22f 0.6149f\n\ 0.0984f 54.70f 0.6025f\n\ 0.1000f 80.00f 0.5217f\n\ 0.1015f 53.46f 0.2671f\n\ ALLPS\n\ 0.0017f 46.64f\n\ 0.0021f 47.88f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 13000.0f\n\ \n\ REVTYPE\n\ Resonator (152 ms)\n\ COMBS\n\ 0.1526f 52.22f 0.6149f\n\ 0.1541f 65.87f 0.6025f\n\ 0.1557f 80.00f 0.5217f\n\ 0.1572f 53.46f 0.2671f\n\ ALLPS\n\ 0.0075f 46.64f\n\ 0.0078f 47.88f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 13000.0f\n\ \n\ REVTYPE\n\ Resonator (208 ms)\n\ COMBS\n\ 0.2082f 52.22f 0.6149f\n\ 0.2098f 54.70f 0.6025f\n\ 0.2113f 80.00f 0.5217f\n\ 0.2129f 53.46f 0.2671f\n\ ALLPS\n\ 0.0075f 46.64f\n\ 0.0078f 47.88f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 13000.0f\n\ \n\ REVTYPE\n\ Room (Small)\n\ COMBS\n\ 0.0536f 82.20f 0.4000f\n\ 0.0629f 75.80f 0.5901f\n\ 0.0690f 77.30f 0.5000f\n\ 0.0738f 75.30f 0.4500f\n\ 0.0799f 59.67f 0.4500f\n\ 0.1170f 74.56f 0.4783f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 13000.0f\n\ \n\ REVTYPE\n\ Room (Medium)\n\ COMBS\n\ 0.0536f 82.20f 0.4000f\n\ 0.0629f 75.80f 0.5901f\n\ 0.0690f 77.30f 0.5000f\n\ 0.0738f 75.30f 0.4500f\n\ 0.0799f 59.67f 0.4500f\n\ 0.1727f 74.56f 0.5590f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 13000.0f\n\ \n\ REVTYPE\n\ Room (Large)\n\ COMBS\n\ 0.0814f 82.20f 0.4000f\n\ 0.0892f 75.80f 0.5901f\n\ 0.0953f 77.30f 0.5000f\n\ 0.1046f 75.30f 0.5714f\n\ 0.1108f 59.67f 0.4500f\n\ 0.1912f 39.81f 0.6832f\n\ ALLPS\n\ 0.0073f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 13000.0f\n\ \n\ REVTYPE\n\ Room (Large) - HD\n\ COMBS\n\ 0.0814f 82.20f 0.4000f\n\ 0.0892f 75.80f 0.5901f\n\ 0.0953f 77.30f 0.5000f\n\ 0.1046f 75.30f 0.5714f\n\ 0.1108f 59.67f 0.4500f\n\ 0.1912f 39.81f 0.6832f\n\ ALLPS\n\ 0.0073f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ 0.0164f 66.49f\n\ 0.0181f 56.57f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 13000.0f\n\ \n\ REVTYPE\n\ Slap Chamber\n\ COMBS\n\ 0.1170f 82.20f 0.5466f\n\ 0.1232f 75.18f 0.4907f\n\ 0.1309f 69.60f 0.6335f\n\ 0.1417f 49.74f 0.6957f\n\ 0.1526f 59.67f 0.5528f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 1000.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Slap Chamber - HD\n\ COMBS\n\ 0.1170f 82.20f 0.5466f\n\ 0.1232f 75.18f 0.4907f\n\ 0.1309f 69.60f 0.6335f\n\ 0.1417f 49.74f 0.6957f\n\ 0.1526f 59.67f 0.5528f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ 0.0143f 56.57f\n\ 0.0153f 66.49f\n\ BANDPS_LO\n\ 1000.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Slap Chamber (Bright)\n\ COMBS\n\ 0.1170f 82.20f 0.6398f\n\ 0.1232f 75.18f 0.7453f\n\ 0.1309f 69.60f 0.6398f\n\ 0.1417f 49.74f 0.6957f\n\ 0.1526f 59.67f 0.7205f\n\ 0.1634f 84.49f 0.7453f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 2000.0f\n\ BANDPS_HI\n\ 15000.0f\n\ \n\ REVTYPE\n\ Slap Chamber (Bright) - HD\n\ COMBS\n\ 0.1170f 82.20f 0.6398f\n\ 0.1232f 75.18f 0.7453f\n\ 0.1309f 69.60f 0.6398f\n\ 0.1417f 49.74f 0.6957f\n\ 0.1526f 59.67f 0.7205f\n\ 0.1634f 84.49f 0.7453f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ 0.0128f 80.00f\n\ 0.0136f 88.83f\n\ BANDPS_LO\n\ 2000.0f\n\ BANDPS_HI\n\ 15000.0f\n\ \n\ REVTYPE\n\ Smooth Hall (Small)\n\ COMBS\n\ 0.0506f 82.20f 0.6832f\n\ 0.0599f 73.94f 0.6832f\n\ 0.0660f 61.53f 0.7453f\n\ 0.0708f 75.30f 0.7702f\n\ 0.0769f 59.67f 0.8012f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 1000.0f\n\ BANDPS_HI\n\ 7000.0f\n\ \n\ REVTYPE\n\ Smooth Hall (Medium)\n\ COMBS\n\ 0.0536f 82.20f 0.6832f\n\ 0.0629f 73.94f 0.6832f\n\ 0.0690f 61.53f 0.7453f\n\ 0.0738f 75.30f 0.7702f\n\ 0.0799f 59.67f 0.8012f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 1000.0f\n\ BANDPS_HI\n\ 7000.0f\n\ \n\ REVTYPE\n\ Smooth Hall (Large)\n\ COMBS\n\ 0.0586f 82.20f 0.6832f\n\ 0.0679f 73.94f 0.6832f\n\ 0.0740f 61.53f 0.7453f\n\ 0.0788f 75.30f 0.7702f\n\ 0.0849f 59.67f 0.8012f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 1000.0f\n\ BANDPS_HI\n\ 7000.0f\n\ \n\ REVTYPE\n\ Smooth Hall (Large) - HD\n\ COMBS\n\ 0.0586f 82.20f 0.6832f\n\ 0.0679f 73.94f 0.6832f\n\ 0.0740f 61.53f 0.7453f\n\ 0.0788f 75.30f 0.7702f\n\ 0.0849f 59.67f 0.8012f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0063f 65.00f\n\ 0.0058f 65.00f\n\ 0.0055f 65.00f\n\ 0.0122f 80.00f\n\ 0.0138f 65.25f\n\ 0.0143f 75.00f\n\ BANDPS_LO\n\ 1000.0f\n\ BANDPS_HI\n\ 7000.0f\n\ \n\ REVTYPE\n\ Vocal Plate\n\ COMBS\n\ 0.0505f 70.22f 0.4720f\n\ 0.0582f 80.76f 0.4000f\n\ 0.0629f 65.25f 0.4000f\n\ 0.0892f 80.00f 0.6957f\n\ 0.0953f 52.84f 0.7205f\n\ ALLPS\n\ 0.0044f 65.00f\n\ 0.0037f 67.11f\n\ 0.0057f 80.00f\n\ 0.0060f 56.57f\n\ BANDPS_LO\n\ 400.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Vocal Plate - HD\n\ COMBS\n\ 0.0505f 70.22f 0.4720f\n\ 0.0582f 80.76f 0.4000f\n\ 0.0629f 65.25f 0.4000f\n\ 0.0892f 80.00f 0.6957f\n\ 0.0953f 52.84f 0.7205f\n\ ALLPS\n\ 0.0044f 65.00f\n\ 0.0037f 67.11f\n\ 0.0057f 80.00f\n\ 0.0060f 56.57f\n\ 0.0142f 80.00f\n\ 0.0151f 59.67f\n\ BANDPS_LO\n\ 400.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Warble Chamber\n\ COMBS\n\ 0.2051f 52.84f 0.7826f\n\ 0.2082f 68.35f 0.7019f\n\ 0.2113f 80.00f 0.6832f\n\ 0.2206f 83.25f 0.7081f\n\ 0.2237f 67.73f 0.5280f\n\ ALLPS\n\ 0.0067f 65.00f\n\ 0.0061f 65.00f\n\ 0.0059f 65.00f\n\ 0.0055f 65.00f\n\ BANDPS_LO\n\ 400.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Warehouse\n\ COMBS\n\ 0.0280f 82.20f 0.4720f\n\ 0.0304f 80.20f 0.5652f\n\ 0.0329f 77.30f 0.6211f\n\ 0.0389f 75.30f 0.5217f\n\ 0.0415f 59.67f 0.6522f\n\ 0.0768f 80.00f 0.7702f\n\ ALLPS\n\ 0.0057f 65.00f\n\ 0.0062f 65.00f\n\ 0.0066f 77.04f\n\ 0.0050f 65.00f\n\ 0.0038f 56.57f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n\ REVTYPE\n\ Warehouse - HD\n\ COMBS\n\ 0.0280f 82.20f 0.4720f\n\ 0.0304f 80.20f 0.5652f\n\ 0.0329f 77.30f 0.6211f\n\ 0.0389f 75.30f 0.5217f\n\ 0.0415f 59.67f 0.6522f\n\ 0.0768f 80.00f 0.7702f\n\ ALLPS\n\ 0.0057f 65.00f\n\ 0.0062f 65.00f\n\ 0.0137f 77.04f\n\ 0.0050f 65.00f\n\ 0.0038f 56.57f\n\ 0.0147f 60.91f\n\ 0.0164f 52.84f\n\ BANDPS_LO\n\ 100.0f\n\ BANDPS_HI\n\ 10000.0f\n\ \n" ; gtk-wave-cleaner-0.22-04/sample_block.c0000777000175000017500000002507213120075107021012 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* FILE - sample_block.c PURPOSE - handle functions related to the sample block facility which speeds audio data display */ #include #include #include #include "gwc.h" #include #include #include #include struct sample_block *sample_buffer = NULL ; static size_t sb_size ; static long n_blocks ; extern gchar wave_filename[255] ; extern long n_markers, markers[] ; extern long num_song_markers, song_markers[] ; extern long cdtext_length; extern char *cdtext_data; void save_sample_block_data(struct sound_prefs *p) { char buf[1000] ; char l ; int fd ; sprintf(buf, "%s.gwc", wave_filename) ; fd = open(buf, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR|S_IWUSR) ; sprintf(buf, "gwc %d %d", GWC_VERSION_MAJOR, GWC_VERSION_MINOR) ; l = (char)strlen(buf) ; write(fd, (void *)&l, 1) ; write(fd, (void *)buf, l) ; sprintf(buf, "%d %ld %d", p->n_channels,p->n_samples,p->rate) ; l = (char)strlen(buf) ; write(fd, (void *)&l, 1) ; write(fd, (void *)buf, l) ; n_blocks = p->n_samples / SBW ; n_blocks += (p->n_samples - n_blocks*SBW > 0 ? 1 : 0) ; sb_size = n_blocks*sizeof(struct sample_block) ; write(fd, (void *)sample_buffer, sb_size) ; write(fd, (void *)&n_markers, sizeof(long)) ; write(fd, (void *)markers, sizeof(long)*n_markers) ; write(fd, (void *)&num_song_markers, sizeof(long)) ; write(fd, (void *)song_markers, sizeof(long)*num_song_markers) ; write(fd, (void *)&cdtext_length, sizeof(long)) ; write(fd, (void *)cdtext_data, cdtext_length) ; close(fd) ; } int load_sample_block_data(struct sound_prefs *p) { char buf[1000] ; int fd ; char l ; sprintf(buf, "%s.gwc", wave_filename) ; fd = open(buf, O_RDONLY) ; if(fd != -1) { int n_channels, rate ; long n_samples ; int v_maj, v_min ; read(fd, (void *)&l, 1) ; read(fd, (void *)buf, l) ; buf[(int)l] = '\0' ; if(buf[0] != 'g' || buf[1] != 'w' || buf[2] != 'c') { close(fd) ; return 0 ; } sscanf(buf, "%*s%d%d", &v_maj,&v_min) ; if(v_maj >= 0 && v_min >= 17) { /* life is good, no need to recreate block data file */ } else { /* Need to recreate block data file, this one is from an older version */ close(fd) ; return 0 ; } read(fd, (void *)&l, 1) ; read(fd, (void *)buf, l) ; buf[(int)l] = '\0' ; sscanf(buf, "%d%ld%d", &n_channels,&n_samples,&rate) ; if(n_channels != p->n_channels || n_samples != p->n_samples || rate != p->rate) { /* something has changed, we must rebuild the sample block data */ printf("n_chan wav:%d gwc:%d\n", p->n_channels, n_channels) ; printf("rate wav:%d gwc:%d\n", p->rate, rate) ; printf("n_samples wav:%ld gwc:%ld\n", p->n_samples, n_samples) ; close(fd) ; return 0 ; } n_blocks = p->n_samples / SBW ; n_blocks += (p->n_samples - n_blocks*SBW > 0 ? 1 : 0) ; sb_size = n_blocks*sizeof(struct sample_block) ; read(fd, (void *)sample_buffer, sb_size) ; if(v_maj >= 0 && v_min >= 18) { /* int i ; */ read(fd, (void *)&n_markers, sizeof(long)) ; read(fd, (void *)markers, sizeof(long)*n_markers) ; /* for(i = 0 ; i < n_markers ; i++) */ /* g_print("marker:%ld\n", markers[i]) ; */ read(fd, (void *)&num_song_markers, sizeof(long)) ; read(fd, (void *)song_markers, sizeof(long)*num_song_markers) ; read(fd, (void *)&cdtext_length, sizeof(long)) ; if (cdtext_length > 0) { if (cdtext_data != NULL) { free(cdtext_data) ; } cdtext_data = calloc(cdtext_length, 1); read(fd, (void *)cdtext_data, cdtext_length) ; } else { cdtext_data = NULL; } } else { n_markers = 0 ; } close(fd) ; return 1 ; } else { return 0 ; } } /* void sum_sample_block(struct sample_block *sb, double left[], double right[], long n) */ void sum_sample_block(struct sample_block *sb, fftw_real left[], fftw_real right[], long n) { long i ; double sum_x2[2] ; sb->n_samples = n ; sum_x2[0] = 0.0 ; sum_x2[1] = 0.0 ; sb->max_value[0] = 0.0 ; sb->max_value[1] = 0.0 ; for(i = 0 ; i < n ; i++) { if(fabs(left[i]) > sb->max_value[0]) sb->max_value[0] = fabs(left[i]) ; if(fabs(right[i]) > sb->max_value[1]) sb->max_value[1] = fabs(right[i]) ; sum_x2[0] += (double)left[i]*(double)left[i] ; sum_x2[1] += (double)right[i]*(double)right[i] ; } sb->rms[0] = sqrt(sum_x2[0]/(n+1.e-30)) ; sb->rms[1] = sqrt(sum_x2[1]/(n+1.e-30)) ; } void stat_sample_block(struct sample_block *sb, struct sound_prefs *p, long block_number) { long first = block_number*SBW ; long last = first + (SBW-1) ; long n ; /* double left[SBW], right[SBW] ; */ fftw_real left[SBW], right[SBW] ; if(last > p->n_samples - 1) last = p->n_samples - 1 ; n = read_fft_real_wavefile_data(left, right, first, last) ; sum_sample_block(sb, left, right, n) ; } void resample_audio_data(struct sound_prefs *p, long first, long last) { long first_block = first/SBW ; long last_block = last/SBW ; long current_block ; #ifndef TRUNCATE_OLD resize_sample_buffer(p); #endif for(current_block = first_block ; current_block <= last_block ; current_block++) { struct sample_block *sb = &sample_buffer[current_block] ; stat_sample_block(sb, p, current_block) ; } } void rescan_sample_buffer(struct sound_prefs *p) { long current_block ; #ifndef TRUNCATE_OLD resize_sample_buffer(p); #endif n_blocks = p->n_samples / SBW ; n_blocks += (p->n_samples - n_blocks*SBW > 0 ? 1 : 0) ; push_status_text("Scanning audio for display information") ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; for(current_block = 0 ; current_block < n_blocks ; current_block++) { struct sample_block *sb = &sample_buffer[current_block] ; update_progress_bar((gfloat)current_block/(gfloat)n_blocks,PROGRESS_UPDATE_INTERVAL,FALSE) ; stat_sample_block(sb, p, current_block) ; } save_sample_block_data(p) ; update_progress_bar(0.0,PROGRESS_UPDATE_INTERVAL,TRUE) ; pop_status_text() ; } #ifndef TRUNCATE_OLD void resize_sample_buffer(struct sound_prefs *p) { n_blocks = p->n_samples / SBW ; n_blocks += (p->n_samples - n_blocks*SBW > 0 ? 1 : 0) ; if(sample_buffer == NULL) { sample_buffer = (struct sample_block *) calloc(n_blocks, sizeof(struct sample_block)) ; sb_size = n_blocks*sizeof(struct sample_block) ; } else { size_t new_size = n_blocks*sizeof(struct sample_block); if (new_size > sb_size) { struct sample_block *new_buffer = realloc(sample_buffer, new_size); if (new_buffer != NULL) { /* like calloc: set new buffer to '0' */ memset((char*)new_buffer+sb_size, 0, new_size-sb_size); sample_buffer = new_buffer; sb_size = new_size; } } } } #endif void fill_sample_buffer(struct sound_prefs *p) { n_blocks = p->n_samples / SBW ; n_blocks += (p->n_samples - n_blocks*SBW > 0 ? 1 : 0) ; if(sample_buffer != NULL) free(sample_buffer) ; sample_buffer = (struct sample_block *) calloc(n_blocks, sizeof(struct sample_block)) ; sb_size = n_blocks*sizeof(struct sample_block) ; if(!load_sample_block_data(p)) { g_print("Building display information, n_samples=%d, hang on...\n", p->n_samples) ; push_status_text("Loading audio information") ; if(load_sample_block_data(p) == 0) { rescan_sample_buffer(p) ; } pop_status_text() ; } p->sample_buffer_exists = TRUE ; } int get_sample_buffer(struct sample_block **result) { *result = sample_buffer; return n_blocks ; } void get_sample_stats(struct sample_display_block *result, long first, long last, double blocks_per_pixel) { long first_block = first/SBW ; long last_block = last/SBW ; long i ; double sum_wgts = 0.0 ; result->n_samples = 0 ; result->rms[0] = 0.0 ; result->rms[1] = 0.0 ; result->max_value[0] = 0.0 ; result->max_value[1] = 0.0 ; if(blocks_per_pixel > 1) { for(i = first_block ; i <= last_block; i++) { struct sample_block *sb = &sample_buffer[i] ; long n_in_block; if (i != first_block && i != last_block) { long first_sample = MAX(first, i*SBW) ; long last_sample = MIN(last, (i+1)*SBW-1) ; double p; n_in_block = last_sample - first_sample + 1 ; p = (double)(n_in_block) / (double)sb->n_samples ; result->rms[0] += p*sb->rms[0] ; result->rms[1] += p*sb->rms[1] ; sum_wgts += p ; } else { n_in_block = SBW ; result->rms[0] += sb->rms[0] ; result->rms[1] += sb->rms[1] ; sum_wgts += 1.0 ; } if(sb->max_value[0] > result->max_value[0]) result->max_value[0] = sb->max_value[0] ; if(sb->max_value[1] > result->max_value[1]) result->max_value[1] = sb->max_value[1] ; result->n_samples += n_in_block ; } result->rms[0] /= sum_wgts+1.e-30 ; result->rms[1] /= sum_wgts+1.e-30 ; } else { /* double left[SBW], right[SBW] ; */ fftw_real left[SBW], right[SBW] ; int n = read_fft_real_wavefile_data(left, right, first, last) ; result->n_samples = n ; for(i = 0 ; i < n ; i++) { if(fabs(left[i]) > result->max_value[0]) result->max_value[0] = fabs(left[i]) ; if(fabs(right[i]) > result->max_value[1]) result->max_value[1] = fabs(right[i]) ; result->rms[0] += left[i]*left[i] ; result->rms[1] += right[i]*right[i] ; sum_wgts += 1.0 ; } result->rms[0] = sqrt(result->rms[0]/(sum_wgts+1.e-30)) ; result->rms[1] = sqrt(result->rms[1]/(sum_wgts+1.e-30)) ; } } gtk-wave-cleaner-0.22-04/soundfile.c0000777000175000017500000003660213120075107020350 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2003 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* soundfile.c some functions to manipulate the sound file ...frank 4.10.03 */ #include #include #include #include "soundfile.h" #include "gwc.h" extern SNDFILE *sndfile; extern SF_INFO sfinfo; static void perr(char *text) { int err = sf_error(sndfile); puts("##########################################################"); puts(text); puts(sf_error_number(err)); } long soundfile_count_samples_in_file(char *filename) { sf_count_t sample_count = -1; SNDFILE *sndfile_new; SF_INFO sfinfo_new = sfinfo; sfinfo_new.format = 0; sndfile_new = sf_open(filename, SFM_READ, &sfinfo_new); if (sndfile_new != NULL) { sample_count = sf_seek(sndfile_new, 0, SEEK_END); sf_close(sndfile_new); } /* printf("soundfile_count_samples_in_file: %lld\n", sample_count); */ return sample_count; } int soundfile_save_file(char *filename, long lpos, long lsample_count, int status_info) { sf_count_t pos = lpos; sf_count_t sample_count = lsample_count; int rc = -1; if (sf_seek(sndfile, pos, SEEK_SET|SFM_READ) == pos) { int channels = sfinfo.channels; sf_count_t buffer_size = SBW*1000; int *buffer = calloc(channels*buffer_size, sizeof(int)); if (buffer != NULL) { SNDFILE *sndfile_new; SF_INFO sfinfo_new = sfinfo; sndfile_new = sf_open(filename, SFM_WRITE, &sfinfo_new); if (sndfile_new != NULL) { sf_count_t processed = 0; sf_count_t read_size; while (processed < sample_count) { if (buffer_size > sample_count - processed) buffer_size = sample_count - processed; read_size = sf_readf_int(sndfile, buffer, buffer_size); if (read_size > 0) sf_writef_int(sndfile_new, buffer, read_size); processed += buffer_size; if (status_info) update_progress_bar((gfloat)processed/sample_count, PROGRESS_UPDATE_INTERVAL, FALSE); } sf_close(sndfile_new); rc = 0; } free(buffer); } } return rc; } int soundfile_load_file(char *filename, long lpos, long lsample_count, int status_info) { sf_count_t pos = lpos; sf_count_t sample_count = lsample_count; int rc = -1; if (sf_seek(sndfile, pos, SEEK_SET|SFM_WRITE) == pos) { int channels = sfinfo.channels; sf_count_t buffer_size = SBW*1000; int *buffer = calloc(channels*buffer_size, sizeof(int)); if (buffer != NULL) { SNDFILE *sndfile_new; SF_INFO sfinfo_new = sfinfo; sfinfo_new.format = 0; sndfile_new = sf_open(filename, SFM_READ, &sfinfo_new); if (sndfile_new != NULL) { sf_count_t processed = 0; sf_count_t read_size; if (sample_count > sfinfo_new.frames) sample_count = sfinfo_new.frames; while (processed < sample_count) { if (buffer_size > sample_count - processed) buffer_size = sample_count - processed; read_size = sf_readf_int(sndfile_new, buffer, buffer_size); if (read_size > 0) sf_writef_int(sndfile, buffer, read_size); processed += buffer_size; if (status_info) update_progress_bar((gfloat)processed/sample_count, PROGRESS_UPDATE_INTERVAL, FALSE); } sf_close(sndfile_new); rc = 0; /* remove(filename); */ } free(buffer); } } return rc; } static void adjust_all_marker_positions(long start, long delta) { adjust_song_marker_positions(start, delta); adjust_marker_positions(start, delta); } long soundfile_count_samples(void) { sf_count_t curr = sf_seek(sndfile, 0, SEEK_SET|SFM_READ); sf_count_t rc = sf_seek(sndfile, 0, SEEK_END|SFM_READ); sf_seek(sndfile, curr, SEEK_SET|SFM_READ); return rc; } /* simply write 'sample_count' silence-samples at 'pos' * (overwrite existing samples) */ static int write_silence(sf_count_t pos, sf_count_t sample_count) { int rc = 0; int channels = sfinfo.channels; sf_count_t buffer_size = SBW*100; int *buffer = calloc(channels*buffer_size, sizeof(int)); /* printf("write_silence: pos=%lld, sample_count=%lld\n", */ /* pos, sample_count); */ if (buffer == NULL) { warning("Out of Memory"); return -1; } /* go to position ... */ if (sf_seek(sndfile, pos, SEEK_SET|SFM_WRITE) < 0) { perr("write_silence: sf_seek write pointer"); warning("Libsndfile reports write pointer seek error in audio file"); rc = -1; } else { /* ... and write sample_count silence */ while (sample_count > 0) { if (sample_count - buffer_size < 0) buffer_size = sample_count; if (sf_writef_int(sndfile, buffer, buffer_size) != buffer_size) { perr("write_silence: sf_writef_int"); warning("Libsndfile reports write error in audio file"); rc = -1; break; } sample_count -= buffer_size; } } free(buffer); /* printf("write_silence: rc=%d\n", rc); */ return rc; } /* append 'sample_count' samples and shift all samples from 'first_pos' * to end of file (this creates 'sample_count' samples at 'first_pos') */ int soundfile_shift_samples_right(long lfirst_pos, long lsample_count, int status_info) { sf_count_t first_pos = lfirst_pos; sf_count_t sample_count = lsample_count; sf_count_t end_pos = sf_seek(sndfile, 0, SEEK_END|SFM_READ); if (sample_count <= 0) { puts("soundfile_shift_samples_right: no samples to move"); return 0; } /* printf("soundfile_shift_samples_right: " */ /* "first_pos=%lld, shift=%lld, samples in file=%lld\n", */ /* first_pos, sample_count, end_pos); */ if (first_pos < end_pos) { sf_count_t processed = 0; sf_count_t read_pos, write_pos; int channels = sfinfo.channels; #define TMPBUFSIZE (4*SBW*1000) int buffer[TMPBUFSIZE]; sf_count_t buffer_size = TMPBUFSIZE/channels; /* go to end position and append enough space for the new data */ if (write_silence(end_pos, sample_count) < 0) { return -1; } /* loop reading-writing from end */ write_pos = end_pos + sample_count; read_pos = end_pos; while (read_pos > first_pos) { if (buffer_size > read_pos - first_pos) buffer_size = read_pos - first_pos; write_pos -= buffer_size; read_pos -= buffer_size; /* printf("soundfile_shift_samples_right: " */ /* "read_pos=%lld, write_pos=%lld, diff=%lld, buffer_size=%lld\n", */ /* read_pos, write_pos, write_pos-read_pos, buffer_size); */ /* start position for reading */ if (sf_seek(sndfile, read_pos, SEEK_SET|SFM_READ) < 0) { perr("soundfile_shift_samples_right: sf_seek read pointer"); warning("Libsndfile reports read pointer seek error in audio file"); return -1; } if (sf_readf_int(sndfile, buffer, buffer_size) != buffer_size) { perr("soundfile_shift_samples_right: sf_readf_int"); warning("Libsndfile reports read error in audio file"); return -1; } /* start position for writing */ if (sf_seek(sndfile, write_pos, SEEK_SET|SFM_WRITE) < 0) { perr("soundfile_shift_samples_right: sf_seek write pointer"); warning("Libsndfile reports write pointer seek error in audio file"); return -1; } if (sf_writef_int(sndfile, buffer, buffer_size) != buffer_size) { perr("soundfile_shift_samples_right: sf_writef_int"); warning("Libsndfile reports write error in audio file"); return -1; } processed += buffer_size; if (status_info) update_progress_bar((gfloat)processed/(end_pos-first_pos), PROGRESS_UPDATE_INTERVAL, FALSE); /* printf("soundfile_shift_samples_right: processed=%lld (%f.2)\n", */ /* processed, (gfloat)processed/(end_pos-first_pos)); */ } } /* printf("soundfile_shift_samples_right: samples in file=%lld\n", */ /* sf_seek(sndfile, 0, SEEK_END|SFM_READ)); */ adjust_all_marker_positions(first_pos, sample_count); return 0; } /* shift all samples from 'first_pos' to begin of file * (this removes 'sample_count' samples at end of file) */ int soundfile_shift_samples_left(long lfirst_pos, long lsample_count, int status_info) { /* if 'last_pos' is equal 'end_pos' simply truncate the end * else move sample i from 'last_pos' to the 'first_pos' position * (for all i between 'last_pos' and end of file) * and then truncate 'last_pos - first_pos' samples at the end. */ sf_count_t first_pos = lfirst_pos; sf_count_t sample_count = lsample_count; sf_count_t end_pos = sf_seek(sndfile, 0, SEEK_END|SFM_READ); sf_count_t last_pos = first_pos + sample_count; if (sample_count <= 0) { puts("soundfile_shift_samples_left: no samples to move"); return 0; } /* printf("soundfile_shift_samples_left: " */ /* "first_pos=%lld, shift=%lld, samples in file=%lld\n", */ /* first_pos, sample_count, end_pos); */ if (last_pos < end_pos) { sf_count_t processed = 0; sf_count_t buffer_size; int channels = sfinfo.channels; #define TMPBUFSIZE (4*SBW*1000) int buffer[TMPBUFSIZE]; /* start position for writing */ if (sf_seek(sndfile, first_pos, SEEK_SET|SFM_WRITE) < 0) { perr("soundfile_shift_samples_left: sf_seek write pointer"); warning("Libsndfile reports write pointer seek error in audio file"); return -1; } /* start position for reading */ if (sf_seek(sndfile, last_pos, SEEK_SET|SFM_READ) < 0) { perr("soundfile_shift_samples_left: sf_seek read pointer"); warning("Libsndfile reports read pointer seek error in audio file"); return -1; } /* loop to end of file */ buffer_size = TMPBUFSIZE/channels; while ((buffer_size = sf_readf_int(sndfile, buffer, buffer_size)) > 0) { if (sf_writef_int(sndfile, buffer, buffer_size) != buffer_size) { perr("soundfile_shift_samples_left: sf_writef_int"); warning("Libsndfile reports write error in audio file"); return -1; } processed += buffer_size; if (status_info) update_progress_bar((gfloat)processed/(end_pos-first_pos-sample_count), PROGRESS_UPDATE_INTERVAL, FALSE); /* printf("soundfile_shift_samples_left: processed=%lld (%f.2)\n", */ /* processed, (gfloat)processed/(end_pos-first_pos-sample_count)); */ } } /* truncate file size for '-sample_count' samples */ end_pos -= sample_count; if (sf_command(sndfile, SFC_FILE_TRUNCATE, &end_pos, sizeof(end_pos))) { perr("soundfile_shift_samples_left: sf_command"); warning("Libsndfile reports truncation of audio file failed"); return -1; } /* printf("soundfile_shift_samples_left: samples in file=%lld\n", */ /* sf_seek(sndfile, 0, SEEK_END|SFM_READ)); */ adjust_all_marker_positions(first_pos, -sample_count); return 0; } /* insert 'sample_count' samples at sample 'insert_pos' * to the soundfile. * 'insert_pos' == -1 means append to end of file. */ int soundfile_insert_samples(long linsert_pos, long lsample_count, int *sample_data, int status_info) { sf_count_t insert_pos = linsert_pos; sf_count_t sample_count = lsample_count; sf_count_t end_pos = sf_seek(sndfile, 0, SEEK_END|SFM_READ); if (insert_pos < 0 || insert_pos > end_pos) insert_pos = end_pos; if (soundfile_shift_samples_right(insert_pos, sample_count, status_info) < 0) { return -1; } /* go to insert position 'insert_pos'... */ if (sf_seek(sndfile, insert_pos, SEEK_SET|SFM_WRITE) < 0) { perr("soundfile_insert_samples: sf_seek write pointer"); warning("Libsndfile reports write pointer seek error in audio file"); return -1; } /* ...and insert new data */ if (sf_writef_int(sndfile, sample_data, sample_count) != sample_count) { perr("soundfile_insert_samples: append with sf_writef_int"); warning("Libsndfile reports write error in audio file"); return -1; } return 0; } int soundfile_insert_silence(long linsert_pos, long lsample_count, int status_info) { sf_count_t insert_pos = linsert_pos; sf_count_t sample_count = lsample_count; sf_count_t end_pos = sf_seek(sndfile, 0, SEEK_END|SFM_READ); int rc = 0; if (insert_pos < 0 || insert_pos > end_pos) insert_pos = end_pos; if (soundfile_shift_samples_right(insert_pos, sample_count, status_info) < 0) { rc = -1; } else if (write_silence(insert_pos, sample_count) < 0) { rc = -1; } return rc; } /* remove 'sample_count' samples from 'first_pos' sample. * 'sample_count' == -1 means to end of file. */ int soundfile_remove_samples(long lfirst_pos, long lsample_count, int status_info) { sf_count_t first_pos = lfirst_pos; sf_count_t sample_count = lsample_count; sf_count_t end_pos = sf_seek(sndfile, 0, SEEK_END|SFM_READ); if (first_pos < 0 || first_pos > end_pos) first_pos = end_pos; if (sample_count < 0 || first_pos + sample_count - 1 > end_pos) sample_count = end_pos - first_pos + 1; return soundfile_shift_samples_left(first_pos, sample_count, status_info); } gtk-wave-cleaner-0.22-04/soundfile.h0000777000175000017500000000362013120075107020347 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2003 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* soundfile.h some functions to manipulate the sound file ...frank 4.10.03 */ #ifndef SOUNDFILE_H #define SOUNDFILE_H /* functions for soundfile file */ long soundfile_count_samples_in_file(char *filename); int soundfile_save_file(char *filename, long pos, long sample_count, int status_info); int soundfile_load_file(char *filename, long pos, long sample_count, int status_info); /* functions for the manipulating of the current loaded soundfile */ int soundfile_shift_samples_right(long first_pos, long sample_count, int status_info); int soundfile_shift_samples_left(long first_pos, long sample_count, int status_info); long soundfile_count_samples(void); int soundfile_insert_silence(long insert_pos, long sample_count, int status_info); int soundfile_insert_samples(long insert_pos, long sample_count, int *sample_data, int status_info); int soundfile_remove_samples(long first_pos, long sample_count, int status_info); #endif /* SOUNDFILE_H */ gtk-wave-cleaner-0.22-04/stat.c0000777000175000017500000000417513120075107017333 0ustar00alisteralister00000000000000/* * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty FILE stat.c PURPOSE - linear regression CONTENTS - */ #include #include "stat.h" void matrix_solve(MAT *) ; #define abs(x) ((x) > 0 ? (x) : -(x)) #define tiny 1e-200 static MAT *coef = MNULL ; static VEC *b = VNULL ; static VEC *answer = VNULL ; static int row, col, N, i ; static int failed ; /* LUsolve -- given an LU factorisation in A, solve Ax=b */ VEC *myLUsolve(A,pivot,b,x) MAT *A; PERM *pivot; VEC *b,*x; { if ( A==(MAT *)NULL || b==(VEC *)NULL || pivot==(PERM *)NULL ) error(E_NULL,"LUsolve"); if ( A->m != A->n || A->n != b->dim ) error(E_SIZES,"LUsolve"); x = v_resize(x,b->dim); px_vec(pivot,b,x); /* x := P.b */ Lsolve(A,x,x,1.0); /* implicit diagonal = 1 */ Usolve(A,x,x,0.0); /* explicit diagonal */ return (x); } void matrix_solve(MAT *A) { PERM *pivot ; failed = 0 ; count_errs(0) ; pivot = px_get(A->m) ; catchall( LUfactor(coef, pivot) ; answer = v_get(b->dim); answer = myLUsolve(A,pivot,b,answer) ; , failed=1 ); if(failed == 1) { answer = v_resize(answer,N) ; v_zero(answer) ; } PX_FREE(pivot) ; } void init_reg(int n) { N = n ; coef = m_resize(coef, N, N) ; b = v_resize(b, N) ; /** zero the coef array which will hold the sums **/ m_zero(coef) ; v_zero(b) ; } /* Paul Sanders' speedup 1/12/2007 works a little better */ #define PAUL_SANDERS #ifdef JW_NEW void sum_reg(double x[], double y) { for(row = 0 ; row < N ; row++) { for(col = 0 ; col < N ; col++) coef->me[row][col] += x[row] * x[col] ; b->ve[row] += y * x[row] ; } } #endif #ifdef PAUL_SANDERS void sum_reg(double x[], double y) { double *pbve = b->ve ; for(row = 0 ; row < N ; row++) { double *coef_row = coef->me[row] ; for(col = 0 ; col < N ; col++) coef_row[col] += x[row] * x[col] ; *pbve += x[row] * y ; pbve++ ; } } #endif int estimate_reg(double *b_solution) { matrix_solve(coef) ; for(row = 0 ; row < N ; row++) b_solution[row] = answer->ve[row] ; V_FREE(answer) ; M_FREE(coef) ; V_FREE(b) ; return failed ; } gtk-wave-cleaner-0.22-04/stat.h0000777000175000017500000000022013120075107017323 0ustar00alisteralister00000000000000#include "meschach/matrix.h" #include "meschach/matrix2.h" int estimate_reg(double *) ; void init_reg(int) ; void sum_reg(double [], double) ; gtk-wave-cleaner-0.22-04/tap_reverb.c0000777000175000017500000004202013120075107020500 0ustar00alisteralister00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: sound.c,v 1.5 2004/06/16 09:52:18 tszilagyi Exp $ */ #include #include #include #include #include #include "tap_reverb_common.h" #include "tap_reverb_file_io.h" #include "tap_reverb.h" /* ***** VERY IMPORTANT! ***** * * If you enable this, the program will use float arithmetics in DSP * calculations. This usually yields lower average CPU usage, but * occasionaly may result in high CPU peaks which cause trouble to you * and your JACK server. The default is to use fixpoint arithmetics * (with the following #define commented out). But (depending on the * processor on which you run the code) you may find floating point * mode usable. */ /* #define REVERBED_CALC_FLOAT */ REVTYPE * curr = NULL ; REVTYPE * reverb_root = NULL ; /* magic numbers */ #define BANDPASS_BWIDTH 1.5f #define FREQ_RESP_BWIDTH 3.0f #define ENH_STEREO_RATIO 0.998f /* compensation ratio of freq_resp in fb_gain calc */ #define FR_R_COMP 0.75f #ifndef M_PI #define M_PI 3.14159265358979323846264338327 #endif #define db2lin(x) ((x) > -90.0f ? powf(10.0f, (x) * 0.05f) : 0.0f) #define LN_2_2 0.34657359f #define LIMIT(v,l,u) ((v)<(l)?(l):((v)>(u)?(u):(v))) /* #define REVERB_INPUT_IS_LONGS */ #ifdef REVERBED_CALC_FLOAT /* ultra-aggressive denormalization */ #define DENORM(x) (((unsigned char)(((*(unsigned int*)&(x))&0x7f800000)>>23))<103)?0.0f:(x) typedef float rev_t; #else #ifdef REVERB_INPUT_IS_LONGS /* coefficient for float to sample (signed int) conversion */ /* this allows for about 60 dB headroom above 0dB, if 0 dB is equivalent to 1.0f */ /* As 2^31 equals more than 180 dB, about 120 dB dynamics remains below 0 dB */ #define F2S 65 #else /* coefficient for float to sample (signed int) conversion */ /* this allows for about 60 dB headroom above 0dB, if 0 dB is equivalent to 1.0f */ /* As 2^31 equals more than 180 dB, about 120 dB dynamics remains below 0 dB */ #define F2S 2147483 #endif typedef signed int rev_t; #endif typedef struct { float a1; float a2; float b0; float b1; float b2; rev_t x1; rev_t x2; rev_t y1; rev_t y2; } biquad; typedef struct { float feedback; float fb_gain; float freq_resp; rev_t ringbuffer[(int)MAX_COMB_DELAY * MAX_SAMPLERATE / 1000]; unsigned long buflen; unsigned long buffer_pos; biquad filter; rev_t last_out; } COMB_FILTER; typedef struct { float feedback; float fb_gain; float in_gain; rev_t ringbuffer[(int)MAX_ALLP_DELAY * MAX_SAMPLERATE / 1000]; unsigned long buflen; unsigned long buffer_pos; rev_t last_out; } ALLP_FILTER; /* data of the running instance */ unsigned long num_combs; /* total number of comb filters */ unsigned long num_allps; /* total number of allpass filters */ COMB_FILTER combs[2 * MAX_COMBS]; ALLP_FILTER allps[2 * MAX_ALLPS]; biquad low_pass[2]; biquad high_pass[2]; float tap_decay = 2500.0f; float drylevel = 0.0f; float wetlevel = 0.0f; int combs_en = 1; /* on/off */ int allps_en = 1; /* on/off */ int bandps_en = 1; /* on/off */ int stereo_en = 1; /* on/off */ int bypass = 0; /* on/off */ int changed_settings = 0; /* additional data for the IR calculating instance */ COMB_FILTER combs_IR[MAX_COMBS]; ALLP_FILTER allps_IR[MAX_ALLPS]; biquad low_pass_IR; biquad high_pass_IR; unsigned long sample_rate; void reverb_setup(long rate, double decay_d, double wet_d, double dry_d, char *name) { tap_decay = decay_d ; wetlevel = wet_d ; drylevel = dry_d ; changed_settings = 1 ; sample_rate = rate ; if(reverb_root == NULL) { reverb_root = parse_reverb_input_file() ; } curr = get_revtype_by_name(reverb_root, name) ; reverb_init() ; } /* push a sample into a ringbuffer and return the sample falling out */ static inline rev_t push_buffer(rev_t insample, rev_t * buffer, unsigned long buflen, unsigned long * pos) { rev_t outsample; outsample = buffer[*pos]; buffer[(*pos)++] = insample; if (*pos >= buflen) *pos = 0; return outsample; } /* read a value from a ringbuffer. */ static inline rev_t read_buffer(rev_t * buffer, unsigned long buflen, unsigned long pos, unsigned long n) { while (n + pos >= buflen) n -= buflen; return buffer[n + pos]; } /* overwrites a value in a ringbuffer, but pos stays the same. */ static inline void write_buffer(rev_t insample, rev_t * buffer, unsigned long buflen, unsigned long pos, unsigned long n) { while (n + pos >= buflen) n -= buflen; buffer[n + pos] = insample; } static inline void biquad_init(biquad *f) { f->x1 = 0.0f; f->x2 = 0.0f; f->y1 = 0.0f; f->y2 = 0.0f; } static inline void lp_set_params(biquad *f, float fc, float bw, float fs) { float omega = 2.0 * M_PI * fc/fs; float sn = sin(omega); float cs = cos(omega); float alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn); const float a0r = 1.0 / (1.0 + alpha); f->b0 = a0r * (1.0 - cs) * 0.5; f->b1 = a0r * (1.0 - cs); f->b2 = a0r * (1.0 - cs) * 0.5; f->a1 = a0r * (2.0 * cs); f->a2 = a0r * (alpha - 1.0); } static inline void hp_set_params(biquad *f, float fc, float bw, float fs) { float omega = 2.0 * M_PI * fc/fs; float sn = sin(omega); float cs = cos(omega); float alpha = sn * sinh(M_LN2 / 2.0 * bw * omega / sn); const float a0r = 1.0 / (1.0 + alpha); f->b0 = a0r * (1.0 + cs) * 0.5; f->b1 = a0r * -(1.0 + cs); f->b2 = a0r * (1.0 + cs) * 0.5; f->a1 = a0r * (2.0 * cs); f->a2 = a0r * (alpha - 1.0); } static inline rev_t biquad_run(biquad *f, rev_t x) { rev_t y; y = f->b0 * x + f->b1 * f->x1 + f->b2 * f->x2 + f->a1 * f->y1 + f->a2 * f->y2; #ifdef REVERBED_CALC_FLOAT y = DENORM(y); #endif f->x2 = f->x1; f->x1 = x; f->y2 = f->y1; f->y1 = y; return y; } /* push a sample into a comb filter and return the sample falling out */ rev_t comb_run(rev_t insample, COMB_FILTER * comb) { rev_t outsample; rev_t pushin; pushin = comb->fb_gain * insample + biquad_run(&(comb->filter), comb->fb_gain * comb->last_out); #ifdef REVERBED_CALC_FLOAT pushin = DENORM(pushin); #endif outsample = push_buffer(pushin, comb->ringbuffer, comb->buflen, &(comb->buffer_pos)); #ifdef REVERBED_CALC_FLOAT outsample = DENORM(outsample); #endif comb->last_out = outsample; return outsample; } /* push a sample into an allpass filter and return the sample falling out */ rev_t allp_run(rev_t insample, ALLP_FILTER * allp) { rev_t outsample; rev_t pushin; pushin = allp->in_gain * allp->fb_gain * insample + allp->fb_gain * allp->last_out; #ifdef REVERBED_CALC_FLOAT pushin = DENORM(pushin); #endif outsample = push_buffer(pushin, allp->ringbuffer, allp->buflen, &(allp->buffer_pos)); #ifdef REVERBED_CALC_FLOAT outsample = DENORM(outsample); #endif allp->last_out = outsample; return outsample; } /* load data from REVTYPE*curr into the running instance */ void load_revtype_data(void) { int i; /* load combs data */ num_combs = 2 * curr->num_combs; for (i = 0; i < curr->num_combs; i++) { combs[2*i].buflen = curr->combs_data[3*i] * sample_rate / 1000.0f; combs[2*i].feedback = curr->combs_data[3*i+1]; combs[2*i].freq_resp = LIMIT(curr->combs_data[3*i+2] * powf(sample_rate / 44100.0f, 0.8f), 0.0f, 1.0f); combs[2*i+1].buflen = combs[2*i].buflen; combs[2*i+1].feedback = combs[2*i].feedback; combs[2*i+1].freq_resp = combs[2*i].freq_resp; lp_set_params(&(combs[2*i].filter), 2000.0f + 13000.0f * (1 - curr->combs_data[3*i+2]) * sample_rate / 44100.0f, BANDPASS_BWIDTH, sample_rate); lp_set_params(&(combs[2*i+1].filter), 2000.0f + 13000.0f * (1 - curr->combs_data[3*i+2]) * sample_rate / 44100.0f, BANDPASS_BWIDTH, sample_rate); } /* load allps data */ num_allps = 2 * curr->num_allps; for (i = 0; i < curr->num_allps; i++) { allps[2*i].buflen = curr->allps_data[2*i] * sample_rate / 1000.0f; allps[2*i].feedback = curr->allps_data[2*i+1]; allps[2*i+1].buflen = allps[2*i].buflen; allps[2*i+1].feedback = allps[2*i].feedback; } /* init bandpass filters */ lp_set_params(&(low_pass[0]), curr->bandps_hi, BANDPASS_BWIDTH, sample_rate); hp_set_params(&(high_pass[0]), curr->bandps_lo, BANDPASS_BWIDTH, sample_rate); lp_set_params(&(low_pass[1]), curr->bandps_hi, BANDPASS_BWIDTH, sample_rate); hp_set_params(&(high_pass[1]), curr->bandps_lo, BANDPASS_BWIDTH, sample_rate); } /* compute user-input-dependent reverberator coefficients */ void comp_coeffs(void) { int i; for (i = 0; i < num_combs / 2; i++) { combs[2*i].fb_gain = powf(0.001f, 1000.0f * combs[2*i].buflen * (1 + FR_R_COMP * combs[2*i].freq_resp) / powf(combs[2*i].feedback / 100.0f, 0.89f) / tap_decay / sample_rate); combs[2*i+1].fb_gain = combs[2*i].fb_gain; if (stereo_en) { if (i % 2 == 0) combs[2*i+1].buflen = ENH_STEREO_RATIO * combs[2*i].buflen; else combs[2*i].buflen = ENH_STEREO_RATIO * combs[2*i+1].buflen; } else { if (i % 2 == 0) combs[2*i+1].buflen = combs[2*i].buflen; else combs[2*i].buflen = combs[2*i+1].buflen; } } for (i = 0; i < num_allps / 2; i++) { allps[2*i].fb_gain = powf(0.001f, 11000.0f * allps[2*i].buflen / powf(allps[2*i].feedback / 100.0f, 0.88f) / tap_decay / sample_rate); allps[2*i+1].fb_gain = allps[2*i].fb_gain; allps[2*i].in_gain = -0.06f / (allps[2*i].feedback / 100.0f) / powf((tap_decay + 3500.0f) / 10000.0f, 1.5f); allps[2*i+1].in_gain = allps[2*i].in_gain; if (stereo_en) { if (i % 2 == 0) allps[2*i+1].buflen = ENH_STEREO_RATIO * ENH_STEREO_RATIO * allps[2*i].buflen; else allps[2*i].buflen = ENH_STEREO_RATIO * ENH_STEREO_RATIO * allps[2*i+1].buflen; } else { if (i % 2 == 0) allps[2*i+1].buflen = allps[2*i].buflen; else allps[2*i].buflen = allps[2*i+1].buflen; } } } void reverb_init(void) { unsigned long i,j; for (i = 0; i < 2 * MAX_COMBS; i++) { for (j = 0; j < (unsigned long)MAX_COMB_DELAY * sample_rate / 1000; j++) combs[i].ringbuffer[j] = 0.0f; combs[i].buffer_pos = 0; combs[i].last_out = 0.0f; biquad_init(&(combs[i].filter)); } for (i = 0; i < 2 * MAX_ALLPS; i++) { for (j = 0; j < (unsigned long)MAX_ALLP_DELAY * sample_rate / 1000; j++) allps[i].ringbuffer[j] = 0.0f; allps[i].buffer_pos = 0; allps[i].last_out = 0.0f; } biquad_init(&(low_pass[0])); biquad_init(&(low_pass[1])); biquad_init(&(high_pass[0])); biquad_init(&(high_pass[1])); } int reverb_process(long nframes, reverb_audio_sample_t *output_L, reverb_audio_sample_t *input_L, reverb_audio_sample_t *output_R, reverb_audio_sample_t *input_R) { unsigned long sample_index; int i; rev_t out_L = 0; rev_t out_R = 0; rev_t in_L = 0; rev_t in_R = 0; rev_t combs_out_L = 0; rev_t combs_out_R = 0; float dry = db2lin(drylevel); float wet = db2lin(wetlevel); if (bypass) { memcpy(output_L, input_L, sizeof(reverb_audio_sample_t) * nframes); memcpy(output_R, input_R, sizeof(reverb_audio_sample_t) * nframes); } else { if (changed_settings) { load_revtype_data(); comp_coeffs(); changed_settings = 0; } for (sample_index = 0; sample_index < nframes; sample_index++) { #ifdef REVERBED_CALC_FLOAT in_L = *(input_L++); in_R = *(input_R++); #else in_L = (float)F2S * *(input_L++); in_R = (float)F2S * *(input_R++); #endif combs_out_L = in_L; combs_out_R = in_R; /* process comb filters */ if (combs_en) { for (i = 0; i < num_combs / 2; i++) { combs_out_L += comb_run(in_L, &(combs[2*i])); combs_out_R += comb_run(in_R, &(combs[2*i+1])); } } /* process allpass filters */ if (allps_en) { for (i = 0; i < num_allps / 2; i++) { combs_out_L += allp_run(combs_out_L, &(allps[2*i])); combs_out_R += allp_run(combs_out_R, &(allps[2*i+1])); } } /* process bandpass filters */ if (bandps_en) { combs_out_L = biquad_run(&(low_pass[0]), combs_out_L); combs_out_L = biquad_run(&(high_pass[0]), combs_out_L); combs_out_R = biquad_run(&(low_pass[1]), combs_out_R); combs_out_R = biquad_run(&(high_pass[1]), combs_out_R); } #ifdef REVERBED_CALC_FLOAT out_L = in_L * dry + combs_out_L * wet; out_R = in_R * dry + combs_out_R * wet; *(output_L++) = out_L; *(output_R++) = out_R; #else out_L = (float)in_L * dry + (float)combs_out_L * wet; out_R = (float)in_R * dry + (float)combs_out_R * wet; *(output_L++) = (float)out_L / (float)F2S; *(output_R++) = (float)out_R / (float)F2S; #endif } } return 0; } void process_impresp(float * data, long int nframes) { unsigned long sample_index; rev_t out = 0; rev_t in = 0; rev_t combs_out = 0; float * output = data; float * input = data; unsigned long i,j; /* make sure the running instance has current data, even if due to some accident JACK is not running */ if (changed_settings) { load_revtype_data(); comp_coeffs(); changed_settings = 0; } /* init IR calc. instance */ for (i = 0; i < MAX_COMBS; i++) { for (j = 0; j < (unsigned long)MAX_COMB_DELAY * sample_rate / 1000; j++) combs_IR[i].ringbuffer[j] = 0.0f; combs_IR[i].buffer_pos = 0; combs_IR[i].last_out = 0.0f; biquad_init(&(combs_IR[i].filter)); } for (i = 0; i < MAX_ALLPS; i++) { for (j = 0; j < (unsigned long)MAX_ALLP_DELAY * sample_rate / 1000; j++) allps_IR[i].ringbuffer[j] = 0.0f; allps_IR[i].buffer_pos = 0; allps_IR[i].last_out = 0.0f; } biquad_init(&low_pass_IR); biquad_init(&high_pass_IR); /* load parameters */ for (i = 0; i < curr->num_combs; i++) { combs_IR[i].buflen = combs[2*i].buflen; combs_IR[i].feedback = combs[2*i].feedback; combs_IR[i].fb_gain = combs[2*i].fb_gain; combs_IR[i].freq_resp = combs[2*i].freq_resp; combs_IR[i].filter.a1 = combs[2*i].filter.a1; combs_IR[i].filter.a2 = combs[2*i].filter.a2; combs_IR[i].filter.b0 = combs[2*i].filter.b0; combs_IR[i].filter.b1 = combs[2*i].filter.b1; combs_IR[i].filter.b2 = combs[2*i].filter.b2; } for (i = 0; i < curr->num_allps; i++) { allps_IR[i].buflen = allps[2*i].buflen; allps_IR[i].feedback = allps[2*i].feedback; allps_IR[i].fb_gain = allps[2*i].fb_gain; allps_IR[i].in_gain = allps[2*i].in_gain; } low_pass_IR.a1 = low_pass[0].a1; low_pass_IR.a2 = low_pass[0].a2; low_pass_IR.b0 = low_pass[0].b0; low_pass_IR.b1 = low_pass[0].b1; low_pass_IR.b2 = low_pass[0].b2; high_pass_IR.a1 = high_pass[0].a1; high_pass_IR.a2 = high_pass[0].a2; high_pass_IR.b0 = high_pass[0].b0; high_pass_IR.b1 = high_pass[0].b1; high_pass_IR.b2 = high_pass[0].b2; /* process */ for (sample_index = 0; sample_index < nframes; sample_index++) { #ifdef REVERBED_CALC_FLOAT in = *(input++); #else in = (float)F2S * *(input++); #endif combs_out = in; if (combs_en) { for (i = 0; i < curr->num_combs; i++) { combs_out += comb_run(in, &(combs_IR[i])); } } if (allps_en) { for (i = 0; i < curr->num_allps; i++) { combs_out += allp_run(combs_out, &(allps_IR[i])); } } if (bandps_en) { combs_out = biquad_run(&low_pass_IR, combs_out); combs_out = biquad_run(&high_pass_IR, combs_out); } out = combs_out; #ifdef REVERBED_CALC_FLOAT *(output++) = out; #else *(output++) = (float)out / (float)F2S; #endif } } gtk-wave-cleaner-0.22-04/tap_reverb.h0000777000175000017500000000252013120075107020506 0ustar00alisteralister00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: sound.h,v 1.3 2004/06/09 18:58:17 tszilagyi Exp $ */ #ifndef _tap_reverb_h #define _tap_reverb_h typedef float reverb_audio_sample_t ; void comp_coeffs(void); void load_revtype_data(void); void reverb_init(void); int reverb_process(long nframes, reverb_audio_sample_t *output_L, reverb_audio_sample_t *input_L, reverb_audio_sample_t *output_R, reverb_audio_sample_t *input_R) ; void reverb_setup(long sample_rate, double decay_d, double wet_d, double dry_d, char *name) ; void reverb_finish(void *arg); #endif /* _tap_reverb_h */ gtk-wave-cleaner-0.22-04/tap_reverb_common.h0000777000175000017500000000522513120075107022063 0ustar00alisteralister00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: common.h,v 1.4 2004/06/12 13:56:46 tszilagyi Exp $ */ #ifndef _tap_reverb_common_h #define _tap_reverb_common_h /* enlarge this if you need to */ #define MAX_SAMPLERATE 192000 #define MAXLEN 32 #define MAX_COMBS 20 #define MAX_ALLPS 20 #define MAX_DECAY 10000.0f #define MAX_COMB_DELAY 250.0f #define MAX_ALLP_DELAY 20.0f #define IMPRESP_MAXLEN 10000 /* file names */ #define NAME_REVERBED ".reverbed" #define NAME_TAP_H "tap_reverb_presets.h" #define NAME_TAP_RDF "tap_reverb.rdf" /* color definitions */ #define NORMAL_R 48000 #define NORMAL_G 51000 #define NORMAL_B 55000 #define ACTIVE_R 40000 #define ACTIVE_G 43000 #define ACTIVE_B 47000 #define PRELIGHT_R 50000 #define PRELIGHT_G 55000 #define PRELIGHT_B 60000 /* toggle_buttons that are green when depressed */ /* it's actually blue, heh :) */ #define G_ACTIVE_R 29000 #define G_ACTIVE_G 29000 #define G_ACTIVE_B 65535 #define G_PRELIGHT_R 39000 #define G_PRELIGHT_G 39000 #define G_PRELIGHT_B 65535 /* toggle_buttons that are red when depressed */ #define R_ACTIVE_R 65535 #define R_ACTIVE_G 15000 #define R_ACTIVE_B 15000 #define R_PRELIGHT_R 65535 #define R_PRELIGHT_G 25000 #define R_PRELIGHT_B 25000 /* widgets on the notebook */ #define N_NORMAL_R 42000 #define N_NORMAL_G 45000 #define N_NORMAL_B 49000 #define N_ACTIVE_R 34000 #define N_ACTIVE_G 37000 #define N_ACTIVE_B 41000 #define N_PRELIGHT_R 44000 #define N_PRELIGHT_G 49000 #define N_PRELIGHT_B 54000 /* color of the notebook */ #define NB_NORMAL_R 52000 #define NB_NORMAL_G 55000 #define NB_NORMAL_B 59000 #define NB_ACTIVE_R 44000 #define NB_ACTIVE_G 47000 #define NB_ACTIVE_B 51000 #define NB_PRELIGHT_R 54000 #define NB_PRELIGHT_G 59000 #define NB_PRELIGHT_B 64000 /* window backgrounds */ #define WINDOW_R 58000 #define WINDOW_G 58000 #define WINDOW_B 62535 #endif /* _tap_reverb_common_h */ gtk-wave-cleaner-0.22-04/tap_reverb_file_io.c0000777000175000017500000001243613120075107022176 0ustar00alisteralister00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: file_io.c,v 1.4 2004/06/12 13:57:24 tszilagyi Exp $ */ #include #include #include #include "tap_reverb_common.h" #include "tap_reverb_file_io.h" extern REVTYPE * reverb_root; REVTYPE *get_revroot() { if(reverb_root == NULL) { reverb_root = parse_reverb_input_file() ; } return reverb_root ; } /* 0: between two REVTYPE records * 1: read REVTYPE keyword, name follows on next line * 2: read name, before COMBS keyword * 3: read COMBS keyword, lines for COMBS follow * 4: read ALLPS keyword, lines for ALLPS follow * 5: read BANDPS_LO keyword, next line contains BANDPS_LO data * 6: read BANDPS_HI keyword, next line contains BANDPS_HI data */ int parser_state = 0; float convf(char * s) { float val, pow; int i, sign; for (i = 0; s[i] == ' ' || s[i] == '\n' || s[i] == '\t'; i++); sign = 1; if (s[i] == '+' || s[i] == '-') sign = (s[i++] == '+') ? 1 : -1; for (val = 0; s[i] >= '0' && s[i] <= '9'; i++) val = 10 * val + s[i] - '0'; if ((s[i] == '.') || (s[i] == ',')) i++; for (pow = 1; s[i] >= '0' && s[i] <= '9'; i++) { val = 10 * val + s[i] - '0'; pow *= 10; } return(sign * val / pow); } #include "reverb_settings.h" int builtin_ptr = 0 ; #define FROM_BUILTIN 0x01 #define FROM_FILE 0x02 int reverb_data_format = FROM_FILE ; int reverb_fgetc(FILE *infile) { if(reverb_data_format == FROM_BUILTIN) { int c ; if(builtin_ptr == sizeof(reverb_default_settings)) return EOF ; c = reverb_default_settings[builtin_ptr] ; builtin_ptr++ ; return c ; } else { return fgetc(infile) ; } } REVTYPE * parse_reverb_input_file(void) { char * home; char path[MAXLEN]; FILE * infile; char line[1024]; int c, i = 0; char str1[MAXLEN]; char str2[MAXLEN]; char str3[MAXLEN]; int num_combs = 0; int num_allps = 0; REVTYPE * root = NULL; REVTYPE * item = NULL; REVTYPE * prev = NULL; if (!(home = getenv("HOME"))) home = "."; sprintf(path, "%s/%s", home, NAME_REVERBED); if ((infile = fopen(path,"rt")) == NULL) { reverb_data_format = FROM_BUILTIN ; } if ((root = malloc(sizeof(REVTYPE))) == NULL) { fprintf(stderr, "file_io.c: couldn't alloc mem for root item\n"); return(NULL); } root->next = NULL; root->name[0] = '\0'; /* Here we read the whole file and fill up our list. */ while ((c = reverb_fgetc(infile)) != EOF) { if (c != '\n') line[i++] = c; else { line[i] = '\0'; i = 0; switch(parser_state) { case 0: if (strcmp(line, "REVTYPE") == 0) { if ((item = malloc(sizeof(REVTYPE))) == NULL) { fprintf(stderr, "tap_reverb_file_io.c: malloc failed.\n"); return(NULL); } item->next = NULL; if (root->next == NULL) root->next = item; else prev->next = item; prev = item; parser_state = 1; num_allps = 0; } break; case 1: strcpy(item->name, line); parser_state = 2; break; case 2: if (strcmp(line, "COMBS") == 0) { num_combs = 0; parser_state = 3; } break; case 3: if (strcmp(line, "ALLPS") == 0) { num_allps = 0; item->num_combs = num_combs; parser_state = 4; } else { sscanf(line, "%s %s %s", str1, str2, str3); item->combs_data[3 * num_combs] = 1000.0f * convf(str1); item->combs_data[3 * num_combs + 1] = convf(str2); item->combs_data[3 * num_combs + 2] = convf(str3); num_combs++; } break; case 4: if (strcmp(line, "BANDPS_LO") == 0) { item->num_allps = num_allps; parser_state = 5; } else { sscanf(line, "%s %s", str1, str2); item->allps_data[2 * num_allps] = 1000.0f * convf(str1); item->allps_data[2 * num_allps + 1] = convf(str2); num_allps++; } break; case 5: if (strcmp(line, "BANDPS_HI") == 0) { parser_state = 6; } else { item->num_allps = num_allps; sscanf(line, "%s", str1); item->bandps_lo = convf(str1); } break; case 6: sscanf(line, "%s", str1); item->bandps_hi = convf(str1); parser_state = 0; break; } } } if(infile != NULL) fclose(infile); return(root); } REVTYPE * get_revtype_by_name(REVTYPE * root, const char * name) { REVTYPE * item = root; if (item->next != NULL) item = item->next; else return NULL; while (item != NULL) { if (strcmp(name, item->name) == 0) return item; item = item->next; } return NULL; } REVTYPE * get_next_revtype(REVTYPE *root) { REVTYPE * item = root; if (item->next != NULL) item = item->next; else return NULL; return item ; } gtk-wave-cleaner-0.22-04/tap_reverb_file_io.h0000777000175000017500000000272413120075107022202 0ustar00alisteralister00000000000000/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: file_io.h,v 1.3 2004/06/11 22:28:57 tszilagyi Exp $ */ #ifndef _tap_reverb_file_io_h #define _tap_reverb_file_io_h typedef struct t_revtype { char name[MAXLEN]; unsigned long num_combs; unsigned long num_allps; float combs_data[3 * MAX_COMBS]; float allps_data[2 * MAX_ALLPS]; float bandps_lo; float bandps_hi; struct t_revtype * next; } REVTYPE; REVTYPE * parse_reverb_input_file(void); void list_revtypes(REVTYPE * root); REVTYPE * get_revtype_by_name(REVTYPE * root, const char * name); REVTYPE * get_next_revtype(REVTYPE * root); REVTYPE * get_revroot(void); #endif /* _tap_reverb_file_io_h */ gtk-wave-cleaner-0.22-04/undo.c0000777000175000017500000002742213120075107017325 0ustar00alisteralister00000000000000/***************************************************************************** * Gnome Wave Cleaner Version 0.19 * Copyright (C) 2001 Jeffrey J. Welty * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You 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. *******************************************************************************/ /* undo.c */ #include #include #include #include #include #include #include #include #include #include "gwc.h" #ifndef TRUNCATE_OLD #include "soundfile.h" #define UNDO_OVERWRITE 0 #define UNDO_INSERT 1 #define UNDO_REMOVE 2 #endif /* TRUNCATE_OLD */ static char current_undo_msg[200] ; static int undo_fd = -1 ; static int undo_level = 0 ; int get_undo_levels(void) { return undo_level ; } int start_save_undo(char *undo_msg, struct view *v) { // Alister: should really tidy this up char _filename[1024]; short l ; undo_level++ ; sprintf(_filename, "gwc_undo_%d.dat", undo_level) ; // Alister: we need to save our working files somewhere other than the working directory (which isn't even necessarily the location of the file we are working on), // because it may not be writeable, and we need to allow for multiple instances of gwc to run from the same working directory without interfering with each other. gchar *filename = _filename ; if (g_file_test (tmpdir, G_FILE_TEST_IS_DIR)) //tmpdir exists filename = g_build_filename (tmpdir, _filename, NULL); //printf("filename: %s\n", *) ; if( (undo_fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, S_IRUSR|S_IWUSR)) == -1) { warning("Can't save undo information") ; undo_level-- ; return -1 ; } if(undo_level == 1) strcpy(current_undo_msg, "Nothing to undo") ; l = strlen(current_undo_msg) ; write(undo_fd, (char *)&l, sizeof(l)) ; write(undo_fd, current_undo_msg, l) ; { long first, last ; get_region_of_interest(&first, &last, v) ; write(undo_fd, (char *)&first, sizeof(first)) ; write(undo_fd, (char *)&last, sizeof(last)) ; write(undo_fd, (char *)&v->channel_selection_mask, sizeof(v->channel_selection_mask)) ; } strcpy(current_undo_msg, undo_msg) ; return undo_level ; } extern int FRAMESIZE ; #ifndef TRUNCATE_OLD static int save_undo_data_impl(long first_sample, long last_sample, int undo_type, int progress_update_flag) #else int save_undo_data(long first_sample, long last_sample, struct sound_prefs *p, int progress_update_flag) #endif { const int BLOCK_SIZE = 1024 ; char buf[BLOCK_SIZE * FRAMESIZE] ; long curr ; long blocks ; gfloat n_sample = (last_sample-first_sample+1) ; #ifndef TRUNCATE_OLD if (undo_type != UNDO_INSERT) { #endif //Alister: the check seems to be far too low - maybe we should try 100MB? //Note that the same amount of space is needed whether we are operating on both channels or only one. if(n_sample*FRAMESIZE > 10000000) { GtkWidget *dialog, *text ; char buf[200] ; int ret ; sprintf(buf, "Undo will need %7.2f Mbytes of disk space (skipping undo commits changes to your original audio file)", n_sample*FRAMESIZE/1000000.0) ; dialog = gtk_dialog_new_with_buttons("Warning", GTK_WINDOW(main_window), GTK_DIALOG_DESTROY_WITH_PARENT, "Cancel edit action", 1, "Save undo data", 2, "Skip undo", 0, NULL) ; gtk_dialog_set_default_response (GTK_DIALOG(dialog), 1); text = gtk_label_new(buf); gtk_widget_show(text); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), text, TRUE, TRUE, 0); ret = gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog) ; if( ret!= 2) { /* Don't save undo */ undo_level-- ; close(undo_fd) ; undo_fd = -1 ; if(ret == 1 || ret == -1) /* we cancelled */ return 1 ; else return 0 ; } } #ifndef TRUNCATE_OLD } #endif write(undo_fd, (char *)&first_sample, sizeof(first_sample)) ; write(undo_fd, (char *)&last_sample, sizeof(last_sample)) ; #ifndef TRUNCATE_OLD write(undo_fd, (char *)&undo_type, sizeof(undo_type)) ; if (undo_type != UNDO_INSERT) { #endif if(progress_update_flag) update_progress_bar(0.0, PROGRESS_UPDATE_INTERVAL, TRUE) ; blocks = (last_sample - first_sample + 1) / BLOCK_SIZE; for(curr = first_sample ; curr <= last_sample ; curr += BLOCK_SIZE) { long end; gfloat p = (gfloat)(curr-first_sample)/n_sample ; if(progress_update_flag) update_progress_bar(p,PROGRESS_UPDATE_INTERVAL,FALSE) ; end = curr + BLOCK_SIZE - 1; if (end > last_sample) end = last_sample; read_raw_wavefile_data(buf, curr, end) ; if (write(undo_fd, buf, FRAMESIZE * (end - curr + 1)) != FRAMESIZE * (end - curr + 1) ) { // Alister: we shouldn't just exit, in case the user has made previous edits successfully, but has now run out of space. //warning("Error saving undo data (out of disk space?), program will exit"); //exit(1); // Alister: I *think* doing it this way has no ill effects. // Ideally I guess we could ask if they want to continue without undo data... warning("Error saving undo data (out of disk space?), cancelling edit"); undo_level-- ; return 1 ; } } #ifndef TRUNCATE_OLD } #endif if(progress_update_flag) update_progress_bar(0.0, PROGRESS_UPDATE_INTERVAL, TRUE) ; return 0 ; } #ifndef TRUNCATE_OLD int save_undo_data(long first_sample, long last_sample, struct sound_prefs *p, int progress_update_flag) { return save_undo_data_impl(first_sample, last_sample, UNDO_OVERWRITE, progress_update_flag); } int save_undo_data_remove(long first_sample, long last_sample, int progress_update_flag) { return save_undo_data_impl(first_sample, last_sample, UNDO_REMOVE, progress_update_flag); } int save_undo_data_insert(long first_sample, long last_sample, int progress_update_flag) { return save_undo_data_impl(first_sample, last_sample, UNDO_INSERT, progress_update_flag); } #endif /* !TRUNCATE_OLD */ int close_undo(void) { close(undo_fd) ; undo_fd = -1 ; return undo_level ; } char *get_undo_msg(void) { return current_undo_msg ; } int undo(struct view *v, struct sound_prefs *p) { short l ; long first_sample, last_sample, curr ; int n_sections ; #define N_ALLOC_INC 1000 int n_sections_max = N_ALLOC_INC ; char _filename[1024] ; const int BLOCK_SIZE = 1024 ; char buf[BLOCK_SIZE * FRAMESIZE] ; long blocks ; off_t *data_start_pos ; long total_sections; #ifndef TRUNCATE_OLD int undo_type; #endif if(undo_level == 0 || undo_fd != -1) { warning("Nothing to undo!") ; return undo_level ; } sprintf(_filename, "gwc_undo_%d.dat", undo_level) ; gchar *filename = _filename ; if (g_file_test (tmpdir, G_FILE_TEST_IS_DIR)) //tmpdir exists filename = g_build_filename (tmpdir, _filename, NULL); if( (undo_fd = open(filename, O_RDONLY)) == -1) { warning("Can't undo, undo save data has been deleted from hard drive!") ; return undo_level ; } push_status_text("Performing Undo") ; update_progress_bar(0.0, PROGRESS_UPDATE_INTERVAL, TRUE) ; read(undo_fd, (char *)&l, sizeof(l)) ; read(undo_fd, current_undo_msg, l) ; current_undo_msg[l] = '\0' ; read(undo_fd, (char *)&v->selected_first_sample, sizeof(v->selected_first_sample)) ; read(undo_fd, (char *)&v->selected_last_sample, sizeof(v->selected_last_sample)) ; read(undo_fd, (char *)&v->channel_selection_mask, sizeof(v->channel_selection_mask)) ; v->selection_region = TRUE ; n_sections = 0 ; data_start_pos = (off_t *)calloc(n_sections_max, sizeof(off_t)) ; data_start_pos[n_sections] = lseek(undo_fd, (off_t)0, SEEK_CUR) ; while(read(undo_fd, (char *)&first_sample, sizeof(first_sample)) == sizeof(first_sample) ) { read(undo_fd, (char *)&last_sample, sizeof(last_sample)) ; #ifndef TRUNCATE_OLD read(undo_fd, (char *)&undo_type, sizeof(undo_type)) ; #endif #if 0 for(curr = first_sample ; curr <= last_sample ; curr++) { read(undo_fd, (char *)buf, sizeof(short)*2) ; } #endif #ifndef TRUNCATE_OLD if (undo_type != UNDO_INSERT) #endif lseek(undo_fd, (off_t)((last_sample - first_sample + 1) * FRAMESIZE), SEEK_CUR); n_sections++ ; if(n_sections == n_sections_max) { n_sections_max += N_ALLOC_INC ; data_start_pos = (off_t *)realloc(data_start_pos, n_sections_max*sizeof(off_t)) ; } data_start_pos[n_sections] = lseek(undo_fd, (off_t)0, SEEK_CUR) ; } total_sections = n_sections; /* the sections of an undo operation have to be applied in the inverse order they were stored to properly do an undo */ for(n_sections-- ; n_sections >= 0 ; n_sections-- ) { lseek(undo_fd, data_start_pos[n_sections], SEEK_SET) ; read(undo_fd, (char *)&first_sample, sizeof(first_sample)) ; read(undo_fd, (char *)&last_sample, sizeof(last_sample)) ; #ifndef TRUNCATE_OLD read(undo_fd, (char *)&undo_type, sizeof(undo_type)) ; if (undo_type == UNDO_INSERT) { soundfile_remove_samples(first_sample, last_sample - first_sample + 1, 1); } else if (undo_type == UNDO_REMOVE) { soundfile_insert_silence(first_sample, last_sample - first_sample + 1, 1); } if (undo_type != UNDO_INSERT) { #endif blocks = (last_sample - first_sample + 1) / BLOCK_SIZE; for(curr = first_sample ; curr <= last_sample ; curr += BLOCK_SIZE) { long end; gfloat p = (gfloat)(curr-first_sample)/(last_sample - first_sample) * (total_sections - n_sections) / total_sections ; update_progress_bar(p,PROGRESS_UPDATE_INTERVAL,FALSE) ; end = curr + BLOCK_SIZE - 1; if (end > last_sample) end = last_sample; read(undo_fd, (char *)buf, FRAMESIZE * (end - curr + 1)) ; write_raw_wavefile_data(buf, curr, end) ; } #ifdef TRUNCATE_OLD resample_audio_data(p, first_sample, last_sample) ; #else } if (undo_type == UNDO_INSERT || undo_type == UNDO_REMOVE) { p->n_samples = soundfile_count_samples(); v->n_samples = p->n_samples; if (v->last_sample > v->n_samples - 1) { v->first_sample = v->n_samples - 1 - (v->last_sample - v->first_sample); v->last_sample = v->n_samples - 1; } if (v->first_sample < 0) v->first_sample = 0; resample_audio_data(p, first_sample, p->n_samples - 1); } else { resample_audio_data(p, first_sample, last_sample); } #endif } save_sample_block_data(p) ; flush_wavefile_data() ; close(undo_fd) ; unlink(filename) ; free(data_start_pos) ; undo_fd = -1 ; undo_level-- ; update_progress_bar(0.0, PROGRESS_UPDATE_INTERVAL, TRUE) ; pop_status_text(); set_status_text("Undo done."); return undo_level ; } void undo_purge(void) { char _filename[1024] ; while(undo_level>0) { sprintf(_filename, "gwc_undo_%d.dat", undo_level) ; gchar *filename = _filename ; if (g_file_test (tmpdir, G_FILE_TEST_IS_DIR)) //tmpdir exists filename = g_build_filename (tmpdir, _filename, NULL); unlink(filename) ; undo_level-- ; } }