From 0a64ff62830495ea21bdafe33b6166c3955d35fd Mon Sep 17 00:00:00 2001 From: admin Date: Fri, 25 Apr 2025 21:13:44 +0200 Subject: First Commit --- .clangd | 3 + .gitignore | 1 + COPYING | 661 ++++++++++++++++++++++++++++++ COPYRIGHT | 8 + Makefile | 31 ++ README.md | 28 ++ compile_flags.txt | 0 include/toldef.h | 147 +++++++ include/tolmacdef.h | 147 +++++++ src/tolsac.c | 691 +++++++++++++++++++++++++++++++ structure.txt | 25 ++ tests/Example.csv | 7 + tests/Sampled_Example.csv | 1002 +++++++++++++++++++++++++++++++++++++++++++++ tests/hist.r | 84 ++++ 14 files changed, 2835 insertions(+) create mode 100644 .clangd create mode 100644 .gitignore create mode 100644 COPYING create mode 100644 COPYRIGHT create mode 100644 Makefile create mode 100644 README.md create mode 100644 compile_flags.txt create mode 100644 include/toldef.h create mode 100644 include/tolmacdef.h create mode 100644 src/tolsac.c create mode 100644 structure.txt create mode 100644 tests/Example.csv create mode 100644 tests/Sampled_Example.csv create mode 100644 tests/hist.r diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..3b87122 --- /dev/null +++ b/.clangd @@ -0,0 +1,3 @@ +CompileFlags: + Add: + - -Iinclude diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3e2fcc7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..ae50619 --- /dev/null +++ b/COPYING @@ -0,0 +1,661 @@ +GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero 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 that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + 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. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +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. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 0000000..dfb4735 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,8 @@ +Copyright (C) 2025 https://optics-design.com + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +See the COPYING file for the full license text. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d192768 --- /dev/null +++ b/Makefile @@ -0,0 +1,31 @@ +CC=gcc +#Base Directories +SRCDIR=src +BINDIR=bin +INCDIR=include + +#Common flags +CFLAGS=-I$(INCDIR) -O2 -march=native -flto #-ffast-math +#tolutils +TOL_SRCS = $(wildcard $(SRCDIR)/*.c) +TOL_EXES = $(patsubst $(SRCDIR)/%.c, $(BINDIR)/%.exe, $(TOL_SRCS)) + +# Setup target +setup: + mkdir -p $(BINDIR) $(INCDIR) + +all: setup tolsac structure + +tolsac: $(TOL_EXES) +$(BINDIR)/%.exe: $(SRCDIR)/%.c + $(CC) $< $(CFLAGS) -o $@ + +clean: + rm -f $(BINDIR)/* + rm -f structure.txt + +rebuild: clean all + +# Generate project structure +structure: + @powershell -Command "(Get-Item .).Name | Set-Content structure.txt; (tree /a /f | Select-Object -Skip 3) | Add-Content structure.txt" diff --git a/README.md b/README.md new file mode 100644 index 0000000..56790bc --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# TolSAC - Tolerance & Sensitivity Analysis in C +Copyright (C) 2025 https://optics-design.com + +## Overview +Sometimes I need small programs for dealing with tolerances in optical systems. This is the collection of such tools. + +## Features +- Generate random tolerancing samples with various sampling methods and probability distributions. + +## License +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +See the [COPYING](COPYING) file for the full license text. + +## Third-Party Components +- xoshiro256** PRNG - Public Domain, by David Blackman and Sebastiano Vigna + (http://xoshiro.di.unimi.it/). A fast, high-quality random number generator. + +Each component maintains its own license. See respective license files for details. + +## Acknowledgements +The following contributions were assisted by Claude AI (Anthropic): +- Documentation and README structure. +- Code optimization suggestions. +- Interface design recommendations. diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 0000000..e69de29 diff --git a/include/toldef.h b/include/toldef.h new file mode 100644 index 0000000..a486054 --- /dev/null +++ b/include/toldef.h @@ -0,0 +1,147 @@ +/** + * raymacdef.h - header file containing various definition for rayfile manipulations. + * + * Copyright (C) 2025 https://optics-design.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * See the COPYING file for the full license text. + */ +#ifndef TOLDEF_H +#define TOLDEF_H + +#include +#include +#include +/* Type definitions for consistent sizing across platforms. Idea taken from https://nullprogram.com/blog/2023/10/08/ (archive link: ) */ +typedef uint8_t u8; +typedef char16_t c16; +typedef int32_t b32; +typedef int32_t i32; +typedef uint32_t u32; +typedef uint64_t u64; +typedef float f32; +typedef double f64; +typedef uintptr_t uptr; +typedef char byte; +typedef ptrdiff_t size; +typedef size_t usize; +/* Utility macros */ +#define countof(a) (size)(sizeof(a) / sizeof(*(a))) +#define lengthof(s) (countof(s) - 1) +// #define new(a, t, n) (t *)alloc(a, sizeof(t), _Alignof(t), n) //From Nullprogram, not using currently +#define new(t, n) (t *)malloc(n*sizeof(t)) +#define new_arr(t,arr) (t)malloc(sizeof(arr)) +#endif /* TOLDEF_H */ + +/* + * xoshiro256** PRNG algorithm by David Blackman and Sebastiano Vigna + * Fast, high-quality random number generator with 256-bit state + * Period: 2^256 - 1 + * References: + * - https://prng.di.unimi.it/ + * - https://vigna.di.unimi.it/ftp/papers/ScrambledLinear.pdf + * Implemented by Claude + */ + +// PRNG state structure +typedef struct { + uint64_t s[4]; +} xoshiro256_state; + +// Static state for the default global generator +static xoshiro256_state xoshiro_global_state; + +// Left rotation operation (helper function) +static inline uint64_t rotl(const uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); +} + +// Main xoshiro256** function: generates a random 64-bit value +static inline uint64_t xoshiro256_next(xoshiro256_state *state) { + const uint64_t result = rotl(state->s[1] * 5, 7) * 9; + const uint64_t t = state->s[1] << 17; + + state->s[2] ^= state->s[0]; + state->s[3] ^= state->s[1]; + state->s[1] ^= state->s[2]; + state->s[0] ^= state->s[3]; + + state->s[2] ^= t; + state->s[3] = rotl(state->s[3], 45); + + return result; +} + +// Jump function - equivalent to 2^128 calls to xoshiro256_next +// Useful for generating non-overlapping sequences for parallel computations +static inline void xoshiro256_jump(xoshiro256_state *state) { + static const uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c }; + + uint64_t s0 = 0; + uint64_t s1 = 0; + uint64_t s2 = 0; + uint64_t s3 = 0; + for(int i = 0; i < sizeof JUMP / sizeof *JUMP; i++) { + for(int b = 0; b < 64; b++) { + if (JUMP[i] & UINT64_C(1) << b) { + s0 ^= state->s[0]; + s1 ^= state->s[1]; + s2 ^= state->s[2]; + s3 ^= state->s[3]; + } + xoshiro256_next(state); + } + } + + state->s[0] = s0; + state->s[1] = s1; + state->s[2] = s2; + state->s[3] = s3; +} + +// Splitmix64 algorithm for initializing the state +static inline uint64_t splitmix64(uint64_t *x) { + uint64_t z = (*x += 0x9e3779b97f4a7c15); + z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; + z = (z ^ (z >> 27)) * 0x94d049bb133111eb; + return z ^ (z >> 31); +} + +// Initialize xoshiro256** state with a 64-bit seed +static inline void xoshiro256_seed(xoshiro256_state *state, uint64_t seed) { + uint64_t tmp = seed; + state->s[0] = splitmix64(&tmp); + state->s[1] = splitmix64(&tmp); + state->s[2] = splitmix64(&tmp); + state->s[3] = splitmix64(&tmp); +} + +// Initialize the global state with current time or provided seed +static inline void rng_init(uint64_t seed) { + if (seed == 0) { + seed = (uint64_t)time(NULL); + } + xoshiro256_seed(&xoshiro_global_state, seed); +} + +// Generate a random double between 0.0 and 1.0 (inclusive 0.0, exclusive 1.0) +static inline f64 rng_uniform_f64(void) { + // Take the top 53 bits (the precision of a double) to get a value in [0,1) + return (xoshiro256_next(&xoshiro_global_state) >> 11) * (1.0 / 9007199254740992.0); +} + +// Generate a random int32 in the range [0, max) +static inline i32 rng_int32(i32 max) { + // Avoid modulo bias by using rejection sampling + const uint64_t threshold = (((uint64_t)-1) - ((uint64_t)-1) % max); + uint64_t r; + do { + r = xoshiro256_next(&xoshiro_global_state); + } while (r >= threshold); + return (i32)(r % max); +} + diff --git a/include/tolmacdef.h b/include/tolmacdef.h new file mode 100644 index 0000000..d8a5543 --- /dev/null +++ b/include/tolmacdef.h @@ -0,0 +1,147 @@ +/** + * tolmacdef.h - header file containing various definitions, including the xoshiro256** PRNG algorithm. + * + * Copyright (C) 2025 https://optics-design.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * See the COPYING file for the full license text. + */ +#ifndef TOLDEF_H +#define TOLDEF_H + +#include +#include +#include +/* Type definitions for consistent sizing across platforms. Idea taken from https://nullprogram.com/blog/2023/10/08/ (archive link: ) */ +typedef uint8_t u8; +typedef char16_t c16; +typedef int32_t b32; +typedef int32_t i32; +typedef uint32_t u32; +typedef uint64_t u64; +typedef float f32; +typedef double f64; +typedef uintptr_t uptr; +typedef char byte; +typedef ptrdiff_t size; +typedef size_t usize; +/* Utility macros */ +#define countof(a) (size)(sizeof(a) / sizeof(*(a))) +#define lengthof(s) (countof(s) - 1) +// #define new(a, t, n) (t *)alloc(a, sizeof(t), _Alignof(t), n) //From Nullprogram, not using currently +#define new(t, n) (t *)malloc(n*sizeof(t)) +#define new_arr(t,arr) (t)malloc(sizeof(arr)) +#endif /* TOLDEF_H */ + +/* + * xoshiro256** PRNG algorithm by David Blackman and Sebastiano Vigna + * Fast, high-quality random number generator with 256-bit state + * Period: 2^256 - 1 + * References: + * - https://prng.di.unimi.it/ + * - https://vigna.di.unimi.it/ftp/papers/ScrambledLinear.pdf + * Implemented by Claude + */ + +// PRNG state structure +typedef struct { + uint64_t s[4]; +} xoshiro256_state; + +// Static state for the default global generator +static xoshiro256_state xoshiro_global_state; + +// Left rotation operation (helper function) +static inline uint64_t rotl(const uint64_t x, int k) { + return (x << k) | (x >> (64 - k)); +} + +// Main xoshiro256** function: generates a random 64-bit value +static inline uint64_t xoshiro256_next(xoshiro256_state *state) { + const uint64_t result = rotl(state->s[1] * 5, 7) * 9; + const uint64_t t = state->s[1] << 17; + + state->s[2] ^= state->s[0]; + state->s[3] ^= state->s[1]; + state->s[1] ^= state->s[2]; + state->s[0] ^= state->s[3]; + + state->s[2] ^= t; + state->s[3] = rotl(state->s[3], 45); + + return result; +} + +// Jump function - equivalent to 2^128 calls to xoshiro256_next +// Useful for generating non-overlapping sequences for parallel computations +static inline void xoshiro256_jump(xoshiro256_state *state) { + static const uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c }; + + uint64_t s0 = 0; + uint64_t s1 = 0; + uint64_t s2 = 0; + uint64_t s3 = 0; + for(int i = 0; i < sizeof JUMP / sizeof *JUMP; i++) { + for(int b = 0; b < 64; b++) { + if (JUMP[i] & UINT64_C(1) << b) { + s0 ^= state->s[0]; + s1 ^= state->s[1]; + s2 ^= state->s[2]; + s3 ^= state->s[3]; + } + xoshiro256_next(state); + } + } + + state->s[0] = s0; + state->s[1] = s1; + state->s[2] = s2; + state->s[3] = s3; +} + +// Splitmix64 algorithm for initializing the state +static inline uint64_t splitmix64(uint64_t *x) { + uint64_t z = (*x += 0x9e3779b97f4a7c15); + z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; + z = (z ^ (z >> 27)) * 0x94d049bb133111eb; + return z ^ (z >> 31); +} + +// Initialize xoshiro256** state with a 64-bit seed +static inline void xoshiro256_seed(xoshiro256_state *state, uint64_t seed) { + uint64_t tmp = seed; + state->s[0] = splitmix64(&tmp); + state->s[1] = splitmix64(&tmp); + state->s[2] = splitmix64(&tmp); + state->s[3] = splitmix64(&tmp); +} + +// Initialize the global state with current time or provided seed +static inline void rng_init(uint64_t seed) { + if (seed == 0) { + seed = (uint64_t)time(NULL); + } + xoshiro256_seed(&xoshiro_global_state, seed); +} + +// Generate a random double between 0.0 and 1.0 (inclusive 0.0, exclusive 1.0) +static inline f64 rng_uniform_f64(void) { + // Take the top 53 bits (the precision of a double) to get a value in [0,1) + return (xoshiro256_next(&xoshiro_global_state) >> 11) * (1.0 / 9007199254740992.0); +} + +// Generate a random int32 in the range [0, max) +static inline i32 rng_int32(i32 max) { + // Avoid modulo bias by using rejection sampling + const uint64_t threshold = (((uint64_t)-1) - ((uint64_t)-1) % max); + uint64_t r; + do { + r = xoshiro256_next(&xoshiro_global_state); + } while (r >= threshold); + return (i32)(r % max); +} + diff --git a/src/tolsac.c b/src/tolsac.c new file mode 100644 index 0000000..4a3a0bc --- /dev/null +++ b/src/tolsac.c @@ -0,0 +1,691 @@ +/** + * tolsac.c - source file containing creation of samples with various distributions. + * + * Copyright (C) 2025 https://optics-design.com + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * See the COPYING file for the full license text. + */ +#include +#include +#include +#include +#include "tolmacdef.h" + +// Enum for sampling methods +typedef enum { + SAMPLING_LHS, // Latin Hypercube Sampling + SAMPLING_MCS, // Monte Carlo Sampling + SAMPLING_GRID, // Grid Sampling + SAMPLING_SENS // Sensitivity Analysis +} SamplingMethod; + +// Enum for probability distribution functions +typedef enum { + PDF_UNIFORM = 'U', + PDF_NORMAL = 'N', + PDF_TRUNCNORMAL = 'T' // Truncated normal +} PdfType; + +// Parameter data structure for improved memory locality +typedef struct { + byte* pdf_types; // Probability distribution types + f64* nominal_values; // Nominal values + f64* min_values; // Minimum values + f64* max_values; // Maximum values + f64* mean_values; // Mean values + f64* stddev_values; // Standard deviation values +} ParameterData; + +// Allocate memory for parameter data structure +ParameterData* allocate_parameter_data(i32 param_count) { + ParameterData* data = (ParameterData*)malloc(sizeof(ParameterData)); + if (!data) return NULL; + + // Single contiguous allocation for all arrays for better cache locality + void* buffer = malloc( + param_count * sizeof(byte) + // pdf_types + param_count * sizeof(f64) * 5 // nominal, min, max, mean, stddev + ); + + if (!buffer) { + free(data); + return NULL; + } + + // Assign pointers to appropriate sections of the buffer + data->pdf_types = (byte*)buffer; + data->nominal_values = (f64*)(data->pdf_types + param_count); + data->min_values = data->nominal_values + param_count; + data->max_values = data->min_values + param_count; + data->mean_values = data->max_values + param_count; + data->stddev_values = data->mean_values + param_count; + + return data; +} + +// Free parameter data structure +void free_parameter_data(ParameterData* data) { + if (data) { + // Only need to free the buffer pointed to by pdf_types (first allocation) + free(data->pdf_types); + free(data); + } +} + +// Normal CDF implementation (cumulative distribution function) +static inline f64 normal_cdf(f64 x) { + // Constants for approximation + const f64 a1 = 0.254829592; + const f64 a2 = -0.284496736; + const f64 a3 = 1.421413741; + const f64 a4 = -1.453152027; + const f64 a5 = 1.061405429; + const f64 p = 0.3275911; + + // Save the sign of x + int sign = 1; + if (x < 0) { + sign = -1; + x = -x; + } + + // A&S formula 7.1.26 + f64 t = 1.0 / (1.0 + p * x); + f64 y = 1.0 - (((((a5 * t + a4) * t + a3) * t + a2) * t + a1) * t * exp(-x * x)); + + return 0.5 * (1 + sign * y); +} + +static inline f64 inverse_normal_cdf(f64 u) { + // Use the approximation of the inverse CDF of the normal distribution + const f64 a1 = -3.969683028665376e+01; + const f64 a2 = 2.209460984245205e+02; + const f64 a3 = -2.759285104469687e+02; + const f64 a4 = 1.383577518672690e+02; + const f64 a5 = -3.066479806614716e+01; + const f64 a6 = 2.506628277459239e+00; + + const f64 b1 = -5.447609879822406e+01; + const f64 b2 = 1.615858368580409e+02; + const f64 b3 = -1.556989798598866e+02; + const f64 b4 = 6.680131188771972e+01; + const f64 b5 = -1.328068155288572e+01; + + const f64 c1 = -7.784894002430293e-03; + const f64 c2 = -3.223964580411365e-01; + const f64 c3 = -2.400758277161838e+00; + const f64 c4 = -2.549732539343734e+00; + const f64 c5 = 4.374664141464968e+00; + const f64 c6 = 2.938163982698783e+00; + + const f64 d1 = 7.784695709041462e-03; + const f64 d2 = 3.224671290700398e-01; + const f64 d3 = 2.445134137142996e+00; + const f64 d4 = 3.754408661907416e+00; + + const f64 p_low = 0.02425; + const f64 p_high = 1.0 - p_low; + + f64 q, r; + + if (u < p_low) { + q = sqrt(-2.0 * log(u)); + return (((((c1 * q + c2) * q + c3) * q + c4) * q + c5) * q + c6) / + ((((d1 * q + d2) * q + d3) * q + d4) * q + 1.0); + } else if (u <= p_high) { + q = u - 0.5; + r = q * q; + return (((((a1 * r + a2) * r + a3) * r + a4) * r + a5) * r + a6) * q / + (((((b1 * r + b2) * r + b3) * r + b4) * r + b5) * r + 1.0); + } else { + q = sqrt(-2.0 * log(1.0 - u)); + return -(((((c1 * q + c2) * q + c3) * q + c4) * q + c5) * q + c6) / + ((((d1 * q + d2) * q + d3) * q + d4) * q + 1.0); + } +} + +// Generate sample based on distribution type +static inline f64 generate_sample(byte pdf_type, f64 u, f64 min, f64 max, f64 mean, f64 stddev) { + switch (pdf_type) { + case PDF_NORMAL: // 'N' + // For normal: mean + stddev * inverse_normal_cdf(u) + return mean + stddev * inverse_normal_cdf(u); + + case PDF_TRUNCNORMAL: // 'T' + // For truncated normal: + { + // 1. Calculate normalized min and max values + f64 z_min = (min - mean) / stddev; + f64 z_max = (max - mean) / stddev; + + // 2. Calculate CDF at min and max + f64 cdf_min = normal_cdf(z_min); + f64 cdf_max = normal_cdf(z_max); + + // 3. Scale u to be between cdf_min and cdf_max + f64 u_scaled = cdf_min + u * (cdf_max - cdf_min); + + // 4. Apply inverse CDF to get value in correct range + return mean + stddev * inverse_normal_cdf(u_scaled); + } + + case PDF_UNIFORM: // 'U' + // For uniform: min + u * (max - min) + return min + u * (max - min); + + default: + // Default to uniform if unknown + return min + u * (max - min); + } +} + +// Function to display help information +void display_help(void) { + printf("Description:\n" + "The program generates random values for parameters based on the " + "given range and the probability distribution. " + "It is expected that the output is used in another program " + "to perform tolerancing.\n\n" + "Usage:\n" + ".\\tolsamp.exe Input.csv 50 [-o Output.csv]\n" + "Where:\n" + "Input.csv is a csv input file of a specific form.\n" + "50 is the number of iterations produced (not required for the " + "grid and sensitivity samplings)\n" + "-o Output.csv specifies the output path and filename.\n" + "If not provided, output will be named Sampled_[Input.csv] in the current directory.\n" + "If you are unsure how the input should look like, " + "run the program with the -e option to generate an example " + "input file.\n\n" + "Options:\n" + "-l, -g, -m, -s are used for latin hypercube, grid, Monte Carlo " + "(random), and sensitivity samplings.\n" + "Use -m only if there are some issues with the LHS. " + "LHS usually is the best.\n" + "-o specifies the output filename (can include path).\n" + "-e is used for example csv generation.\n\n" + "Defaults:\n" + "In the default case the program runs with -l.\n\n" + "Input CSV file info:\n" + "CSV file also contains possible probability density functions " + "(U-Uniform, N-Normal, T-Truncated Normal) and the associated mean " + "and standard deviation parameters.\n" + "This program can produce symmetric normal and truncated normal distributions."); +} + +// Function to generate example file +void generate_example(void) { + FILE *writefile = fopen("Example.csv", "w"); + if (!writefile) { + printf("Error creating example file!\n"); + return; + } + + fprintf(writefile, "Iteration Number,Parameter 1 Name,Parameter 2 Name,Parameter 3 Name,Parameter 4 Name\n"); + fprintf(writefile, "Probability Density Function (U=Uniform; N=Normal/Gaussian; T=Truncated Normal),U,U,N,T\n"); + fprintf(writefile, "Nominal, 0, 0, 6, 5\n"); + fprintf(writefile, "Max, 1, 0.1, 10, 7\n"); + fprintf(writefile, "Min, -1, -0.1, 2, 3\n"); + fprintf(writefile, "Mean,0.0, 0.0, 6.0, 5.0\n"); + fprintf(writefile, "Standard Deviation, 0, 0, 1.3, 1.0\n"); + fclose(writefile); + + printf("Example.csv file generated!\n"); +} + +// Optimized LHS interval generation that transposes for better cache locality +void generate_lhs_intervals(i32 iterations, i32 param_count, i32* intervals) { + // Initialize intervals for LHS in column-major order for better cache locality + for (i32 i = 0; i < iterations; i++) { + for (i32 j = 0; j < param_count; j++) { + // Store in transposed form: intervals[i * param_count + j] = i + intervals[i * param_count + j] = i; + } + } + + // Fisher-Yates shuffle for each parameter (each column) + for (i32 j = 0; j < param_count; j++) { + for (i32 i = iterations - 1; i > 0; i--) { + i32 k = rng_int32(i + 1); + // Swap intervals[i * param_count + j] and intervals[k * param_count + j] + i32 temp = intervals[i * param_count + j]; + intervals[i * param_count + j] = intervals[k * param_count + j]; + intervals[k * param_count + j] = temp; + } + } +} + +i32 main(i32 argc, char *argv[]) { + // Initialize variables + SamplingMethod sampling_method = SAMPLING_LHS; // Default to LHS + i32 iterations = 0; + char rfilename[FILENAME_MAX] = {0}; + char wfilename[FILENAME_MAX] = {0}; + i32 input_specified = 0; + i32 output_specified = 0; + i32 expect_output_file = 0; + + // Check for no arguments + if (argc == 1) { + printf("No input provided. Use -h for help.\n"); + return 1; + } + + // Process all arguments + for (i32 i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + // Process flag arguments + switch (argv[i][1]) { + case 'h': + display_help(); + return 0; + case 'e': + generate_example(); + return 0; + case 'm': + sampling_method = SAMPLING_MCS; + break; + case 'g': + sampling_method = SAMPLING_GRID; + break; + case 'l': + sampling_method = SAMPLING_LHS; + break; + case 's': + sampling_method = SAMPLING_SENS; + break; + case 'o': + // Next argument should be the output file + expect_output_file = 1; + break; + default: + printf("Unknown option: -%c\n", argv[i][1]); + break; + } + } else if (expect_output_file) { + // This is the output file specified after -o + strcpy(wfilename, argv[i]); + output_specified = 1; + expect_output_file = 0; + } else if (strstr(argv[i], ".csv")) { + // This is an input CSV file (we now only allow one) + if (!input_specified) { + strcpy(rfilename, argv[i]); + input_specified = 1; + } else { + printf("Warning: Multiple input files specified. Using only the first one: %s\n", rfilename); + } + } else { + // Parse iteration count + i32 tmp = atoi(argv[i]); + if (tmp > 0) { + iterations = tmp; + } + } + } + + // Error checks + if (!input_specified) { + printf("Error! No input CSV provided. Use -e if you want to see how it looks like.\n"); + return 1; + } + + if (expect_output_file) { + printf("Error! Expected an output file after -o option.\n"); + return 1; + } + + if (iterations == 0 && sampling_method != SAMPLING_GRID && sampling_method != SAMPLING_SENS) { + printf("Error! You didn't provide an integer number of iterations.\n"); + return 1; + } + + // Generate default output filename if not specified + if (!output_specified) { + // Generate default output filename - handle both Windows and Unix paths + char *file_ptr = strrchr(rfilename, '\\'); + if (!file_ptr) { + file_ptr = strrchr(rfilename, '/'); + } + + strcpy(wfilename, "Sampled_"); + if (file_ptr) { + strcat(wfilename, file_ptr + 1); + } else { + strcat(wfilename, rfilename); + } + } + + // Check if input file exists + FILE *readfile = fopen(rfilename, "r"); + if (!readfile) { + printf("Error! Input file not found: %s\n", rfilename); + return 1; + } + + // Open output file + FILE *writefile = fopen(wfilename, "w"); + if (!writefile) { + printf("Error! Could not create output file: %s\n", wfilename); + fclose(readfile); + return 1; + } + + // Read the header line + char header_line[1024] = {0}; + if (!fgets(header_line, sizeof(header_line), readfile)) { + printf("Error reading header line!\n"); + fclose(readfile); + fclose(writefile); + return 1; + } + + // Write the header line to output + fputs(header_line, writefile); + + // Count parameters (commas) + i32 param_count = 0; + for (char *p = header_line; *p; p++) { + if (*p == ',') param_count++; + } + + printf("1. Total of %d parameters detected in %s. Output file is named %s.\n", param_count, rfilename, wfilename); + + // Initialize RNG with current time as seed + rng_init(0); + + // Allocate parameter data structure + ParameterData* params = allocate_parameter_data(param_count); + if (!params) { + printf("Error! Memory allocation failed for parameter data.\n"); + fclose(readfile); + fclose(writefile); + return 1; + } + + // Parse input file - using larger fixed size buffers to avoid potential overflows + char buffer[32768]; // 32KB buffer for reading lines + char *token, *err_ptr; + i32 k = 0; + + // PDFs + if (!fgets(buffer, sizeof(buffer), readfile)) { + printf("Error reading PDF line from input file!\n"); + free_parameter_data(params); + fclose(readfile); + fclose(writefile); + return 1; + } + + token = strtok(buffer, ","); + while ((token = strtok(NULL, ","))) { + params->pdf_types[k++] = *token; + } + + // Nominal + k = 0; + if (!fgets(buffer, sizeof(buffer), readfile)) { + printf("Error reading nominal values from input file!\n"); + free_parameter_data(params); + fclose(readfile); + fclose(writefile); + return 1; + } + + token = strtok(buffer, ","); + while ((token = strtok(NULL, ","))) { + params->nominal_values[k++] = strtof(token, &err_ptr); + } + + // Maxima + k = 0; + if (!fgets(buffer, sizeof(buffer), readfile)) { + printf("Error reading maximum values from input file!\n"); + free_parameter_data(params); + fclose(readfile); + fclose(writefile); + return 1; + } + + token = strtok(buffer, ","); + while ((token = strtok(NULL, ","))) { + params->max_values[k++] = strtof(token, &err_ptr); + } + + // Minima + k = 0; + if (!fgets(buffer, sizeof(buffer), readfile)) { + printf("Error reading minimum values from input file!\n"); + free_parameter_data(params); + fclose(readfile); + fclose(writefile); + return 1; + } + + token = strtok(buffer, ","); + while ((token = strtok(NULL, ","))) { + params->min_values[k++] = strtof(token, &err_ptr); + } + + // Means + k = 0; + if (!fgets(buffer, sizeof(buffer), readfile)) { + printf("Error reading mean values from input file!\n"); + free_parameter_data(params); + fclose(readfile); + fclose(writefile); + return 1; + } + + token = strtok(buffer, ","); + while ((token = strtok(NULL, ","))) { + params->mean_values[k++] = strtof(token, &err_ptr); + } + + // Standard Deviations + k = 0; + if (!fgets(buffer, sizeof(buffer), readfile)) { + printf("Error reading standard deviation values from input file!\n"); + free_parameter_data(params); + fclose(readfile); + fclose(writefile); + return 1; + } + + token = strtok(buffer, ","); + while ((token = strtok(NULL, ","))) { + params->stddev_values[k++] = strtof(token, &err_ptr); + } + + fclose(readfile); + printf("2. Input CSV successfully parsed.\n"); + + // Write initial reference row + fprintf(writefile, "1"); + for (i32 j = 0; j < param_count; j++) { + fprintf(writefile, ",%g", params->nominal_values[j]); + } + fprintf(writefile, "\n"); + + // Generate and write samples based on sampling method + switch (sampling_method) { + case SAMPLING_MCS: + // Monte Carlo sampling + for (i32 i = 0; i < iterations; i++) { + // Write row number + fprintf(writefile, "%d", i + 2); + + // Generate samples for each parameter + for (i32 j = 0; j < param_count; j++) { + f64 u = rng_uniform_f64(); + f64 sample = generate_sample(params->pdf_types[j], u, + params->min_values[j], params->max_values[j], + params->mean_values[j], params->stddev_values[j]); + + // If truncated normal and out of bounds, use uniform random between min and max + if (params->pdf_types[j] == PDF_TRUNCNORMAL && + (sample < params->min_values[j] || sample > params->max_values[j])) { + f64 u_uniform = rng_uniform_f64(); + sample = generate_sample('U', u_uniform, + params->min_values[j], params->max_values[j], + params->mean_values[j], params->stddev_values[j]); + } + + fprintf(writefile, ",%g", sample); + } + + fprintf(writefile, "\n"); + } + break; + + case SAMPLING_GRID: + // Handle grid sampling iterations for large parameter counts + if (param_count >= 30) { // 2^30 would be over a billion iterations + printf("Error: Grid sampling with %d parameters would result in too many iterations (2^%d).\n", + param_count, param_count); + free_parameter_data(params); + fclose(writefile); + return 1; + } else { + iterations = 1 << param_count; + if (param_count > 17) { + char response; + printf("You have %d parameters, which corresponds to %d iterations. Are you sure this is what you want? (y/n): ", + param_count, iterations); + scanf("%c", &response); + if (response != 'y') { + printf("Quitting.\n"); + free_parameter_data(params); + fclose(writefile); + return 1; + } + } + } + + // Grid sampling + for (i32 i = 0; i < iterations; i++) { + // Write row number + fprintf(writefile, "%d", i + 2); + + // Generate samples for each parameter + for (i32 j = 0; j < param_count; j++) { + f64 sample; + + // Safe bit manipulation even for large parameter counts + if ((i >> j) & 1) { + sample = params->max_values[j]; + } else { + sample = params->min_values[j]; + } + + fprintf(writefile, ",%g", sample); + } + + fprintf(writefile, "\n"); + } + break; + + case SAMPLING_SENS: + // Calculate number of iterations needed: 2 * number of parameters + iterations = 2 * param_count; + + // For each parameter + for (i32 j = 0; j < param_count; j++) { + // Parameter at minimum, others at nominal + fprintf(writefile, "%d", j*2 + 2); + for (i32 k = 0; k < param_count; k++) { + if (k == j) { + // This parameter at minimum + fprintf(writefile, ",%g", params->min_values[k]); + } else { + // Others at nominal + fprintf(writefile, ",%g", params->nominal_values[k]); + } + } + fprintf(writefile, "\n"); + + // Parameter at maximum, others at nominal + fprintf(writefile, "%d", j*2 + 3); + for (i32 k = 0; k < param_count; k++) { + if (k == j) { + // This parameter at maximum + fprintf(writefile, ",%g", params->max_values[k]); + } else { + // Others at nominal + fprintf(writefile, ",%g", params->nominal_values[k]); + } + } + fprintf(writefile, "\n"); + } + break; + + case SAMPLING_LHS: + // Allocate intervals for LHS (transposed for better cache locality) + i32 *intervals = (i32*)malloc(iterations * param_count * sizeof(i32)); + if (!intervals) { + printf("Error! Memory allocation failed for intervals.\n"); + free_parameter_data(params); + fclose(writefile); + return 1; + } + + // Generate LHS intervals with improved cache locality + generate_lhs_intervals(iterations, param_count, intervals); + + // Latin Hypercube sampling + for (i32 i = 0; i < iterations; i++) { + // Write row number + fprintf(writefile, "%d", i + 2); + + // Generate samples for each parameter + for (i32 j = 0; j < param_count; j++) { + // Get interval for this parameter (accessing in transposed form) + i32 interval = intervals[i * param_count + j]; + f64 interval_start = (f64)interval / iterations; + f64 interval_end = (f64)(interval + 1) / iterations; + f64 u = interval_start + rng_uniform_f64() * (interval_end - interval_start); + + f64 sample = generate_sample(params->pdf_types[j], u, + params->min_values[j], params->max_values[j], + params->mean_values[j], params->stddev_values[j]); + + // Handle truncated normal out-of-bounds samples with improved approach + while (params->pdf_types[j] == PDF_TRUNCNORMAL && + (sample < params->min_values[j] || sample > params->max_values[j])) { + // Try a new sample within the same interval for better statistical properties + i32 i_rej = rng_int32(iterations); + i32 j_rej = rng_int32(param_count); + i32 interval_rej = intervals[i_rej * param_count + j_rej]; + f64 interval_start_rej = (f64)interval_rej / iterations; + f64 interval_end_rej = (f64)(interval_rej + 1) / iterations; + f64 u_rej = interval_start_rej + rng_uniform_f64() * (interval_end_rej - interval_start_rej); + sample = generate_sample(params->pdf_types[j], u_rej, + params->min_values[j], params->max_values[j], + params->mean_values[j], params->stddev_values[j]); + } + + fprintf(writefile, ",%g", sample); + } + + fprintf(writefile, "\n"); + } + + // Free LHS intervals + free(intervals); + break; + } + + // Clean up + free_parameter_data(params); + + printf("3. %d rows and %d columns have been written to the file.\nProgram finished! Check the output!\n", + iterations + 1, param_count + 1); + fclose(writefile); + + return 0; +} diff --git a/structure.txt b/structure.txt new file mode 100644 index 0000000..3b7407e --- /dev/null +++ b/structure.txt @@ -0,0 +1,25 @@ +tolsac +| .clangd +| .gitignore +| compile_flags.txt +| COPYING +| COPYRIGHT +| Makefile +| README.md +| structure.txt +| ++---bin +| tolsac.exe +| ++---include +| toldef.h +| tolmacdef.h +| ++---src +| tolsac.c +| +\---tests + Example.csv + hist.r + Sampled_Example.csv + diff --git a/tests/Example.csv b/tests/Example.csv new file mode 100644 index 0000000..2c6ed66 --- /dev/null +++ b/tests/Example.csv @@ -0,0 +1,7 @@ +Iteration Number,Parameter 1 Name,Parameter 2 Name,Parameter 3 Name,Parameter 4 Name +Probability Density Function (U=Uniform; N=Normal/Gaussian; T=Truncated Normal),U,U,N,T +Nominal, 0, 0, 6, 5 +Max, 1, 0.1, 10, 7 +Min, -1, -0.1, 2, 3 +Mean,0.0, 0.0, 6.0, 5.0 +Standard Deviation, 0, 0, 1.3, 1.5 diff --git a/tests/Sampled_Example.csv b/tests/Sampled_Example.csv new file mode 100644 index 0000000..4357a72 --- /dev/null +++ b/tests/Sampled_Example.csv @@ -0,0 +1,1002 @@ +Iteration Number,Parameter 1 Name,Parameter 2 Name,Parameter 3 Name,Parameter 4 Name +1,0,0,6,5 +2,-0.447882,-0.0167241,2.57527,4.37054 +3,0.968682,-0.0586998,7.45248,5.06988 +4,-0.842439,-0.0561725,6.52784,5.01692 +5,-0.395612,0.0442927,4.92421,5.38399 +6,0.0420414,0.0584518,8.34442,3.96429 +7,-0.730353,0.00440439,7.07359,4.5874 +8,-0.464467,-0.00851533,6.55851,4.45161 +9,-0.996313,0.0883977,5.48266,3.83068 +10,-0.716747,0.0174173,7.06949,5.65414 +11,-0.218966,0.0199446,7.29352,6.10357 +12,0.716854,-0.00492169,5.5187,4.27839 +13,0.654153,-0.00251044,5.53421,5.51787 +14,0.265945,-0.0634619,8.16951,4.17465 +15,0.736711,-0.0784835,4.87941,4.75171 +16,-0.732259,-0.0571093,5.59827,4.18606 +17,0.826133,-0.0293251,6.51912,6.4991 +18,0.986128,0.014704,5.47865,3.89358 +19,-0.672543,-0.0179533,7.21728,4.71736 +20,0.339959,0.0226431,6.15126,5.12981 +21,0.712746,-0.0704099,5.71231,4.53799 +22,-0.713658,-0.0568181,5.76801,5.43618 +23,0.697891,-0.0548865,5.5665,5.29645 +24,-0.746132,0.0634282,4.62583,4.83363 +25,0.781298,-0.0111269,4.26713,6.79052 +26,0.795403,0.0501854,5.22077,3.26088 +27,0.657083,-0.0880077,3.84039,3.87686 +28,-0.710088,-0.0532829,7.09584,4.47555 +29,0.701074,-0.0691546,8.04346,4.01534 +30,0.650317,-0.0203927,5.82273,3.84334 +31,0.0681637,0.0888699,6.53559,3.81846 +32,-0.900036,0.0988853,5.56396,3.23206 +33,-0.939905,-0.0604353,5.63373,5.726 +34,-0.285908,0.0605226,7.77042,4.78695 +35,0.359812,-0.0106921,6.72127,6.19754 +36,-0.971847,0.0587401,5.84393,5.93756 +37,-0.192236,0.0783495,4.46394,6.07152 +38,0.527827,0.0127592,5.68722,3.761 +39,-0.629812,-0.0360936,4.54711,3.87198 +40,0.955132,0.0494486,5.80461,4.66938 +41,-0.502164,-0.0948897,6.96044,4.406 +42,-0.8638,-0.0364034,5.39141,4.11295 +43,0.456398,-0.0667134,5.74804,5.84887 +44,0.0230029,-0.0822804,6.51306,3.99537 +45,0.678608,0.0979709,6.01203,5.78782 +46,0.52493,-0.0645964,4.84491,3.88287 +47,-0.314555,-0.096328,5.68084,3.67162 +48,-0.57384,0.0377082,5.45966,4.52394 +49,0.964836,0.0856935,8.93762,3.62629 +50,-0.985586,-0.0135407,5.94306,5.71236 +51,-0.17499,0.0588124,4.73971,3.16714 +52,0.453448,-0.0366041,7.23516,6.32631 +53,0.575641,-0.0452107,4.80583,6.09766 +54,-0.561616,0.0203688,6.20688,4.93558 +55,0.413243,0.00117644,5.38056,4.96387 +56,-0.119488,-0.0208496,7.11087,4.70102 +57,0.908748,-0.0554151,6.94175,5.46428 +58,0.436673,-0.076233,6.95583,4.72678 +59,-0.812224,-0.0741759,4.00006,6.54116 +60,-0.213875,0.0815374,3.43701,6.11375 +61,0.0997154,-0.0959217,6.10218,5.54485 +62,-0.182745,-0.0713067,5.2254,4.8262 +63,0.643063,-0.0777787,6.29343,4.97055 +64,-0.657443,-0.0261338,7.44153,5.81302 +65,0.907553,0.0529798,1.21361,4.73027 +66,-0.727405,-0.000964708,6.71294,4.59887 +67,0.991171,0.0410835,4.09214,5.75676 +68,-0.403396,0.0474208,5.73934,3.92465 +69,0.369762,-0.0263021,7.06172,5.55773 +70,-0.535768,0.0908397,6.74394,6.24678 +71,0.470341,0.0117787,5.72393,6.94032 +72,-0.659509,0.0535654,6.79983,5.96893 +73,0.229148,-0.070948,6.24115,6.3896 +74,0.0194076,0.0467775,7.82273,4.99095 +75,-0.565808,0.0381452,7.41394,5.89978 +76,-0.373072,-0.0787176,7.18893,5.5416 +77,0.24659,0.0968746,6.22648,5.49112 +78,-0.139242,-0.0447999,5.50334,4.57077 +79,-0.898432,-0.0510666,5.83581,4.68997 +80,0.0759989,0.0954872,8.25718,3.65297 +81,-0.244209,-0.0922574,4.51292,4.89523 +82,-0.972266,-0.0758223,7.19227,4.32329 +83,-0.488452,-0.079611,5.27467,3.55407 +84,0.923246,0.0957127,4.25643,5.45439 +85,0.353145,0.0213887,7.61903,5.40905 +86,0.706658,0.0825657,3.31347,4.42219 +87,-0.825253,0.0642244,4.94751,4.81509 +88,-0.687673,0.0686716,5.41272,5.11562 +89,-0.83432,-0.0573159,5.39984,4.30768 +90,0.0802876,0.0295784,4.97041,5.38632 +91,-0.549515,-0.0266952,6.4171,4.38665 +92,0.371264,-0.0773921,5.22885,4.33423 +93,0.556976,-0.0151217,3.66933,4.73687 +94,0.932123,-0.0820083,5.44319,5.00806 +95,-0.933178,-0.0678849,6.01781,4.44967 +96,-0.674372,-0.0258927,7.28393,5.05837 +97,-0.735469,-0.0240827,5.82916,5.53068 +98,-0.689544,-0.00692896,6.00083,5.50792 +99,-0.567228,0.0062815,4.17524,3.80887 +100,0.306025,0.0242629,7.91922,6.18336 +101,-0.719473,-0.00370206,7.22046,6.63811 +102,-0.934549,-0.031138,6.53755,4.62173 +103,0.100405,0.0141187,5.82583,6.00714 +104,0.232662,-0.0425564,6.61035,4.986 +105,0.0504862,0.0414032,7.02963,5.01913 +106,0.345798,0.0869024,6.89868,6.26711 +107,0.178741,0.065199,3.95032,6.15243 +108,0.89192,0.0403636,6.50625,5.59484 +109,-0.820973,-0.097744,6.43467,4.20883 +110,-0.756392,-0.0651285,3.89501,3.48304 +111,-0.738683,-0.0363131,5.1808,6.6803 +112,-0.467467,-0.0724549,5.01244,4.96739 +113,0.598525,-0.00785212,5.85621,4.55869 +114,-0.995193,-0.000253996,8.88759,5.56799 +115,0.259586,0.0617719,6.84112,5.89832 +116,0.647481,-0.0710609,4.99052,4.33819 +117,0.301813,0.0855286,7.40323,5.49383 +118,0.604621,0.0160448,5.89458,6.32008 +119,-0.154248,0.0190188,6.10808,6.36604 +120,0.984922,0.099552,9.05249,4.82814 +121,0.682685,0.0666382,5.55203,3.64061 +122,-0.799513,0.0301887,5.21158,3.3093 +123,0.974139,-0.0542228,5.26875,5.31889 +124,-0.937418,-0.0441004,7.57021,4.00431 +125,-0.764542,0.0105609,4.64943,6.41319 +126,0.141831,-0.052722,5.88616,4.89187 +127,-0.897664,-0.0021101,5.90348,3.0079 +128,0.704236,-0.0590139,6.26458,5.77059 +129,-0.208156,-0.0254016,7.17396,5.53251 +130,-0.396605,-0.00350822,5.15711,5.36691 +131,-0.926232,-0.082603,6.20571,5.49721 +132,-0.26272,-0.0022374,5.85127,4.39383 +133,0.884893,0.0810895,6.38736,3.33906 +134,-0.85282,0.0912056,7.40907,5.08187 +135,0.116389,0.0452358,6.13414,3.472 +136,-0.905177,0.00416206,7.04262,5.47137 +137,0.44843,0.0433479,4.87319,6.44758 +138,-0.617761,-0.0488104,6.12911,3.96596 +139,0.174553,-0.09882,5.75764,5.55024 +140,0.988424,-0.0600381,4.00996,3.77518 +141,0.123911,0.00881982,3.53782,3.52492 +142,-0.921843,0.0136343,5.20361,4.03158 +143,0.54157,-0.0331757,6.41406,6.10018 +144,-0.430945,0.0754509,4.50248,3.95513 +145,-0.0910368,0.0159377,6.79227,5.56403 +146,-0.0943865,0.0673901,5.95812,4.19634 +147,-0.660774,0.0850891,4.79937,6.41451 +148,-0.544388,-0.043736,4.64065,3.18219 +149,0.630193,-0.0305334,7.4989,6.53869 +150,-0.786742,0.0138837,5.19373,5.42473 +151,0.54869,0.0438838,5.57561,5.66366 +152,0.46726,0.059771,8.10334,4.99764 +153,-0.78854,-0.00667272,6.29983,6.97996 +154,0.335494,-0.0719047,7.30519,3.3768 +155,-0.220027,0.0644722,3.415,4.88206 +156,0.588577,0.0215093,6.62933,3.12618 +157,0.842895,0.0692282,8.13171,5.64374 +158,-0.819189,0.0972089,7.35688,4.50819 +159,0.614577,-0.0174063,4.21834,3.37839 +160,-0.952023,0.0055239,4.92834,4.79392 +161,-0.833396,0.0680885,4.31944,3.80561 +162,0.173786,-0.0276478,3.74784,5.86632 +163,-0.592177,-0.0199384,4.89485,3.64448 +164,0.740539,0.0274154,3.81028,6.45662 +165,0.360042,-0.0499098,4.93024,4.28887 +166,0.979022,-0.0114882,7.32906,3.09969 +167,-0.517457,0.0394904,4.45691,6.91519 +168,-0.224939,0.0348959,4.21479,4.80894 +169,0.445653,0.0427182,5.81551,6.34243 +170,-0.613498,0.0574911,6.13966,4.67793 +171,0.674897,0.0284446,6.83371,4.03345 +172,0.597087,0.0779726,5.98402,3.42582 +173,0.925651,-0.0314347,6.89272,4.43453 +174,0.255717,0.0471462,6.97478,3.02556 +175,0.518187,0.0131116,7.36307,5.10906 +176,0.952062,0.0925079,6.37074,3.71522 +177,-0.229939,-0.0669795,4.75404,3.13559 +178,0.728821,-0.0152894,6.98833,4.49151 +179,0.761291,-0.0729278,6.9939,4.84006 +180,0.0216248,0.0975493,6.03085,4.78019 +181,-0.837999,0.0553182,6.78562,5.4768 +182,-0.85994,0.0148813,5.80217,5.64577 +183,-0.162013,-0.0902881,8.54107,6.28248 +184,-0.0813104,0.0886957,3.40036,4.54778 +185,0.611182,-0.0229593,4.32705,6.75535 +186,0.380256,0.035328,6.47261,4.15551 +187,0.505778,-0.0834097,6.2971,4.04227 +188,0.570607,0.0684035,6.17184,4.80449 +189,-0.742795,-0.00118026,6.63021,5.03103 +190,0.666085,0.0259659,5.68754,6.65378 +191,-0.587616,-0.00594362,4.95333,5.62173 +192,0.475471,0.0124374,6.06577,4.77336 +193,-0.721046,0.0637672,4.0255,6.90545 +194,0.269683,0.0205119,8.55635,3.71897 +195,0.77679,0.0152585,9.60269,4.98546 +196,0.256514,-0.0535,4.72483,4.89772 +197,0.873463,0.00338909,4.60508,5.14936 +198,0.281765,0.0821528,8.08739,4.90181 +199,0.688119,-0.0225357,6.90892,5.29216 +200,0.765095,0.0337324,7.25798,5.6659 +201,0.889383,-0.0222998,5.4247,4.41416 +202,0.897011,0.0156682,3.3655,3.19315 +203,0.208447,0.0608197,5.01801,4.79494 +204,-0.423545,-0.0505884,6.54883,3.97621 +205,0.158625,0.00944769,6.08214,6.99696 +206,-0.0693748,-0.0556187,6.78096,4.86038 +207,0.133182,0.0712631,5.2789,6.28937 +208,-0.910302,0.0506966,6.93456,3.91164 +209,0.222531,0.0271163,5.70961,5.40393 +210,0.432682,0.0919812,2.82477,4.97308 +211,0.917315,0.0302886,5.07316,4.08406 +212,-0.0824936,-0.0348718,5.04029,5.77685 +213,-0.0293627,-0.037113,7.04671,4.77231 +214,0.930167,0.0335741,8.99116,3.31549 +215,0.328307,-0.086189,6.97263,3.93135 +216,-0.276393,0.0661015,6.96495,3.20922 +217,-0.473442,0.0527808,5.88474,5.86005 +218,-0.185443,0.0674854,6.49477,3.54912 +219,0.253531,0.00236887,5.92409,5.51487 +220,0.823332,0.0031927,6.35539,3.47801 +221,-0.0314977,-0.023755,5.99195,4.06917 +222,0.559419,-0.0415516,5.07394,5.96741 +223,-0.387405,-0.0483364,8.58131,4.72155 +224,0.000938099,-0.0782131,5.96624,6.97783 +225,-0.870667,-0.0852506,7.59355,3.05904 +226,0.882753,-0.0647502,2.88994,5.39605 +227,0.477114,-0.0566438,7.21354,3.79257 +228,0.126349,-0.0925395,6.11935,5.79767 +229,0.276526,-0.0735531,7.31262,6.66461 +230,-0.0561094,0.0496187,5.44242,6.46741 +231,-0.524611,-0.0492514,6.27246,3.40635 +232,0.241191,0.0493998,5.26523,3.43 +233,0.660705,0.0731228,7.52495,4.12086 +234,-0.526091,0.0896358,4.55273,6.21669 +235,0.506942,-0.0632736,5.97479,6.69781 +236,0.910124,-0.0997819,5.13694,6.11498 +237,-0.949761,0.0664112,6.40907,5.27953 +238,-0.359428,0.0398529,7.03676,4.51869 +239,0.881267,-0.097307,6.13182,5.49898 +240,0.425903,0.0520036,4.67988,6.5505 +241,-0.017614,0.0458008,3.11509,5.77312 +242,0.177183,-0.0375532,7.55761,6.43617 +243,-0.413749,0.0668244,5.32521,6.53206 +244,-0.682656,-0.06418,5.09414,5.46825 +245,-0.335924,-0.0404222,5.48525,3.97914 +246,-0.621607,0.0281545,5.97244,3.30292 +247,-0.410954,-0.081589,6.81962,3.70504 +248,-0.131579,0.025133,4.81337,5.91483 +249,-0.643893,0.0571846,6.46175,4.22122 +250,0.137833,-0.0907484,6.24317,4.32529 +251,-0.699381,-0.0194648,7.02091,4.42987 +252,-0.906464,-0.0380112,4.08496,5.61688 +253,-0.109872,0.0976799,6.33594,4.16758 +254,-0.345451,0.0473003,6.53995,6.24834 +255,-0.552631,-0.0806535,5.10951,3.33145 +256,0.114965,-0.077854,7.46491,6.79924 +257,0.510624,-0.0828562,6.50407,6.58315 +258,-0.123538,-0.063637,5.40647,4.92253 +259,0.316427,0.0752851,8.32626,5.65877 +260,-0.306819,-0.0653918,7.50288,6.17207 +261,0.458155,-0.00875415,6.1457,6.7592 +262,0.19638,-0.0353143,5.38342,5.79475 +263,0.303132,0.0544628,5.81288,3.94937 +264,0.617004,-0.0553057,5.46806,4.03044 +265,-0.2895,-0.00771967,4.44776,3.74083 +266,0.866102,-0.0239031,6.70215,5.73104 +267,-0.595586,-0.0932501,5.78692,4.43624 +268,0.216168,0.0424111,5.64751,5.19029 +269,-0.231704,0.0558981,4.90141,5.33625 +270,0.645678,-0.0593946,3.63611,6.47477 +271,-0.584133,-0.0766389,6.94862,5.83625 +272,0.0482031,0.0238402,3.59925,4.27756 +273,-0.281485,-0.00752095,6.16198,5.26941 +274,0.860021,0.0142417,6.42672,5.80516 +275,-0.233452,-0.0904275,6.0539,4.55596 +276,0.994371,-0.0218868,6.72751,6.17783 +277,0.0410687,-0.0580399,5.87293,6.61679 +278,-0.676406,-0.0329075,7.2413,5.45124 +279,-0.633464,0.0513249,6.93616,4.2497 +280,0.797463,0.077395,5.33842,5.24904 +281,0.626169,-0.0983996,5.88137,6.40028 +282,-0.441236,0.0509016,5.6217,4.69873 +283,-0.255037,0.00921438,6.29056,5.16087 +284,0.936719,-0.0597182,6.02341,6.49352 +285,0.215629,-0.0454262,7.65356,4.95031 +286,0.86423,0.0548596,7.08162,4.22542 +287,-0.816846,-0.0521026,4.8167,4.09052 +288,0.82949,-0.00329349,7.20475,6.67813 +289,-0.648816,-0.0626137,7.45065,5.08661 +290,0.0549662,0.0628333,4.58718,6.07945 +291,-0.499267,0.0234465,5.76192,3.34746 +292,-0.361465,-0.029046,5.37334,6.26888 +293,0.501744,0.00961031,7.36609,5.83955 +294,0.724132,0.0253344,6.09187,3.66157 +295,0.29541,0.013509,5.24727,5.58327 +296,-0.630608,-0.0359966,7.24987,6.00026 +297,-0.241374,0.0249721,4.78122,5.15333 +298,-0.391692,-0.0422698,6.80457,4.59099 +299,-0.569316,-0.000751098,8.82007,5.48347 +300,-0.480839,0.0305361,5.01688,5.12234 +301,-0.215622,0.0324984,7.51963,4.65202 +302,-0.144384,-0.0137796,7.79852,5.02624 +303,0.160852,-0.0235047,6.11576,6.8196 +304,-0.0459201,0.00779192,5.52068,4.63473 +305,0.685963,0.048583,5.27151,4.45684 +306,-0.615854,-0.0141622,3.97086,4.63124 +307,0.231453,0.0792219,4.69414,6.45437 +308,0.585943,-0.0217014,4.24678,4.82178 +309,0.245821,0.0894909,8.28076,4.44263 +310,-0.452166,-0.0154468,7.09199,5.72026 +311,-0.363099,-0.0323235,5.41686,4.4803 +312,0.859871,0.0670861,7.14066,4.94039 +313,-0.581503,0.0363407,4.43193,3.85719 +314,-0.650316,0.0487371,4.62326,3.10615 +315,-0.399613,0.00151389,5.42409,3.56217 +316,-0.623515,0.0490866,5.30741,5.18395 +317,0.783009,-0.0665819,4.41966,6.64165 +318,-0.992391,0.000179528,7.16667,5.91732 +319,0.10229,-0.0270928,8.29753,4.55387 +320,0.686166,0.0993995,4.89936,5.60966 +321,0.03456,0.0178079,5.69818,3.5575 +322,0.591913,0.0767356,7.82944,4.87204 +323,-0.00933091,0.0543017,3.45373,4.30853 +324,-0.0497384,-0.0376161,8.63966,6.08434 +325,-0.873749,0.0983233,5.4744,3.89722 +326,-0.236903,0.0905202,5.46204,4.88379 +327,0.184567,-0.0753118,7.66202,4.26859 +328,0.39878,-0.0338946,6.3049,4.87874 +329,-0.479952,0.080193,4.01354,3.94669 +330,-0.543418,-0.0943023,8.47049,5.90547 +331,-0.439032,-0.0702886,5.66299,3.57201 +332,-0.0402448,0.00279236,6.56118,6.71805 +333,-0.40593,0.00138462,5.54612,5.35031 +334,-0.324062,0.0991148,4.57931,6.76916 +335,-0.77795,-0.0356648,5.0478,3.32442 +336,0.59517,-0.0746242,4.72252,5.26569 +337,-0.497067,-0.0227192,6.05114,3.98407 +338,0.747131,0.0610521,3.09424,4.50353 +339,-0.211979,-0.00817785,4.96723,5.65285 +340,-0.529852,-0.00303366,7.33176,4.771 +341,0.0287736,0.0760201,5.35109,4.34441 +342,-0.247779,0.0822478,5.10023,5.73361 +343,0.632293,0.0531918,4.85099,5.94669 +344,-0.0116691,0.0967781,5.95012,6.94889 +345,0.848955,0.0911154,5.60918,6.38924 +346,0.0917821,0.0640931,4.94183,6.13031 +347,-0.982618,0.0211953,4.65753,4.61662 +348,-0.268048,-0.00297396,3.57463,6.28172 +349,0.582139,0.00860731,5.63819,6.78215 +350,-0.0759892,-0.0599111,6.45111,5.62273 +351,-0.107291,-0.0251437,7.27559,5.8695 +352,0.0641808,-0.0191646,8.31377,5.61138 +353,0.383891,-0.0274609,4.78865,4.13383 +354,0.63896,-0.0514747,5.16197,5.19846 +355,-0.293211,-0.0378605,6.48545,5.85016 +356,-0.347835,-0.0283341,3.34977,6.48047 +357,0.778001,-0.0165353,5.39776,5.70961 +358,0.544432,0.0106265,6.21842,5.16637 +359,-0.418403,0.0102214,4.50679,4.31918 +360,-0.23928,0.0330596,4.94599,4.11073 +361,-0.807522,0.0936346,7.75342,5.28549 +362,0.792339,0.0632117,5.28679,5.66883 +363,0.45123,0.0613219,6.44441,4.23577 +364,-0.172954,0.0768933,7.8444,5.4302 +365,0.313298,-0.0692083,5.57291,5.19428 +366,0.13842,0.0218695,6.52972,3.94147 +367,-0.321588,-0.0392394,7.63814,5.13938 +368,-0.917753,0.0451538,5.75724,3.54491 +369,0.0663606,0.0254507,3.78852,5.07646 +370,-0.547309,0.0364548,5.17326,5.69291 +371,0.187332,0.0269347,4.59158,3.43798 +372,-0.421581,0.0947174,6.10598,3.38803 +373,-0.808228,0.0728471,5.24034,5.97069 +374,0.803048,-0.0897571,3.88338,5.89512 +375,0.0163484,0.0428364,4.57387,3.35312 +376,0.402944,-0.0321824,7.00863,4.7881 +377,-0.318217,0.0906388,6.87317,3.16166 +378,0.508925,0.0834661,7.15664,4.75823 +379,-0.437824,0.0123147,4.80041,6.85933 +380,-0.511178,-0.0623559,7.87173,4.55762 +381,-0.33241,0.00616004,6.57141,6.33098 +382,0.798718,-0.00438772,9.21337,4.6276 +383,-0.032534,-0.0844832,7.35084,6.44034 +384,0.393172,0.00525329,3.47903,4.80582 +385,0.567789,0.0808012,8.1386,5.75068 +386,0.512714,-0.051729,6.16729,3.51802 +387,0.814941,-0.0606589,7.50894,6.23457 +388,0.293212,-0.0176001,7.4925,5.78138 +389,-0.186157,-0.0460405,7.48206,5.13134 +390,0.790397,-0.0508458,7.08726,6.42703 +391,-0.541337,-0.0248437,6.19127,3.76707 +392,0.830345,0.0342872,4.70623,4.00569 +393,0.66468,0.0853083,5.49115,4.8173 +394,-0.740067,0.0816044,6.48792,3.7985 +395,-0.0895001,0.0885201,6.60196,4.65711 +396,-0.966493,-0.0564625,7.28157,3.61649 +397,0.602997,0.0812314,5.61954,6.92965 +398,-0.697117,-0.0770692,5.64634,4.67346 +399,0.204999,0.0128247,4.52246,6.06085 +400,0.388844,0.00480167,9.19093,3.22474 +401,0.207337,0.0522494,7.53227,6.65447 +402,-0.954319,-0.0256555,8.02203,4.21984 +403,0.748586,-0.0301821,7.72778,3.72534 +404,-0.267463,-0.0888338,6.34742,4.27441 +405,-0.1806,0.0865655,6.67489,6.18518 +406,0.542814,0.0316725,5.02259,3.4953 +407,-0.199849,0.0638234,5.87099,4.76091 +408,-0.434723,-0.0654511,7.90705,5.15769 +409,-0.201483,-0.0280003,4.68294,3.78385 +410,0.479443,0.0469453,4.5999,6.49783 +411,-0.48335,-0.0547165,5.60491,3.99108 +412,-0.94677,-0.0403818,6.33953,5.70251 +413,-0.0995917,-0.0960379,6.36381,4.58356 +414,-0.759582,0.0121358,7.16275,4.82493 +415,0.996777,0.0457364,5.47614,5.38631 +416,-0.301954,0.0369245,7.31989,4.02271 +417,-0.791738,0.0407898,7.22974,3.19928 +418,0.905175,-0.0347686,4.85403,6.05581 +419,0.181316,0.045568,8.21942,4.84848 +420,0.0855941,0.0877682,5.52726,4.6209 +421,-0.393668,0.0207996,4.79371,4.38223 +422,-0.356479,0.0417326,7.1263,6.58965 +423,-0.329374,-0.032534,7.59972,5.24243 +424,0.58181,-0.0161752,6.58609,6.3526 +425,-0.370638,0.0525331,7.55021,5.40032 +426,0.820049,0.038406,5.70406,6.44769 +427,-0.875578,0.0561351,4.86174,4.64629 +428,-0.364359,-0.0910919,6.96371,4.07667 +429,-0.943819,-0.00968003,6.52327,6.1056 +430,0.463098,0.0838425,5.58189,3.88977 +431,-0.110156,0.00378651,5.89622,5.07373 +432,0.612172,0.0338849,6.72653,3.59391 +433,0.105695,0.0841082,8.11842,4.20609 +434,0.96267,-0.0421921,4.83503,3.37025 +435,-0.282461,0.02609,5.49519,5.2704 +436,-0.892747,0.0849486,8.21582,6.51257 +437,-0.270907,0.0173874,7.62482,5.22567 +438,0.721243,-0.0699674,6.73239,6.36112 +439,0.00283749,-0.0173461,5.66519,5.17206 +440,-0.601342,0.0444921,4.82388,3.08261 +441,0.0577089,-0.0545411,4.35439,6.69224 +442,0.323587,0.0837654,5.58837,3.29778 +443,0.480969,0.00296886,7.7629,4.69717 +444,0.374932,0.0100135,6.54389,5.57432 +445,-0.0382771,0.0949732,5.64284,4.25272 +446,-0.457963,0.0844537,4.066,4.90493 +447,0.786136,0.0431109,6.91438,4.44512 +448,0.405889,-0.00999712,4.1832,3.86163 +449,0.62486,-0.0491397,4.88567,5.11415 +450,0.14816,0.043795,6.91986,4.84443 +451,-0.317443,0.075799,4.71062,4.28647 +452,0.0978568,-0.0794782,6.64646,4.52471 +453,0.670415,-0.026468,7.86306,5.25928 +454,0.468599,-0.0800634,6.74631,3.24641 +455,-0.626834,-0.0398973,5.83872,5.38197 +456,-0.202494,0.0224374,4.41893,3.867 +457,0.348749,-0.0868036,5.12123,3.77186 +458,0.900193,-0.0426021,4.17335,3.70114 +459,-0.748512,-0.0803691,5.03079,3.71145 +460,0.762341,-0.091686,5.77708,6.28181 +461,0.851884,-0.0927373,5.60287,3.96284 +462,-0.468561,0.00713548,4.53302,4.64102 +463,-0.407582,0.0166179,5.45312,5.96282 +464,0.351125,-0.0813509,5.05635,5.99148 +465,0.0702506,0.0842353,5.35841,3.78767 +466,0.564023,-0.0761019,6.31472,3.95563 +467,0.434635,-0.014894,5.49776,3.01764 +468,0.692717,0.0648941,6.22051,3.33056 +469,0.758045,0.0863439,6.38305,3.12703 +470,0.966156,0.00855882,5.8776,3.57503 +471,0.837238,-0.0878692,4.75718,6.03808 +472,-0.0075595,0.078772,5.95465,4.52762 +473,0.94082,-0.0950293,7.20607,6.8102 +474,0.539169,0.0176739,5.79545,6.31791 +475,0.743569,0.0282529,5.28828,5.33248 +476,0.711565,0.0744213,6.09983,3.73122 +477,0.485938,-0.0269474,5.0626,6.82159 +478,0.915705,0.0441107,4.2753,6.22049 +479,0.514101,0.0998842,6.07333,5.35528 +480,0.182719,0.0592243,2.75351,5.32595 +481,-0.684571,-0.0475112,5.11858,5.78901 +482,0.144518,0.0180858,8.46019,4.15149 +483,0.193973,-0.00896704,7.47345,3.53888 +484,0.774095,-0.00401251,6.88302,3.40121 +485,-0.923751,-0.0840488,6.32374,5.13177 +486,0.577043,0.0462565,5.25227,5.58855 +487,-0.0847672,-0.0837984,6.61645,5.04604 +488,0.0821666,0.0830697,5.12566,6.29619 +489,0.628561,0.0351335,5.36924,6.27606 +490,0.731938,0.0646117,6.0863,5.0947 +491,-0.662513,-0.0306837,5.4468,4.84396 +492,0.0779639,0.0928209,6.75789,6.5069 +493,0.397644,-0.0809951,6.15611,4.74509 +494,-0.400087,0.0705417,5.55126,5.83 +495,-0.78212,-0.0854487,6.3759,4.5928 +496,-0.66419,-0.0716704,6.39658,3.12395 +497,0.489042,-0.0428393,7.37796,5.18503 +498,-0.409393,-0.0743604,6.59267,5.81108 +499,-0.769189,0.0594132,4.47239,4.26417 +500,-0.606063,0.049868,6.71003,4.01193 +501,0.621165,0.0892848,4.55923,5.93028 +502,0.00878203,0.0971377,6.26067,4.41964 +503,0.163585,0.0505757,3.21341,5.79326 +504,-0.828652,0.00679444,5.90647,4.63847 +505,0.415548,-0.0182413,2.98397,6.33638 +506,0.128296,-0.0659696,6.09516,3.17492 +507,-0.295343,-0.0384684,4.03602,5.69941 +508,-0.887377,0.0630387,5.13972,6.30143 +509,0.562382,-0.0661419,4.05915,5.08995 +510,0.482313,0.065428,7.11406,6.73786 +511,0.494935,-0.0969903,5.34319,3.97039 +512,-0.0644706,-0.0706471,3.76576,4.15946 +513,-0.644628,0.085826,7.89674,5.92978 +514,0.0453791,-0.0170345,5.24333,5.75461 +515,-0.963038,-0.00181963,6.73839,5.58427 +516,0.200297,0.0676864,5.84265,4.30207 +517,0.816657,0.0390577,5.5161,5.32867 +518,-0.70347,-0.0273254,5.55767,5.7732 +519,0.811589,0.0110693,6.04253,5.98155 +520,0.226695,0.0725527,6.50818,4.95306 +521,-0.745642,0.0355997,4.5255,3.34506 +522,-0.591927,-0.0473839,4.90867,3.28818 +523,0.239019,-0.088574,5.69603,5.17624 +524,0.234896,-0.0344129,6.40517,3.69173 +525,-0.223711,0.0326848,5.5894,3.41256 +526,-0.101152,-0.0187652,9.10725,5.67476 +527,-0.583642,0.0697624,6.23245,5.60533 +528,0.553543,0.0653783,6.64214,4.9177 +529,0.0389811,0.0819441,5.91193,4.7683 +530,-0.915935,-0.0340187,7.1334,4.93174 +531,0.384208,0.0209315,6.20255,5.96695 +532,0.807337,0.0747914,6.25211,4.40438 +533,0.672968,0.0400215,6.18415,4.24649 +534,0.757524,0.00168239,6.58865,3.85111 +535,-0.381866,0.0229169,7.37097,4.61047 +536,-0.830557,0.0714985,4.98493,4.87381 +537,-0.341692,0.0736235,6.20981,4.77813 +538,0.464132,0.0315909,5.30126,3.03283 +539,0.669004,-0.0319115,4.12653,5.60005 +540,0.819434,-0.0793965,6.22404,4.97915 +541,0.491854,0.0246791,8.15391,5.50296 +542,-0.570743,0.0802277,4.56517,5.97474 +543,-0.389368,-0.0221264,5.33511,5.34972 +544,-0.822898,-0.0940023,6.14777,4.71331 +545,0.430352,-0.0201878,6.81405,5.43542 +546,0.652424,-0.0913342,5.33051,4.22942 +547,0.211962,-0.0738739,7.10145,5.94296 +548,0.401728,0.0074323,7.00721,3.75681 +549,-0.458349,-0.0212742,4.49153,4.64723 +550,0.059603,0.0601949,7.48645,5.82023 +551,-0.750896,0.0266349,7.26518,4.14161 +552,0.750557,0.0770946,6.47969,6.34582 +553,-0.486987,-0.0390704,5.67032,6.2838 +554,0.699283,0.058082,7.8379,5.7185 +555,0.406233,-0.0965267,7.38172,3.41174 +556,0.708288,-0.0246066,4.73391,6.92835 +557,-0.792304,0.070705,6.46761,5.1417 +558,-0.20504,0.0796905,5.93078,5.74777 +559,0.695907,-0.0674069,5.97831,5.22917 +560,0.773384,-0.0125768,6.25509,6.37976 +561,0.31533,-0.0577308,7.1475,5.36338 +562,0.999394,0.087488,6.23528,3.58437 +563,0.417339,0.0741649,5.92053,5.9255 +564,0.929848,0.0195636,6.77708,4.8903 +565,-0.714114,0.0827074,7.86001,4.79853 +566,-0.178568,-0.0631679,7.177,5.54344 +567,-0.103323,-0.0886173,4.2003,4.28673 +568,0.170725,-0.0629331,6.75679,5.88646 +569,0.142383,0.0622402,8.0548,3.0442 +570,0.440021,-0.00631069,6.80959,5.20657 +571,0.372584,-0.0649933,4.76048,5.112 +572,0.250818,-0.0685398,5.53067,6.55909 +573,-0.113303,-0.047738,6.84699,5.64566 +574,0.56016,-0.0955253,6.2389,4.54835 +575,-0.866947,-0.0920091,6.17388,3.50128 +576,0.242711,-0.0146621,8.07374,6.37694 +577,-0.679483,0.0196021,6.84891,3.15696 +578,-0.754581,-0.0120654,6.70017,4.04942 +579,-0.608347,-0.0497702,7.58158,6.34348 +580,0.516804,0.0656129,6.09022,5.03544 +581,0.111767,0.0132075,5.09839,5.14583 +582,0.834408,0.0950004,6.84031,4.5634 +583,0.333473,0.0922637,6.27756,4.05363 +584,-0.445729,0.0090344,5.56968,3.28153 +585,-0.968734,0.0320431,9.32438,5.67625 +586,0.529008,-0.0386009,5.39382,5.54687 +587,-0.881349,-0.0673343,7.69818,6.72858 +588,-0.0027237,-0.0825312,4.8311,4.9199 +589,-0.961652,-0.0677917,7.02525,5.40574 +590,-0.0437755,0.0878116,7.63022,4.45884 +591,0.261174,-0.0156299,3.50178,4.60249 +592,-0.471064,0.0880642,3.1929,6.8511 +593,0.378525,-0.0119326,4.77067,4.85753 +594,-0.188387,-0.0196013,4.64479,6.46586 +595,0.635516,0.0784222,7.69358,3.75149 +596,0.663042,0.0662472,4.16333,5.391 +597,0.357785,-0.0299689,6.86191,3.90343 +598,-0.655919,-0.0938072,4.63285,4.35877 +599,0.753439,-0.0789283,2.68078,4.39916 +600,0.93515,-0.0643011,6.06461,5.36797 +601,-0.128047,0.0871991,5.59392,4.18273 +602,-0.539298,0.0739856,4.34068,4.39361 +603,0.289162,-0.0480172,5.06675,6.04927 +604,-0.449393,-0.0915268,6.86955,5.89892 +605,-0.847629,0.0716219,4.86927,3.00039 +606,-0.981232,0.0804618,5.35931,5.32411 +607,-0.05902,0.000702393,3.77008,5.92151 +608,0.395031,-0.0934349,6.12531,6.15779 +609,0.677656,0.00995964,4.37001,4.94178 +610,0.194385,0.0446751,5.05093,3.30103 +611,-0.299815,0.0694613,5.65539,4.21248 +612,-0.577297,-0.0562531,6.36802,4.07728 +613,0.0116277,0.0318512,3.71868,6.22615 +614,0.886302,0.0703535,6.14326,6.98688 +615,-0.170535,0.00576095,8.09945,6.30828 +616,0.44258,-0.0206594,5.35293,6.63313 +617,0.151615,0.0245912,7.43423,5.803 +618,-0.556419,-0.0430822,7.5748,4.69514 +619,-0.512985,-0.068973,5.36464,4.29507 +620,-0.637474,-0.0831121,5.29743,5.48619 +621,-0.161591,-0.0681129,5.90127,3.60267 +622,-0.124166,0.0333306,6.56606,4.97595 +623,-0.794303,-0.0865624,5.78309,4.54743 +624,0.1191,0.0287952,8.23676,4.31252 +625,0.825228,0.0658296,4.9977,4.23816 +626,0.715693,0.0185637,4.1295,4.622 +627,0.275776,0.0183003,5.52392,5.64078 +628,-0.451473,0.0118849,4.34371,4.25941 +629,-0.494931,-0.0126002,5.23486,3.66975 +630,-0.977403,-0.0870259,5.10593,4.49617 +631,0.648046,0.0701644,6.17918,6.56559 +632,-0.811331,-0.0308257,4.86808,5.11521 +633,-0.0258303,0.0373438,6.86843,3.91808 +634,0.755367,0.048161,4.91695,3.58288 +635,0.769974,0.0798691,5.43252,5.68567 +636,-0.374476,-0.075077,5.40867,6.12892 +637,0.659419,0.0418474,5.37445,5.08585 +638,-0.990531,0.000201552,6.94506,5.8576 +639,0.892909,0.0568451,7.39459,5.23803 +640,-0.484425,-0.0745293,5.14819,5.10525 +641,0.0940622,0.015104,7.39167,6.046 +642,-0.884302,-0.0316608,7.03352,6.11194 +643,0.426362,-0.00562234,8.17717,4.12146 +644,0.592392,0.0422186,5.16429,5.69043 +645,-0.454968,0.0806891,5.08982,6.61502 +646,-0.909561,0.0371138,6.0391,5.8911 +647,-0.891986,-0.0289616,5.99508,3.88071 +648,0.722231,0.094143,7.81018,4.54209 +649,-0.800061,-0.0701085,6.8008,5.05359 +650,-0.127042,-0.0799904,6.01532,5.22359 +651,-0.383681,0.0965828,5.88953,5.4158 +652,0.47309,0.0986429,7.051,5.52938 +653,-0.06664,-0.0609715,4.61731,6.39537 +654,0.438713,-0.0501048,6.19451,3.59783 +655,0.284768,-0.0810205,5.9515,4.84458 +656,-0.304438,-0.0683383,3.90171,5.32407 +657,-0.13675,-0.00605947,7.61373,3.91982 +658,-0.959584,0.0421806,4.89039,4.06342 +659,-0.944143,-0.0354491,8.67851,6.37182 +660,0.876737,-0.061517,5.85948,3.61031 +661,-0.635947,0.0750396,4.30767,5.28224 +662,-0.504713,0.00590093,5.774,4.03773 +663,-0.804826,0.019255,6.03918,6.38178 +664,-0.018102,0.0200955,7.71668,5.82858 +665,-0.167075,-0.0443437,3.05278,4.69306 +666,-0.62427,0.0310771,8.71476,5.95915 +667,0.267894,0.0169219,6.06156,3.73814 +668,-0.518219,0.0621315,5.61076,4.15023 +669,-0.27417,-0.0980305,5.50713,4.60799 +670,-0.150221,-0.013254,7.05304,5.55465 +671,-0.046783,-0.0297676,9.35456,4.85828 +672,0.898942,-0.0715337,7.23803,4.09451 +673,-0.501134,-0.000415277,5.74375,5.13757 +674,0.248043,0.0590539,6.82261,6.88137 +675,-0.279701,0.0237219,6.55727,4.65775 +676,0.0617258,0.0829137,3.51959,6.20069 +677,0.496094,-0.0351035,5.28329,5.4435 +678,0.734492,-0.0726292,5.9352,6.01559 +679,-0.0932465,-0.00137002,3.93651,6.56488 +680,0.521124,0.0357582,6.9779,5.68386 +681,0.305437,-0.098485,4.49618,5.00529 +682,0.318189,0.000409147,6.66833,4.14707 +683,0.55083,0.0379717,5.65859,3.95787 +684,-0.700389,0.0626781,4.84229,3.04776 +685,0.0477623,-0.0129973,5.11433,5.95509 +686,0.311785,0.000811977,3.56419,4.52983 +687,-0.778725,-0.0435639,6.31064,6.53099 +688,-0.291044,-0.0558958,4.93764,6.42652 +689,-0.98694,-0.0142408,9.82258,4.34681 +690,0.73331,-0.0947134,9.48592,3.22005 +691,-0.350771,-0.0695994,6.00811,5.70412 +692,-0.520906,-0.066345,7.06405,3.11388 +693,0.681038,-0.0617997,5.8661,6.87499 +694,0.555187,-0.0843271,4.60809,6.60437 +695,0.024257,0.0171616,4.47342,3.50634 +696,0.568121,0.0579973,6.32026,3.95823 +697,-0.522464,-0.0894416,5.58331,6.60424 +698,0.420804,-0.00469771,6.88536,4.53052 +699,0.296157,-0.0588625,5.17777,4.29745 +700,-0.0235208,-0.0410573,6.59421,6.14254 +701,0.326683,-0.0470727,6.05632,4.3581 +702,-0.589975,0.00501098,7.56334,5.15955 +703,-0.367715,-0.0768979,4.82624,3.97611 +704,0.608504,0.091755,5.43739,4.50766 +705,-0.772685,-0.0343163,6.55198,3.99651 +706,0.340461,0.0915266,2.0467,6.79619 +707,-0.0771141,-0.0833148,5.23454,5.41218 +708,0.4283,0.0847235,4.44318,6.70409 +709,0.739605,0.0297553,6.67408,6.77152 +710,0.125684,-0.0732184,6.73999,4.12624 +711,0.365909,0.00649754,5.03201,3.25357 +712,-0.0126156,0.0476963,6.07846,4.98041 +713,0.951558,-0.0373712,6.02819,4.72487 +714,0.785279,-0.0850895,6.66676,4.07365 +715,-0.691102,0.0958281,6.5814,4.04435 +716,-0.474423,-0.00912901,4.40108,4.9087 +717,0.0336678,0.0216089,7.67236,3.27655 +718,0.619895,-0.0139626,5.83105,3.84769 +719,0.993001,-0.0736413,6.76824,4.42519 +720,-0.287169,-0.0890796,6.18911,6.89577 +721,0.134711,0.0577562,6.21391,5.17767 +722,-0.692851,-0.0574307,5.67597,6.82576 +723,-0.17734,-0.0730251,2.97525,4.3205 +724,-0.216062,0.0984007,3.64617,5.46028 +725,-0.0342454,-0.0657766,3.82867,4.38673 +726,0.977713,0.0723957,3.91658,4.34733 +727,0.869598,0.0257374,3.28867,3.30423 +728,-0.753513,0.068395,7.99331,4.66837 +729,-0.191263,-0.0892299,6.89554,5.44597 +730,-0.774611,0.0483416,4.66757,3.09357 +731,0.809332,-0.0551673,4.76501,4.91384 +732,0.0877907,-0.0817161,7.01399,4.55185 +733,-0.13585,0.0691198,5.84946,6.10831 +734,-0.989873,0.027397,5.65293,6.87286 +735,0.273359,-0.0862361,6.61389,5.7351 +736,-0.868551,0.0953571,4.37453,4.512 +737,0.0129135,0.0367664,4.67146,4.5006 +738,0.455984,0.0777132,5.98346,4.77756 +739,-0.796389,-0.0117465,6.85554,5.63409 +740,0.744173,0.0718157,3.70197,5.0995 +741,-0.142053,-0.00160353,6.25872,4.8873 +742,0.331948,0.00210731,5.31134,5.06213 +743,-0.931165,-0.051942,5.80802,6.11966 +744,-0.0711987,0.0931548,5.61511,6.51986 +745,-0.555301,0.0699618,6.2801,5.08047 +746,-0.894273,0.0557824,5.34681,4.66948 +747,0.92753,0.0290459,3.73595,3.51245 +748,-0.425901,-0.0451426,5.13223,4.56866 +749,-0.428373,-0.0918194,5.43073,5.27408 +750,-0.639066,-0.0898141,4.99279,6.13811 +751,-0.336314,-0.0618263,6.18122,3.21696 +752,0.487902,-0.0113113,6.59807,5.43121 +753,0.324154,0.089826,6.68386,5.52705 +754,0.970776,-0.0754456,4.40701,3.90045 +755,0.447983,-0.00440053,8.03922,5.30875 +756,-0.156752,-0.0230555,6.905,4.92819 +757,0.0531236,0.0562521,7.72392,6.90119 +758,0.503163,0.0518663,5.94662,5.63284 +759,-0.331431,-0.0900463,6.36086,4.14454 +760,0.972662,0.0276566,6.82835,5.30293 +761,-0.940563,0.00399979,7.64708,5.34125 +762,-0.618118,-0.0445456,4.38979,6.4859 +763,0.120667,0.0223269,7.96646,6.06405 +764,0.189308,0.0934142,4.96152,5.73609 +765,0.0722468,-0.020403,5.46725,4.16517 +766,-0.25372,0.0735373,4.43749,3.96289 +767,-0.918103,0.0689724,4.53815,5.84208 +768,0.944945,-0.0764415,4.68818,4.48577 +769,-0.670639,0.0903683,7.26794,6.25562 +770,0.83205,0.0567819,3.61273,5.30116 +771,0.156949,-0.0838942,5.69214,3.49084 +772,-0.737993,-0.0284223,7.30119,4.95522 +773,0.199367,0.00837941,7.93749,3.82134 +774,0.0622665,-0.0625728,4.69657,5.2021 +775,0.0887055,0.074234,6.00632,5.37677 +776,0.225683,-0.0945606,6.6876,5.23518 +777,0.320813,-0.0528808,6.57409,4.57471 +778,0.522773,-0.0335976,5.91528,6.38679 +779,-0.533293,-0.0244061,6.63739,4.26079 +780,-0.603201,0.0516845,5.31659,5.31147 +781,-0.725117,0.0448295,6.48311,5.7621 +782,0.423159,-0.0336343,4.28971,4.3815 +783,0.879951,0.0189532,3.16085,4.86528 +784,-0.15919,-0.0313895,6.30604,5.59783 +785,-0.882582,-0.0294432,6.65124,6.50541 +786,-0.249742,0.0606238,8.91957,6.71348 +787,-0.132985,-0.0523952,3.86282,5.45839 +788,-0.652406,-0.0303476,8.40295,4.09807 +789,0.870318,0.067845,7.70639,5.30718 +790,-0.0505713,0.0555841,5.632,6.16253 +791,-0.729368,-0.0418412,8.44165,5.94178 +792,-0.121376,0.00197733,5.91413,4.39184 +793,-0.888929,0.0540055,3.25612,4.66138 +794,-0.0140146,-0.010858,6.11116,6.74328 +795,0.623776,-0.0721996,6.43778,3.44993 +796,-0.00529783,-0.0974514,6.4744,6.57264 +797,0.804483,0.0832017,5.2944,6.4094 +798,0.64168,-0.0469144,5.00776,5.03966 +799,-0.563057,0.0115694,4.04196,5.38042 +800,0.54618,-0.087786,6.38452,5.57096 +801,0.00662737,-0.04493,4.10787,6.59069 +802,-0.763299,0.0546241,7.07916,6.59719 +803,-0.226136,0.0043143,8.74308,6.04341 +804,0.789304,-0.0791651,3.9337,4.59342 +805,-0.7805,-0.0774817,8.76209,3.94229 +806,0.130361,-0.0722945,5.9391,6.23926 +807,0.840825,-0.0538285,6.65675,4.70514 +808,0.949297,-0.000126278,7.11872,4.34068 +809,-0.669464,-0.0531104,4.19882,4.10185 +810,-0.95059,-0.0413466,6.28607,4.37725 +811,-0.343311,-0.0485155,4.66082,5.74244 +812,0.410041,-0.01014,6.26793,3.82932 +813,-0.114924,0.0341628,7.78011,5.51736 +814,-0.148504,-0.0936128,5.79855,3.9087 +815,-0.0200297,0.0435515,7.2517,5.52519 +816,-0.929127,-0.0846247,6.8797,4.26281 +817,-0.925229,-0.0168575,5.19134,5.20335 +818,0.875094,0.0872505,5.86703,6.8438 +819,0.960771,0.0328715,7.53411,4.76269 +820,-0.879262,-0.0867797,5.62549,4.24238 +821,0.947721,0.0393681,5.67263,4.94397 +822,-0.802174,0.0465498,6.82586,5.23228 +823,-0.78528,0.0960253,6.02167,5.63984 +824,-0.323092,-0.00732531,5.54361,5.31171 +825,-0.827088,-0.0585367,8.38761,3.07572 +826,-0.264933,-0.00552647,5.00102,6.66963 +827,0.838733,0.023283,5.30505,4.46905 +828,-0.463708,0.0386732,6.49386,5.21786 +829,-0.903693,-0.0383234,5.49964,3.3861 +830,0.493477,0.0762365,4.7479,3.4513 +831,0.939445,0.0155625,6.68172,5.57626 +832,-0.0263149,0.0710446,6.39162,4.8313 +833,-0.302487,-0.0696456,6.51813,4.57827 +834,-0.844284,-0.0503844,7.29085,4.99467 +835,0.263944,0.0409088,6.3978,5.90301 +836,-0.0530445,-0.0333402,5.19745,3.62557 +837,-0.998391,-0.0494917,4.95814,6.01812 +838,0.202945,-0.0610685,4.28136,4.73957 +839,0.856475,-0.0956092,5.81746,3.45932 +840,0.46187,0.0598813,6.60444,6.62654 +841,-0.490779,-0.050657,5.72619,5.11757 +842,-0.850086,0.0619607,4.71494,6.54435 +843,0.342676,-0.0541091,3.85748,4.6813 +844,-0.536723,-0.013026,5.13034,6.56995 +845,0.213724,0.0515963,6.99811,5.3723 +846,-0.706154,-0.04877,8.00652,4.53438 +847,-0.0370284,-0.00957575,6.98282,5.58967 +848,-0.0629267,-0.0122837,4.29983,4.1766 +849,-0.153381,0.0510216,8.59892,5.31515 +850,0.801767,-0.0188333,7.88958,6.11731 +851,-0.379039,-0.0990548,5.76574,3.63081 +852,0.58655,-0.0433399,5.51146,6.02489 +853,-0.273292,0.00473937,6.91172,3.83579 +854,-0.605531,-0.0874878,7.34476,4.472 +855,0.942247,0.079592,7.74061,6.21466 +856,-0.766859,-0.010262,7.54197,5.87641 +857,-0.147175,0.027938,6.92532,4.74327 +858,-0.165433,-0.0253409,5.72029,3.10117 +859,-0.169552,-0.0416011,5.45472,5.99613 +860,-0.848553,0.0602886,6.33743,6.01249 +861,-0.353136,-0.0602245,6.32944,3.74291 +862,-0.297799,0.0749666,4.48012,5.12335 +863,0.863466,-0.047953,5.75337,5.26118 +864,-0.575182,0.0732694,6.3796,4.69939 +865,-0.257065,-0.0162486,5.92524,6.36949 +866,0.146878,-0.0781223,6.32887,4.48396 +867,-0.000125689,-0.038833,3.96075,3.42103 +868,0.918046,-0.005188,5.73652,3.51085 +869,0.287023,-0.0464874,4.73362,5.2137 +870,0.855093,0.00810487,4.23953,5.35782 +871,0.355618,0.0359837,4.15481,6.42069 +872,0.845715,0.0413306,6.7058,5.82179 +873,-0.416135,0.0461781,6.43031,3.62155 +874,0.0793325,0.0932822,7.60779,6.22808 +875,-0.864437,0.0231277,5.71648,4.3545 +876,-0.443641,-0.0181232,4.98065,6.72242 +877,0.727273,-0.0594136,5.21808,3.63747 +878,-0.369177,0.0187874,6.16388,3.24284 +879,-0.313521,-0.0857057,7.10363,3.83354 +880,-0.857257,-0.0671396,6.40287,3.5648 +881,-0.70474,-0.0995491,6.43992,6.0279 +882,0.113618,-0.0525133,6.42342,3.73423 +883,-0.771972,0.0780207,5.32662,5.91123 +884,-0.196133,-0.0620308,10.7863,4.28216 +885,0.10885,0.0397169,8.49379,6.13231 +886,0.957545,0.0162311,7.97294,4.68648 +887,0.309326,0.0764873,7.95145,4.19987 +888,0.363845,0.0920962,4.91113,5.47081 +889,0.0932878,0.00348162,5.85973,5.00181 +890,-0.461101,-0.0858948,7.74741,4.85365 +891,-0.506687,0.00732457,6.65367,5.93531 +892,-0.0965575,0.0788209,5.0381,3.35857 +893,-0.97983,0.00246105,7.45844,4.36769 +894,-0.338724,-0.0993018,4.11803,3.14479 +895,-0.234553,0.0489848,7.12827,6.68237 +896,-0.854084,0.00781307,4.318,6.12243 +897,0.19089,-0.0462181,4.14421,5.04252 +898,0.00485137,-0.00716309,6.45455,4.27612 +899,0.91361,-0.0193397,5.20198,5.6265 +900,-0.610555,0.0564197,5.78936,5.01608 +901,0.958496,-0.0953318,6.06949,5.25453 +902,0.703016,0.0539233,8.42228,5.03467 +903,-0.206067,0.0867647,5.73116,4.08699 +904,-0.251161,-0.0243522,3.98588,5.42497 +905,-0.680446,-0.0457308,4.38221,3.41938 +906,-0.355423,0.010925,6.27152,6.83071 +907,0.902806,-0.0105134,4.3583,4.93878 +908,-0.261848,0.0346375,5.08392,4.36593 +909,-0.0794762,0.0721642,6.45575,5.16712 +910,0.386618,0.0614697,7.15429,6.09141 +911,-0.51444,0.0726078,6.7169,3.1155 +912,0.16618,0.0289601,6.76175,6.96716 +913,-0.531893,0.0944495,7.80355,5.74384 +914,0.408011,0.0382003,7.33859,6.30917 +915,-0.327231,-0.0408641,6.62391,4.13101 +916,-0.117974,-0.0537461,8.01627,4.18941 +917,0.690734,-0.00827199,5.2095,6.03269 +918,0.498127,0.0532412,6.63479,5.41938 +919,0.336595,0.0996195,7.18139,6.14959 +920,-0.195162,-0.0909495,5.93222,6.59382 +921,0.107309,0.0306457,8.36013,3.81558 +922,-0.723926,-0.0513506,4.57035,6.25902 +923,0.534546,-0.0882461,5.25657,6.16484 +924,-0.597379,-0.021594,7.68675,6.11602 +925,0.376283,0.0901611,5.18538,5.767 +926,-0.243139,-0.0233,6.68922,3.52843 +927,0.366699,-0.0038212,6.19855,3.39191 +928,-0.492344,-0.0757015,5.96865,3.45227 +929,0.766663,-0.0401482,4.77773,5.87958 +930,-0.0605845,-0.00930352,5.74711,5.63139 +931,0.57961,0.0791467,6.92708,4.40855 +932,0.0146754,-0.0144301,6.12138,5.12415 +933,-0.414661,0.0537111,5.77917,5.24727 +934,-0.8395,0.029923,6.44803,5.34435 +935,0.279223,-0.0406373,5.32111,3.26536 +936,-0.376924,0.0573254,5.1535,5.52075 +937,0.601103,0.0709887,6.62137,4.19212 +938,0.531671,-0.0582152,6.28485,6.08119 +939,0.536932,-0.0970463,6.78252,4.3308 +940,-0.309011,0.0963427,6.77115,6.96002 +941,0.346453,0.0264563,4.23091,6.06676 +942,-0.667912,0.0927224,4.26265,4.51634 +943,-0.140741,0.0308698,7.98287,5.2899 +944,0.0361835,-0.039529,6.24758,5.02449 +945,-0.76077,-0.0686738,7.14334,4.46385 +946,-0.349286,0.0503461,7.31639,6.69562 +947,0.981371,0.00699961,6.04639,5.95067 +948,0.2988,-0.0439108,3.80016,4.46322 +949,-0.385463,-0.00536302,8.19362,5.09558 +950,-0.974767,0.0322486,5.67873,4.01858 +951,0.169766,0.0774676,6.03446,4.71045 +952,-0.815403,-0.0849639,6.85795,3.93764 +953,0.23789,-0.0185966,5.98774,6.62837 +954,-0.432744,-0.0998664,6.69458,3.06386 +955,0.221224,-0.0748747,7.675,5.53471 +956,0.165006,-0.0210901,5.17018,5.21077 +957,-0.508319,-0.0967233,5.41967,4.86588 +958,0.154839,0.0360976,8.52607,4.49215 +959,-0.861623,-0.0326443,7.94019,5.74298 +960,0.606466,-0.0396946,5.56003,5.94331 +961,0.270955,0.024117,7.42063,3.20895 +962,-0.311037,-0.0931,6.34295,3.68214 +963,0.391457,-0.0459519,6.99964,6.83821 +964,-0.965011,0.0344026,6.46301,4.23682 +965,-0.0559797,-0.0287417,8.26424,4.06119 +966,0.418002,-0.0986306,7.42933,3.77225 +967,0.921235,-0.0929447,5.72831,3.46718 +968,-0.956646,-0.0979286,5.96212,3.58644 +969,0.0267077,0.0551188,5.70519,6.52888 +970,0.283622,-0.0579239,3.68884,4.10593 +971,0.852563,0.0942635,2.35611,6.19124 +972,0.5321,-0.0278766,5.53959,6.07171 +973,-0.104991,-0.0639874,7.19607,5.0513 +974,-0.694438,-0.0818324,4.97787,5.50976 +975,-0.709881,-0.0368245,5.14535,5.06481 +976,-0.640689,0.0582502,7.91429,4.74846 +977,-0.0872924,0.0891228,6.7527,3.67781 +978,0.982614,0.086089,5.38762,5.55255 +979,0.71854,0.0980083,7.79215,5.67805 +980,-0.558871,-0.0158528,5.25993,5.55002 +981,0.846157,0.0112532,2.51018,5.87282 +982,-0.646593,0.0625478,6.41934,4.26177 +983,-0.912197,-0.0805476,6.65959,5.01095 +984,-0.579414,-0.00153314,5.62982,5.98658 +985,0.219826,0.0758952,8.65167,6.08546 +986,0.637656,-0.00261932,4.0774,3.65467 +987,0.894483,0.0220492,6.3516,6.21094 +988,-0.599582,0.0312658,5.99708,4.95826 +989,-0.477396,0.0478024,5.05813,3.78107 +990,0.77148,0.0263749,5.79275,5.85187 +991,-0.877208,0.0374405,6.49968,6.20805 +992,-0.841083,0.0164645,7.42465,4.08155 +993,0.29179,-0.0466414,6.07588,5.98402 +994,-0.551414,0.0939925,6.57836,5.44054 +995,0.573059,-0.0612158,5.07888,4.60452 +996,0.812209,-0.00642389,6.15946,5.47961 +997,-0.0727279,-0.0872131,6.31868,3.69122 +998,-0.427931,0.0389265,8.83136,3.20849 +999,0.153333,0.0144079,6.79316,5.29992 +1000,-0.259719,0.0292732,6.35644,3.44228 +1001,0.0315253,0.0405276,4.39354,5.4837 diff --git a/tests/hist.r b/tests/hist.r new file mode 100644 index 0000000..ee20d09 --- /dev/null +++ b/tests/hist.r @@ -0,0 +1,84 @@ +#!/usr/bin/env Rscript + +# Parse arguments (filename, column number, min, max, bins) +args <- commandArgs(trailingOnly = TRUE) +filename <- args[1] +# start_row <- as.numeric(args[2]) +start_row <- 2 +col_num <- as.numeric(args[2]) + +# Optional min and max values (positions 3 and 4) +user_min <- ifelse(length(args) >= 3, as.numeric(args[3]), NA) +user_max <- ifelse(length(args) >= 4, as.numeric(args[4]), NA) + +# Number of bins now at the end (position 5) +num_bins <- ifelse(length(args) >= 5, as.numeric(args[5]), 20) # Default to 20 bins if not specified + +# Read the CSV file (assuming it has a header) +data <- read.csv(filename, header = TRUE) + +# Extract the data +plot_data <- data[start_row:nrow(data), col_num] + +# Convert to numeric +plot_data <- as.numeric(as.character(plot_data)) +plot_data <- plot_data[!is.na(plot_data)] + +# Determine range bounds +data_min <- min(plot_data) +data_max <- max(plot_data) + +range_min <- ifelse(is.na(user_min), data_min, user_min) +range_max <- ifelse(is.na(user_max), data_max, user_max) + +# Calculate percentage of samples within the range +count_in_range <- sum(plot_data >= range_min & plot_data <= range_max) +total_count <- length(plot_data) +percent_in_range <- (count_in_range / total_count) * 100 + +# Output to command line +cat(sprintf("%.2f%% of samples are within the range [%.2f, %.2f]\n", + percent_in_range, range_min, range_max)) + +# Set up graphics +windows(width = 8, height = 6) + +# Create the histogram +hist(plot_data, + breaks = num_bins, + main = paste("Histogram of Column", col_num), + xlab = "Value", + col = "lightblue", + border = "black") + +# Add vertical lines for min and max if provided by user +if(!is.na(user_min)) { + abline(v = user_min, col = "red", lwd = 2, lty = 2) +} +if(!is.na(user_max)) { + abline(v = user_max, col = "red", lwd = 2, lty = 2) +} + +# Add basic statistics including standard deviation +stats_text <- paste0("n = ", length(plot_data), "\n", + "min = ", sprintf("%.2f", data_min), "\n", + "max = ", sprintf("%.2f", data_max), "\n", + "mean = ", sprintf("%.2f", mean(plot_data)), "\n", + "median = ", sprintf("%.2f", median(plot_data)), "\n", + "sd = ", sprintf("%.2f", sd(plot_data)), "\n", + sprintf("%.2f%% in [%.2f, %.2f]", + percent_in_range, range_min, range_max)) + +text_x <- par("usr")[1] + 0.05 * (par("usr")[2] - par("usr")[1]) +text_y <- par("usr")[4] - 0.1 * (par("usr")[4] - par("usr")[3]) +text(text_x, text_y, stats_text, adj = c(0, 1)) + +# Add text to instruct user +mtext("Close this window using the X button when done", side = 1, line = 4, col = "red") + +# Tell user what to do +cat("Histogram displayed. Close the window manually when done viewing.\n") +cat("Usage: Rscript hist.r filename.csv column_number [min] [max] [bins]\n") + +# Keep the script running until the window is closed +Sys.sleep(1000) # Keep script running for a long time -- cgit v1.2.3