commit 99ef5ec9c665b0e259deb46f727e38722fb82186
parent 11ad465f0df73b0ec623558656ea9b9b2741a61c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 30 Mar 2016 14:31:11 +0200
Merge remote-tracking branch 'gitlab/phase_function'
Diffstat:
15 files changed, 5714 insertions(+), 2119 deletions(-)
diff --git a/COPYING b/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is 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. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ 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.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ 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 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. Use with the GNU Affero General Public License.
+
+ 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 Affero 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 special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 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 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 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ 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 GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/COPYING.en b/COPYING.en
@@ -1,519 +0,0 @@
-
- CeCILL FREE SOFTWARE LICENSE AGREEMENT
-
-Version 2.1 dated 2013-06-21
-
-
- Notice
-
-This Agreement is a Free Software license agreement that is the result
-of discussions between its authors in order to ensure compliance with
-the two main principles guiding its drafting:
-
- * firstly, compliance with the principles governing the distribution
- of Free Software: access to source code, broad rights granted to users,
- * secondly, the election of a governing law, French law, with which it
- is conformant, both as regards the law of torts and intellectual
- property law, and the protection that it offers to both authors and
- holders of the economic rights over software.
-
-The authors of the CeCILL (for Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre])
-license are:
-
-Commissariat à l'énergie atomique et aux énergies alternatives - CEA, a
-public scientific, technical and industrial research establishment,
-having its principal place of business at 25 rue Leblanc, immeuble Le
-Ponant D, 75015 Paris, France.
-
-Centre National de la Recherche Scientifique - CNRS, a public scientific
-and technological establishment, having its principal place of business
-at 3 rue Michel-Ange, 75794 Paris cedex 16, France.
-
-Institut National de Recherche en Informatique et en Automatique -
-Inria, a public scientific and technological establishment, having its
-principal place of business at Domaine de Voluceau, Rocquencourt, BP
-105, 78153 Le Chesnay cedex, France.
-
-
- Preamble
-
-The purpose of this Free Software license agreement is to grant users
-the right to modify and redistribute the software governed by this
-license within the framework of an open source distribution model.
-
-The exercising of this right is conditional upon certain obligations for
-users so as to preserve this status for all subsequent redistributions.
-
-In consideration of access to the source code and the rights to copy,
-modify and redistribute granted by the license, users are provided only
-with a limited warranty and the software's author, the holder of the
-economic rights, and the successive licensors only have limited liability.
-
-In this respect, the risks associated with loading, using, modifying
-and/or developing or reproducing the software by the user are brought to
-the user's attention, given its Free Software status, which may make it
-complicated to use, with the result that its use is reserved for
-developers and experienced professionals having in-depth computer
-knowledge. Users are therefore encouraged to load and test the
-suitability of the software as regards their requirements in conditions
-enabling the security of their systems and/or data to be ensured and,
-more generally, to use and operate it in the same conditions of
-security. This Agreement may be freely reproduced and published,
-provided it is not altered, and that no provisions are either added or
-removed herefrom.
-
-This Agreement may apply to any or all software for which the holder of
-the economic rights decides to submit the use thereof to its provisions.
-
-Frequently asked questions can be found on the official website of the
-CeCILL licenses family (http://www.cecill.info/index.en.html) for any
-necessary clarification.
-
-
- Article 1 - DEFINITIONS
-
-For the purpose of this Agreement, when the following expressions
-commence with a capital letter, they shall have the following meaning:
-
-Agreement: means this license agreement, and its possible subsequent
-versions and annexes.
-
-Software: means the software in its Object Code and/or Source Code form
-and, where applicable, its documentation, "as is" when the Licensee
-accepts the Agreement.
-
-Initial Software: means the Software in its Source Code and possibly its
-Object Code form and, where applicable, its documentation, "as is" when
-it is first distributed under the terms and conditions of the Agreement.
-
-Modified Software: means the Software modified by at least one
-Contribution.
-
-Source Code: means all the Software's instructions and program lines to
-which access is required so as to modify the Software.
-
-Object Code: means the binary files originating from the compilation of
-the Source Code.
-
-Holder: means the holder(s) of the economic rights over the Initial
-Software.
-
-Licensee: means the Software user(s) having accepted the Agreement.
-
-Contributor: means a Licensee having made at least one Contribution.
-
-Licensor: means the Holder, or any other individual or legal entity, who
-distributes the Software under the Agreement.
-
-Contribution: means any or all modifications, corrections, translations,
-adaptations and/or new functions integrated into the Software by any or
-all Contributors, as well as any or all Internal Modules.
-
-Module: means a set of sources files including their documentation that
-enables supplementary functions or services in addition to those offered
-by the Software.
-
-External Module: means any or all Modules, not derived from the
-Software, so that this Module and the Software run in separate address
-spaces, with one calling the other when they are run.
-
-Internal Module: means any or all Module, connected to the Software so
-that they both execute in the same address space.
-
-GNU GPL: means the GNU General Public License version 2 or any
-subsequent version, as published by the Free Software Foundation Inc.
-
-GNU Affero GPL: means the GNU Affero General Public License version 3 or
-any subsequent version, as published by the Free Software Foundation Inc.
-
-EUPL: means the European Union Public License version 1.1 or any
-subsequent version, as published by the European Commission.
-
-Parties: mean both the Licensee and the Licensor.
-
-These expressions may be used both in singular and plural form.
-
-
- Article 2 - PURPOSE
-
-The purpose of the Agreement is the grant by the Licensor to the
-Licensee of a non-exclusive, transferable and worldwide license for the
-Software as set forth in Article 5 <#scope> hereinafter for the whole
-term of the protection granted by the rights over said Software.
-
-
- Article 3 - ACCEPTANCE
-
-3.1 The Licensee shall be deemed as having accepted the terms and
-conditions of this Agreement upon the occurrence of the first of the
-following events:
-
- * (i) loading the Software by any or all means, notably, by
- downloading from a remote server, or by loading from a physical medium;
- * (ii) the first time the Licensee exercises any of the rights granted
- hereunder.
-
-3.2 One copy of the Agreement, containing a notice relating to the
-characteristics of the Software, to the limited warranty, and to the
-fact that its use is restricted to experienced users has been provided
-to the Licensee prior to its acceptance as set forth in Article 3.1
-<#accepting> hereinabove, and the Licensee hereby acknowledges that it
-has read and understood it.
-
-
- Article 4 - EFFECTIVE DATE AND TERM
-
-
- 4.1 EFFECTIVE DATE
-
-The Agreement shall become effective on the date when it is accepted by
-the Licensee as set forth in Article 3.1 <#accepting>.
-
-
- 4.2 TERM
-
-The Agreement shall remain in force for the entire legal term of
-protection of the economic rights over the Software.
-
-
- Article 5 - SCOPE OF RIGHTS GRANTED
-
-The Licensor hereby grants to the Licensee, who accepts, the following
-rights over the Software for any or all use, and for the term of the
-Agreement, on the basis of the terms and conditions set forth hereinafter.
-
-Besides, if the Licensor owns or comes to own one or more patents
-protecting all or part of the functions of the Software or of its
-components, the Licensor undertakes not to enforce the rights granted by
-these patents against successive Licensees using, exploiting or
-modifying the Software. If these patents are transferred, the Licensor
-undertakes to have the transferees subscribe to the obligations set
-forth in this paragraph.
-
-
- 5.1 RIGHT OF USE
-
-The Licensee is authorized to use the Software, without any limitation
-as to its fields of application, with it being hereinafter specified
-that this comprises:
-
- 1. permanent or temporary reproduction of all or part of the Software
- by any or all means and in any or all form.
-
- 2. loading, displaying, running, or storing the Software on any or all
- medium.
-
- 3. entitlement to observe, study or test its operation so as to
- determine the ideas and principles behind any or all constituent
- elements of said Software. This shall apply when the Licensee
- carries out any or all loading, displaying, running, transmission or
- storage operation as regards the Software, that it is entitled to
- carry out hereunder.
-
-
- 5.2 ENTITLEMENT TO MAKE CONTRIBUTIONS
-
-The right to make Contributions includes the right to translate, adapt,
-arrange, or make any or all modifications to the Software, and the right
-to reproduce the resulting software.
-
-The Licensee is authorized to make any or all Contributions to the
-Software provided that it includes an explicit notice that it is the
-author of said Contribution and indicates the date of the creation thereof.
-
-
- 5.3 RIGHT OF DISTRIBUTION
-
-In particular, the right of distribution includes the right to publish,
-transmit and communicate the Software to the general public on any or
-all medium, and by any or all means, and the right to market, either in
-consideration of a fee, or free of charge, one or more copies of the
-Software by any means.
-
-The Licensee is further authorized to distribute copies of the modified
-or unmodified Software to third parties according to the terms and
-conditions set forth hereinafter.
-
-
- 5.3.1 DISTRIBUTION OF SOFTWARE WITHOUT MODIFICATION
-
-The Licensee is authorized to distribute true copies of the Software in
-Source Code or Object Code form, provided that said distribution
-complies with all the provisions of the Agreement and is accompanied by:
-
- 1. a copy of the Agreement,
-
- 2. a notice relating to the limitation of both the Licensor's warranty
- and liability as set forth in Articles 8 and 9,
-
-and that, in the event that only the Object Code of the Software is
-redistributed, the Licensee allows effective access to the full Source
-Code of the Software for a period of at least three years from the
-distribution of the Software, it being understood that the additional
-acquisition cost of the Source Code shall not exceed the cost of the
-data transfer.
-
-
- 5.3.2 DISTRIBUTION OF MODIFIED SOFTWARE
-
-When the Licensee makes a Contribution to the Software, the terms and
-conditions for the distribution of the resulting Modified Software
-become subject to all the provisions of this Agreement.
-
-The Licensee is authorized to distribute the Modified Software, in
-source code or object code form, provided that said distribution
-complies with all the provisions of the Agreement and is accompanied by:
-
- 1. a copy of the Agreement,
-
- 2. a notice relating to the limitation of both the Licensor's warranty
- and liability as set forth in Articles 8 and 9,
-
-and, in the event that only the object code of the Modified Software is
-redistributed,
-
- 3. a note stating the conditions of effective access to the full source
- code of the Modified Software for a period of at least three years
- from the distribution of the Modified Software, it being understood
- that the additional acquisition cost of the source code shall not
- exceed the cost of the data transfer.
-
-
- 5.3.3 DISTRIBUTION OF EXTERNAL MODULES
-
-When the Licensee has developed an External Module, the terms and
-conditions of this Agreement do not apply to said External Module, that
-may be distributed under a separate license agreement.
-
-
- 5.3.4 COMPATIBILITY WITH OTHER LICENSES
-
-The Licensee can include a code that is subject to the provisions of one
-of the versions of the GNU GPL, GNU Affero GPL and/or EUPL in the
-Modified or unmodified Software, and distribute that entire code under
-the terms of the same version of the GNU GPL, GNU Affero GPL and/or EUPL.
-
-The Licensee can include the Modified or unmodified Software in a code
-that is subject to the provisions of one of the versions of the GNU GPL,
-GNU Affero GPL and/or EUPL and distribute that entire code under the
-terms of the same version of the GNU GPL, GNU Affero GPL and/or EUPL.
-
-
- Article 6 - INTELLECTUAL PROPERTY
-
-
- 6.1 OVER THE INITIAL SOFTWARE
-
-The Holder owns the economic rights over the Initial Software. Any or
-all use of the Initial Software is subject to compliance with the terms
-and conditions under which the Holder has elected to distribute its work
-and no one shall be entitled to modify the terms and conditions for the
-distribution of said Initial Software.
-
-The Holder undertakes that the Initial Software will remain ruled at
-least by this Agreement, for the duration set forth in Article 4.2 <#term>.
-
-
- 6.2 OVER THE CONTRIBUTIONS
-
-The Licensee who develops a Contribution is the owner of the
-intellectual property rights over this Contribution as defined by
-applicable law.
-
-
- 6.3 OVER THE EXTERNAL MODULES
-
-The Licensee who develops an External Module is the owner of the
-intellectual property rights over this External Module as defined by
-applicable law and is free to choose the type of agreement that shall
-govern its distribution.
-
-
- 6.4 JOINT PROVISIONS
-
-The Licensee expressly undertakes:
-
- 1. not to remove, or modify, in any manner, the intellectual property
- notices attached to the Software;
-
- 2. to reproduce said notices, in an identical manner, in the copies of
- the Software modified or not.
-
-The Licensee undertakes not to directly or indirectly infringe the
-intellectual property rights on the Software of the Holder and/or
-Contributors, and to take, where applicable, vis-Ã -vis its staff, any
-and all measures required to ensure respect of said intellectual
-property rights of the Holder and/or Contributors.
-
-
- Article 7 - RELATED SERVICES
-
-7.1 Under no circumstances shall the Agreement oblige the Licensor to
-provide technical assistance or maintenance services for the Software.
-
-However, the Licensor is entitled to offer this type of services. The
-terms and conditions of such technical assistance, and/or such
-maintenance, shall be set forth in a separate instrument. Only the
-Licensor offering said maintenance and/or technical assistance services
-shall incur liability therefor.
-
-7.2 Similarly, any Licensor is entitled to offer to its licensees, under
-its sole responsibility, a warranty, that shall only be binding upon
-itself, for the redistribution of the Software and/or the Modified
-Software, under terms and conditions that it is free to decide. Said
-warranty, and the financial terms and conditions of its application,
-shall be subject of a separate instrument executed between the Licensor
-and the Licensee.
-
-
- Article 8 - LIABILITY
-
-8.1 Subject to the provisions of Article 8.2, the Licensee shall be
-entitled to claim compensation for any direct loss it may have suffered
-from the Software as a result of a fault on the part of the relevant
-Licensor, subject to providing evidence thereof.
-
-8.2 The Licensor's liability is limited to the commitments made under
-this Agreement and shall not be incurred as a result of in particular:
-(i) loss due the Licensee's total or partial failure to fulfill its
-obligations, (ii) direct or consequential loss that is suffered by the
-Licensee due to the use or performance of the Software, and (iii) more
-generally, any consequential loss. In particular the Parties expressly
-agree that any or all pecuniary or business loss (i.e. loss of data,
-loss of profits, operating loss, loss of customers or orders,
-opportunity cost, any disturbance to business activities) or any or all
-legal proceedings instituted against the Licensee by a third party,
-shall constitute consequential loss and shall not provide entitlement to
-any or all compensation from the Licensor.
-
-
- Article 9 - WARRANTY
-
-9.1 The Licensee acknowledges that the scientific and technical
-state-of-the-art when the Software was distributed did not enable all
-possible uses to be tested and verified, nor for the presence of
-possible defects to be detected. In this respect, the Licensee's
-attention has been drawn to the risks associated with loading, using,
-modifying and/or developing and reproducing the Software which are
-reserved for experienced users.
-
-The Licensee shall be responsible for verifying, by any or all means,
-the suitability of the product for its requirements, its good working
-order, and for ensuring that it shall not cause damage to either persons
-or properties.
-
-9.2 The Licensor hereby represents, in good faith, that it is entitled
-to grant all the rights over the Software (including in particular the
-rights set forth in Article 5 <#scope>).
-
-9.3 The Licensee acknowledges that the Software is supplied "as is" by
-the Licensor without any other express or tacit warranty, other than
-that provided for in Article 9.2 <#good-faith> and, in particular,
-without any warranty as to its commercial value, its secured, safe,
-innovative or relevant nature.
-
-Specifically, the Licensor does not warrant that the Software is free
-from any error, that it will operate without interruption, that it will
-be compatible with the Licensee's own equipment and software
-configuration, nor that it will meet the Licensee's requirements.
-
-9.4 The Licensor does not either expressly or tacitly warrant that the
-Software does not infringe any third party intellectual property right
-relating to a patent, software or any other property right. Therefore,
-the Licensor disclaims any and all liability towards the Licensee
-arising out of any or all proceedings for infringement that may be
-instituted in respect of the use, modification and redistribution of the
-Software. Nevertheless, should such proceedings be instituted against
-the Licensee, the Licensor shall provide it with technical and legal
-expertise for its defense. Such technical and legal expertise shall be
-decided on a case-by-case basis between the relevant Licensor and the
-Licensee pursuant to a memorandum of understanding. The Licensor
-disclaims any and all liability as regards the Licensee's use of the
-name of the Software. No warranty is given as regards the existence of
-prior rights over the name of the Software or as regards the existence
-of a trademark.
-
-
- Article 10 - TERMINATION
-
-10.1 In the event of a breach by the Licensee of its obligations
-hereunder, the Licensor may automatically terminate this Agreement
-thirty (30) days after notice has been sent to the Licensee and has
-remained ineffective.
-
-10.2 A Licensee whose Agreement is terminated shall no longer be
-authorized to use, modify or distribute the Software. However, any
-licenses that it may have granted prior to termination of the Agreement
-shall remain valid subject to their having been granted in compliance
-with the terms and conditions hereof.
-
-
- Article 11 - MISCELLANEOUS
-
-
- 11.1 EXCUSABLE EVENTS
-
-Neither Party shall be liable for any or all delay, or failure to
-perform the Agreement, that may be attributable to an event of force
-majeure, an act of God or an outside cause, such as defective
-functioning or interruptions of the electricity or telecommunications
-networks, network paralysis following a virus attack, intervention by
-government authorities, natural disasters, water damage, earthquakes,
-fire, explosions, strikes and labor unrest, war, etc.
-
-11.2 Any failure by either Party, on one or more occasions, to invoke
-one or more of the provisions hereof, shall under no circumstances be
-interpreted as being a waiver by the interested Party of its right to
-invoke said provision(s) subsequently.
-
-11.3 The Agreement cancels and replaces any or all previous agreements,
-whether written or oral, between the Parties and having the same
-purpose, and constitutes the entirety of the agreement between said
-Parties concerning said purpose. No supplement or modification to the
-terms and conditions hereof shall be effective as between the Parties
-unless it is made in writing and signed by their duly authorized
-representatives.
-
-11.4 In the event that one or more of the provisions hereof were to
-conflict with a current or future applicable act or legislative text,
-said act or legislative text shall prevail, and the Parties shall make
-the necessary amendments so as to comply with said act or legislative
-text. All other provisions shall remain effective. Similarly, invalidity
-of a provision of the Agreement, for any reason whatsoever, shall not
-cause the Agreement as a whole to be invalid.
-
-
- 11.5 LANGUAGE
-
-The Agreement is drafted in both French and English and both versions
-are deemed authentic.
-
-
- Article 12 - NEW VERSIONS OF THE AGREEMENT
-
-12.1 Any person is authorized to duplicate and distribute copies of this
-Agreement.
-
-12.2 So as to ensure coherence, the wording of this Agreement is
-protected and may only be modified by the authors of the License, who
-reserve the right to periodically publish updates or new versions of the
-Agreement, each with a separate number. These subsequent versions may
-address new issues encountered by Free Software.
-
-12.3 Any Software distributed under a given version of the Agreement may
-only be subsequently distributed under the same version of the Agreement
-or a subsequent version, subject to the provisions of Article 5.3.4
-<#compatibility>.
-
-
- Article 13 - GOVERNING LAW AND JURISDICTION
-
-13.1 The Agreement is governed by French law. The Parties agree to
-endeavor to seek an amicable solution to any disagreements or disputes
-that may arise during the performance of the Agreement.
-
-13.2 Failing an amicable solution within two (2) months as from their
-occurrence, and unless emergency proceedings are necessary, the
-disagreements or disputes shall be referred to the Paris Courts having
-jurisdiction, by the more diligent Party.
-
diff --git a/COPYING.fr b/COPYING.fr
@@ -1,550 +0,0 @@
-
- CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL
-
-Version 2.1 du 2013-06-21
-
-
- Avertissement
-
-Ce contrat est une licence de logiciel libre issue d'une concertation
-entre ses auteurs afin que le respect de deux grands principes préside Ã
-sa rédaction:
-
- * d'une part, le respect des principes de diffusion des logiciels
- libres: accès au code source, droits étendus conférés aux utilisateurs,
- * d'autre part, la désignation d'un droit applicable, le droit
- français, auquel elle est conforme, tant au regard du droit de la
- responsabilité civile que du droit de la propriété intellectuelle et
- de la protection qu'il offre aux auteurs et titulaires des droits
- patrimoniaux sur un logiciel.
-
-Les auteurs de la licence CeCILL (Ce[a] C[nrs] I[nria] L[ogiciel] L[ibre])
-sont:
-
-Commissariat à l'énergie atomique et aux énergies alternatives - CEA,
-établissement public de recherche à caractère scientifique, technique et
-industriel, dont le siège est situé 25 rue Leblanc, immeuble Le Ponant
-D, 75015 Paris.
-
-Centre National de la Recherche Scientifique - CNRS, établissement
-public à caractère scientifique et technologique, dont le siège est
-situé 3 rue Michel-Ange, 75794 Paris cedex 16.
-
-Institut National de Recherche en Informatique et en Automatique -
-Inria, établissement public à caractère scientifique et technologique,
-dont le siège est situé Domaine de Voluceau, Rocquencourt, BP 105, 78153
-Le Chesnay cedex.
-
-
- Préambule
-
-Ce contrat est une licence de logiciel libre dont l'objectif est de
-conférer aux utilisateurs la liberté de modification et de
-redistribution du logiciel régi par cette licence dans le cadre d'un
-modèle de diffusion en logiciel libre.
-
-L'exercice de ces libertés est assorti de certains devoirs à la charge
-des utilisateurs afin de préserver ce statut au cours des
-redistributions ultérieures.
-
-L'accessibilité au code source et les droits de copie, de modification
-et de redistribution qui en découlent ont pour contrepartie de n'offrir
-aux utilisateurs qu'une garantie limitée et de ne faire peser sur
-l'auteur du logiciel, le titulaire des droits patrimoniaux et les
-concédants successifs qu'une responsabilité restreinte.
-
-A cet égard l'attention de l'utilisateur est attirée sur les risques
-associés au chargement, à l'utilisation, à la modification et/ou au
-développement et à la reproduction du logiciel par l'utilisateur étant
-donné sa spécificité de logiciel libre, qui peut le rendre complexe Ã
-manipuler et qui le réserve donc à des développeurs ou des
-professionnels avertis possédant des connaissances informatiques
-approfondies. Les utilisateurs sont donc invités à charger et tester
-l'adéquation du logiciel à leurs besoins dans des conditions permettant
-d'assurer la sécurité de leurs systèmes et/ou de leurs données et, plus
-généralement, à l'utiliser et l'exploiter dans les mêmes conditions de
-sécurité. Ce contrat peut être reproduit et diffusé librement, sous
-réserve de le conserver en l'état, sans ajout ni suppression de clauses.
-
-Ce contrat est susceptible de s'appliquer à tout logiciel dont le
-titulaire des droits patrimoniaux décide de soumettre l'exploitation aux
-dispositions qu'il contient.
-
-Une liste de questions fréquemment posées se trouve sur le site web
-officiel de la famille des licences CeCILL
-(http://www.cecill.info/index.fr.html) pour toute clarification qui
-serait nécessaire.
-
-
- Article 1 - DEFINITIONS
-
-Dans ce contrat, les termes suivants, lorsqu'ils seront écrits avec une
-lettre capitale, auront la signification suivante:
-
-Contrat: désigne le présent contrat de licence, ses éventuelles versions
-postérieures et annexes.
-
-Logiciel: désigne le logiciel sous sa forme de Code Objet et/ou de Code
-Source et le cas échéant sa documentation, dans leur état au moment de
-l'acceptation du Contrat par le Licencié.
-
-Logiciel Initial: désigne le Logiciel sous sa forme de Code Source et
-éventuellement de Code Objet et le cas échéant sa documentation, dans
-leur état au moment de leur première diffusion sous les termes du Contrat.
-
-Logiciel Modifié: désigne le Logiciel modifié par au moins une
-Contribution.
-
-Code Source: désigne l'ensemble des instructions et des lignes de
-programme du Logiciel et auquel l'accès est nécessaire en vue de
-modifier le Logiciel.
-
-Code Objet: désigne les fichiers binaires issus de la compilation du
-Code Source.
-
-Titulaire: désigne le ou les détenteurs des droits patrimoniaux d'auteur
-sur le Logiciel Initial.
-
-Licencié: désigne le ou les utilisateurs du Logiciel ayant accepté le
-Contrat.
-
-Contributeur: désigne le Licencié auteur d'au moins une Contribution.
-
-Concédant: désigne le Titulaire ou toute personne physique ou morale
-distribuant le Logiciel sous le Contrat.
-
-Contribution: désigne l'ensemble des modifications, corrections,
-traductions, adaptations et/ou nouvelles fonctionnalités intégrées dans
-le Logiciel par tout Contributeur, ainsi que tout Module Interne.
-
-Module: désigne un ensemble de fichiers sources y compris leur
-documentation qui permet de réaliser des fonctionnalités ou services
-supplémentaires à ceux fournis par le Logiciel.
-
-Module Externe: désigne tout Module, non dérivé du Logiciel, tel que ce
-Module et le Logiciel s'exécutent dans des espaces d'adressage
-différents, l'un appelant l'autre au moment de leur exécution.
-
-Module Interne: désigne tout Module lié au Logiciel de telle sorte
-qu'ils s'exécutent dans le même espace d'adressage.
-
-GNU GPL: désigne la GNU General Public License dans sa version 2 ou
-toute version ultérieure, telle que publiée par Free Software Foundation
-Inc.
-
-GNU Affero GPL: désigne la GNU Affero General Public License dans sa
-version 3 ou toute version ultérieure, telle que publiée par Free
-Software Foundation Inc.
-
-EUPL: désigne la Licence Publique de l'Union européenne dans sa version
-1.1 ou toute version ultérieure, telle que publiée par la Commission
-Européenne.
-
-Parties: désigne collectivement le Licencié et le Concédant.
-
-Ces termes s'entendent au singulier comme au pluriel.
-
-
- Article 2 - OBJET
-
-Le Contrat a pour objet la concession par le Concédant au Licencié d'une
-licence non exclusive, cessible et mondiale du Logiciel telle que
-définie ci-après à l'article 5 <#etendue> pour toute la durée de
-protection des droits portant sur ce Logiciel.
-
-
- Article 3 - ACCEPTATION
-
-3.1 L'acceptation par le Licencié des termes du Contrat est réputée
-acquise du fait du premier des faits suivants:
-
- * (i) le chargement du Logiciel par tout moyen notamment par
- téléchargement à partir d'un serveur distant ou par chargement Ã
- partir d'un support physique;
- * (ii) le premier exercice par le Licencié de l'un quelconque des
- droits concédés par le Contrat.
-
-3.2 Un exemplaire du Contrat, contenant notamment un avertissement
-relatif aux spécificités du Logiciel, à la restriction de garantie et Ã
-la limitation à un usage par des utilisateurs expérimentés a été mis Ã
-disposition du Licencié préalablement à son acceptation telle que
-définie à l'article 3.1 <#acceptation-acquise> ci dessus et le Licencié
-reconnaît en avoir pris connaissance.
-
-
- Article 4 - ENTREE EN VIGUEUR ET DUREE
-
-
- 4.1 ENTREE EN VIGUEUR
-
-Le Contrat entre en vigueur à la date de son acceptation par le Licencié
-telle que définie en 3.1 <#acceptation-acquise>.
-
-
- 4.2 DUREE
-
-Le Contrat produira ses effets pendant toute la durée légale de
-protection des droits patrimoniaux portant sur le Logiciel.
-
-
- Article 5 - ETENDUE DES DROITS CONCEDES
-
-Le Concédant concède au Licencié, qui accepte, les droits suivants sur
-le Logiciel pour toutes destinations et pour la durée du Contrat dans
-les conditions ci-après détaillées.
-
-Par ailleurs, si le Concédant détient ou venait à détenir un ou
-plusieurs brevets d'invention protégeant tout ou partie des
-fonctionnalités du Logiciel ou de ses composants, il s'engage à ne pas
-opposer les éventuels droits conférés par ces brevets aux Licenciés
-successifs qui utiliseraient, exploiteraient ou modifieraient le
-Logiciel. En cas de cession de ces brevets, le Concédant s'engage Ã
-faire reprendre les obligations du présent alinéa aux cessionnaires.
-
-
- 5.1 DROIT D'UTILISATION
-
-Le Licencié est autorisé à utiliser le Logiciel, sans restriction quant
-aux domaines d'application, étant ci-après précisé que cela comporte:
-
- 1.
-
- la reproduction permanente ou provisoire du Logiciel en tout ou
- partie par tout moyen et sous toute forme.
-
- 2.
-
- le chargement, l'affichage, l'exécution, ou le stockage du Logiciel
- sur tout support.
-
- 3.
-
- la possibilité d'en observer, d'en étudier, ou d'en tester le
- fonctionnement afin de déterminer les idées et principes qui sont Ã
- la base de n'importe quel élément de ce Logiciel; et ceci, lorsque
- le Licencié effectue toute opération de chargement, d'affichage,
- d'exécution, de transmission ou de stockage du Logiciel qu'il est en
- droit d'effectuer en vertu du Contrat.
-
-
- 5.2 DROIT D'APPORTER DES CONTRIBUTIONS
-
-Le droit d'apporter des Contributions comporte le droit de traduire,
-d'adapter, d'arranger ou d'apporter toute autre modification au Logiciel
-et le droit de reproduire le logiciel en résultant.
-
-Le Licencié est autorisé à apporter toute Contribution au Logiciel sous
-réserve de mentionner, de façon explicite, son nom en tant qu'auteur de
-cette Contribution et la date de création de celle-ci.
-
-
- 5.3 DROIT DE DISTRIBUTION
-
-Le droit de distribution comporte notamment le droit de diffuser, de
-transmettre et de communiquer le Logiciel au public sur tout support et
-par tout moyen ainsi que le droit de mettre sur le marché à titre
-onéreux ou gratuit, un ou des exemplaires du Logiciel par tout procédé.
-
-Le Licencié est autorisé à distribuer des copies du Logiciel, modifié ou
-non, à des tiers dans les conditions ci-après détaillées.
-
-
- 5.3.1 DISTRIBUTION DU LOGICIEL SANS MODIFICATION
-
-Le Licencié est autorisé à distribuer des copies conformes du Logiciel,
-sous forme de Code Source ou de Code Objet, Ã condition que cette
-distribution respecte les dispositions du Contrat dans leur totalité et
-soit accompagnée:
-
- 1.
-
- d'un exemplaire du Contrat,
-
- 2.
-
- d'un avertissement relatif à la restriction de garantie et de
- responsabilité du Concédant telle que prévue aux articles 8
- <#responsabilite> et 9 <#garantie>,
-
-et que, dans le cas où seul le Code Objet du Logiciel est redistribué,
-le Licencié permette un accès effectif au Code Source complet du
-Logiciel pour une durée d'au moins 3 ans à compter de la distribution du
-logiciel, étant entendu que le coût additionnel d'acquisition du Code
-Source ne devra pas excéder le simple coût de transfert des données.
-
-
- 5.3.2 DISTRIBUTION DU LOGICIEL MODIFIE
-
-Lorsque le Licencié apporte une Contribution au Logiciel, les conditions
-de distribution du Logiciel Modifié en résultant sont alors soumises Ã
-l'intégralité des dispositions du Contrat.
-
-Le Licencié est autorisé à distribuer le Logiciel Modifié, sous forme de
-code source ou de code objet, Ã condition que cette distribution
-respecte les dispositions du Contrat dans leur totalité et soit
-accompagnée:
-
- 1.
-
- d'un exemplaire du Contrat,
-
- 2.
-
- d'un avertissement relatif à la restriction de garantie et de
- responsabilité du Concédant telle que prévue aux articles 8
- <#responsabilite> et 9 <#garantie>,
-
-et, dans le cas où seul le code objet du Logiciel Modifié est redistribué,
-
- 3.
-
- d'une note précisant les conditions d'accès effectif au code source
- complet du Logiciel Modifié, pendant une période d'au moins 3 ans Ã
- compter de la distribution du Logiciel Modifié, étant entendu que le
- coût additionnel d'acquisition du code source ne devra pas excéder
- le simple coût de transfert des données.
-
-
- 5.3.3 DISTRIBUTION DES MODULES EXTERNES
-
-Lorsque le Licencié a développé un Module Externe les conditions du
-Contrat ne s'appliquent pas à ce Module Externe, qui peut être distribué
-sous un contrat de licence différent.
-
-
- 5.3.4 COMPATIBILITE AVEC D'AUTRES LICENCES
-
-Le Licencié peut inclure un code soumis aux dispositions d'une des
-versions de la licence GNU GPL, GNU Affero GPL et/ou EUPL dans le
-Logiciel modifié ou non et distribuer l'ensemble sous les conditions de
-la même version de la licence GNU GPL, GNU Affero GPL et/ou EUPL.
-
-Le Licencié peut inclure le Logiciel modifié ou non dans un code soumis
-aux dispositions d'une des versions de la licence GNU GPL, GNU Affero
-GPL et/ou EUPL et distribuer l'ensemble sous les conditions de la même
-version de la licence GNU GPL, GNU Affero GPL et/ou EUPL.
-
-
- Article 6 - PROPRIETE INTELLECTUELLE
-
-
- 6.1 SUR LE LOGICIEL INITIAL
-
-Le Titulaire est détenteur des droits patrimoniaux sur le Logiciel
-Initial. Toute utilisation du Logiciel Initial est soumise au respect
-des conditions dans lesquelles le Titulaire a choisi de diffuser son
-oeuvre et nul autre n'a la faculté de modifier les conditions de
-diffusion de ce Logiciel Initial.
-
-Le Titulaire s'engage à ce que le Logiciel Initial reste au moins régi
-par le Contrat et ce, pour la durée visée à l'article 4.2 <#duree>.
-
-
- 6.2 SUR LES CONTRIBUTIONS
-
-Le Licencié qui a développé une Contribution est titulaire sur celle-ci
-des droits de propriété intellectuelle dans les conditions définies par
-la législation applicable.
-
-
- 6.3 SUR LES MODULES EXTERNES
-
-Le Licencié qui a développé un Module Externe est titulaire sur celui-ci
-des droits de propriété intellectuelle dans les conditions définies par
-la législation applicable et reste libre du choix du contrat régissant
-sa diffusion.
-
-
- 6.4 DISPOSITIONS COMMUNES
-
-Le Licencié s'engage expressément:
-
- 1.
-
- à ne pas supprimer ou modifier de quelque manière que ce soit les
- mentions de propriété intellectuelle apposées sur le Logiciel;
-
- 2.
-
- à reproduire à l'identique lesdites mentions de propriété
- intellectuelle sur les copies du Logiciel modifié ou non.
-
-Le Licencié s'engage à ne pas porter atteinte, directement ou
-indirectement, aux droits de propriété intellectuelle du Titulaire et/ou
-des Contributeurs sur le Logiciel et à prendre, le cas échéant, Ã
-l'égard de son personnel toutes les mesures nécessaires pour assurer le
-respect des dits droits de propriété intellectuelle du Titulaire et/ou
-des Contributeurs.
-
-
- Article 7 - SERVICES ASSOCIES
-
-7.1 Le Contrat n'oblige en aucun cas le Concédant à la réalisation de
-prestations d'assistance technique ou de maintenance du Logiciel.
-
-Cependant le Concédant reste libre de proposer ce type de services. Les
-termes et conditions d'une telle assistance technique et/ou d'une telle
-maintenance seront alors déterminés dans un acte séparé. Ces actes de
-maintenance et/ou assistance technique n'engageront que la seule
-responsabilité du Concédant qui les propose.
-
-7.2 De même, tout Concédant est libre de proposer, sous sa seule
-responsabilité, à ses licenciés une garantie, qui n'engagera que lui,
-lors de la redistribution du Logiciel et/ou du Logiciel Modifié et ce,
-dans les conditions qu'il souhaite. Cette garantie et les modalités
-financières de son application feront l'objet d'un acte séparé entre le
-Concédant et le Licencié.
-
-
- Article 8 - RESPONSABILITE
-
-8.1 Sous réserve des dispositions de l'article 8.2
-<#limite-responsabilite>, le Licencié a la faculté, sous réserve de
-prouver la faute du Concédant concerné, de solliciter la réparation du
-préjudice direct qu'il subirait du fait du Logiciel et dont il apportera
-la preuve.
-
-8.2 La responsabilité du Concédant est limitée aux engagements pris en
-application du Contrat et ne saurait être engagée en raison notamment:
-(i) des dommages dus à l'inexécution, totale ou partielle, de ses
-obligations par le Licencié, (ii) des dommages directs ou indirects
-découlant de l'utilisation ou des performances du Logiciel subis par le
-Licencié et (iii) plus généralement d'un quelconque dommage indirect. En
-particulier, les Parties conviennent expressément que tout préjudice
-financier ou commercial (par exemple perte de données, perte de
-bénéfices, perte d'exploitation, perte de clientèle ou de commandes,
-manque à gagner, trouble commercial quelconque) ou toute action dirigée
-contre le Licencié par un tiers, constitue un dommage indirect et
-n'ouvre pas droit à réparation par le Concédant.
-
-
- Article 9 - GARANTIE
-
-9.1 Le Licencié reconnaît que l'état actuel des connaissances
-scientifiques et techniques au moment de la mise en circulation du
-Logiciel ne permet pas d'en tester et d'en vérifier toutes les
-utilisations ni de détecter l'existence d'éventuels défauts. L'attention
-du Licencié a été attirée sur ce point sur les risques associés au
-chargement, à l'utilisation, la modification et/ou au développement et Ã
-la reproduction du Logiciel qui sont réservés à des utilisateurs avertis.
-
-Il relève de la responsabilité du Licencié de contrôler, par tous
-moyens, l'adéquation du produit à ses besoins, son bon fonctionnement et
-de s'assurer qu'il ne causera pas de dommages aux personnes et aux biens.
-
-9.2 Le Concédant déclare de bonne foi être en droit de concéder
-l'ensemble des droits attachés au Logiciel (comprenant notamment les
-droits visés à l'article 5 <#etendue>).
-
-9.3 Le Licencié reconnaît que le Logiciel est fourni "en l'état" par le
-Concédant sans autre garantie, expresse ou tacite, que celle prévue Ã
-l'article 9.2 <#bonne-foi> et notamment sans aucune garantie sur sa
-valeur commerciale, son caractère sécurisé, innovant ou pertinent.
-
-En particulier, le Concédant ne garantit pas que le Logiciel est exempt
-d'erreur, qu'il fonctionnera sans interruption, qu'il sera compatible
-avec l'équipement du Licencié et sa configuration logicielle ni qu'il
-remplira les besoins du Licencié.
-
-9.4 Le Concédant ne garantit pas, de manière expresse ou tacite, que le
-Logiciel ne porte pas atteinte à un quelconque droit de propriété
-intellectuelle d'un tiers portant sur un brevet, un logiciel ou sur tout
-autre droit de propriété. Ainsi, le Concédant exclut toute garantie au
-profit du Licencié contre les actions en contrefaçon qui pourraient être
-diligentées au titre de l'utilisation, de la modification, et de la
-redistribution du Logiciel. Néanmoins, si de telles actions sont
-exercées contre le Licencié, le Concédant lui apportera son expertise
-technique et juridique pour sa défense. Cette expertise technique et
-juridique est déterminée au cas par cas entre le Concédant concerné et
-le Licencié dans le cadre d'un protocole d'accord. Le Concédant dégage
-toute responsabilité quant à l'utilisation de la dénomination du
-Logiciel par le Licencié. Aucune garantie n'est apportée quant Ã
-l'existence de droits antérieurs sur le nom du Logiciel et sur
-l'existence d'une marque.
-
-
- Article 10 - RESILIATION
-
-10.1 En cas de manquement par le Licencié aux obligations mises à sa
-charge par le Contrat, le Concédant pourra résilier de plein droit le
-Contrat trente (30) jours après notification adressée au Licencié et
-restée sans effet.
-
-10.2 Le Licencié dont le Contrat est résilié n'est plus autorisé Ã
-utiliser, modifier ou distribuer le Logiciel. Cependant, toutes les
-licences qu'il aura concédées antérieurement à la résiliation du Contrat
-resteront valides sous réserve qu'elles aient été effectuées en
-conformité avec le Contrat.
-
-
- Article 11 - DISPOSITIONS DIVERSES
-
-
- 11.1 CAUSE EXTERIEURE
-
-Aucune des Parties ne sera responsable d'un retard ou d'une défaillance
-d'exécution du Contrat qui serait dû à un cas de force majeure, un cas
-fortuit ou une cause extérieure, telle que, notamment, le mauvais
-fonctionnement ou les interruptions du réseau électrique ou de
-télécommunication, la paralysie du réseau liée à une attaque
-informatique, l'intervention des autorités gouvernementales, les
-catastrophes naturelles, les dégâts des eaux, les tremblements de terre,
-le feu, les explosions, les grèves et les conflits sociaux, l'état de
-guerre...
-
-11.2 Le fait, par l'une ou l'autre des Parties, d'omettre en une ou
-plusieurs occasions de se prévaloir d'une ou plusieurs dispositions du
-Contrat, ne pourra en aucun cas impliquer renonciation par la Partie
-intéressée à s'en prévaloir ultérieurement.
-
-11.3 Le Contrat annule et remplace toute convention antérieure, écrite
-ou orale, entre les Parties sur le même objet et constitue l'accord
-entier entre les Parties sur cet objet. Aucune addition ou modification
-aux termes du Contrat n'aura d'effet à l'égard des Parties à moins
-d'être faite par écrit et signée par leurs représentants dûment habilités.
-
-11.4 Dans l'hypothèse où une ou plusieurs des dispositions du Contrat
-s'avèrerait contraire à une loi ou à un texte applicable, existants ou
-futurs, cette loi ou ce texte prévaudrait, et les Parties feraient les
-amendements nécessaires pour se conformer à cette loi ou à ce texte.
-Toutes les autres dispositions resteront en vigueur. De même, la
-nullité, pour quelque raison que ce soit, d'une des dispositions du
-Contrat ne saurait entraîner la nullité de l'ensemble du Contrat.
-
-
- 11.5 LANGUE
-
-Le Contrat est rédigé en langue française et en langue anglaise, ces
-deux versions faisant également foi.
-
-
- Article 12 - NOUVELLES VERSIONS DU CONTRAT
-
-12.1 Toute personne est autorisée à copier et distribuer des copies de
-ce Contrat.
-
-12.2 Afin d'en préserver la cohérence, le texte du Contrat est protégé
-et ne peut être modifié que par les auteurs de la licence, lesquels se
-réservent le droit de publier périodiquement des mises à jour ou de
-nouvelles versions du Contrat, qui posséderont chacune un numéro
-distinct. Ces versions ultérieures seront susceptibles de prendre en
-compte de nouvelles problématiques rencontrées par les logiciels libres.
-
-12.3 Tout Logiciel diffusé sous une version donnée du Contrat ne pourra
-faire l'objet d'une diffusion ultérieure que sous la même version du
-Contrat ou une version postérieure, sous réserve des dispositions de
-l'article 5.3.4 <#compatibilite>.
-
-
- Article 13 - LOI APPLICABLE ET COMPETENCE TERRITORIALE
-
-13.1 Le Contrat est régi par la loi française. Les Parties conviennent
-de tenter de régler à l'amiable les différends ou litiges qui
-viendraient à se produire par suite ou à l'occasion du Contrat.
-
-13.2 A défaut d'accord amiable dans un délai de deux (2) mois à compter
-de leur survenance et sauf situation relevant d'une procédure d'urgence,
-les différends ou litiges seront portés par la Partie la plus diligente
-devant les Tribunaux compétents de Paris.
-
-
diff --git a/README.md b/README.md
@@ -1,7 +1,7 @@
# Star Schiff
The purpose of this library is to numericaly solve the radiative properties of
-micro organism with respect to an "Approximation Method for Short Wavelength or
+soft particles with respect to an "Approximation Method for Short Wavelength or
High-Energy Scattering" (L. Schiff, 1956).
It will estimate total cross-sections (absorption, scattering and
@@ -23,22 +23,25 @@ computation time in order to obtain more accurate results if needed.
## How to build
-The *Star-Schiff* library relies on the [CMake](http://www.cmake.org) and the
+The Star-Schiff library relies on the [CMake](http://www.cmake.org) and the
[RCMake](https://gitlab.com/vaplv/rcmake/) package to build. It also depends on the
+[GNU Scientific Library](http://www.gnu.org/software/gsl/),
[RSys](https://gitlab.com/vaplv/rsys/),
[Star-3D](https://gitlab.com/meso-star/star-3d/) and
[Star-SP](https://gitlab.com/meso-star/star-sp/) libraries.
First ensure that CMake is installed on your system. Then install the RCMake
-package as well as all the *Star-Schiff* prerequisites. Then generate the
-project from the `cmake/CMakeLists.txt` file by appending to the
+package as well as all the aforementioned Star-Schiff prerequisites. Then
+generate the project from the `cmake/CMakeLists.txt` file by appending to the
`CMAKE_PREFIX_PATH` variable the install directories of its dependencies and
-the RCMake package.
+the one of the RCMake package.
-## Licenses
+## License
-*Star-Schiff* is Copyright (C) |Meso|Star> 2015 (<contact@meso-star.com>). It is a
-free software released under the [OSI](http://opensource.org)-approved CeCILL
-license. You are welcome to redistribute it under certain conditions; refer to
-the COPYING files for details.
+Star-Schiff is developped by [|Meso|Star>](http://www.meso-star.com) for the
+the [National Center for Scientific Research](http://www.cnrs.fr/index.php)
+(CNRS). It is a free software copyright (C) CNRS 2015-2016 released under the
+[OSI](http://opensource.org)-approved GPL v3.0 license. You are welcome to
+redistribute it under certain conditions; refer to the COPYING file for
+details.
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -1,30 +1,17 @@
-# Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+# Copyright (C) 2015-2016 CNRS
#
-# This software is governed by the CeCILL license under French law and
-# abiding by the rules of distribution of free software. You can use,
-# modify and/or redistribute the software under the terms of the CeCILL
-# license as circulated by CEA, CNRS and INRIA at the following URL
-# "http://www.cecill.info".
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
#
-# As a counterpart to the access to the source code and rights to copy,
-# modify and redistribute granted by the license, users are provided only
-# with a limited warranty and the software's author, the holder of the
-# economic rights, and the successive licensors have only limited
-# liability.
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
#
-# In this respect, the user's attention is drawn to the risks associated
-# with loading, using, modifying and/or developing or reproducing the
-# software by the user in light of its specific status of free software,
-# that may mean that it is complicated to manipulate, and that also
-# therefore means that it is reserved for developers and experienced
-# professionals having in-depth computer knowledge. Users are therefore
-# encouraged to load and test the software's suitability as regards their
-# requirements in conditions enabling the security of their systems and/or
-# data to be ensured and, more generally, to use and operate it in the
-# same conditions as regards security.
-#
-# The fact that you are presently reading this means that you have had
-# knowledge of the CeCILL license and that you accept its terms.
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 2.8)
project(star-schiff C)
@@ -41,11 +28,13 @@ find_package(RSys 0.3 REQUIRED)
find_package(StarSP 0.3 REQUIRED)
find_package(Star3D 0.3 REQUIRED)
find_package(OpenMP 1.2 REQUIRED)
+find_package(GSL REQUIRED)
include_directories(
${RSys_INCLUDE_DIR}
${StarSP_INCLUDE_DIR}
- ${Star3D_INCLUDE_DIR})
+ ${Star3D_INCLUDE_DIR}
+ ${GSL_INCLUDE_DIRS})
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR})
include(rcmake)
@@ -59,10 +48,13 @@ set(VERSION_MINOR 3)
set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
-set(SSCHIFF_FILES_SRC sschiff_device.c sschiff_estimator.c)
+set(SSCHIFF_FILES_SRC
+ sschiff_device.c
+ sschiff_estimator.c
+ sschiff_scattering_angles_distributions.c)
set(SSCHIFF_FILES_INC_API sschiff.h)
set(SSCHIFF_FILES_INC sschiff_device.h)
-set(SSCHIFF_FILES_DOC COPYING.en COPYING.fr README.md)
+set(SSCHIFF_FILES_DOC COPYING README.md)
# Prepend each file in the `SSCHIFF_FILES_<SRC|INC>' list by `SSCHIFF_SOURCE_DIR'
rcmake_prepend_path(SSCHIFF_FILES_SRC ${SSCHIFF_SOURCE_DIR})
@@ -76,12 +68,12 @@ set_target_properties(sschiff PROPERTIES
VERSION ${VERSION}
SOVERSION ${VERSION_MAJOR})
-target_link_libraries(sschiff RSys Star3D StarSP)
+target_link_libraries(sschiff RSys Star3D StarSP GSL::gsl)
if(CMAKE_COMPILER_IS_GNUCC)
target_link_libraries(sschiff m)
endif()
-set_target_properties(sschiff PROPERTIES
+set_target_properties(sschiff PROPERTIES
COMPILE_FLAGS ${OpenMP_C_FLAGS}
COMPILE_DEFINITIONS SSCHIFF_USE_OPENMP)
if(CMAKE_COMPILER_IS_GNUCC)
@@ -102,6 +94,7 @@ if(NOT NO_TEST)
new_test(test_sschiff_device)
new_test(test_sschiff_estimator_sphere)
new_test(test_sschiff_estimator_cylinder)
+ new_test(test_sschiff_estimator_rhodo)
rcmake_copy_runtime_libraries(test_sschiff_device)
endif()
diff --git a/src/sschiff.h b/src/sschiff.h
@@ -1,30 +1,17 @@
-/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+/* Copyright (C) 2015-2016 CNRS
*
- * This software is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms. */
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef SSCHIFF_H
#define SSCHIFF_H
@@ -58,15 +45,6 @@ struct s3d_device;
struct s3d_shape;
struct ssp_rng;
-/* Type of estimated data */
-enum sschiff_data {
- SSCHIFF_EXTINCTION_CROSS_SECTION,
- SSCHIFF_ABSORPTION_CROSS_SECTION,
- SSCHIFF_SCATTERING_CROSS_SECTION,
- SSCHIFF_AVERAGE_PROJECTED_AREA,
- SSCHIFF_DATA_COUNT__
-};
-
/* Optical properties of a material handled by the Schiff integrator */
struct sschiff_material_properties {
double medium_refractive_index;
@@ -89,35 +67,51 @@ static const struct sschiff_material SSCHIFF_NULL_MATERIAL = { NULL, NULL };
/* User defined distribution of the geometries. The unit of the geometry is the
* micron, i.e. 1.0f == 1 micron */
struct sschiff_geometry_distribution {
+ struct sschiff_material material; /* Material of the geometry distribution */
+ double characteristic_length;
res_T (*sample) /* Sample a geometry i.e. a shape and its material */
(struct ssp_rng* rng,
- struct sschiff_material* mtl, /* Sampled material */
struct s3d_shape* shape, /* Sampled shape */
void* context);
void* context;
};
static const struct sschiff_geometry_distribution
-SSCHIFF_NULL_GEOMETRY_DISTRIBUTION = { NULL, NULL };
+SSCHIFF_NULL_GEOMETRY_DISTRIBUTION = { {NULL, NULL}, -1.0, NULL, NULL };
/* State of the Monte Carlo estimation */
-struct sschiff_estimator_state {
- double wavelength; /* Estimated wavelength in micron */
- struct sschiff_estimator_value { /* Values of the estimation */
- double E; /* Expected value */
- double V; /* Variance */
- double SE; /* Standard error */
- } values[SSCHIFF_DATA_COUNT__];
+struct sschiff_state {
+ double E; /* Expected value */
+ double V; /* Variance */
+ double SE; /* Standard error */
+};
+
+struct sschiff_cross_section {
+ struct sschiff_state extinction;
+ struct sschiff_state absorption;
+ struct sschiff_state scattering;
+ struct sschiff_state average_projected_area;
};
+/* Type of the function use to distribute the scattering angles in [0, PI].
+ * nangles is assumed to be greater than or equal to 2 and the angles is
+ * ensured to have `nangles' entries. */
+typedef void (*sschiff_scattering_angles_distribution_T)
+ (double angles[], const size_t nangles);
+
/* Opaque types */
struct sschiff_device;
struct sschiff_estimator;
+BEGIN_DECLS
+
+/* Built-in uniform distribution of scattering angles */
+SSCHIFF_API const sschiff_scattering_angles_distribution_T
+sschiff_uniform_scattering_angles;
+
/*******************************************************************************
* Star Schiff API
******************************************************************************/
-BEGIN_DECLS
SSCHIFF_API res_T
sschiff_device_create
@@ -141,9 +135,11 @@ sschiff_integrate
(struct sschiff_device* dev,
struct ssp_rng* rng,
struct sschiff_geometry_distribution* distribution,
- const double* wavelengths, /* list of wavelengths to estimate in micron */
+ /* Wavelengths to estimate in micron. Must be sorted in ascending order. */
+ const double* wavelengths,
const size_t wavelengths_count, /* # wavelengths to estimate */
- const size_t scattering_angles_count, /* # of scattering angles to handle */
+ const sschiff_scattering_angles_distribution_T angles, /* angles distrib */
+ const size_t scattering_angles_count, /* # scattering angles. Must be >= 3 */
const size_t sampled_geometries_count, /* # geometries to sample */
const size_t sampled_directions_count, /* # directions to sample per geometry */
struct sschiff_estimator** estimator);
@@ -156,11 +152,19 @@ SSCHIFF_API res_T
sschiff_estimator_ref_put
(struct sschiff_estimator* estimator);
-/* Return the number of estimated wavelength */
+/* Return the list of estimated wavelengths. */
SSCHIFF_API res_T
-sschiff_estimator_get_wavelengths_count
+sschiff_estimator_get_wavelengths
(const struct sschiff_estimator* estimator,
- size_t* count);
+ const double** wavelengths, /* May be NULL, i.e. do not return this list */
+ size_t* count); /* May be NULL, i.e. do not return the # wavelengths */
+
+/* Return the list of scattering angles. */
+SSCHIFF_API res_T
+sschiff_estimator_get_scattering_angles
+ (const struct sschiff_estimator* estimator,
+ const double** angles, /* May be NULL, i.e. do not return the angles */
+ size_t* count); /* May be NULL, i.e. do not return the # scattering angles */
/* Return the number of Monte Carlo realisations */
SSCHIFF_API res_T
@@ -168,21 +172,95 @@ sschiff_estimator_get_realisations_count
(const struct sschiff_estimator* estimator,
size_t* count);
-/* Retrieve the estimation state of a given wavelength */
+/* Retrieve the estimation state of a given wavelength. */
+SSCHIFF_API res_T
+sschiff_estimator_get_cross_section
+ (const struct sschiff_estimator* estimator,
+ const size_t wavelength_index, /* Id of the wavelengths */
+ struct sschiff_cross_section* cross_section);
+
+/* Retrieve the estimated cross sections of all wavelengths. The length of
+ * `cross_sections' must be at least equal to the count of integrated
+ * wavelengths. One can use the sschiff_estimator_get_wavelengths function to
+ * retrieve this information. */
+SSCHIFF_API res_T
+sschiff_estimator_get_cross_sections
+ (const struct sschiff_estimator* estimator,
+ struct sschiff_cross_section cross_sections[]);
+
+/* Retrieve a pointer onto the estimated phase function for the scattering
+ * angles of the estimator. Use the sschiff_estimator_get_scattering_angles
+ * function to retrieve these scattering angles. Return RES_BAD_OP if the phase
+ * function couldn't be estimated for this wavelength */
+SSCHIFF_API res_T
+sschiff_estimator_get_phase_function
+ (const struct sschiff_estimator* estimator,
+ const size_t wavelength_index,
+ const struct sschiff_state** states);
+
+/* Retrieve a pointer onto the estimated phase function cumulative for the
+ * scattering angles of the estimator. Use the
+ * sschiff_estimator_get_scattering_angles function to retrieve these
+ * scattering angles. Return RES_BAD_OP if the phase function couldn't be
+ * estimated for this wavelength */
+SSCHIFF_API res_T
+sschiff_estimator_get_phase_function_cumulative
+ (const struct sschiff_estimator* estimator,
+ const size_t wavelength_index,
+ const struct sschiff_state** states);
+
+/* Compute the inverse cumulative of the estimated phase function. The inverse
+ * cumulative is computed for a set of `nthetas' values distributed in [0, 1]
+ * as [0, 1*S, 2*S, ..., i*S, ..., (nthetas-1)*S] with S=1/(nthetas-1). The
+ * ouput array `thetas' stored the angles corresponding to these cumulative
+ * values. Its length must be at least equal to `nthetas'. Return RES_BAD_OP of
+ * the cumulative phase function cannot be inverted. */
+SSCHIFF_API res_T
+sschiff_estimator_inverse_cumulative_phase_function
+ (const struct sschiff_estimator* estimator,
+ const size_t wavelength_index,
+ double thetas[],
+ const size_t nthetas); /* Must be >= 2 */
+
+
+/* Retrieve, for the submitted wavelength, the index of the last small
+ * scattering angle, i.e. the last angle from which the phase function
+ * [cumulative] is estimated by Monte Carlo. One can use this index to get the
+ * value of the limit angle from the scattering angles returned by the
+ * sschiff_estimator_get_scattering_angles function. Return RES_BAD_OP if the
+ * phase function is not computable for this wavelength. */
+SSCHIFF_API res_T
+sschiff_estimator_get_limit_scattering_angle_index
+ (const struct sschiff_estimator* estimator,
+ const size_t wavelength_index,
+ size_t* scattering_angle_index);
+
+/* Return the `n' parameter of the model used to compute the phase function of
+ * the wide scattering angles for a given wavelength. Return RES_BAD_OP if the
+ * phase function is not computable for this wavelength */
+SSCHIFF_API res_T
+sschiff_estimator_get_wide_scattering_angle_model_parameter
+ (const struct sschiff_estimator* estimator,
+ const size_t wavelength_index,
+ double* n);
+
+/* Return the estimated differential cross section for a wavelength at a given
+ * scattering angle. Return RES_BAD_OP if it was not computable. */
SSCHIFF_API res_T
-sschiff_estimator_get_wavelength_state
+sschiff_estimator_get_differential_cross_section
(const struct sschiff_estimator* estimator,
- const double wavelength, /* In micron */
- struct sschiff_estimator_state* state);
+ const size_t wavelength_index,
+ const size_t scattering_angle_index,
+ struct sschiff_state* state);
-/* Retrieve the estimation state of all wavelengths. The length of `states'
- * must be at least equal to the count of integrated wavelengths. One can use
- * the sschiff_estimator_get_wavelengths_count function to retrieve this
- * information. */
+/* Return the estimated differential cross section cumulative for a wavelength
+ * at a given scattering angle. Return RES_BAD_OP if it was not computable. */
SSCHIFF_API res_T
-sschiff_estimator_get_states
+sschiff_estimator_get_differential_cross_section_cumulative
(const struct sschiff_estimator* estimator,
- struct sschiff_estimator_state states[]);
+ const size_t wavelength_index,
+ const size_t scanttering_angle_index,
+ struct sschiff_state* state);
END_DECLS
diff --git a/src/sschiff_device.c b/src/sschiff_device.c
@@ -1,30 +1,17 @@
-/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+/* Copyright (C) 2015-2016 CNRS
*
- * This software is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms. */
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "sschiff.h"
#include "sschiff_device.h"
@@ -75,6 +62,20 @@ log_error(struct sschiff_device* dev, const char* msg, ...)
}
}
+void
+log_warning(struct sschiff_device* dev, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(dev && msg);
+ if(dev->verbose) {
+ res_T res; (void)res;
+ va_start(vargs_list, msg);
+ res = logger_vprint(dev->logger, LOG_WARNING, msg, vargs_list);
+ ASSERT(res == RES_OK);
+ va_end(vargs_list);
+ }
+}
+
/*******************************************************************************
* API functions
******************************************************************************/
diff --git a/src/sschiff_device.h b/src/sschiff_device.h
@@ -1,30 +1,17 @@
-/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+/* Copyright (C) 2015-2016 CNRS
*
- * This software is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms. */
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef SSCHIFF_DEVICE_H
#define SSCHIFF_DEVICE_H
@@ -54,5 +41,16 @@ log_error
__attribute((format(printf, 2, 3)))
#endif
;
+
+extern LOCAL_SYM void
+log_warning
+ (struct sschiff_device* dev,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
#endif /* SSCHIFF_DEVICE_H */
diff --git a/src/sschiff_estimator.c b/src/sschiff_estimator.c
@@ -1,36 +1,24 @@
-/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+/* Copyright (C) 2015-2016 CNRS
*
- * This software is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms. */
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
#define _POSIX_C_SOURCE 200112L /* nextafterf support */
#include "sschiff.h"
#include "sschiff_device.h"
+#include <rsys/algorithm.h>
#include <rsys/float2.h>
#include <rsys/float3.h>
#include <rsys/image.h>
@@ -45,44 +33,97 @@
#include <math.h>
#include <omp.h>
+#include <gsl/gsl_sf.h>
+#include <gsl/gsl_multiroots.h>
+
#define MAX_FAILURES 10
+#define INVALID_LIMIT_ANGLE SIZE_MAX
/* Accumulator of double precision values */
-struct accum { double weights[SSCHIFF_DATA_COUNT__]; };
+struct accum {
+ double extinction_cross_section;
+ double absorption_cross_section;
+ double scattering_cross_section;
+ double avg_projected_area;
+
+ /* Per scattering angles weights */
+ double* differential_cross_section;
+ double* differential_cross_section_cumulative;
+};
/* Monte carlo data */
struct mc_data { double weight; double sqr_weight; };
-
static const struct mc_data MC_DATA_NULL = { 0.0, 0.0 };
/* Accumulator of Monte Carlo data */
-struct mc_accum { struct mc_data mc_data[SSCHIFF_DATA_COUNT__]; };
+struct mc_accum {
+ struct mc_data extinction_cross_section;
+ struct mc_data absorption_cross_section;
+ struct mc_data scattering_cross_section;
+ struct mc_data avg_projected_area;
+
+ /* Per scattering angles weight */
+ struct mc_data* differential_cross_section;
+ struct mc_data* differential_cross_section_cumulative;
+};
+
+/* Estimated phase function */
+struct phase_function {
+ /* Per angle values */
+ struct sschiff_state* values;
+ struct sschiff_state* cumulative;
+};
-static const struct mc_accum MC_ACCUM_NULL =
-{{{0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}, {0.0, 0.0}}};
+/* The integrator context stores per thread data */
+struct integrator_context {
+ /* Geometry of the micro particle */
+ struct s3d_shape* shape;
+ struct s3d_scene* scene;
+
+ struct ssp_rng* rng; /* Random Number Generator */
+ size_t nwavelengths; /* #wavelengths */
+ size_t nangles; /* #scattering angles */
+
+ /* Per wavelengths data */
+ struct accum* accums; /* Temporary accumulators */
+ struct mc_accum* mc_accums; /* Monte Carlo accumulators */
+
+ /* Pointer toward the estimator */
+ struct sschiff_estimator* estimator;
+};
+
+/* Store per thread data of the post integration process */
+struct solver_context {
+ gsl_multiroot_fdfsolver* solver;
+ gsl_vector* init_val;
+};
struct sschiff_estimator {
- double* wavelengths;
- struct mc_accum* accums;
+ double* wavelengths; /* List of wavelengths in vacuum */
+ double* angles; /* List of scattering angles */
+
+ /* Per wavelength index of the scattering angle from which the MC estimation
+ * of the phase function is no more valid. Must be < nangles. */
+ size_t* limit_angles;
+ double* wide_angles_parameter;
+
+ double* wavenumbers;
+ struct sschiff_material_properties* properties; /* Material properties */
+
+ /* Per wavelength results */
+ struct phase_function* phase_functions;
+ struct mc_accum* accums; /* Monte Carlo estimation */
+
+ size_t nrealisations; /* # realisation used by MC estimations */
+ int no_phase_function; /* Set to 1 when no phase function is computed */
+
struct sschiff_device* dev;
- size_t nrealisations;
ref_T ref;
};
/*******************************************************************************
* Helper functions
******************************************************************************/
-static FINLINE uint16_t
-morton2D_decode(const uint32_t u32)
-{
- uint32_t x = u32 & 0x55555555;
- x = (x | (x >> 1)) & 0x33333333;
- x = (x | (x >> 2)) & 0x0F0F0F0F;
- x = (x | (x >> 4)) & 0x00FF00FF;
- x = (x | (x >> 8)) & 0x0000FFFF;
- return (uint16_t)x;
-}
-
static FINLINE int
cmp_double(const void* a, const void* b)
{
@@ -92,6 +133,15 @@ cmp_double(const void* a, const void* b)
return i;
}
+static FINLINE int
+cmp_schiff_state(const void* a, const void* b)
+{
+ const struct sschiff_state* op0 = a;
+ const struct sschiff_state* op1 = b;
+ const int i = op0->E < op1->E ? -1 : (op0->E > op1->E ? 1 : 0);
+ return i;
+}
+
/* Compute an orthonormal basis where `dir' is the Z axis. */
static void
build_basis(const float dir[3], float basis[9])
@@ -140,78 +190,55 @@ build_transform
transform[11] = -f3_dot(basis+6, pos);
}
-/* Dump a thumbnail of the sampled geometry in given sampled direction */
-static INLINE void
-draw_thumbnail
- (struct s3d_scene* scn,
- const float basis[9], /* World space basis of the RT volume */
- const float pos[3], /* World space centroid of the RT volume */
- const float lower[3], /* Lower boundary of the RT volume */
- const float upper[3], /* Upper boundary of the RT volume */
- const char* name) /* Filename of the thumbnail */
+static FINLINE double
+expected_value(const struct mc_data* data, const size_t nrealisations)
{
-#define DEFINITION 128
- STATIC_ASSERT(IS_POW2(DEFINITION), Invalid_thumbnail_definition);
- const float range[2] = { 0, FLT_MAX };
- const float pixel_size = 1.f/(float)DEFINITION;
- float axis_x[3], axis_y[3], axis_z[3];
- float plane_size[2];
- float ray_org[3];
- float org[3];
- uint32_t npixels = (uint32_t)(DEFINITION * DEFINITION);
- uint32_t mcode;
- unsigned char* img = NULL;
- ASSERT(basis && pos && lower && upper);
-
- /* Allocate the thumbnail buffer */
- img = sa_add(img, DEFINITION*DEFINITION);
- ASSERT(img != NULL);
+ return data->weight / (double)nrealisations;
+}
- /* Define the projection axis */
- f2_sub(plane_size, upper, lower);
- f3_mulf(axis_x, basis + 0, plane_size[0] * 0.5f);
- f3_mulf(axis_y, basis + 3, plane_size[1] * 0.5f);
- f3_set(axis_z, basis + 6);
+static INLINE void
+get_mc_value
+ (const struct mc_data* data,
+ const size_t nrealisations,
+ struct sschiff_state* value)
+{
+ ASSERT(data && value);
+ value->E = expected_value(data, nrealisations);
+ value->V = data->sqr_weight / (double)nrealisations
+ - (data->weight * data->weight) / (double)(nrealisations * nrealisations);
+ value->SE = sqrt(value->V / (double)nrealisations);
+}
- /* Compute the origin of the projection plane */
- f3_add(org, pos, f3_mulf(org, axis_z, lower[2]));
+static FINLINE int
+hit_on_edge(const struct s3d_hit* hit)
+{
+ const float on_edge_eps = 1.e-4f;
+ float w;
+ ASSERT(hit && !S3D_HIT_NONE(hit));
+ w = 1.f - hit->uv[0] - hit->uv[1];
+ return eq_epsf(hit->uv[0], 0.f, on_edge_eps)
+ || eq_epsf(hit->uv[0], 1.f, on_edge_eps)
+ || eq_epsf(hit->uv[1], 0.f, on_edge_eps)
+ || eq_epsf(hit->uv[1], 1.f, on_edge_eps)
+ || eq_epsf(w, 0.f, on_edge_eps)
+ || eq_epsf(w, 1.f, on_edge_eps);
+}
- FOR_EACH(mcode, 0, npixels) {
- struct s3d_hit hit;
- size_t ipixel;
- float sample[2], x[3], y[3];
- uint16_t ipixel_x, ipixel_y;
-
- /* Compute the sample position in [0, 1)^2 onto the projection plane */
- ipixel_x = morton2D_decode(mcode);
- ipixel_y = morton2D_decode(mcode>>1);
- sample[0] = ((float)ipixel_x + 0.5f) * pixel_size;
- sample[1] = ((float)ipixel_y + 0.5f) * pixel_size;
-
- /* Compute the ray origin */
- f3_mulf(x, axis_x, sample[0]*2.f - 1.f);
- f3_mulf(y, axis_y, sample[1]*2.f - 1.f);
- f3_add(ray_org, f3_add(ray_org, x, y), org);
-
- S3D(scene_trace_ray(scn, ray_org, axis_z, range, &hit));
-
- /* Simple shading */
- ipixel = (size_t)(ipixel_y * DEFINITION + ipixel_x);
- if(S3D_HIT_NONE(&hit)) {
- img[ipixel] = 0;
- } else {
- float N[3] = {0.f,0.f,0.f};
- float cosine;
- f3_normalize(N, hit.normal);
- if(0 > (cosine = f3_dot(N, axis_z))) {
- cosine = f3_dot(f3_minus(N, N), axis_z);
- }
- img[ipixel] = (unsigned char)(cosine*255.f + 0.5f/*Round*/);
- }
- }
- image_ppm_write(name, DEFINITION, DEFINITION, 1, img);
- sa_release(img);
-#undef DEFINITION
+static FINLINE int
+self_hit
+ (const struct s3d_hit* hit_from,
+ const struct s3d_hit* hit_to,
+ const float epsilon)
+{
+ ASSERT(hit_from && hit_to);
+
+ if(S3D_HIT_NONE(hit_from) || S3D_HIT_NONE(hit_to))
+ return 0;
+ if(S3D_PRIMITIVE_EQ(&hit_from->prim, &hit_to->prim))
+ return 1;
+ if(eq_epsf(hit_to->distance - hit_from->distance, 0.f, epsilon))
+ return hit_on_edge(hit_from) && hit_on_edge(hit_to);
+ return 0;
}
/* Compute the length in micron of the ray part that traverses the scene */
@@ -225,38 +252,35 @@ compute_path_length
double* length)
{
float range[2] = { 0, FLT_MAX };
- struct s3d_primitive prim_from;
- struct s3d_hit hit;
+ struct s3d_hit hit_from, hit;
double len = 0;
float dst;
ASSERT(scn && first_hit && ray_org && ray_dir && !S3D_HIT_NONE(first_hit));
+ (void)dev;
dst = range[0] = first_hit->distance;
- prim_from = first_hit->prim;
+ hit_from = *first_hit;
+
do {
do {
range[0] = nextafterf(range[0], range[1]);
S3D(scene_trace_ray(scn, ray_org, ray_dir, range, &hit));
- } while(S3D_PRIMITIVE_EQ(&hit.prim, &prim_from) /* Self-intersection */
- || hit.distance < range[0]); /* Precision issue */
+ } while(hit.distance < range[0] || self_hit(&hit_from, &hit, 1.e-6f));
- if(S3D_HIT_NONE(&hit)) {
- log_error(dev, "Error in computing the radiative path length.\n");
- return RES_BAD_ARG;
- }
+ if(S3D_HIT_NONE(&hit))
+ return RES_BAD_OP;
len += hit.distance - dst;
dst = range[0] = hit.distance;
- prim_from = hit.prim;
+ hit_from = hit;
do {
range[0] = nextafterf(range[0], range[1]);
S3D(scene_trace_ray(scn, ray_org, ray_dir, range, &hit));
- } while(S3D_PRIMITIVE_EQ(&hit.prim, &prim_from) /* Self-intersection */
- || hit.distance < range[0]); /* Precision issue */
+ } while(hit.distance < range[0] || self_hit(&hit_from, &hit, 1.e-6f));
range[0] = hit.distance;
- prim_from = hit.prim;
+ hit_from = hit;
} while(!S3D_HIT_NONE(&hit));
@@ -264,19 +288,117 @@ compute_path_length
return RES_OK;
}
+static INLINE void
+accum_cross_section
+ (struct integrator_context* ctx,
+ const double plane_area,
+ const double path_length)
+{
+ size_t iwlen;
+ ASSERT(ctx && plane_area > 0 && path_length > 0);
+
+ FOR_EACH(iwlen, 0, ctx->nwavelengths) {
+ double n_r, k_r;
+ double k_e;
+ double w_extinction, w_absorption, w_scattering;
+
+ k_e = ctx->estimator->wavenumbers[iwlen];
+ n_r = ctx->estimator->properties[iwlen].relative_real_refractive_index;
+ k_r = ctx->estimator->properties[iwlen].relative_imaginary_refractive_index;
+
+ /* Extinction cross section */
+ w_extinction = 2.0 * plane_area *
+ (1.0 - exp(-k_e*k_r*path_length) * cos(k_e*(n_r - 1.0)*path_length));
+ ctx->accums[iwlen].extinction_cross_section += w_extinction;
+
+ /* Absorption cross section */
+ w_absorption = plane_area * (1.0 - exp(-2.0*k_e*k_r*path_length));
+ ctx->accums[iwlen].absorption_cross_section += w_absorption;
+
+ /* Scattering cross section */
+ w_scattering = w_extinction - w_absorption;
+ ctx->accums[iwlen].scattering_cross_section += w_scattering;
+
+ /* Average projected area */
+ ctx->accums[iwlen].avg_projected_area += plane_area;
+ }
+}
+
+static INLINE void
+accum_differential_cross_section
+ (struct integrator_context* ctx,
+ const double plane_area,
+ const double path_length[2],
+ float ray_org[2][3])
+{
+ double delta_r;
+ size_t iwlen;
+ float vec[3];
+
+ /* Compute the length between the 2 ray starting points in footprint space */
+ delta_r = f3_len(f3_sub(vec, ray_org[0], ray_org[1]));
+
+ FOR_EACH(iwlen, 0, ctx->nwavelengths) {
+ double k_e_delta_r;
+ double n_r, k_r;
+ double k_e;
+ double beta_r[2];
+ double beta_i[2];
+ double tmp;
+ size_t iangle;
+
+ /* Avoid evaluating the differential cross sections for wavelengths with no
+ * valid limit scattering angle */
+ if(ctx->estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE) continue;
+
+ /* Fetch optical properties */
+ k_e = ctx->estimator->wavenumbers[iwlen];
+ n_r = ctx->estimator->properties[iwlen].relative_real_refractive_index;
+ k_r = ctx->estimator->properties[iwlen].relative_imaginary_refractive_index;
+
+ /* Precompute some values. TODO can be stored on the context */
+ k_e_delta_r = k_e * delta_r;
+ beta_r[0] = k_e * (n_r - 1) * path_length[0];
+ beta_r[1] = k_e * (n_r - 1) * path_length[1];
+ beta_i[0] = k_e * k_r * path_length[0];
+ beta_i[1] = k_e * k_r * path_length[1];
+ tmp = (k_e * plane_area) / (2*PI);
+ tmp *= tmp;
+ tmp *= (1
+ + exp(-(beta_i[0] + beta_i[1])) * cos(beta_r[0] - beta_r[1])
+ - exp(-beta_i[0]) * cos(beta_r[0])
+ - exp(-beta_i[1]) * cos(beta_r[1]));
+
+ /* Compute and accumulate the MC weights of the differential cross section
+ * and its cumulative. Note that ctx->limit_angles store the index of the
+ * first scattering angle whos phase function is not estimated by
+ * Monte-Carlo */
+ FOR_EACH(iangle, 0, ctx->estimator->limit_angles[iwlen]) {
+ double bessel_j0, bessel_j1;
+ double weight;
+ double k_e_angle_delta_r;
+
+ k_e_angle_delta_r = ctx->estimator->angles[iangle] * k_e_delta_r;
+
+ bessel_j0 = gsl_sf_bessel_J0(k_e_angle_delta_r);
+ weight = bessel_j0 * tmp;
+ ctx->accums[iwlen].differential_cross_section[iangle] += weight;
+
+ bessel_j1 = gsl_sf_bessel_J1(k_e_angle_delta_r);
+ weight = 2*PI*ctx->estimator->angles[iangle]*bessel_j1/k_e_delta_r*tmp;
+ ctx->accums[iwlen].differential_cross_section_cumulative[iangle] += weight;
+ }
+ }
+}
+
static res_T
accum_monte_carlo_weight
(struct sschiff_device* dev,
- struct s3d_scene* scn,
- struct ssp_rng* rng,
- const struct sschiff_material_properties* props,
- const double* wavelengths, /* In micron */
- const size_t nwavelengths,
+ struct integrator_context* ctx,
const float basis[9], /* World space basis of the RT volume */
const float pos[3], /* World space centroid of the RT volume */
const float lower[3], /* Lower boundary of the RT volume */
- const float upper[3], /* Upper boundary of the RT volume */
- struct accum* accums)
+ const float upper[3]) /* Upper boundary of the RT volume */
{
struct s3d_hit hit;
double sample[2];
@@ -284,16 +406,15 @@ accum_monte_carlo_weight
size_t nfailures = 0;
float axis_x[3], axis_y[3], axis_z[3];
float plane_size[2];
- float ray_org[3];
+ float ray_org[2][3];
float org[3];
float x[3], y[3];
- float rcp_pdf;
+ float plane_area;
res_T res = RES_OK;
- ASSERT(scn && rng && props && wavelengths && accums && basis && pos);
- ASSERT(lower && upper);
+ ASSERT(dev && ctx && basis && pos && lower && upper);
f2_sub(plane_size, upper, lower); /* In micron */
- rcp_pdf = plane_size[0] * plane_size[1];
+ plane_area = plane_size[0] * plane_size[1];
/* Define the projection axis */
f3_mulf(axis_x, basis + 0, plane_size[0] * 0.5f);
@@ -304,58 +425,60 @@ accum_monte_carlo_weight
f3_add(org, pos, f3_mulf(org, axis_z, lower[2]));
do {
+ double path_length[2];
+
/* Uniformly sample a position onto the projection plane and use it as the
- * origin of the ray to trace */
- sample[0] = ssp_rng_uniform_double(rng, -1.0, 1.0);
- sample[1] = ssp_rng_uniform_double(rng, -1.0, 1.0);
+ * origin of the 1st ray to trace */
+ sample[0] = ssp_rng_uniform_double(ctx->rng, -1.0, 1.0);
+ sample[1] = ssp_rng_uniform_double(ctx->rng, -1.0, 1.0);
f3_mulf(x, axis_x, (float)sample[0]);
f3_mulf(y, axis_y, (float)sample[1]);
- f3_add(ray_org, f3_add(ray_org, x, y), org);
+ f3_add(ray_org[0], f3_add(ray_org[0], x, y), org);
- S3D(scene_trace_ray(scn, ray_org, axis_z, range, &hit));
+ S3D(scene_trace_ray(ctx->scene, ray_org[0], axis_z, range, &hit));
+ /* NULL cross section and differential cross section weight */
+ if(S3D_HIT_NONE(&hit))
+ break;
- if(!S3D_HIT_NONE(&hit)) {
- double path_length;
- size_t iwlen;
-
- res = compute_path_length(dev, scn, &hit, ray_org, axis_z, &path_length);
- if(res != RES_OK) { /* Handle numerical/geometry issues */
- ++nfailures;
- continue;
- }
-
- FOR_EACH(iwlen, 0, nwavelengths) {
- double n_r, k_r;
- double n_e, k_e, lambda_e;
- double w_extinction, w_absorption, w_scattering;
-
- n_e = props[iwlen].medium_refractive_index;
- n_r = props[iwlen].relative_real_refractive_index;
- k_r = props[iwlen].relative_imaginary_refractive_index;
-
- lambda_e = wavelengths[iwlen] / n_e;
- k_e = 2.0 * PI / lambda_e;
+ res = compute_path_length
+ (dev, ctx->scene, &hit, ray_org[0], axis_z, &path_length[0]);
+ if(res != RES_OK) { /* Handle numerical/geometry issues */
+ ++nfailures;
+ continue;
+ }
+ /* Compute and accumulate the cross section weight */
+ accum_cross_section(ctx, plane_area, path_length[0]);
- /* Extinction cross section */
- w_extinction = 2.0 * rcp_pdf *
- (1.0 - exp(-k_e*k_r*path_length) * cos(k_e*(n_r - 1.0)*path_length));
- accums[iwlen].weights[SSCHIFF_EXTINCTION_CROSS_SECTION] += w_extinction;
+ /* Avoid the estimation of the phase function */
+ if(ctx->estimator->no_phase_function) break;
- /* Absorption cross section */
- w_absorption = rcp_pdf * (1.0 - exp(-2.0*k_e*k_r*path_length));
- accums[iwlen].weights[SSCHIFF_ABSORPTION_CROSS_SECTION] += w_absorption;
+ /* Uniformly sample a position onto the projection plane and use it as the
+ * origin of the 2nd ray to trace */
+ sample[0] = ssp_rng_uniform_double(ctx->rng, -1.0, 1.0);
+ sample[1] = ssp_rng_uniform_double(ctx->rng, -1.0, 1.0);
+ f3_mulf(x, axis_x, (float)sample[0]);
+ f3_mulf(y, axis_y, (float)sample[1]);
+ f3_add(ray_org[1], f3_add(ray_org[1], x, y), org);
- /* Scattering cross section */
- w_scattering = w_extinction - w_absorption;
- accums[iwlen].weights[SSCHIFF_SCATTERING_CROSS_SECTION] += w_scattering;
+ S3D(scene_trace_ray(ctx->scene, ray_org[1], axis_z, range, &hit));
+ if(S3D_HIT_NONE(&hit)) /* NULL differential cross section weight */
+ break;
- /* Average projected area */
- accums[iwlen].weights[SSCHIFF_AVERAGE_PROJECTED_AREA] += rcp_pdf;
- }
+ res = compute_path_length
+ (dev, ctx->scene, &hit, ray_org[1], axis_z, &path_length[1]);
+ if(res != RES_OK) { /* Handle numerical/geometry issues */
+ ++nfailures;
+ continue;
}
+ /* Compute and accumulate the per scattering angle differential cross
+ * section weight */
+ accum_differential_cross_section(ctx, plane_area, path_length, ray_org);
+
} while(res != RES_OK && nfailures < MAX_FAILURES);
- if(res != RES_OK) {
+ if(nfailures < MAX_FAILURES) {
+ res = RES_OK;
+ } else {
log_error(dev,
"Too many failures in computing the radiative path length. The sampled geometry\n"
"might not defined a closed volume.\n");
@@ -366,15 +489,9 @@ accum_monte_carlo_weight
static res_T
radiative_properties
(struct sschiff_device* dev,
- struct ssp_rng* rng,
const int istep,
- const double* wavelengths, /* Sorted in ascending order */
- const size_t nwavelengths,
const size_t ndirs,
- struct s3d_scene* scene,
- const struct sschiff_material_properties* props,
- struct mc_accum* mc_accums,
- struct accum* accums)
+ struct integrator_context* ctx)
{
float lower[3], upper[3];
float aabb_pt[8][3];
@@ -383,11 +500,10 @@ radiative_properties
size_t iwlen;
int i;
res_T res = RES_OK;
- ASSERT(dev && rng && wavelengths && nwavelengths && ndirs && props);
- ASSERT(mc_accums && accums);
+ ASSERT(dev && ndirs && ctx);
(void)istep;
- S3D(scene_get_aabb(scene, lower, upper));
+ S3D(scene_get_aabb(ctx->scene, lower, upper));
/* AABB vertex layout
* 6-------7
@@ -407,14 +523,30 @@ radiative_properties
f3_mulf(centroid, f3_add(centroid, lower, upper), 0.5f);
- memset(accums, 0, sizeof(struct accum)*nwavelengths);
+ /* Clear direction accumulators */
+ FOR_EACH(iwlen, 0, ctx->nwavelengths) {
+ ctx->accums[iwlen].extinction_cross_section = 0;
+ ctx->accums[iwlen].absorption_cross_section = 0;
+ ctx->accums[iwlen].scattering_cross_section = 0;
+ ctx->accums[iwlen].avg_projected_area = 0;
+
+ /* Do not clean up accumulators of invalid differential cross section */
+ if(ctx->estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE) continue;
+
+ /* Clean up to "limit_angle" since great angles are analytically computed */
+ memset(ctx->accums[iwlen].differential_cross_section, 0,
+ sizeof(double)*ctx->estimator->limit_angles[iwlen]);
+ memset(ctx->accums[iwlen].differential_cross_section_cumulative, 0,
+ sizeof(double)*ctx->estimator->limit_angles[iwlen]);
+ }
+
FOR_EACH(idir, 0, ndirs) {
float dir[4];
float basis[9];
float transform[12];
float pt[8][3];
- ssp_ran_sphere_uniform(rng, dir);
+ ssp_ran_sphere_uniform(ctx->rng, dir);
/* Build the transformation matrix from world to footprint space. Use the
* AABB centroid as the origin of the footprint space. */
@@ -433,52 +565,630 @@ radiative_properties
f3_max(upper, upper, pt[i]);
}
- res = accum_monte_carlo_weight(dev, scene, rng, props, wavelengths,
- nwavelengths, basis, centroid, lower, upper, accums);
+ res = accum_monte_carlo_weight(dev, ctx, basis, centroid, lower, upper);
if(res != RES_OK) goto error;
+ }
+ /* Compute the Monte Carlo weight of the temporary accumulator */
+ FOR_EACH(iwlen, 0, ctx->nwavelengths) {
+ size_t iangle;
+
+ #define MC_ACCUM(Data) { \
+ const double w = ctx->accums[iwlen].Data / (double)ndirs; \
+ ctx->mc_accums[iwlen].Data.weight += w; \
+ ctx->mc_accums[iwlen].Data.sqr_weight += w*w; \
+ } (void)0
+
+ MC_ACCUM(extinction_cross_section);
+ MC_ACCUM(absorption_cross_section);
+ MC_ACCUM(scattering_cross_section);
+ MC_ACCUM(avg_projected_area);
+
+ if(ctx->estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE)
+ continue;
-#if 0
- {
- /* Compute an image of the shape transformed in the footprint space */
- char thumb_name[64];
- sprintf(thumb_name, "%d_%lu.ppm", istep, idir);
- draw_thumbnail(scene, basis, centroid, lower, upper, thumb_name);
+ /* Accum up to "limit angle" since great angles are analitically computed */
+ FOR_EACH(iangle, 0, ctx->estimator->limit_angles[iwlen]) {
+ MC_ACCUM(differential_cross_section[iangle]);
+ MC_ACCUM(differential_cross_section_cumulative[iangle]);
}
-#endif
+
+ #undef MC_ACCUM
}
- FOR_EACH(iwlen, 0, nwavelengths) {
- int iweight;
- FOR_EACH(iweight, 0, SSCHIFF_DATA_COUNT__) {
- const double w = accums[iwlen].weights[iweight] / (double)ndirs;
- mc_accums[iwlen].mc_data[iweight].weight += w;
- mc_accums[iwlen].mc_data[iweight].sqr_weight += w * w;
+exit:
+ return res;
+error:
+ FOR_EACH(iwlen, 0, ctx->nwavelengths) {
+ ctx->mc_accums[iwlen].extinction_cross_section = MC_DATA_NULL;
+ ctx->mc_accums[iwlen].absorption_cross_section = MC_DATA_NULL;
+ ctx->mc_accums[iwlen].scattering_cross_section = MC_DATA_NULL;
+ ctx->mc_accums[iwlen].avg_projected_area = MC_DATA_NULL;
+
+ if(ctx->estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE)
+ continue;
+
+ memset(ctx->mc_accums[iwlen].differential_cross_section, 0,
+ sizeof(double)*ctx->estimator->limit_angles[iwlen]);
+ memset(ctx->mc_accums[iwlen].differential_cross_section_cumulative, 0,
+ sizeof(double)*ctx->estimator->limit_angles[iwlen]);
+ }
+ goto exit;
+}
+
+struct function_arg {
+ double scattering_cross_section;
+ double angle;
+ double differential_cross_section;
+ double differential_cross_section_cumulative;
+
+ /* Precomputed values */
+ double cos_2_angle;
+ double cos_angle;
+ double cos_half_angle;
+ double sin_half_angle;
+ double sqr_cos_angle;
+ double sqr_sin_half_angle;
+};
+
+static int
+function_fdf(const gsl_vector* vec, void* params, gsl_vector* res, gsl_matrix* J)
+{
+ struct function_arg* arg = params;
+ const double n = gsl_vector_get(vec, 0);
+ double u, u_prime;
+ double v, v_prime;
+ double coef;
+ double f, df;
+
+ if(n==2 || n==4 || n==6)
+ return GSL_EDOM;
+
+ coef = (4*PI * arg->differential_cross_section) / (1+arg->sqr_cos_angle);
+
+ u = ( arg->sqr_sin_half_angle
+ * ( (n*n - 6*n + 8) * arg->cos_2_angle
+ + 3*n*n
+ - 8*(n - 2) * arg->cos_angle
+ - 26*n + 72 )
+ - pow(arg->sin_half_angle, n) * (4*n*n - 24*n + 64) );
+ v = ((n - 2) * (n - 4) * (n - 6));
+
+ u_prime = arg->sqr_sin_half_angle
+ * ((2*n - 6) * arg->cos_2_angle + 6*n - 8*arg->cos_angle - 26)
+ - pow(arg->sin_half_angle, n)
+ * (log(arg->sin_half_angle) * (4*n*n - 24*n + 64) + 8*n-24);
+ v_prime = (n-4)*(n-6) + (n-2)*(n-6) + (n-2)*(n-4);
+
+ f = arg->differential_cross_section_cumulative
+ - arg->scattering_cross_section
+ + coef * u / v;
+ df = (v*u_prime - u*v_prime) / (v*v);
+ df = df * coef;
+
+ gsl_vector_set(res, 0, f);
+ gsl_matrix_set(J, 0, 0, df);
+ return GSL_SUCCESS;
+}
+
+/* Solve the parameters used to connect the Monte-Carlo estimation of the
+ * [cumulative] differential cross sections for small angles with their
+ * analytical estimation for wide angles */
+static res_T
+solve_wide_angles_phase_function_model_parameters
+ (struct sschiff_device* dev,
+ struct solver_context* ctx,
+ const double angle,
+ const double sin_half_angle,
+ const double cos_angle,
+ const double cos_2_angle,
+ const double scattering_cross_section,
+ const double differential_cross_section,
+ const double differential_cross_section_cumulative,
+ double* n,
+ double* r)
+{
+ gsl_multiroot_function_fdf func;
+ gsl_vector* root = NULL;
+ struct function_arg arg;
+ int status;
+ int iter;
+ const int max_iter = 1000; /* Maximum number of Newton iterations */
+ res_T res = RES_OK;
+ ASSERT(dev && n && r);
+ ASSERT(eq_eps(sin(angle*0.5), sin_half_angle, 1.e-6));
+ ASSERT(eq_eps(cos(angle), cos_angle, 1.e-6));
+ ASSERT(eq_eps(cos(2.0*angle), cos_2_angle, 1.e-6));
+
+ /* Fill system arguments */
+ arg.angle = angle;
+ arg.scattering_cross_section = scattering_cross_section;
+ arg.differential_cross_section = differential_cross_section;
+ arg.differential_cross_section_cumulative = differential_cross_section_cumulative;
+
+ /* Precompute some values to speed up Newton iterations */
+ arg.cos_2_angle = cos_2_angle;
+ arg.cos_angle = cos_angle;
+ arg.cos_half_angle = cos(angle * 0.5);
+ arg.sin_half_angle = sin_half_angle;
+ arg.sqr_cos_angle = arg.cos_angle * arg.cos_angle;
+ arg.sqr_sin_half_angle = arg.sin_half_angle * arg.sin_half_angle;
+
+ /* Setup system functions */
+ func.f = NULL;
+ func.df = NULL;
+ func.fdf = function_fdf; /* Compute the function *and* its derivative */
+ func.n = 1; /* Number of equations */
+ func.params = &arg; /* System parameters */
+
+ /* Initialise the solver. TODO perform this in an initialisation step of a
+ * phase_function context */
+ gsl_multiroot_fdfsolver_set(ctx->solver, &func, ctx->init_val);
+ gsl_set_error_handler_off();
+
+ /* Launch the Newton estimation. Iterate up to `max_iter'or until the
+ * estimation is "good enough". */
+ iter = 0;
+ do {
+ status = gsl_multiroot_fdfsolver_iterate(ctx->solver);
+ if(status == GSL_SUCCESS) {
+ status = gsl_multiroot_test_residual(ctx->solver->f, 1.e-6);
}
+ } while(status == GSL_CONTINUE && ++iter < max_iter);
+
+ /* Retrieve the estimated "n" value */
+ root = gsl_multiroot_fdfsolver_root(ctx->solver);
+ *n = gsl_vector_get(root, 0);
+
+ if(status != GSL_SUCCESS) {
+ log_error(dev,
+"Cannot estimate the parameters of the wide scattering phase function model.\n"
+"GSL error: %s - %d.\n",
+ gsl_strerror(status), iter);
+ res = RES_BAD_OP;
+ goto error;
}
+
+ if(*n < 0) {
+ log_error(dev,
+"The estimated parameter `n' of the wide scattering angles phase function\n"
+"model cannot be negative.\n"
+"n = %g\n", *n);
+ res = RES_BAD_OP;
+ goto error;
+ }
+
+ /* Compute r from the estimated n */
+ *r = 2 * arg.differential_cross_section * pow(arg.sin_half_angle, *n)
+ / (1 + arg.sqr_cos_angle);
+
exit:
return res;
error:
- memset(mc_accums, 0, sizeof(struct mc_accum)*nwavelengths);
goto exit;
}
-static void
-get_mc_value
- (const struct mc_data* data,
- const size_t nrealisations,
- struct sschiff_estimator_value* value)
+/* Helper function used to compute one term of the analytic evaluation of the
+ * cumulative differential cross section */
+static FINLINE double
+compute_differential_cross_section_cumulative_term
+ (const double sin_half_angle,
+ const double cos_angle,
+ const double cos_2_angle,
+ const double n)
{
- ASSERT(data && value);
- value->E = data->weight / (double)nrealisations;
- value->V = data->sqr_weight / (double)nrealisations
- - (data->weight * data->weight) / (double)(nrealisations * nrealisations);
- value->SE = sqrt(value->V / (double)nrealisations);
+ return
+ -pow(sin_half_angle, 2-n)
+ * ((n*n - 6*n + 8)*cos_2_angle + 3*n*n - 8*(n-2)*cos_angle - 26*n + 72)
+ / ((n-2)*(n-4)*(n-6));
+}
+
+static res_T
+compute_phase_function
+ (struct sschiff_device* dev,
+ struct solver_context* ctx,
+ const size_t iwlen,
+ const size_t nangles,
+ struct sschiff_estimator* estimator)
+{
+ double limit_angle;
+ double sin_half_limit_angle;
+ double cos_limit_angle;
+ double cos_2_limit_angle;
+ double coef_limit;
+ double n, r; /* Connector values */
+ double rcp_scattering_cross_section;
+ double rcp_sqr_scattering_cross_section;
+ struct sschiff_state scattering_cross_section;
+ struct sschiff_state limit_differential_cross_section;
+ struct sschiff_state limit_differential_cross_section_cumulative;
+ size_t ilimit_angle; /* Index of the limit angle of the current wavelength */
+ size_t iangle;
+ res_T res = RES_OK;
+ ASSERT(dev && estimator && iwlen < sa_size(estimator->wavelengths) && ctx);
+
+ /* Fetch the limit angle and precompute some values */
+ ilimit_angle = estimator->limit_angles[iwlen]-1;
+ limit_angle = estimator->angles[ilimit_angle];
+ sin_half_limit_angle = sin(0.5*limit_angle);
+ cos_limit_angle = cos(limit_angle);
+ cos_2_limit_angle = cos(2.0*limit_angle);
+
+ get_mc_value
+ (&estimator->accums[iwlen].scattering_cross_section,
+ estimator->nrealisations,
+ &scattering_cross_section);
+ get_mc_value
+ (&estimator->accums[iwlen].differential_cross_section[ilimit_angle],
+ estimator->nrealisations,
+ &limit_differential_cross_section);
+ get_mc_value
+ (&estimator->accums[iwlen].differential_cross_section_cumulative[ilimit_angle],
+ estimator->nrealisations,
+ &limit_differential_cross_section_cumulative);
+
+ /* Find the connector values between small and wide angles */
+ res = solve_wide_angles_phase_function_model_parameters
+ (dev,
+ ctx,
+ limit_angle,
+ sin_half_limit_angle,
+ cos_limit_angle,
+ cos_2_limit_angle,
+ scattering_cross_section.E,
+ limit_differential_cross_section.E,
+ limit_differential_cross_section_cumulative.E,
+ &n, &r);
+ if(res != RES_OK) {
+ log_error(estimator->dev,
+"Couldn't estimate the parameters of the phase function for wide scattering\n"
+"angles. The phase function is thus not computed.\n"
+"Wavelength = %g micron\n",
+ estimator->wavelengths[iwlen]);
+
+ goto error;
+ }
+
+ if(n < 2 || n > 4) {
+ log_warning(estimator->dev,
+"The wide scattering angles phase function model parameter `n' is not in\n"
+"[2, 4]. One might increase the number of realisations.\n"
+" wavelength = %g micron\n"
+" n = %g\n"
+" scattering cross section = %g +/- %g\n"
+" differential cross section = %g +/- %g\n"
+" differential cross section cumulative = %g +/- %g\n",
+ estimator->wavelengths[iwlen],
+ n,
+ scattering_cross_section.E,
+ scattering_cross_section.SE,
+ limit_differential_cross_section.E,
+ limit_differential_cross_section.SE,
+ limit_differential_cross_section_cumulative.E,
+ limit_differential_cross_section_cumulative.SE);
+ }
+
+ /* Save the `n' wide angle parameter */
+ estimator->wide_angles_parameter[iwlen] = n;
+
+ /* Precomputed vlaue */
+ coef_limit = compute_differential_cross_section_cumulative_term
+ (sin_half_limit_angle, cos_limit_angle, cos_2_limit_angle, n);
+
+ /* Fill the [cumulative] differential cross sections of wide angles with the
+ * analytic model */
+ FOR_EACH(iangle, ilimit_angle+1, nangles) {
+ struct mc_accum* accum = estimator->accums + iwlen;
+ double angle, sin_half_angle, cos_angle, cos_2_angle;
+ double coef;
+
+ /* Precompute some values */
+ angle = estimator->angles[iangle];
+ cos_angle = cos(angle);
+ cos_2_angle = cos(2.0*angle);
+ sin_half_angle = sin(angle*0.5);
+
+ /* Analytically compute the differential cross section */
+ accum->differential_cross_section[iangle].sqr_weight = -1.f;
+ accum->differential_cross_section[iangle].weight =
+ r * (1+cos_angle*cos_angle) / (2.0*pow(sin_half_angle, n));
+
+ /* Analytically compute the differential cross section cumulative */
+ coef = compute_differential_cross_section_cumulative_term
+ (sin_half_angle, cos_angle, cos_2_angle, n);
+ accum->differential_cross_section_cumulative[iangle].sqr_weight = -1.f;
+ accum->differential_cross_section_cumulative[iangle].weight =
+ limit_differential_cross_section_cumulative.E + 2*PI*r*(coef-coef_limit);
+ }
+
+ /* Check the post condition of the cumulative differential cross section */
+ /*ASSERT(eq_eps
+ (estimator->accums[iwlen].differential_cross_section_cumulative[nangles-1].weight,
+ scattering_cross_section.E, 1.e-3));*/
+
+ /* Compute the [cumulative] phase function for small angles */
+ rcp_scattering_cross_section = 1.0/scattering_cross_section.E;
+ rcp_sqr_scattering_cross_section =
+ rcp_scattering_cross_section * rcp_scattering_cross_section;
+ FOR_EACH(iangle, 0, ilimit_angle+1) {
+ struct mc_data mc_data;
+
+ mc_data = estimator->accums[iwlen].differential_cross_section[iangle];
+ mc_data.weight *= rcp_scattering_cross_section;
+ mc_data.sqr_weight *= rcp_sqr_scattering_cross_section;
+ get_mc_value(&mc_data, estimator->nrealisations,
+ &estimator->phase_functions[iwlen].values[iangle]);
+
+ mc_data = estimator->accums[iwlen].differential_cross_section_cumulative[iangle];
+ mc_data.weight *= rcp_scattering_cross_section;
+ mc_data.sqr_weight *= rcp_sqr_scattering_cross_section;
+ get_mc_value(&mc_data, estimator->nrealisations,
+ &estimator->phase_functions[iwlen].cumulative[iangle]);
+ }
+ /* Compute the [cumulative] phase function for wide angles */
+ FOR_EACH(iangle, ilimit_angle + 1, nangles) {
+ estimator->phase_functions[iwlen].values[iangle].E =
+ estimator->accums[iwlen].differential_cross_section[iangle].weight
+ * rcp_scattering_cross_section;
+
+ estimator->phase_functions[iwlen].cumulative[iangle].E =
+ estimator->accums[iwlen].differential_cross_section_cumulative[iangle].weight
+ * rcp_scattering_cross_section;
+
+ /* The phase function for wide angles is analitically computed, i.e. there
+ * is no variance or standard error */
+ estimator->phase_functions[iwlen].values[iangle].V = 0;
+ estimator->phase_functions[iwlen].values[iangle].SE = 0;
+ estimator->phase_functions[iwlen].cumulative[iangle].V = 0;
+ estimator->phase_functions[iwlen].cumulative[iangle].SE = 0;
+ }
+
+exit:
+ return res;
+error:
+ FOR_EACH(iangle, 0, nangles) {
+ estimator->phase_functions[iwlen].values[iangle].E = -1;
+ estimator->phase_functions[iwlen].values[iangle].V = -1;
+ estimator->phase_functions[iwlen].values[iangle].SE = -1;
+ estimator->phase_functions[iwlen].cumulative[iangle].E = -1;
+ estimator->phase_functions[iwlen].cumulative[iangle].V = -1;
+ estimator->phase_functions[iwlen].cumulative[iangle].SE = -1;
+ }
+ goto exit;
+}
+
+
+static res_T
+inverse_cumulative_phase_function
+ (const struct sschiff_estimator* estimator,
+ const double* cumulative_small_angles,
+ const size_t iwlen,
+ const double cumulative,
+ double* theta)
+{
+ double u, lower, upper;
+ size_t iangle, nsmall_angles;
+ ASSERT(estimator && cumulative_small_angles && theta);
+ ASSERT(cumulative >= 0.0 && cumulative <= 1.0);
+ ASSERT(iwlen < sa_size(estimator->phase_functions));
+
+ nsmall_angles = estimator->limit_angles[iwlen];
+ if(cumulative < cumulative_small_angles[nsmall_angles-1]) {
+ /* Look for the cumulative in the filtered small angles array */
+ double* found = search_lower_bound(&cumulative, cumulative_small_angles,
+ nsmall_angles, sizeof(double), cmp_double);
+ if(!found) {
+ log_error(estimator->dev,
+ "Error in inverting the phase function cumulative for small angles.\n");
+ return RES_BAD_OP;
+ }
+ iangle = (size_t)(found - cumulative_small_angles);
+ upper = cumulative_small_angles[iangle];
+ lower = cumulative_small_angles[iangle-1];
+ } else {
+ /* Look for the cumulative in the wide angles cumulative */
+ struct sschiff_state cumul;
+ struct sschiff_state* found = NULL;
+ size_t nangles;
+ cumul.E = cumulative;
+
+ nangles = sa_size(estimator->angles);
+ found = search_lower_bound
+ (&cumul,
+ estimator->phase_functions[iwlen].cumulative + nsmall_angles,
+ nangles - nsmall_angles,
+ sizeof(struct sschiff_state), cmp_schiff_state);
+ if(!found) {
+ log_error(estimator->dev,
+ "Error in inverting the phase function cumulative for wide angles.\n");
+ return RES_BAD_OP;
+ }
+ iangle = (size_t)(found - estimator->phase_functions[iwlen].cumulative);
+ ASSERT(iangle >= nsmall_angles);
+ upper = estimator->phase_functions[iwlen].cumulative[iangle].E;
+ if(iangle == nsmall_angles) {
+ lower = cumulative_small_angles[nsmall_angles-1];
+ } else {
+ lower = estimator->phase_functions[iwlen].cumulative[iangle-1].E;
+ }
+ }
+
+ /* Use the cumulative bounds to linearly interpolate the angles */
+ u = (cumulative - lower) / (upper - lower);
+ *theta = u*estimator->angles[iangle] + (1.0 - u)*estimator->angles[iangle-1];
+
+ return RES_OK;
}
static char
check_distribution(struct sschiff_geometry_distribution* distrib)
{
ASSERT(distrib);
- return distrib->sample != NULL;
+ return distrib->sample != NULL && distrib->characteristic_length > 0;
+}
+
+static void
+integrator_context_release(struct integrator_context* ctx)
+{
+ size_t iwlen;
+ ASSERT(ctx);
+
+ if(ctx->rng) SSP(rng_ref_put(ctx->rng));
+ if(ctx->estimator) SSCHIFF(estimator_ref_put(ctx->estimator));
+ if(ctx->shape) S3D(shape_ref_put(ctx->shape));
+ if(ctx->scene) S3D(scene_ref_put(ctx->scene));
+
+ #define RELEASE(Data) if(Data) sa_release(Data)
+ if(ctx->accums) {
+ FOR_EACH(iwlen, 0, ctx->nwavelengths) {
+ RELEASE(ctx->accums[iwlen].differential_cross_section);
+ RELEASE(ctx->accums[iwlen].differential_cross_section_cumulative);
+ }
+ sa_release(ctx->accums);
+ }
+ if(ctx->mc_accums) {
+ FOR_EACH(iwlen, 0, ctx->nwavelengths) {
+ RELEASE(ctx->mc_accums[iwlen].differential_cross_section);
+ RELEASE(ctx->mc_accums[iwlen].differential_cross_section_cumulative);
+ }
+ sa_release(ctx->mc_accums);
+ }
+ #undef RELEASE
+}
+
+static res_T
+integrator_context_init
+ (struct integrator_context* ctx,
+ struct s3d_device* s3d,
+ struct ssp_rng* rng,
+ struct sschiff_estimator* estimator,
+ const size_t nwavelengths,
+ const size_t nangles)
+{
+ size_t iwlen;
+ res_T res = RES_OK;
+ ASSERT(ctx && s3d && rng && nwavelengths && nangles >= 3);
+
+ memset(ctx, 0, sizeof(struct integrator_context));
+
+ if(RES_OK!=(res = s3d_shape_create_mesh(s3d, &ctx->shape))) goto error;
+ if(RES_OK!=(res = s3d_scene_create(s3d, &ctx->scene))) goto error;
+ if(RES_OK!=(res = s3d_scene_attach_shape(ctx->scene, ctx->shape))) goto error;
+
+ #define RESIZE(Data, N) { \
+ if(!sa_add((Data), (N))) { \
+ res = RES_MEM_ERR; \
+ goto error; \
+ } \
+ memset((Data), 0, sizeof((Data)[0])*(N)); \
+ } (void)0
+ RESIZE(ctx->accums, nwavelengths);
+ FOR_EACH(iwlen, 0, nwavelengths) {
+ /* Do not allocate the accumulators if no limit angle was found */
+ if(estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE) continue;
+ RESIZE(ctx->accums[iwlen].differential_cross_section, nangles);
+ RESIZE(ctx->accums[iwlen].differential_cross_section_cumulative, nangles);
+ }
+
+ RESIZE(ctx->mc_accums, nwavelengths);
+ FOR_EACH(iwlen, 0, nwavelengths) {
+ /* Do not allocate the accumulators if no limit angle was found */
+ if(estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE) continue;
+ RESIZE(ctx->mc_accums[iwlen].differential_cross_section, nangles);
+ RESIZE(ctx->mc_accums[iwlen].differential_cross_section_cumulative, nangles);
+ }
+ #undef RESIZE
+
+ SSP(rng_ref_get(rng));
+ ctx->rng = rng;
+ SSCHIFF(estimator_ref_get(estimator));
+ ctx->estimator = estimator;
+ ctx->nwavelengths = nwavelengths;
+ ctx->nangles = nangles;
+
+exit:
+ return res;
+error:
+ integrator_context_release(ctx);
+ goto exit;
+}
+
+static void
+solver_context_release(struct solver_context* ctx)
+{
+ ASSERT(ctx);
+ if(ctx->solver) gsl_multiroot_fdfsolver_free(ctx->solver);
+ if(ctx->init_val) gsl_vector_free(ctx->init_val);
+}
+
+static res_T
+solver_context_init(struct sschiff_device* dev, struct solver_context* ctx)
+{
+ res_T res = RES_OK;
+ ASSERT(ctx);
+ memset(ctx, 0, sizeof(*ctx));
+
+ /* Create a Newton-Raphson nonlinear solver with derivatives */
+ ctx->solver = gsl_multiroot_fdfsolver_alloc(gsl_multiroot_fdfsolver_newton, 1);
+ if(!ctx->solver) {
+ log_error(dev,
+ "Not enough memory. Couldn't allocate the GSL Newton solver.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
+ /* Allocate the initial value vector */
+ ctx->init_val = gsl_vector_alloc(1);
+ if(!ctx->init_val) {
+ log_error(dev,
+ "Not enough memory. Couldn't allocate the GSL init vector.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ gsl_vector_set(ctx->init_val, 0, 3);
+
+exit:
+ return res;
+error:
+ solver_context_release(ctx);
+ goto exit;
+}
+
+static res_T
+begin_realisation
+ (struct sschiff_device* dev,
+ struct sschiff_geometry_distribution* distrib,
+ struct integrator_context* ctx)
+{
+ res_T res = RES_OK;
+ ASSERT(dev && distrib && ctx);
+
+ /* Sample a particle */
+ res = distrib->sample(ctx->rng, ctx->shape, distrib->context);
+ if(res != RES_OK) {
+ log_error(dev, "Error in sampling a particle.\n");
+ goto error;
+ }
+
+ /* Build the Star-3D representation of the sampled shape */
+ S3D(scene_begin_session(ctx->scene, S3D_TRACE));
+
+exit:
+ return res;
+error:
+ {
+ /* Disable active session if necessary */
+ int mask;
+ if(S3D(scene_get_session_mask(ctx->scene, &mask)), mask) {
+ S3D(scene_end_session(ctx->scene));
+ }
+ }
+ goto exit;
+}
+
+static FINLINE void
+end_realisation(struct integrator_context* ctx)
+{
+ ASSERT(ctx);
+ S3D(scene_end_session(ctx->scene));
}
static void
@@ -486,11 +1196,37 @@ estimator_release(ref_T* ref)
{
struct sschiff_estimator* estimator;
struct sschiff_device* dev;
+ size_t nwavelengths;
+ size_t i;
ASSERT(ref);
+
estimator = CONTAINER_OF(ref, struct sschiff_estimator, ref);
dev = estimator->dev;
- if(estimator->wavelengths) sa_release(estimator->wavelengths);
- if(estimator->accums) sa_release(estimator->accums);
+ nwavelengths = sa_size(estimator->accums);
+
+ #define RELEASE(Data) if(Data) sa_release(Data)
+ RELEASE(estimator->wavelengths);
+ RELEASE(estimator->angles);
+ RELEASE(estimator->limit_angles);
+ RELEASE(estimator->wide_angles_parameter);
+ RELEASE(estimator->wavenumbers);
+ RELEASE(estimator->properties);
+ if(estimator->accums) {
+ FOR_EACH(i, 0, nwavelengths) {
+ RELEASE(estimator->accums[i].differential_cross_section);
+ RELEASE(estimator->accums[i].differential_cross_section_cumulative);
+ }
+ sa_release(estimator->accums);
+ }
+ if(estimator->phase_functions) {
+ FOR_EACH(i, 0, nwavelengths) {
+ RELEASE(estimator->phase_functions[i].values);
+ RELEASE(estimator->phase_functions[i].cumulative);
+ }
+ sa_release(estimator->phase_functions);
+ }
+ #undef RELEASE
+
MEM_RM(dev->allocator, estimator);
SSCHIFF(device_ref_put(dev));
}
@@ -498,17 +1234,25 @@ estimator_release(ref_T* ref)
static res_T
estimator_create
(struct sschiff_device* dev,
+ struct sschiff_geometry_distribution* distrib,
+ const double* wavelengths,
const size_t nwavelengths,
+ sschiff_scattering_angles_distribution_T angles_distrib,
+ const size_t nangles,
struct sschiff_estimator** out_estimator)
{
struct sschiff_estimator* estimator = NULL;
+ double rcp_PI_Lc;
+ size_t i;
+ int hold_valid_limit_angle = 0;
res_T res = RES_OK;
- ASSERT(dev && out_estimator);
+ ASSERT(dev && distrib && wavelengths && nwavelengths);
+ ASSERT(angles_distrib && nangles && out_estimator);
estimator = MEM_CALLOC(dev->allocator, 1, sizeof(struct sschiff_estimator));
if(!estimator) {
log_error
- (dev, "Not enough memory: couldn't allocate the Star-Schiff estimator.\n");
+ (dev, "Couldn't allocate the Star-Schiff estimator.\n");
res = RES_MEM_ERR;
goto error;
}
@@ -516,18 +1260,144 @@ estimator_create
SSCHIFF(device_ref_get(dev));
estimator->dev = dev;
- if(!sa_add(estimator->wavelengths, nwavelengths)) {
- log_error(dev,
- "Not enough memory: couldn't allocate the list of estimated wavelengths.\n");
- res = RES_MEM_ERR;
- goto error;
+ #define RESIZE(Array, Count, ErrMsg) { \
+ if(!sa_add(Array, Count)) { \
+ log_error(dev, ErrMsg); \
+ res = RES_MEM_ERR; \
+ goto error; \
+ } \
+ memset(Array, 0, sizeof(Array[0])*Count); \
+ } (void)0
+
+ /* Check the wavelengths */
+ FOR_EACH(i, 1, nwavelengths) {
+ if(wavelengths[i] <= wavelengths[i-1]) {
+ log_error(dev,
+ "The submitted wavelengths are not sorted in ascending order.\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
}
- if(!sa_add(estimator->accums, nwavelengths)) {
- log_error(dev,
- "Not enough memory: couldn't allocate the Monte Carlo accumulator.\n");
- res = RES_MEM_ERR;
+ /* Copy the wavelengths */
+ RESIZE(estimator->wavelengths, nwavelengths,
+ "Couldn't allocate the list of estimated wavelengths.\n");
+ memcpy(estimator->wavelengths, wavelengths, nwavelengths*sizeof(double));
+
+ /* Generate the scattering angles */
+ RESIZE(estimator->angles, nangles,
+ "Couldn't allocate the list of scattering angles.\n");
+ angles_distrib(estimator->angles, nangles);
+ if(estimator->angles[0] != 0.f
+ || !eq_eps(estimator->angles[nangles-1], PI, 1.e-6)) {
+ log_error(dev, "Invalid scattering angle distribution.\n");
+ log_error(dev, "The first and last angles must be 0 and PI, respectively.\n");
+ res = RES_BAD_ARG;
goto error;
}
+ FOR_EACH(i, 1, nangles) {
+ if(estimator->angles[i] <= estimator->angles[i-1]) {
+ log_error(dev, "Invalid scattering angle distribution.\n");
+ log_error(dev, "Angles must be sorted in ascending order in [0, PI]\n");
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ }
+
+ /* Allocate miscellaneous array of temporary/precomputed data */
+ RESIZE(estimator->limit_angles, nwavelengths,
+ "Couldn't allocate the per wavelength indices of the limit scattering angle.\n");
+ RESIZE(estimator->wide_angles_parameter, nwavelengths,
+ "Couldn't allocate the per wavelength `n' parameter of the wide scattering\n"
+ "angles model.\n");
+ RESIZE(estimator->wavenumbers, nwavelengths,
+ "Couldn't allocate the list of wavenumbers.\n");
+ RESIZE(estimator->properties, nwavelengths,
+ "Couldn't allocate the per wavelength optical properties.\n");
+
+ rcp_PI_Lc = 1.0 / (PI*distrib->characteristic_length);
+ FOR_EACH(i, 0, nwavelengths) {
+ double lambda_e, theta_l;
+ double* angle;
+
+ /* Fetch the particle optical properties */
+ distrib->material.get_property
+ (distrib->material.material,
+ estimator->wavelengths[i],
+ &estimator->properties[i]);
+
+ /* Precompute the wavenumbers */
+ lambda_e =
+ estimator->wavelengths[i]
+ / estimator->properties[i].medium_refractive_index;
+ estimator->wavenumbers[i] = 2.0*PI/lambda_e;
+
+ /* Search for limit scattering angle */
+ theta_l = sqrt(lambda_e * rcp_PI_Lc);
+ if(theta_l <= 0 || theta_l >= PI) {
+ log_warning(dev,
+"Invalid theta limit, i.e. angle between small and wide scattering angles\n"
+"`%g'. The phase function for the wavelengths `%g' and its [inverse]\n"
+"cumulative will be not computed.\n",
+ theta_l, estimator->wavelengths[i]);
+ estimator->limit_angles[i] = INVALID_LIMIT_ANGLE;
+ } else {
+ angle = search_lower_bound(&theta_l, estimator->angles, nangles,
+ sizeof(double), cmp_double);
+ if(!angle) {
+ log_error(dev,
+"Can't find a limit scattering angle for theta limit `%g'.\n", theta_l);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ if(eq_eps(*angle, PI, 1.e-6)) {
+ log_error(dev, "Invalid limit scattering angle `%g'.\n", *angle);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ /* Define the index of the first "wide scattering angle" */
+ estimator->limit_angles[i] = (size_t)(angle - estimator->angles);
+ ASSERT(estimator->limit_angles[i] < nangles);
+ hold_valid_limit_angle = 1;
+ }
+ }
+ estimator->no_phase_function = !hold_valid_limit_angle;
+ if(estimator->no_phase_function) {
+ /* No phase function => scattering angles and wide angle parameter are
+ * useless */
+ sa_release(estimator->angles);
+ sa_release(estimator->wide_angles_parameter);
+ estimator->angles = NULL;
+ estimator->wide_angles_parameter = NULL;
+ }
+
+ /* Allocate the estimator accumulators */
+ RESIZE(estimator->accums, nwavelengths,
+ "Couldn't allocate the Monte Carlo accumulator of the estimator.\n");
+ if(!estimator->no_phase_function) {
+ FOR_EACH(i, 0, nwavelengths) {
+ /* Do not allocate the MC accumulator if no limit angle was found */
+ if(estimator->limit_angles[i] == INVALID_LIMIT_ANGLE) continue;
+ RESIZE(estimator->accums[i].differential_cross_section, nangles,
+ "Couldn't allocate the differential cross sections to estimate.\n");
+ RESIZE(estimator->accums[i].differential_cross_section_cumulative, nangles,
+ "Couldn't allocate the cumulative differential cross sections to estimate.\n");
+ }
+ }
+
+ if(!estimator->no_phase_function) {
+ /* Allocate the phase function data */
+ RESIZE(estimator->phase_functions, nwavelengths,
+ "Couldn't allocate the per wavelength phase functions data.\n");
+ FOR_EACH(i, 0, nwavelengths) {
+ /* Do not allocate the phase functions data if no limit angle was found */
+ if(estimator->limit_angles[i] == INVALID_LIMIT_ANGLE) continue;
+ RESIZE(estimator->phase_functions[i].values, nangles,
+ "Couldn't allocate the per angle phase function values.\n");
+ RESIZE(estimator->phase_functions[i].cumulative, nangles,
+ "Couldn't allocate the per angle cumulative phase function.\n");
+ }
+ }
+ #undef RESIZE
exit:
*out_estimator = estimator;
@@ -550,212 +1420,161 @@ sschiff_integrate
struct sschiff_geometry_distribution* distrib,
const double* wavelengths,
const size_t nwavelengths,
+ const sschiff_scattering_angles_distribution_T angles_distrib,
const size_t nangles,
const size_t ngeoms,
const size_t ndirs,
struct sschiff_estimator** out_estimator)
{
- struct sschiff_material_properties** mtls = NULL;
- struct accum** accums = NULL;
- struct mc_accum** mc_accums = NULL;
+ struct integrator_context* ctxs = NULL;
+ struct solver_context* solver_ctxs = NULL;
struct sschiff_estimator* estimator = NULL;
- struct s3d_shape** shapes = NULL;
- struct s3d_scene** scenes = NULL;
struct ssp_rng** rngs = NULL;
struct ssp_rng_proxy* rng_proxy = NULL;
size_t i;
+ int iwlen;
int igeom;
ATOMIC res = (ATOMIC)RES_OK;
- (void)nangles;
- if(!dev || !rng || !distrib || !wavelengths || !nwavelengths || !nangles
- || !ngeoms || !ndirs || !out_estimator || !check_distribution(distrib)) {
+ if(!dev || !rng || !distrib || !wavelengths || !nwavelengths
+ || !angles_distrib || nangles < 3 || !ngeoms || !ndirs || !out_estimator
+ || !check_distribution(distrib)) {
return RES_BAD_ARG;
}
- res = estimator_create(dev, nwavelengths, &estimator);
+ /* Create the Schiff estimator */
+ res = estimator_create(dev, distrib, wavelengths, nwavelengths,
+ angles_distrib, nangles, &estimator);
if(res != RES_OK) goto error;
estimator->nrealisations = ngeoms;
+ /* Create a RNG proxy from the submitted RNG state */
res = ssp_rng_proxy_create_from_rng
(dev->allocator, rng, dev->nthreads, &rng_proxy);
if(res != RES_OK) {
log_error(dev, "Couldn't create the proxy allocator\n");
goto error;
}
- /* Create the containers of per thread data structures */
- if(!sa_add(mtls, dev->nthreads)) {
- log_error(dev,
- "No enough memory: couldn't allocate the list of optical properties.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- if(!sa_add(accums, dev->nthreads)) {
- log_error(dev,
- "No enough memory: couldn't allocate the list of temporary accumulators.\n");
+
+ /* Create per thread data structures */
+ if(!sa_add(ctxs, dev->nthreads)) {
+ log_error(dev, "Couldn't allocate the integrator contexts.\n");
res = RES_MEM_ERR;
goto error;
}
- if(!sa_add(mc_accums, dev->nthreads)) {
- log_error(dev,
- "Not enough memory: couldn't allocate the list Monte Carlo accumulators.\n");
+ if(!sa_add(solver_ctxs, dev->nthreads)) {
+ log_error(dev, "Couldn'nt allocate the solver contexts.\n");
res = RES_MEM_ERR;
goto error;
}
if(!sa_add(rngs, dev->nthreads)) {
- log_error(dev,
- "Not enough memory: couldn't allocate the list of RNGs.\n");
- }
- if(!sa_add(scenes, dev->nthreads)) {
- log_error(dev,
- "Not enough memory: couldn't allocate the list of Star-3D scenes.\n");
+ log_error(dev, "Couldn't allocate the list of RNGs.\n");
res = RES_MEM_ERR;
goto error;
}
- if(!sa_add(shapes, dev->nthreads)) {
- log_error(dev,
- "Not enough memory: couldn't allocate the list of Star-3D shapes.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- memset(mtls, 0, sizeof(struct sschiff_material_properties*)*dev->nthreads);
- memset(accums, 0, sizeof(struct accum*)*dev->nthreads);
- memset(mc_accums, 0, sizeof(struct mc_accum*)*dev->nthreads);
- memset(rngs, 0, sizeof(struct ssp_rng*)*dev->nthreads);
- memset(scenes, 0, sizeof(struct s3d_scene*)*dev->nthreads);
- memset(shapes, 0, sizeof(struct s3d_shape*)*dev->nthreads);
+ memset(ctxs, 0, sizeof(ctxs[0])*dev->nthreads);
+ memset(solver_ctxs, 0, sizeof(solver_ctxs[0])*dev->nthreads);
+ memset(rngs, 0, sizeof(rngs[0])*dev->nthreads);
- /* Create the per thread data structures */
+ /* Init the per thread data structures */
FOR_EACH(i, 0, dev->nthreads) {
- if(!sa_add(mtls[i], nwavelengths)) {
- log_error(dev,
- "Not enough memory: couldn't allocate the optical properties.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- if(!sa_add(accums[i], nwavelengths)) {
- log_error(dev,
- "Not enough memory: couldn't allocate the temporary accumulator.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- if(!sa_add(mc_accums[i], nwavelengths)) {
- log_error(dev,
- "Not enough memory: couldn't allocate the Monte Carlo accumulator.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- memset(mc_accums[i], 0, sizeof(struct mc_accum)*nwavelengths);
-
res = ssp_rng_proxy_create_rng(rng_proxy, i, rngs + i);
if(res != RES_OK) {
- log_error(dev, "Couldn't create the RNG.\n");
- goto error;
- }
- res = s3d_shape_create_mesh(dev->s3d[i], shapes + i);
- if(res != RES_OK) {
- log_error(dev, "Couldn't create the Star-3D shape.\n");
+ log_error(dev,
+ "Couldn't create the RNG of the thread \"%lu\".\n", (unsigned long)i);
goto error;
}
- res = s3d_scene_create(dev->s3d[i], scenes + i);
+ res = integrator_context_init(ctxs + i, dev->s3d[i], rngs[i], estimator,
+ nwavelengths, nangles);
if(res != RES_OK) {
- log_error(dev, "Couldn't create the Star-3D scene.\n");
+ log_error(dev,
+ "Couldn't initialise the integrator context of the thread \"%lu\".\n",
+ (unsigned long)i);
goto error;
}
- res = s3d_scene_attach_shape(scenes[i], shapes[i]);
+ res = solver_context_init(dev, solver_ctxs + i);
if(res != RES_OK) {
log_error(dev,
- "Couldn't attach the Star-3D Schiff shape to the Star-3D Schiff scene.\n");
+ "Couldn't initialise the solver context of the thread \"%lu\".\n",
+ (unsigned long)i);
goto error;
}
}
- /* Clear the accumulators */
- memset(estimator->accums, 0, sizeof(struct mc_accum)*nwavelengths);
-
- /* Setup and sort the wavelengths */
- FOR_EACH(i, 0, nwavelengths) estimator->wavelengths[i] = wavelengths[i];
- qsort(estimator->wavelengths, nwavelengths, sizeof(double), cmp_double);
-
/* Paralell Schiff integration */
#pragma omp parallel for schedule(static)
for(igeom=0; igeom < (int)ngeoms; ++igeom) {
- const double* wlengths = estimator->wavelengths;
- struct sschiff_material material = SSCHIFF_NULL_MATERIAL;
- size_t iwavelength;
const int ithread = omp_get_thread_num();
- ATOMIC res_local;
+ ATOMIC res_local = RES_OK;
if(ATOMIC_GET(&res) != RES_OK) continue;
- /* Sample a geometry, i.e. a shape and its associated material */
- res_local = distrib->sample
- (rngs[ithread], &material, shapes[ithread], distrib->context);
+ /* Setup the data for the current realisation */
+ res_local = begin_realisation(dev, distrib, ctxs + ithread);
if(res_local != RES_OK) {
- log_error(dev, "Error in sampling a Schiff geometry.\n");
- ATOMIC_SET(&res, res_local);
+ ATOMIC_CAS(&res, res_local, RES_OK);
continue;
}
- /* Fetch the per wavelength material properties */
- FOR_EACH(iwavelength, 0, nwavelengths) {
- material.get_property(material.material, wavelengths[iwavelength],
- mtls[ithread] + iwavelength);
- }
-
- /* Build the Star-3D representation of the sampled shape */
- S3D(scene_begin_session(scenes[ithread], S3D_TRACE));
/* Schiff Estimation */
- res_local = radiative_properties(dev, rngs[ithread], igeom, wlengths,
- nwavelengths, ndirs, scenes[ithread], mtls[ithread], mc_accums[ithread],
- accums[ithread]);
- if(res != RES_OK) ATOMIC_SET(&res, res_local);
+ res_local = radiative_properties(dev, igeom, ndirs, ctxs+ithread);
+ if(res_local != RES_OK) ATOMIC_CAS(&res, res_local, RES_OK);
- S3D(scene_end_session(scenes[ithread]));
+ end_realisation(ctxs + ithread);
}
if(res != RES_OK) goto error; /* Handle integration error */
- /* Merge the per thread integration ressults */
+ /* Merge the per thread integration results */
FOR_EACH(i, 0, dev->nthreads) {
size_t iwlen;
FOR_EACH(iwlen, 0, nwavelengths) {
- size_t idata;
- FOR_EACH(idata, 0, SSCHIFF_DATA_COUNT__) {
- estimator->accums[iwlen].mc_data[idata].weight +=
- mc_accums[i][iwlen].mc_data[idata].weight;
- estimator->accums[iwlen].mc_data[idata].sqr_weight +=
- mc_accums[i][iwlen].mc_data[idata].sqr_weight;
+ size_t iangle;
+ #define MC_ACCUM(Data) { \
+ const struct mc_accum* mc_accum = ctxs[i].mc_accums + iwlen; \
+ estimator->accums[iwlen].Data.weight += mc_accum->Data.weight; \
+ estimator->accums[iwlen].Data.sqr_weight += mc_accum->Data.sqr_weight; \
+ } (void)0
+ MC_ACCUM(extinction_cross_section);
+ MC_ACCUM(absorption_cross_section);
+ MC_ACCUM(scattering_cross_section);
+ MC_ACCUM(avg_projected_area);
+
+ /* Discard differential cross section accumulation for invalid angle */
+ if(estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE) continue;
+
+ /* Accum up to "limit angle"; Great angles are analitically computed */
+ FOR_EACH(iangle, 0, estimator->limit_angles[iwlen]) {
+ MC_ACCUM(differential_cross_section[iangle]);
+ MC_ACCUM(differential_cross_section_cumulative[iangle]);
}
}
}
+ /* Static scheduling is not necessary to ensure the reproductability;
+ * computations are purely analytics */
+ #pragma omp parallel for
+ for(iwlen=0; iwlen < (int)nwavelengths; ++iwlen) {
+ const int ithread = omp_get_thread_num();
+ if(estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE) continue;
+ /* Do not handle phase function errors */
+ compute_phase_function
+ (dev, &solver_ctxs[ithread], (size_t)iwlen, nangles, estimator);
+ }
+
exit:
if(rng_proxy) SSP(rng_proxy_ref_put(rng_proxy));
- /* Release per thread data */
- if(mtls) {
- FOR_EACH(i, 0, dev->nthreads) if(mtls[i]) sa_release(mtls[i]);
- sa_release(mtls);
- }
- if(accums) {
- FOR_EACH(i, 0, dev->nthreads) if(accums[i]) sa_release(accums[i]);
- sa_release(accums);
+ if(ctxs) {
+ FOR_EACH(i, 0, dev->nthreads) integrator_context_release(ctxs+i);
+ sa_release(ctxs);
}
- if(mc_accums) {
- FOR_EACH(i, 0, dev->nthreads) if(mc_accums[i]) sa_release(mc_accums[i]);
- sa_release(mc_accums);
+ if(solver_ctxs) {
+ FOR_EACH(i, 0, dev->nthreads) solver_context_release(solver_ctxs+i);
+ sa_release(solver_ctxs);
}
if(rngs) {
FOR_EACH(i, 0, dev->nthreads) if(rngs[i]) SSP(rng_ref_put(rngs[i]));
sa_release(rngs);
}
- if(shapes) {
- FOR_EACH(i, 0, dev->nthreads) if(shapes[i]) S3D(shape_ref_put(shapes[i]));
- sa_release(shapes);
- }
- if(scenes) {
- FOR_EACH(i, 0, dev->nthreads) if(scenes[i]) S3D(scene_ref_put(scenes[i]));
- sa_release(scenes);
- }
if(out_estimator) *out_estimator = estimator;
return (res_T)res;
error:
@@ -783,11 +1602,26 @@ sschiff_estimator_ref_put(struct sschiff_estimator* estimator)
}
res_T
-sschiff_estimator_get_wavelengths_count
- (const struct sschiff_estimator* estimator, size_t* count)
+sschiff_estimator_get_wavelengths
+ (const struct sschiff_estimator* estimator,
+ const double** wavelengths,
+ size_t* count)
{
- if(!estimator || !count) return RES_BAD_ARG;
- *count = sa_size(estimator->wavelengths);
+ if(!estimator) return RES_BAD_ARG;
+ if(wavelengths) *wavelengths = estimator->wavelengths;
+ if(count) *count = sa_size(estimator->wavelengths);
+ return RES_OK;
+}
+
+res_T
+sschiff_estimator_get_scattering_angles
+ (const struct sschiff_estimator* estimator,
+ const double** angles,
+ size_t* count)
+{
+ if(!estimator) return RES_BAD_ARG;
+ if(angles) *angles = estimator->angles;
+ if(count) *count = sa_size(estimator->angles);
return RES_OK;
}
@@ -801,62 +1635,247 @@ sschiff_estimator_get_realisations_count
}
res_T
-sschiff_estimator_get_wavelength_state
+sschiff_estimator_get_cross_section
(const struct sschiff_estimator* estimator,
- const double wavelength,
- struct sschiff_estimator_state* state)
+ const size_t iwlen,
+ struct sschiff_cross_section* cross_section)
{
- const struct mc_accum* accum;
- const double* wavelengths;
- const double* find;
- size_t iwavelength;
- size_t nwavelengths;
- int i;
+ const struct mc_accum* acc;
+ size_t N;
- if(!estimator || !state)
+ if(!estimator || !cross_section || iwlen >= sa_size(estimator->wavelengths))
return RES_BAD_ARG;
- wavelengths = estimator->wavelengths;
- nwavelengths = sa_size(estimator->wavelengths);
- find = bsearch
- (&wavelength, wavelengths, nwavelengths, sizeof(double), cmp_double);
- if(!find) return RES_BAD_ARG;
-
- iwavelength = (size_t)(find - wavelengths);
- accum = estimator->accums + iwavelength;
-
- FOR_EACH(i, 0, SSCHIFF_DATA_COUNT__) {
- get_mc_value(accum->mc_data+i, estimator->nrealisations, state->values+i);
- }
- state->wavelength = wavelength;
+ acc = estimator->accums + iwlen;
+ N = estimator->nrealisations;
+ get_mc_value(&acc->extinction_cross_section, N, &cross_section->extinction);
+ get_mc_value(&acc->absorption_cross_section, N, &cross_section->absorption);
+ get_mc_value(&acc->scattering_cross_section, N, &cross_section->scattering);
+ get_mc_value(&acc->avg_projected_area, N,
+ &cross_section->average_projected_area);
return RES_OK;
}
res_T
-sschiff_estimator_get_states
+sschiff_estimator_get_cross_sections
(const struct sschiff_estimator* estimator,
- struct sschiff_estimator_state* states)
+ struct sschiff_cross_section* cross_sections)
{
- const double* wavelengths;
- const struct mc_accum* accums;
size_t nwavelengths;
size_t iwlen;
- int i;
- if(!estimator || !states) return RES_BAD_ARG;
+ size_t N;
+ if(!estimator || !cross_sections) return RES_BAD_ARG;
nwavelengths = sa_size(estimator->wavelengths);
- wavelengths = estimator->wavelengths;
- accums = estimator->accums;
-
+ N = estimator->nrealisations;
FOR_EACH(iwlen, 0, nwavelengths) {
- states[iwlen].wavelength = wavelengths[iwlen];
- FOR_EACH(i, 0, SSCHIFF_DATA_COUNT__) {
- get_mc_value
- (accums[iwlen].mc_data + i,
- estimator->nrealisations,
- states[iwlen].values + i);
+ const struct mc_accum* acc = estimator->accums + iwlen;
+ get_mc_value(&acc->extinction_cross_section, N, &cross_sections->extinction);
+ get_mc_value(&acc->absorption_cross_section, N, &cross_sections->absorption);
+ get_mc_value(&acc->scattering_cross_section, N, &cross_sections->scattering);
+ get_mc_value(&acc->avg_projected_area, N,
+ &cross_sections->average_projected_area);
+ }
+ return RES_OK;
+}
+
+res_T
+sschiff_estimator_get_phase_function
+ (const struct sschiff_estimator* estimator,
+ const size_t iwlen,
+ const struct sschiff_state** states)
+{
+ if(!estimator || !states || iwlen >= sa_size(estimator->wavelengths))
+ return RES_BAD_ARG;
+ /* No phase function was computed */
+ if(estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE)
+ return RES_BAD_OP;
+ /* Invalid phase function */
+ if(estimator->phase_functions[iwlen].values[0].V < 0)
+ return RES_BAD_OP;
+ *states = estimator->phase_functions[iwlen].values;
+ return RES_OK;
+}
+
+/* Retrieve a pointer onto the estimated phase function cumulative. */
+SSCHIFF_API res_T
+sschiff_estimator_get_phase_function_cumulative
+ (const struct sschiff_estimator* estimator,
+ const size_t iwlen,
+ const struct sschiff_state** states)
+{
+ if(!estimator || !states || iwlen >= sa_size(estimator->wavelengths))
+ return RES_BAD_ARG;
+ /* No phase function cumulative was computed */
+ if(estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE)
+ return RES_BAD_OP;
+ /* Invalid cumulative phase function */
+ if(estimator->phase_functions[iwlen].cumulative[0].V < 0)
+ return RES_BAD_OP;
+ *states = estimator->phase_functions[iwlen].cumulative;
+ return RES_OK;
+}
+
+res_T
+sschiff_estimator_inverse_cumulative_phase_function
+ (const struct sschiff_estimator* estimator,
+ const size_t iwlen,
+ double* thetas,
+ const size_t nthetas)
+{
+ struct sschiff_state* cumul[2];
+ double* cumulative_small_angles = NULL;
+ double cumulative;
+ double step;
+ size_t itheta;
+ size_t iangle, nsmall_angles;
+ res_T res = RES_OK;
+
+ if(!estimator
+ || nthetas < 2
+ || !thetas
+ || iwlen >= sa_size(estimator->wavelengths)) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* No phase function cumulative is computed => nothing to inverse */
+ if(estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE) {
+ res = RES_BAD_OP;
+ goto error;
+ }
+
+ /* Allocate the "filtered" phase function cumulative of small angles, i.e.
+ * the increasing cumulative defined from the Monte-Carlo estimation. */
+ nsmall_angles = estimator->limit_angles[iwlen];
+ if(!sa_add(cumulative_small_angles, nsmall_angles)) {
+ log_error(estimator->dev,
+"Couldn't allocate the filtered phase function cumulative of small angles.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
+ /* Fill the phase function cumulative for small angles. Ensure that the
+ * resulting array is sorted in increasing order, i.e. increasing function */
+ cumul[0] = &estimator->phase_functions[iwlen].cumulative[0];
+ cumulative_small_angles[0] = cumul[0]->E;
+ FOR_EACH(iangle, 1, nsmall_angles) {
+ cumul[1] = &estimator->phase_functions[iwlen].cumulative[iangle];
+
+ if(cumul[0]->E <= cumul[1]->E) {
+ cumulative_small_angles[iangle] = cumul[1]->E;
+ } else {
+ /* Numerical imprecisions may lead to a cumulative that is not an
+ * increasing function. In such case, check that the standard-error
+ * ensure at least a threshold between the decreasing entry an the
+ * previous one. If not, return an error */
+ cumulative = MMIN(cumul[1]->E + cumul[1]->SE, cumul[0]->E);
+ if(cumulative < cumul[0]->E) {
+ log_error(estimator->dev,
+"The phase function cumulative of small angles is not an increasing function.\n"
+"This may be due to numerical imprecisions.\n");
+ res = RES_BAD_OP;
+ goto error;
+ }
+ cumulative_small_angles[iangle] = cumulative;
}
+ cumul[0] = cumul[1];
+ }
+
+ /* Inverse the phase function cumulative */
+ thetas[0] = 0.0;
+ thetas[nthetas-1] = PI;
+ cumulative = step = 1.0/(double)(nthetas-1);
+ FOR_EACH(itheta, 1, nthetas-1) {
+ /* TODO since the submitted cumulative are strictly increasing, one can
+ * speed up the inversion by using the previous search result to reduce the
+ * search domain in the cumulative arrays */
+ res = inverse_cumulative_phase_function
+ (estimator, cumulative_small_angles, iwlen, cumulative, &thetas[itheta]);
+ if(res != RES_OK) goto error;
+ cumulative += step;
}
+
+exit:
+ if(cumulative_small_angles) sa_release(cumulative_small_angles);
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+sschiff_estimator_get_limit_scattering_angle_index
+ (const struct sschiff_estimator* estimator,
+ const size_t iwlen,
+ size_t* iangle)
+{
+ size_t limit_angle;
+ if(!estimator || iwlen >= sa_size(estimator->wavelengths) || !iangle)
+ return RES_BAD_ARG;
+ limit_angle = estimator->limit_angles[iwlen];
+ if(limit_angle == INVALID_LIMIT_ANGLE)
+ return RES_BAD_OP;
+ *iangle = limit_angle - 1/*<=>index of the last small angle*/;
+ return RES_OK;
+}
+
+res_T
+sschiff_estimator_get_wide_scattering_angle_model_parameter
+ (const struct sschiff_estimator* estimator,
+ const size_t iwlen,
+ double* out_n)
+{
+ if(!estimator || iwlen >= sa_size(estimator->wavelengths) || !out_n)
+ return RES_BAD_ARG;
+ if(estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE)
+ return RES_BAD_OP;
+ *out_n = estimator->wide_angles_parameter[iwlen];
+ return RES_OK;
+}
+
+res_T
+sschiff_estimator_get_differential_cross_section
+ (const struct sschiff_estimator* estimator,
+ const size_t iwlen,
+ const size_t iangle,
+ struct sschiff_state* state)
+{
+ if(!estimator
+ || iwlen >= sa_size(estimator->wavelengths)
+ || iangle >= sa_size(estimator->angles)
+ || !state)
+ return RES_BAD_ARG;
+
+ if(estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE)
+ return RES_BAD_OP;
+
+ get_mc_value
+ (&estimator->accums[iwlen].differential_cross_section[iangle],
+ estimator->nrealisations,
+ state);
+ return RES_OK;
+}
+
+res_T
+sschiff_estimator_get_differential_cross_section_cumulative
+ (const struct sschiff_estimator* estimator,
+ const size_t iwlen,
+ const size_t iangle,
+ struct sschiff_state* state)
+{
+ if(!estimator
+ || iwlen >= sa_size(estimator->wavelengths)
+ || iangle >= sa_size(estimator->angles)
+ || !state)
+ return RES_BAD_ARG;
+
+ if(estimator->limit_angles[iwlen] == INVALID_LIMIT_ANGLE)
+ return RES_BAD_OP;
+
+ get_mc_value
+ (&estimator->accums[iwlen].differential_cross_section_cumulative[iangle],
+ estimator->nrealisations,
+ state);
return RES_OK;
}
diff --git a/src/sschiff_scattering_angles_distributions.c b/src/sschiff_scattering_angles_distributions.c
@@ -0,0 +1,35 @@
+/* Copyright (C) 2015-2016 CNRS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "sschiff.h"
+#include <rsys/math.h>
+
+static void
+uniform(double* angles, const size_t nangles)
+{
+ size_t iangle;
+ const double step = PI / (double)(nangles - 1);
+ ASSERT(nangles >= 2);
+
+ angles[0] = 0.0;
+ FOR_EACH(iangle, 1, nangles-1) {
+ angles[iangle] = angles[iangle-1] + step;
+ }
+ angles[nangles-1] = PI;
+}
+
+const sschiff_scattering_angles_distribution_T
+sschiff_uniform_scattering_angles = uniform;
+
diff --git a/src/test_sschiff_device.c b/src/test_sschiff_device.c
@@ -1,30 +1,17 @@
-/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+/* Copyright (C) 2015-2016 CNRS
*
- * This software is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms. */
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "sschiff.h"
#include "test_sschiff_utils.h"
diff --git a/src/test_sschiff_estimator_cylinder.c b/src/test_sschiff_estimator_cylinder.c
@@ -1,30 +1,17 @@
-/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+/* Copyright (C) 2015-2016 CNRS
*
- * This software is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms. */
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "sschiff.h"
#include "test_sschiff_utils.h"
@@ -47,11 +34,6 @@ struct result {
double avg_proj_area_SE;
};
-struct geometry {
- float* vertices;
- unsigned* indices;
-};
-
struct sampler_context {
struct geometry geometry;
double aspect_ratio;
@@ -59,12 +41,6 @@ struct sampler_context {
double sigma;
};
-struct cylinder {
- struct geometry* geometry;
- float radius;
- float height;
-};
-
static void
get_material_property
(void* mtl,
@@ -78,66 +54,13 @@ get_material_property
props->relative_real_refractive_index = 1.01;
}
-static void
-get_indices(const unsigned itri, unsigned ids[3], void* ctx)
-{
- struct cylinder* cylinder = ctx;
- const size_t i = itri * 3;
-
- CHECK(sa_size(cylinder->geometry->indices) % 3, 0);
- CHECK(itri < sa_size(cylinder->geometry->indices) / 3, 1);
- ids[0] = cylinder->geometry->indices[i + 0];
- ids[1] = cylinder->geometry->indices[i + 1];
- ids[2] = cylinder->geometry->indices[i + 2];
-}
-
-static void
-get_position(const unsigned ivert, float vertex[3], void* ctx)
-{
- struct cylinder* cylinder = ctx;
- const size_t i = ivert * 3;
-
- CHECK(sa_size(cylinder->geometry->vertices) % 3, 0);
- CHECK(ivert < sa_size(cylinder->geometry->vertices) / 3, 1);
- vertex[0] = cylinder->geometry->vertices[i + 0] * cylinder->radius;
- vertex[1] = cylinder->geometry->vertices[i + 1] * cylinder->radius;
- vertex[2] = cylinder->geometry->vertices[i + 2] * cylinder->height;
-}
-
-static FINLINE void
-dump_geometry(struct geometry* geom)
-{
- size_t i;
- NCHECK(geom, NULL);
- CHECK(sa_size(geom->vertices)%3, 0);
- CHECK(sa_size(geom->indices)%3, 0);
-
- FOR_EACH(i, 0, sa_size(geom->vertices)/3) {
- printf("v %f %f %f\n",
- geom->vertices[i*3+0],
- geom->vertices[i*3+1],
- geom->vertices[i*3+2]);
- }
- FOR_EACH(i, 0, sa_size(geom->indices)/3) {
- printf("f %d %d %d\n",
- geom->indices[i*3+0] + 1,
- geom->indices[i*3+1] + 1,
- geom->indices[i*3+2] + 1);
- }
-}
-
static res_T
sample_cylinder
- (struct ssp_rng* rng,
- struct sschiff_material* mtl,
- struct s3d_shape* shape,
- void* sampler_context)
+ (struct ssp_rng* rng, struct s3d_shape* shape, void* sampler_context)
{
- struct s3d_vertex_data attrib;
struct sampler_context* sampler_ctx = sampler_context;
struct cylinder cylinder;
double sample;
- size_t nverts, nprims;
(void)rng, (void)sampler_context;
sample = ssp_ran_lognormal(rng, log(sampler_ctx->mean_radius), log(sampler_ctx->sigma));
@@ -145,85 +68,7 @@ sample_cylinder
cylinder.radius = (float)(sample / pow(3.0 / (2.0*sampler_ctx->aspect_ratio), 1.0/3.0));
cylinder.height = (float)(2.f * cylinder.radius / sampler_ctx->aspect_ratio);
- attrib.usage = S3D_POSITION;
- attrib.type = S3D_FLOAT3;
- attrib.get = get_position;
-
- mtl->get_property = get_material_property;
- mtl->material = sampler_ctx;
-
- nverts = sa_size(cylinder.geometry->vertices) / 3/*#coords*/;
- nprims = sa_size(cylinder.geometry->indices) / 3/*#indices per prim*/;
-
- return s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprims,
- get_indices, (unsigned)nverts, &attrib, 1, &cylinder);
-}
-
-static void
-cylinder_init(struct geometry* geometry, const unsigned nsteps)
-{
- const double step = 2*PI / (double)nsteps;
- unsigned istep;
-
- NCHECK(geometry, NULL);
- NCHECK(nsteps, 0);
-
- geometry->vertices = NULL;
- geometry->indices = NULL;
-
- /* Generate the vertex coordinates */
- FOR_EACH(istep, 0, nsteps) {
- const float theta = (float)(istep * step);
- const float x = (float)cos(theta);
- const float y = (float)sin(theta);
- f3(sa_add(geometry->vertices, 3), x, y, -1.f);
- f3(sa_add(geometry->vertices, 3), x, y, 0.f);
- }
-
- /* "Polar" vertices */
- f3(sa_add(geometry->vertices, 3), 0.f, 0.f, -1.f);
- f3(sa_add(geometry->vertices, 3), 0.f, 0.f, 0.f);
-
- /* Contour primitives */
- FOR_EACH(istep, 0, nsteps) {
- const unsigned id = istep * 2;
- unsigned* iprim;
-
- iprim = sa_add(geometry->indices, 3);
- iprim[0] = (id + 0);
- iprim[1] = (id + 1);
- iprim[2] = (id + 2) % (nsteps*2);
-
- iprim = sa_add(geometry->indices, 3);
- iprim[0] = (id + 2) % (nsteps*2);
- iprim[1] = (id + 1);
- iprim[2] = (id + 3) % (nsteps*2);
- }
-
- /* Cap primitives */
- FOR_EACH(istep, 0, nsteps) {
- const unsigned id = istep * 2;
- unsigned* iprim;
-
- iprim = sa_add(geometry->indices, 3);
- iprim[0] = (nsteps * 2);
- iprim[1] = (id + 0);
- iprim[2] = (id + 2) % (nsteps*2);
-
- iprim = sa_add(geometry->indices, 3);
- iprim[0] = (nsteps * 2) + 1;
- iprim[1] = (id + 3) % (nsteps*2);
- iprim[2] = (id + 1);
- }
-}
-
-static void
-cylinder_release(struct geometry* geometry)
-{
- sa_release(geometry->vertices);
- sa_release(geometry->indices);
- geometry->vertices = NULL;
- geometry->indices = NULL;
+ return cylinder_setup_s3d_shape(&cylinder, shape);
}
static INLINE void
@@ -559,9 +404,9 @@ main(int argc, char** argv)
2.010619438e+2, 2.018997018e+2, 2.027374599e+2
};
const size_t nx = sizeof(x)/sizeof(double);
- const size_t nscatt_angles = 1;
+ const size_t nscatt_angles = 1000;
const size_t ngeoms = 100;
- const size_t ndirs = 10;
+ const size_t ndirs = 100;
size_t i;
(void)argc, (void)argv;
@@ -569,64 +414,72 @@ main(int argc, char** argv)
CHECK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng), RES_OK);
CHECK(sschiff_device_create
- (NULL, &allocator, SSCHIFF_NTHREADS_DEFAULT, 0, NULL, &dev), RES_OK);
+ (NULL, &allocator, SSCHIFF_NTHREADS_DEFAULT, 1, NULL, &dev), RES_OK);
- cylinder_init(&sampler_ctx.geometry, 64);
+ geometry_init_cylinder(&sampler_ctx.geometry, 64);
FOR_EACH(i, 0, nx) {
const double wavelength = 0.6; /* In micron */
- struct sschiff_estimator_state state;
+ struct sschiff_cross_section cross_section;
double interval[2];
- struct sschiff_estimator_value* val;
+ struct sschiff_state* val;
+ struct sschiff_state result;
sampler_ctx.aspect_ratio = 0.837;
sampler_ctx.mean_radius = (x[i] * 0.450) / (2*PI);
sampler_ctx.sigma = 1.18;
+ distrib.characteristic_length = sampler_ctx.mean_radius;
+ distrib.material.get_property = get_material_property;
+ distrib.material.material = &sampler_ctx;
distrib.sample = sample_cylinder;
distrib.context = &sampler_ctx;
time_current(&t0);
- CHECK(sschiff_integrate(dev, rng, &distrib, &wavelength, 1, nscatt_angles,
- ngeoms, ndirs, &estimator), RES_OK);
+ CHECK(sschiff_integrate(dev, rng, &distrib, &wavelength, 1,
+ sschiff_uniform_scattering_angles, nscatt_angles, ngeoms, ndirs,
+ &estimator), RES_OK);
time_current(&t1);
time_sub(&t0, &t1, &t0);
time_dump(&t0, TIME_MIN|TIME_SEC|TIME_MSEC, NULL, buf, sizeof(buf));
- CHECK(sschiff_estimator_get_wavelength_state
- (estimator, wavelength, &state), RES_OK);
- CHECK(eq_eps(state.wavelength, wavelength, 1.e-6), 1);
+ CHECK(sschiff_estimator_get_cross_section
+ (estimator, 0, &cross_section), RES_OK);
printf("%u - x = %g - Wavelength = %g micron - %s\n",
(unsigned)i, x[i], wavelength, buf);
- val = state.values + SSCHIFF_EXTINCTION_CROSS_SECTION;
- compute_intersection(interval, results[i].extinction_E,
- results[i].extinction_SE, val->E, val->SE);
+ val = &cross_section.extinction;
+ result.E = results[i].extinction_E;
+ result.SE = results[i].extinction_SE;
+ compute_estimation_intersection(interval, 4, &result, val);
printf(" Extinction ~ %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
results[i].extinction_E, results[i].extinction_SE,
val->E, val->SE, interval[1] - interval[0]);
CHECK(interval[0] <= interval[1], 1);
- val = state.values + SSCHIFF_ABSORPTION_CROSS_SECTION;
- compute_intersection(interval, results[i].absorption_E,
- results[i].absorption_SE, val->E, val->SE);
+ val = &cross_section.absorption;
+ result.E = results[i].absorption_E;
+ result.SE = results[i].absorption_SE;
+ compute_estimation_intersection(interval, 4, &result, val);
printf(" Absorption ~ %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
results[i].absorption_E, results[i].absorption_SE,
val->E, val->SE, interval[1] - interval[0]);
CHECK(interval[0] <= interval[1], 1);
- val = state.values + SSCHIFF_SCATTERING_CROSS_SECTION;
- compute_intersection(interval, results[i].scattering_E,
- results[i].scattering_SE, val->E, val->SE);
+ val = &cross_section.scattering;
+ result.E = results[i].scattering_E;
+ result.SE = results[i].scattering_SE;
+ compute_estimation_intersection(interval, 4, &result, val);
printf(" Scattering ~ %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
results[i].scattering_E, results[i].scattering_SE,
val->E, val->SE, interval[1] - interval[0]);
CHECK(interval[0] <= interval[1], 1);
- val = state.values + SSCHIFF_AVERAGE_PROJECTED_AREA;
- compute_intersection(interval, results[i].avg_proj_area_E,
- results[i].avg_proj_area_SE, val->E, val->SE);
+ val = &cross_section.average_projected_area;
+ result.E = results[i].avg_proj_area_E;
+ result.SE = results[i].avg_proj_area_SE;
+ compute_estimation_intersection(interval, 4, &result, val);
printf(" Proj Area ~ %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
results[i].avg_proj_area_E, results[i].avg_proj_area_SE,
val->E, val->SE, interval[1] - interval[0]);
@@ -638,7 +491,7 @@ main(int argc, char** argv)
CHECK(sschiff_device_ref_put(dev), RES_OK);
CHECK(ssp_rng_ref_put(rng), RES_OK);
- cylinder_release(&sampler_ctx.geometry);
+ geometry_release(&sampler_ctx.geometry);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
CHECK(mem_allocated_size(), 0);
diff --git a/src/test_sschiff_estimator_rhodo.c b/src/test_sschiff_estimator_rhodo.c
@@ -0,0 +1,2847 @@
+/* Copyright (C) 2015-2016 CNRS
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "sschiff.h"
+#include "test_sschiff_utils.h"
+
+#include <rsys/stretchy_array.h>
+
+#include <star/s3d.h>
+#include <star/ssp.h>
+
+static const double phase_func[][2] = { /* Expected-value Standard-error */
+ { 27.8639012515142, 0.0104219265037484 },
+ { 27.8097473381001, 0.010397871478357 },
+ { 27.6481328692231, 0.0103270459457762 },
+ { 27.3815769133766, 0.0102133666109714 },
+ { 27.0142029259005, 0.0100630267526927 },
+ { 26.5516291165535, 0.0098840133305036 },
+ { 26.0008205445445, 0.00968547152934431 },
+ { 25.3699082222265, 0.00947696290217467 },
+ { 24.6679816078446, 0.00926768196113287 },
+ { 23.904861689194, 0.00906571349748875 },
+ { 23.0908623729002, 0.00887742227325763 },
+ { 22.2365480829303, 0.00870705960655899 },
+ { 21.3524953373762, 0.00855664223656603 },
+ { 20.4490656308234, 0.00842611046725715 },
+ { 19.5361962309318, 0.00831371794844758 },
+ { 18.6232145449251, 0.0082165629257017 },
+ { 17.7186805765593, 0.00813115454554301 },
+ { 16.8302607352971, 0.00805392036869873 },
+ { 15.9646349386728, 0.00798159357252883 },
+ { 15.1274376275275, 0.00791145628249234 },
+ { 14.3232320502063, 0.0078414472105489 },
+ { 13.5555160178292, 0.00777016148089376 },
+ { 12.8267563319888, 0.00769677804502422 },
+ { 12.1384482720108, 0.00762094853040654 },
+ { 11.4911959234416, 0.00754267468605382 },
+ { 10.8848087432756, 0.00746219314898021 },
+ { 10.318409589964, 0.0073798783006216 },
+ { 9.79054948640664, 0.00729616765465551 },
+ { 9.29932461192675, 0.00721150982105626 },
+ { 8.84249140741701, 0.00712633241407738 },
+ { 8.41757619406262, 0.00704102588511451 },
+ { 8.02197631475114, 0.0069559387428905 },
+ { 7.65305047210333, 0.00687137968007232 },
+ { 7.30819662250046, 0.00678762261045772 },
+ { 6.98491645884851, 0.00670491147231578 },
+ { 6.68086614748023, 0.00662346280295104 },
+ { 6.39389355304139, 0.00654346539386561 },
+ { 6.1220626717808, 0.00646507756644009 },
+ { 5.86366638663766, 0.0063884235033138 },
+ { 5.61722895118534, 0.00631359042621706 },
+ { 5.38149980357944, 0.00624062816413725 },
+ { 5.15544041078256, 0.00616955192267286 },
+ { 4.93820585607353, 0.00610034811055088 },
+ { 4.72912282078604, 0.00603298222447669 },
+ { 4.52766548799073, 0.00596740730435197 },
+ { 4.33343072605244, 0.00590357146623586 },
+ { 4.14611370844303, 0.0058414234415159 },
+ { 3.96548490696357, 0.00578091570025391 },
+ { 3.79136917142595, 0.00572200536717062 },
+ { 3.62362739093223, 0.00566465355149385 },
+ { 3.46214102912589, 0.00560882382511788 },
+ { 3.30679964498747, 0.00555448044539151 },
+ { 3.15749135650642, 0.00550158666572009 },
+ { 3.01409607943379, 0.00545010326020052 },
+ { 2.87648127803476, 0.00539998730363449 },
+ { 2.74449989849243, 0.00535119129972995 },
+ { 2.61799011631235, 0.0053036628609894 },
+ { 2.49677651380392, 0.00525734520318185 },
+ { 2.38067230891331, 0.00521217864216896 },
+ { 2.26948227854277, 0.0051681030593242 },
+ { 2.16300605407113, 0.00512506100131097 },
+ { 2.06104151033916, 0.00508300081750709 },
+ { 1.96338801834785, 0.00504187912789507 },
+ { 1.86984938322351, 0.00500166201653721 },
+ { 1.78023633989709, 0.00496232464181974 },
+ { 1.6943685272102, 0.00492384935312064 },
+ { 1.61207590499642, 0.00488622277664308 },
+ { 1.53319961678277, 0.00484943256480007 },
+ { 1.4575923322178, 0.0048134645299754 },
+ { 1.38511812767801, 0.00477830071161003 },
+ { 1.31565198060704, 0.00474391862457846 },
+ { 1.24907896323038, 0.00471029160926755 },
+ { 1.18529322486208, 0.00467738994865887 },
+ { 1.12419684983762, 0.00464518229961856 },
+ { 1.06569867111887, 0.00461363701891924 },
+ { 1.0097131089113, 0.00458272311577593 },
+ { 0.95615909037997, 0.00455241076684375 },
+ { 0.904959091921401, 0.00452267151344723 },
+ { 0.856038330573855, 0.00449347836559986 },
+ { 0.809324117034655, 0.00446480603508896 },
+ { 0.764745370236995, 0.00443663141967281 },
+ { 0.722232283151437, 0.00440893430408208 },
+ { 0.681716121804176, 0.00438169809177785 },
+ { 0.64312913459013, 0.00435491029408095 },
+ { 0.606404546714079, 0.00432856251880684 },
+ { 0.571476614719875, 0.0043026498214007 },
+ { 0.538280718116107, 0.00427716947120289 },
+ { 0.506753468517307, 0.0042521193789479 },
+ { 0.476832820899294, 0.00422749655789089 },
+ { 0.448458175944596, 0.00420329599933904 },
+ { 0.421570466526901, 0.00417951022413797 },
+ { 0.396112224784657, 0.00415612956220942 },
+ { 0.372027628727257, 0.00413314298493553 },
+ { 0.34926252883483, 0.00411053915086031 },
+ { 0.327764455725817, 0.00408830728225869 },
+ { 0.307482609868524, 0.00406643758196836 },
+ { 0.288367833779875, 0.00404492108980586 },
+ { 0.27037256649635, 0.00402374909389535 },
+ { 0.253450779616592, 0.00400291237536915 },
+ { 0.237557894145684, 0.00398240061935438 },
+ { 0.222650677869614, 0.003962202258034 },
+ { 0.208687124098142, 0.00394230485464946 },
+ { 0.195626314261759, 0.00392269595151553 },
+ { 0.183428268856779, 0.00390336415514364 },
+ { 0.172053793343728, 0.00388430016205827 },
+ { 0.161464327517107, 0.00386549745148821 },
+ { 0.151621808273235, 0.00384695246621416 },
+ { 0.142488556341787, 0.00382866423283275 },
+ { 0.134027197225246, 0.00381063349888717 },
+ { 0.126200625223001, 0.00379286155980179 },
+ { 0.118972017036516, 0.0037753490020576 },
+ { 0.11230489821309, 0.00375809460082263 },
+ { 0.106163261847014, 0.00374109458462931 },
+ { 0.100511734859306, 0.00372434242006628 },
+ { 0.095315783202815, 0.00370782917879917 },
+ { 0.0905419438730762, 0.00369154443527497 },
+ { 0.0861580689923781, 0.00367547752398726 },
+ { 0.0821335657418107, 0.00365961888847036 },
+ { 0.0784396157059796, 0.00364396121204173 },
+ { 0.0750493583057482, 0.0036285000555342 },
+ { 0.0719380253389912, 0.00361323384121503 },
+ { 0.0690830170243102, 0.00359816318900595 },
+ { 0.0664639140507078, 0.00358328978320089 },
+ { 0.0640624246178966, 0.00356861507072045 },
+ { 0.061862269921658, 0.00355413912448753 },
+ { 0.059849015624047, 0.00353985993644454 },
+ { 0.0580098602245617, 0.00352577325807623 },
+ { 0.0563333936678203, 0.00351187293334816 },
+ { 0.0548093408342655, 0.00349815152948963 },
+ { 0.0534283047171724, 0.00348460101113133 },
+ { 0.0521815231483196, 0.00347121323876327 },
+ { 0.0510606510442706, 0.003457980183939 },
+ { 0.0500575775233974, 0.00344489389509226 },
+ { 0.0491642841540651, 0.00343194636437493 },
+ { 0.0483727473169407, 0.00341912949411207 },
+ { 0.0476748844702159, 0.00340643532428257 },
+ { 0.0470625412328754, 0.00339385657428759 },
+ { 0.0465275138354938, 0.00338138741289236 },
+ { 0.0460615997555366, 0.00336902425037735 },
+ { 0.0456566683158406, 0.00335676629114717 },
+ { 0.0453047426791992, 0.00334461561705969 },
+ { 0.0449980849641331, 0.00333257668679761 },
+ { 0.0447292770407506, 0.00332065530249377 },
+ { 0.0444912908175968, 0.00330885726117436 },
+ { 0.0442775433639401, 0.00329718702177206 },
+ { 0.0440819338898934, 0.00328564673822858 },
+ { 0.0438988613015472, 0.00327423592232077 },
+ { 0.0437232226492196, 0.00326295182644977 },
+ { 0.0435503942040859, 0.00325179042651057 },
+ { 0.0433761980640087, 0.00324074770352933 },
+ { 0.0431968580574175, 0.00322982083041083 },
+ { 0.0430089492580248, 0.00321900890111767 },
+ { 0.0428093456345139, 0.00320831298813106 },
+ { 0.042595170245328, 0.00319773553345556 },
+ { 0.0423637519708264, 0.00318727929518009 },
+ { 0.042112592088644, 0.00317694621031335 },
+ { 0.0418393430917898, 0.00316673654568404 },
+ { 0.0415418010837461, 0.00315664858814309 },
+ { 0.0412179119330498, 0.00314667891819218 },
+ { 0.0408657902127377, 0.00313682309621684 },
+ { 0.0404837488732303, 0.00312707645060109 },
+ { 0.0400703366859101, 0.00311743464668489 },
+ { 0.0396243798257329, 0.00310789383843362 },
+ { 0.0391450235969651, 0.0030984504105761 },
+ { 0.0386317702858619, 0.00308910052232553 },
+ { 0.0380845094590404, 0.00307983977734889 },
+ { 0.0375035376952539, 0.00307066331484325 },
+ { 0.0368895656870136, 0.00306156644672417 },
+ { 0.0362437117927368, 0.0030525457174005 },
+ { 0.0355674823518726, 0.00304360003281617 },
+ { 0.0348627402726544, 0.00303473139084071 },
+ { 0.0341316644409644, 0.00302594480339155 },
+ { 0.0333767032667836, 0.00301724722687405 },
+ { 0.0326005260937293, 0.00300864564314919 },
+ { 0.0318059761943847, 0.00300014474906579 },
+ { 0.0309960286497157, 0.00299174490672025 },
+ { 0.0301737556012419, 0.00298344100396871 },
+ { 0.0293423002504574, 0.00297522266399672 },
+ { 0.0299516429908675, 0.000938723060011486 },
+ { 0.029268188588675, 0.000917302718963749 },
+ { 0.0286037110947699, 0.000896477138658268 },
+ { 0.0279575872542805, 0.000876226785484804 },
+ { 0.0273292174927134, 0.00085653286800666 },
+ { 0.026718024894305, 0.000837377304940913 },
+ { 0.0261234542296794, 0.000818742694683954 },
+ { 0.0255449710301824, 0.000800612286299926 },
+ { 0.0249820607064155, 0.00078296995189444 },
+ { 0.0244342277086368, 0.000765800160300474 },
+ { 0.023900994726832, 0.000749087952007545 },
+ { 0.0233819019283824, 0.000732818915269257 },
+ { 0.0228765062313778, 0.000716979163327987 },
+ { 0.0223843806117313, 0.000701555312698977 },
+ { 0.0219051134423594, 0.000686534462459374 },
+ { 0.0214383078627848, 0.000671904174490787 },
+ { 0.0209835811776166, 0.000657652454626869 },
+ { 0.0205405642824433, 0.000643767734660066 },
+ { 0.0201089011157586, 0.000630238855164271 },
+ { 0.0196882481356153, 0.000617055049092481 },
+ { 0.0192782738197732, 0.000604205926110789 },
+ { 0.0188786581881761, 0.000591681457632193 },
+ { 0.018489092346654, 0.000579471962515645 },
+ { 0.0181092780508085, 0.000567568093397652 },
+ { 0.0177389272890942, 0.000555960823625504 },
+ { 0.0173777618841613, 0.000544641434762855 },
+ { 0.0170255131115766, 0.000533601504639927 },
+ { 0.0166819213350833, 0.000522832895922104 },
+ { 0.0163467356576088, 0.000512327745172049 },
+ { 0.0160197135872668, 0.000502078452381789 },
+ { 0.0157006207176422, 0.000492077670952433 },
+ { 0.0153892304216842, 0.000482318298100376 },
+ { 0.0150853235585655, 0.000472793465669904 },
+ { 0.0147886881929018, 0.00046349653133317 },
+ { 0.0144991193257556, 0.000454421070159487 },
+ { 0.0142164186368751, 0.000445560866536796 },
+ { 0.0139403942376528, 0.000436909906429038 },
+ { 0.0136708604343077, 0.000428462369954001 },
+ { 0.0134076375008253, 0.000420212624266957 },
+ { 0.0131505514612099, 0.000412155216736174 },
+ { 0.0128994338806274, 0.000404284868397054 },
+ { 0.0126541216650364, 0.000396596467672326 },
+ { 0.0124144568689274, 0.000389085064346334 },
+ { 0.0121802865108059, 0.00038174586378205 },
+ { 0.0119514623960758, 0.000374574221370002 },
+ { 0.0117278409469938, 0.000367565637198829 },
+ { 0.0115092830393834, 0.000360715750937685 },
+ { 0.0112956538458104, 0.000354020336921174 },
+ { 0.0110868226849391, 0.000347475299427951 },
+ { 0.0108826628767972, 0.000341076668144559 },
+ { 0.010683051603695, 0.000334820593806455 },
+ { 0.0104878697765545, 0.000328703344008578 },
+ { 0.0102970019064142, 0.000322721299178161 },
+ { 0.0101103359808899, 0.000316870948702849 },
+ { 0.00992776334537916, 0.000311148887207481 },
+ { 0.00974917858880738, 0.000305551810973246 },
+ { 0.00957447943372507, 0.000300076514493174 },
+ { 0.00940356663057152, 0.000294719887158227 },
+ { 0.00923634385593102, 0.000289478910068523 },
+ { 0.00907271761461473, 0.000284350652964449 },
+ { 0.008912597145409, 0.000279332271272696 },
+ { 0.00875589433033843, 0.000274421003262447 },
+ { 0.00860252360729873, 0.000269614167307174 },
+ { 0.00845240188592081, 0.000264909159247715 },
+ { 0.00830544846653409, 0.000260303449852477 },
+ { 0.0081615849621028, 0.00025579458237082 },
+ { 0.00802073522301435, 0.000251380170175828 },
+ { 0.00788282526460502, 0.00024705789449287 },
+ { 0.00774778319731221, 0.000242825502210483 },
+ { 0.00761553915934852, 0.000238680803770287 },
+ { 0.00748602525179653, 0.000234621671132778 },
+ { 0.00735917547602825, 0.000230646035815968 },
+ { 0.00723492567335711, 0.000226751887004003 },
+ { 0.00711321346683437, 0.000222937269722988 },
+ { 0.00699397820510569, 0.000219200283081375 },
+ { 0.00687716090824715, 0.000215539078572402 },
+ { 0.00676270421550374, 0.000211951858436143 },
+ { 0.00665055233485605, 0.000208436874078866 },
+ { 0.00654065099434482, 0.000204992424547482 },
+ { 0.00643294739508526, 0.000201616855056953 },
+ { 0.00632739016590651, 0.000198308555568634 },
+ { 0.00622392931955386, 0.000195065959417593 },
+ { 0.00612251621039432, 0.000191887541987052 },
+ { 0.00602310349356846, 0.00018877181942815 },
+ { 0.00592564508553371, 0.000185717347423321 },
+ { 0.00583009612594681, 0.000182722719991641 },
+ { 0.00573641294083507, 0.000179786568334568 },
+ { 0.00564455300700834, 0.000176907559720564 },
+ { 0.00555447491766526, 0.000174084396407155 },
+ { 0.00546613834914974, 0.000171315814599036 },
+ { 0.00537950402881485, 0.000168600583440879 },
+ { 0.00529453370395352, 0.000165937504043588 },
+ { 0.00521119011175673, 0.000163325408542745 },
+ { 0.00512943695026177, 0.000160763159188091 },
+ { 0.00504923885025431, 0.000158249647462906 },
+ { 0.00497056134808973, 0.000155783793232187 },
+ { 0.00489337085940047, 0.00015336454391861 },
+ { 0.0048176346536574, 0.000150990873705245 },
+ { 0.00474332082955456, 0.000148661782764082 },
+ { 0.00467039829118774, 0.000146376296509442 },
+ { 0.00459883672499868, 0.000144133464875374 },
+ { 0.00452860657745758, 0.0001419323616162 },
+ { 0.00445967903345784, 0.000139772083629371 },
+ { 0.00439202599539782, 0.000137651750299873 },
+ { 0.00432562006292552, 0.000135570502865389 },
+ { 0.0042604345133229, 0.000133527503801526 },
+ { 0.00419644328250756, 0.000131521936226379 },
+ { 0.00413362094663017, 0.000129553003323771 },
+ { 0.00407194270424716, 0.000127619927784523 },
+ { 0.00401138435904859, 0.000125721951265126 },
+ { 0.00395192230312223, 0.00012385833386321 },
+ { 0.00389353350073536, 0.000122028353609248 },
+ { 0.00383619547261662, 0.000120231305973929 },
+ { 0.00377988628072077, 0.000118466503390666 },
+ { 0.00372458451346011, 0.000116733274792729 },
+ { 0.00367026927138658, 0.000115030965164504 },
+ { 0.00361692015330938, 0.000113358935106399 },
+ { 0.00356451724283362, 0.000111716560412954 },
+ { 0.00351304109530554, 0.00011010323166368 },
+ { 0.00346247272515112, 0.00010851835382624 },
+ { 0.00341279359359459, 0.000106961345871528 },
+ { 0.00336398559674452, 0.000105431640400276 },
+ { 0.00331603105403517, 0.000103928683280785 },
+ { 0.00326891269701145, 0.000102451933297436 },
+ { 0.00322261365844611, 0.000101000861809609 },
+ { 0.00317711746177841, 9.9574952420671e-05 },
+ { 0.00313240801086364, 9.8173700656721e-05 },
+ { 0.0030884695800234, 9.67966136547482e-05 },
+ { 0.00304528680438698, 9.54432098599192e-05 },
+ { 0.00300284467051429, 9.41130187316882e-05 },
+ { 0.00296112850729126, 9.28055804584489e-05 },
+ { 0.00292012397708914, 9.15204456804534e-05 },
+ { 0.00287981706717899, 9.02571752207328e-05 },
+ { 0.0028401940813934, 8.90153398237637e-05 },
+ { 0.00280124163202747, 8.77945199016352e-05 },
+ { 0.00276294663197147, 8.65943052874766e-05 },
+ { 0.00272529628706795, 8.54142949959177e-05 },
+ { 0.00268827808868602, 8.42540969903592e-05 },
+ { 0.00265187980650613, 8.31133279568381e-05 },
+ { 0.00261608948150882, 8.1991613084284e-05 },
+ { 0.00258089541916074, 8.08885858509633e-05 },
+ { 0.00254628618279223, 7.98038878169218e-05 },
+ { 0.00251225058716016, 7.87371684222365e-05 },
+ { 0.00247877769219047, 7.76880847908989e-05 },
+ { 0.00244585679689484, 7.6656301540155e-05 },
+ { 0.00241347743345604, 7.56414905951341e-05 },
+ { 0.00238162936147699, 7.46433310086049e-05 },
+ { 0.00235030256238827, 7.36615087857006e-05 },
+ { 0.00231948723400942, 7.26957167134633e-05 },
+ { 0.00228917378525928, 7.17456541950598e-05 },
+ { 0.00225935283101098, 7.08110270885279e-05 },
+ { 0.00223001518708693, 6.98915475499161e-05 },
+ { 0.00220115186538994, 6.89869338806842e-05 },
+ { 0.00217275406916611, 6.80969103792372e-05 },
+ { 0.00214481318839565, 6.72212071964682e-05 },
+ { 0.00211732079530787, 6.63595601951913e-05 },
+ { 0.0020902686400165, 6.55117108133474e-05 },
+ { 0.0020636486462719, 6.46774059308727e-05 },
+ { 0.00203745290732659, 6.385639774012e-05 },
+ { 0.00201167368191087, 6.30484436197282e-05 },
+ { 0.00198630339031517, 6.22533060118395e-05 },
+ { 0.00196133461057614, 6.14707523025647e-05 },
+ { 0.00193676007476325, 6.07005547056026e-05 },
+ { 0.00191257266536322, 5.99424901489212e-05 },
+ { 0.00188876541175914, 5.91963401644111e-05 },
+ { 0.00186533148680185, 5.84618907804258e-05 },
+ { 0.0018422642034706, 5.77389324171247e-05 },
+ { 0.00181955701162071, 5.70272597845384e-05 },
+ { 0.00179720349481546, 5.63266717832776e-05 },
+ { 0.00177519736723997, 5.56369714078103e-05 },
+ { 0.00175353247069473, 5.49579656522334e-05 },
+ { 0.00173220277166633, 5.42894654184677e-05 },
+ { 0.00171120235847343, 5.36312854268074e-05 },
+ { 0.00169052543848568, 5.29832441287579e-05 },
+ { 0.00167016633541353, 5.23451636220957e-05 },
+ { 0.00165011948666707, 5.17168695680901e-05 },
+ { 0.00163037944078177, 5.10981911108226e-05 },
+ { 0.00161094085490937, 5.0488960798549e-05 },
+ { 0.00159179849237209, 4.98890145070441e-05 },
+ { 0.0015729472202783, 4.92981913648749e-05 },
+ { 0.00155438200719808, 4.87163336805491e-05 },
+ { 0.00153609792089693, 4.81432868714853e-05 },
+ { 0.00151809012612593, 4.75788993947567e-05 },
+ { 0.00150035388246704, 4.70230226795576e-05 },
+ { 0.00148288454223177, 4.64755110613457e-05 },
+ { 0.00146567754841189, 4.59362217176149e-05 },
+ { 0.00144872843268072, 4.54050146052539e-05 },
+ { 0.00143203281344369, 4.48817523994458e-05 },
+ { 0.00141558639393662, 4.43663004340691e-05 },
+ { 0.00139938496037074, 4.38585266435572e-05 },
+ { 0.00138342438012291, 4.33583015061792e-05 },
+ { 0.00136770059996992, 4.28654979887006e-05 },
+ { 0.00135220964436576, 4.23799914923901e-05 },
+ { 0.00133694761376057, 4.19016598003337e-05 },
+ { 0.00132191068296025, 4.14303830260224e-05 },
+ { 0.00130709509952559, 4.09660435631794e-05 },
+ { 0.00129249718220989, 4.05085260367932e-05 },
+ { 0.0012781133194341, 4.00577172553251e-05 },
+ { 0.00126393996779831, 3.96135061640598e-05 },
+ { 0.00124997365062891, 3.9175783799569e-05 },
+ { 0.00123621095656017, 3.87444432452578e-05 },
+ { 0.00122264853814957, 3.83193795879675e-05 },
+ { 0.0012092831105259, 3.79004898756041e-05 },
+ { 0.00119611145006925, 3.74876730757688e-05 },
+ { 0.00118313039312213, 3.70808300353618e-05 },
+ { 0.00117033683473081, 3.66798634411354e-05 },
+ { 0.00115772772741624, 3.62846777811718e-05 },
+ { 0.00114530007997364, 3.58951793072608e-05 },
+ { 0.00113305095630004, 3.55112759981554e-05 },
+ { 0.0011209774742492, 3.51328775236806e-05 },
+ { 0.001109076804513, 3.47598952096767e-05 },
+ { 0.00109734616952874, 3.43922420037521e-05 },
+ { 0.00108578284241168, 3.40298324418276e-05 },
+ { 0.00107438414591214, 3.36725826154507e-05 },
+ { 0.00106314745139656, 3.33204101398608e-05 },
+ { 0.00105207017785192, 3.29732341227861e-05 },
+ { 0.00104114979091287, 3.26309751339534e-05 },
+ { 0.0010303838019111, 3.2293555175293e-05 },
+ { 0.0010197697669463, 3.1960897651822e-05 },
+ { 0.00100930528597817, 3.16329273431872e-05 },
+ { 0.000998988001939045, 3.13095703758526e-05 },
+ { 0.000988815599866506, 3.09907541959151e-05 },
+ { 0.000978785806055534, 3.06764075425315e-05 },
+ { 0.000968896387229724, 3.03664604219435e-05 },
+ { 0.000959145149731077, 3.00608440820846e-05 },
+ { 0.000949529938727894, 2.97594909877547e-05 },
+ { 0.000940048637440358, 2.94623347963484e-05 },
+ { 0.000930699166383331, 2.91693103341238e-05 },
+ { 0.000921479482625972, 2.88803535729977e-05 },
+ { 0.000912387579067751, 2.85954016078549e-05 },
+ { 0.000903421483730461, 2.83143926343592e-05 },
+ { 0.000894579259065824, 2.80372659272524e-05 },
+ { 0.000885859001278342, 2.77639618191322e-05 },
+ { 0.000877258839662987, 2.74944216796941e-05 },
+ { 0.000868776935957397, 2.72285878954284e-05 },
+ { 0.000860411483708211, 2.69664038497609e-05 },
+ { 0.000852160707651214, 2.67078139036249e-05 },
+ { 0.00084402286310495, 2.64527633764569e-05 },
+ { 0.000835996235377483, 2.62011985276038e-05 },
+ { 0.000828079139185996, 2.59530665381319e-05 },
+ { 0.000820269918088911, 2.5708315493029e-05 },
+ { 0.000812566943930242, 2.54668943637901e-05 },
+ { 0.000804968616295881, 2.52287529913762e-05 },
+ { 0.000797473361981547, 2.49938420695392e-05 },
+ { 0.000790079634472097, 2.47621131285032e-05 },
+ { 0.000782785913431966, 2.45335185189939e-05 },
+ { 0.00077559070420644, 2.43080113966077e-05 },
+ { 0.000768492537333525, 2.40855457065136e-05 },
+ { 0.000761489968066167, 2.38660761684785e-05 },
+ { 0.00075458157590456, 2.36495582622094e-05 },
+ { 0.00074776596413834, 2.34359482130049e-05 },
+ { 0.000741041759398393, 2.32252029777084e-05 },
+ { 0.000734407611218095, 2.30172802309569e-05 },
+ { 0.000727862191603729, 2.28121383517175e-05 },
+ { 0.000721404194613896, 2.26097364101048e-05 },
+ { 0.000715032335947696, 2.2410034154475e-05 },
+ { 0.000708745352541474, 2.22129919987866e-05 },
+ { 0.000702542002173954, 2.20185710102252e-05 },
+ { 0.00069642106307954, 2.18267328970838e-05 },
+ { 0.000690381333569628, 2.16374399968941e-05 },
+ { 0.000684421631661716, 2.14506552648026e-05 },
+ { 0.000678540794716163, 2.12663422621856e-05 },
+ { 0.000672737679080397, 2.1084465145499e-05 },
+ { 0.000667011159740422, 2.09049886553553e-05 },
+ { 0.000661360129979451, 2.07278781058255e-05 },
+ { 0.000655783501043505, 2.05530993739577e-05 },
+ { 0.00065028020181382, 2.03806188895107e-05 },
+ { 0.00064484917848591, 2.02104036248949e-05 },
+ { 0.000639489394255141, 2.00424210853179e-05 },
+ { 0.000634199829008657, 1.98766392991293e-05 },
+ { 0.000628979479023536, 1.97130268083601e-05 },
+ { 0.000623827356671021, 1.95515526594535e-05 },
+ { 0.000618742490126692, 1.93921863941806e-05 },
+ { 0.000613723923086461, 1.92348980407398e-05 },
+ { 0.000608770714488245, 1.90796581050338e-05 },
+ { 0.000603881938239195, 1.892643756212e-05 },
+ { 0.000599056682948373, 1.8775207847833e-05 },
+ { 0.000594294051664734, 1.86259408505718e-05 },
+ { 0.000589593161620314, 1.84786089032519e-05 },
+ { 0.000584953143978502, 1.8333184775415e-05 },
+ { 0.00058037314358729, 1.8189641665496e-05 },
+ { 0.000575852318737385, 1.80479531932419e-05 },
+ { 0.000571389840925085, 1.79080933922796e-05 },
+ { 0.000566984894619811, 1.77700367028307e-05 },
+ { 0.000562636677036195, 1.76337579645681e-05 },
+ { 0.000558344397910626, 1.74992324096125e-05 },
+ { 0.000554107279282155, 1.73664356556661e-05 },
+ { 0.000549924555277676, 1.72353436992794e-05 },
+ { 0.000545795471901266, 1.71059329092494e-05 },
+ { 0.000541719286827633, 1.69781800201454e-05 },
+ { 0.000537695269199542, 1.68520621259607e-05 },
+ { 0.000533722699429167, 1.6727556673886e-05 },
+ { 0.000529800869003272, 1.66046414582044e-05 },
+ { 0.000525929080292131, 1.64832946143017e-05 },
+ { 0.000522106646362129, 1.63634946127941e-05 },
+ { 0.000518332890791946, 1.62452202537662e-05 },
+ { 0.000514607147492258, 1.61284506611209e-05 },
+ { 0.000510928760528883, 1.60131652770363e-05 },
+ { 0.000507297083949286, 1.58993438565282e-05 },
+ { 0.000503711481612393, 1.57869664621162e-05 },
+ { 0.000500171327021625, 1.56760134585908e-05 },
+ { 0.000496676003161098, 1.55664655078795e-05 },
+ { 0.000493224902334915, 1.54583035640105e-05 },
+ { 0.000489817426009489, 1.53515088681704e-05 },
+ { 0.000486452984658838, 1.52460629438558e-05 },
+ { 0.000483130997612775, 1.51419475921154e-05 },
+ { 0.000479850892907955, 1.50391448868813e-05 },
+ { 0.000476612107141704, 1.49376371703883e-05 },
+ { 0.000473414085328574, 1.48374070486777e-05 },
+ { 0.000470256280759579, 1.47384373871861e-05 },
+ { 0.00046713815486404, 1.46407113064147e-05 },
+ { 0.000464059177074002, 1.45442121776806e-05 },
+ { 0.000461018824691157, 1.44489236189459e-05 },
+ { 0.000458016582756232, 1.43548294907237e-05 },
+ { 0.000455051943920786, 1.42619138920607e-05 },
+ { 0.000452124408321363, 1.41701611565924e-05 },
+ { 0.000449233483455972, 1.40795558486721e-05 },
+ { 0.000446378684062815, 1.39900827595705e-05 },
+ { 0.000443559532001252, 1.3901726903744e-05 },
+ { 0.000440775556134931, 1.38144735151727e-05 },
+ { 0.000438026292217057, 1.37283080437642e-05 },
+ { 0.000435311282777744, 1.36432161518233e-05 },
+ { 0.000432630077013417, 1.35591837105854e-05 },
+ { 0.000429982230678222, 1.34761967968133e-05 },
+ { 0.000427367305977398, 1.33942416894556e-05 },
+ { 0.000424784871462578, 1.33133048663648e-05 },
+ { 0.000422234501928979, 1.32333730010754e-05 },
+ { 0.000419715778314438, 1.31544329596398e-05 },
+ { 0.000417228287600268, 1.30764717975203e-05 },
+ { 0.000414771622713892, 1.29994767565382e-05 },
+ { 0.000412345382433211, 1.29234352618764e-05 },
+ { 0.000409949171292692, 1.28483349191357e-05 },
+ { 0.000407582599491127, 1.27741635114443e-05 },
+ { 0.000405245282801027, 1.2700908996618e-05 },
+ { 0.000402936842479638, 1.26285595043711e-05 },
+ { 0.000400656905181522, 1.2557103333577e-05 },
+ { 0.000398405102872699, 1.24865289495766e-05 },
+ { 0.000396181072746295, 1.24168249815354e-05 },
+ { 0.000393984457139683, 1.23479802198462e-05 },
+ { 0.000391814903453081, 1.22799836135776e-05 },
+ { 0.000389672064069582, 1.22128242679683e-05 },
+ { 0.000387555596276584, 1.21464914419639e-05 },
+ { 0.0003854651621886, 1.20809745457982e-05 },
+ { 0.00038340042867141, 1.20162631386158e-05 },
+ { 0.000381361067267545, 1.19523469261366e-05 },
+ { 0.000379346754123059, 1.18892157583609e-05 },
+ { 0.000377357169915582, 1.18268596273145e-05 },
+ { 0.000375391999783619, 1.17652686648327e-05 },
+ { 0.000373450933257068, 1.17044331403827e-05 },
+ { 0.000371533664188946, 1.16443434589237e-05 },
+ { 0.000369639890688292, 1.15849901588044e-05 },
+ { 0.000367769315054221, 1.15263639096957e-05 },
+ { 0.00036592164371112, 1.14684555105598e-05 },
+ { 0.000364096587144948, 1.14112558876539e-05 },
+ { 0.000362293859840633, 1.13547560925679e-05 },
+ { 0.000360513180220536, 1.1298947300296e-05 },
+ { 0.000358754270583972, 1.12438208073413e-05 },
+ { 0.000357016857047753, 1.11893680298519e-05 },
+ { 0.000355300669487747, 1.11355805017896e-05 },
+ { 0.000353605441481433, 1.10824498731296e-05 },
+ { 0.000351930910251424, 1.10299679080902e-05 },
+ { 0.000350276816609946, 1.09781264833928e-05 },
+ { 0.000348642904904262, 1.09269175865515e-05 },
+ { 0.000347028922963007, 1.08763333141909e-05 },
+ { 0.000345434622043434, 1.0826365870393e-05 },
+ { 0.000343859756779542, 1.07770075650714e-05 },
+ { 0.000342304085131077, 1.07282508123729e-05 },
+ { 0.000340767368333383, 1.06800881291056e-05 },
+ { 0.0003392493708481, 1.06325121331942e-05 },
+ { 0.000337749860314675, 1.05855155421596e-05 },
+ { 0.000336268607502685, 1.05390911716252e-05 },
+ { 0.000334805386264957, 1.04932319338474e-05 },
+ { 0.00033335997349146, 1.04479308362705e-05 },
+ { 0.000331932149063961, 1.04031809801057e-05 },
+ { 0.000330521695811445, 1.03589755589337e-05 },
+ { 0.000329128399466246, 1.031530785733e-05 },
+ { 0.000327752048620931, 1.02721712495132e-05 },
+ { 0.000326392434685867, 1.02295591980159e-05 },
+ { 0.000325049351847507, 1.01874652523763e-05 },
+ { 0.000323722597027346, 1.01458830478526e-05 },
+ { 0.000322411969841556, 1.01048063041576e-05 },
+ { 0.000321117272561279, 1.00642288242143e-05 },
+ { 0.000319838310073571, 1.00241444929318e-05 },
+ { 0.000318574889842977, 9.98454727600101e-06 },
+ { 0.000317326821873739, 9.94543121871019e-06 },
+ { 0.000316093918672612, 9.90679044477957e-06 },
+ { 0.00031487599521228, 9.8686191552149e-06 },
+ { 0.000313672868895378, 9.83091162717957e-06 },
+ { 0.000312484359519081, 9.79366221288498e-06 },
+ { 0.000311310289240269, 9.75686533849879e-06 },
+ { 0.000310150482541258, 9.72051550307075e-06 },
+ { 0.000309004766196076, 9.68460727747586e-06 },
+ { 0.000307872969237287, 9.64913530337444e-06 },
+ { 0.000306754922923335, 9.61409429218892e-06 },
+ { 0.000305650460706426, 9.57947902409697e-06 },
+ { 0.000304559418200915, 9.54528434704075e-06 },
+ { 0.000303481633152193, 9.51150517575191e-06 },
+ { 0.000302416945406082, 9.47813649079224e-06 },
+ { 0.000301365196878701, 9.44517333760943e-06 },
+ { 0.000300326231526829, 9.41261082560791e-06 },
+ { 0.000299299895318719, 9.3804441272344e-06 },
+ { 0.000298286036205384, 9.34866847707793e-06 },
+ { 0.000297284504092342, 9.31727917098405e-06 },
+ { 0.00029629515081179, 9.28627156518308e-06 },
+ { 0.000295317830095233, 9.25564107543203e-06 },
+ { 0.000294352397546534, 9.22538317617001e-06 },
+ { 0.000293398710615389, 9.19549339968696e-06 },
+ { 0.000292456628571222, 9.16596733530536e-06 },
+ { 0.000291526012477477, 9.13680062857472e-06 },
+ { 0.00029060672516633, 9.10798898047873e-06 },
+ { 0.000289698631213778, 9.07952814665475e-06 },
+ { 0.000288801596915122, 9.0514139366254e-06 },
+ { 0.000287915490260838, 9.02364221304217e-06 },
+ { 0.000287040180912813, 8.99620889094078e-06 },
+ { 0.000286175540180955, 8.969109937008e-06 },
+ { 0.000285321441000161, 8.9423413688599e-06 },
+ { 0.000284477757907645, 8.91589925433124e-06 },
+ { 0.000283644367020616, 8.88977971077577e-06 },
+ { 0.000282821146014292, 8.86397890437735e-06 },
+ { 0.000282007974100266, 8.83849304947175e-06 },
+ { 0.000281204732005191, 8.81331840787865e-06 },
+ { 0.000280411301949796, 8.78845128824411e-06 },
+ { 0.000279627567628232, 8.76388804539298e-06 },
+ { 0.000278853414187717, 8.73962507969124e-06 },
+ { 0.000278088728208509, 8.71565883641806e-06 },
+ { 0.000277333397684169, 8.69198580514747e-06 },
+ { 0.000276587312002138, 8.66860251913942e-06 },
+ { 0.000275850361924599, 8.64550555474003e-06 },
+ { 0.000275122439569634, 8.62269153079109e-06 },
+ { 0.000274403438392663, 8.60015710804828e-06 },
+ { 0.000273693253168171, 8.57789898860844e-06 },
+ { 0.000272991779971702, 8.55591391534531e-06 },
+ { 0.00027229891616213, 8.53419867135382e-06 },
+ { 0.000271614560364196, 8.51275007940282e-06 },
+ { 0.000270938612451306, 8.49156500139591e-06 },
+ { 0.000270270973528589, 8.4706403378405e-06 },
+ { 0.000269611545916208, 8.44997302732471e-06 },
+ { 0.000268960233132921, 8.42956004600218e-06 },
+ { 0.000268316939879889, 8.40939840708456e-06 },
+ { 0.000267681572024721, 8.38948516034154e-06 },
+ { 0.000267054036585764, 8.36981739160835e-06 },
+ { 0.00026643424171662, 8.35039222230062e-06 },
+ { 0.000265822096690896, 8.33120680893638e-06 },
+ { 0.000265217511887183, 8.31225834266522e-06 },
+ { 0.00026462039877425, 8.29354404880439e-06 },
+ { 0.000264030669896463, 8.27506118638174e-06 },
+ { 0.000263448238859422, 8.25680704768544e-06 },
+ { 0.000262873020315798, 8.23877895782036e-06 },
+ { 0.000262304929951393, 8.22097427427094e-06 },
+ { 0.000261743884471393, 8.2033903864705e-06 },
+ { 0.000261189801586834, 8.18602471537687e-06 },
+ { 0.000260642600001254, 8.16887471305427e-06 },
+ { 0.000260102199397551, 8.1519378622613e-06 },
+ { 0.000259568520425027, 8.13521167604492e-06 },
+ { 0.000259041484686624, 8.1186936973404e-06 },
+ { 0.000258521014726347, 8.10238149857707e-06 },
+ { 0.000258007034016864, 8.08627268128983e-06 },
+ { 0.000257499466947295, 8.07036487573632e-06 },
+ { 0.00025699823881117, 8.05465574051958e-06 },
+ { 0.000256503275794569, 8.03914296221629e-06 },
+ { 0.000256014504964425, 8.02382425501026e-06 },
+ { 0.000255531854257008, 8.00869736033135e-06 },
+ { 0.000255055252466562, 7.99376004649949e-06 },
+ { 0.000254584629234115, 7.97901010837388e-06 },
+ { 0.000254119915036445, 7.96444536700726e-06 },
+ { 0.000253661041175211, 7.95006366930512e-06 },
+ { 0.00025320793976623, 7.93586288768977e-06 },
+ { 0.000252760543728917, 7.9218409197693e-06 },
+ { 0.000252318786775872, 7.90799568801124e-06 },
+ { 0.000251882603402616, 7.89432513942084e-06 },
+ { 0.000251451928877473, 7.88082724522403e-06 },
+ { 0.000251026699231597, 7.86750000055481e-06 },
+ { 0.000250606851249143, 7.85434142414719e-06 },
+ { 0.000250192322457572, 7.84134955803137e-06 },
+ { 0.000249783051118102, 7.82852246723438e-06 },
+ { 0.000249378976216284, 7.81585823948488e-06 },
+ { 0.000248980037452722, 7.80335498492211e-06 },
+ { 0.000248586175233917, 7.79101083580909e-06 },
+ { 0.000248197330663242, 7.77882394624965e-06 },
+ { 0.000247813445532044, 7.7667924919097e-06 },
+ { 0.000247434462310875, 7.75491466974223e-06 },
+ { 0.000247060324140839, 7.74318869771626e-06 },
+ { 0.000246690974825069, 7.73161281454955e-06 },
+ { 0.000246326358820315, 7.7201852794452e-06 },
+ { 0.000245966421228658, 7.70890437183165e-06 },
+ { 0.000245611107789332, 7.69776839110668e-06 },
+ { 0.000245260364870666, 7.68677565638466e-06 },
+ { 0.000244914139462137, 7.67592450624751e-06 },
+ { 0.000244572379166531, 7.66521329849911e-06 },
+ { 0.000244235032192219, 7.65464040992306e-06 },
+ { 0.00024390204734553, 7.64420423604383e-06 },
+ { 0.000243573374023243, 7.6339031908913e-06 },
+ { 0.000243248962205172, 7.62373570676844e-06 },
+ { 0.000242928762446859, 7.61370023402224e-06 },
+ { 0.000242612725872367, 7.60379524081794e-06 },
+ { 0.000242300804167173, 7.59401921291612e-06 },
+ { 0.000241992949571156, 7.58437065345312e-06 },
+ { 0.000241689114871685, 7.5748480827243e-06 },
+ { 0.000241389253396802, 7.56545003797038e-06 },
+ { 0.000241093319008495, 7.55617507316665e-06 },
+ { 0.000240801266096067, 7.54702175881514e-06 },
+ { 0.000240513049569594, 7.53798868173957e-06 },
+ { 0.000240228624853473, 7.52907444488312e-06 },
+ { 0.000239947947880057, 7.52027766710902e-06 },
+ { 0.000239670975083379, 7.51159698300375e-06 },
+ { 0.000239397663392959, 7.50303104268302e-06 },
+ { 0.0002391279702277, 7.49457851160037e-06 },
+ { 0.000238861853489856, 7.4862380703583e-06 },
+ { 0.000238599271559098, 7.47800841452205e-06 },
+ { 0.000238340183286646, 7.46988825443591e-06 },
+ { 0.00023808454798949, 7.46187631504191e-06 },
+ { 0.000237832325444681, 7.45397133570105e-06 },
+ { 0.000237583475883706, 7.44617207001697e-06 },
+ { 0.000237337959986938, 7.43847728566188e-06 },
+ { 0.000237095738878156, 7.43088576420496e-06 },
+ { 0.000236856774119144, 7.42339630094302e-06 },
+ { 0.000236621027704358, 7.41600770473338e-06 },
+ { 0.000236388462055669, 7.4087187978291e-06 },
+ { 0.000236159040017174, 7.40152841571632e-06 },
+ { 0.000235932724850077, 7.39443540695386e-06 },
+ { 0.000235709480227638, 7.3874386330149e-06 },
+ { 0.000235489270230188, 7.38053696813082e-06 },
+ { 0.000235272059340217, 7.37372929913705e-06 },
+ { 0.000235057812437519, 7.36701452532112e-06 },
+ { 0.000234846494794405, 7.36039155827256e-06 },
+ { 0.000234638072070982, 7.35385932173491e-06 },
+ { 0.000234432510310492, 7.34741675145965e-06 },
+ { 0.000234229775934714, 7.34106279506207e-06 },
+ { 0.000234029835739425, 7.33479641187909e-06 },
+ { 0.000233832656889924, 7.32861657282887e-06 },
+ { 0.000233638206916612, 7.32252226027239e-06 },
+ { 0.000233446453710633, 7.31651246787674e-06 },
+ { 0.000233257365519571, 7.31058620048032e-06 },
+ { 0.000233070910943204, 7.30474247395975e-06 },
+ { 0.000232887058929314, 7.29898031509851e-06 },
+ { 0.000232705778769551, 7.29329876145742e-06 },
+ { 0.000232527040095355, 7.28769686124665e-06 },
+ { 0.000232350812873926, 7.28217367319956e-06 },
+ { 0.000232177067404248, 7.27672826644812e-06 },
+ { 0.000232005774313171, 7.27135972039995e-06 },
+ { 0.000231836904551536, 7.26606712461701e-06 },
+ { 0.000231670429390354, 7.26084957869582e-06 },
+ { 0.000231506320417039, 7.25570619214929e-06 },
+ { 0.000231344549531681, 7.25063608429008e-06 },
+ { 0.000231185088943374, 7.24563838411543e-06 },
+ { 0.000231027911166592, 7.24071223019354e-06 },
+ { 0.000230872989017609, 7.23585677055142e-06 },
+ { 0.000230720295610964, 7.23107116256415e-06 },
+ { 0.00023056980435598, 7.22635457284561e-06 },
+ { 0.000230421488953316, 7.22170617714064e-06 },
+ { 0.000230275323391574, 7.21712516021853e-06 },
+ { 0.000230131281943947, 7.21261071576797e-06 },
+ { 0.000229989339164902, 7.20816204629325e-06 },
+ { 0.000229849469886921, 7.2037783630119e-06 },
+ { 0.00022971164921727, 7.19945888575361e-06 },
+ { 0.000229575852534817, 7.19520284286036e-06 },
+ { 0.000229442055486887, 7.19100947108804e-06 },
+ { 0.000229310233986165, 7.18687801550907e-06 },
+ { 0.000229180364207623, 7.18280772941651e-06 },
+ { 0.000229052422585508, 7.17879787422921e-06 },
+ { 0.000228926385810346, 7.17484771939831e-06 },
+ { 0.000228802230826003, 7.17095654231483e-06 },
+ { 0.000228679934826769, 7.16712362821851e-06 },
+ { 0.000228559475254493, 7.16334827010778e-06 },
+ { 0.000228440829795738, 7.15962976865087e-06 },
+ { 0.000228323976378991, 7.15596743209809e-06 },
+ { 0.000228208893171893, 7.15236057619517e-06 },
+ { 0.000228095558578508, 7.14880852409773e-06 },
+ { 0.000227983951236635, 7.14531060628687e-06 },
+ { 0.000227874050015145, 7.14186616048574e-06 },
+ { 0.000227765834011349, 7.13847453157724e-06 },
+ { 0.000227659282548415, 7.13513507152274e-06 },
+ { 0.000227554375172797, 7.13184713928183e-06 },
+ { 0.000227451091651713, 7.12861010073307e-06 },
+ { 0.000227349411970649, 7.12542332859577e-06 },
+ { 0.000227249316330887, 7.12228620235266e-06 },
+ { 0.000227150785147081, 7.11919810817373e-06 },
+ { 0.000227053799044843, 7.11615843884078e-06 },
+ { 0.00022695833885838, 7.11316659367312e-06 },
+ { 0.000226864385628144, 7.1102219784541e-06 },
+ { 0.000226771920598518, 7.10732400535858e-06 },
+ { 0.000226680925215536, 7.10447209288133e-06 },
+ { 0.000226591381124622, 7.10166566576629e-06 },
+ { 0.000226503270168361, 7.09890415493677e-06 },
+ { 0.000226416574384305, 7.09618699742645e-06 },
+ { 0.000226331276002794, 7.09351363631131e-06 },
+ { 0.000226247357444811, 7.09088352064235e-06 },
+ { 0.000226164801319867, 7.08829610537922e-06 },
+ { 0.000226083590423903, 7.08575085132458e-06 },
+ { 0.000226003707737228, 7.08324722505939e-06 },
+ { 0.000225925136422475, 7.08078469887889e-06 },
+ { 0.000225847859822588, 7.07836275072949e-06 },
+ { 0.000225771861458829, 7.07598086414632e-06 },
+ { 0.000225697125028814, 7.07363852819168e-06 },
+ { 0.00022562363440457, 7.07133523739415e-06 },
+ { 0.000225551373630622, 7.06907049168853e-06 },
+ { 0.000225480326922091, 7.06684379635645e-06 },
+ { 0.000225410478662832, 7.06465466196781e-06 },
+ { 0.000225341813403584, 7.06250260432282e-06 },
+ { 0.000225274315860142, 7.0603871443949e-06 },
+ { 0.000225207970911563, 7.05830780827414e-06 },
+ { 0.000225142763598378, 7.05626412711159e-06 },
+ { 0.000225078679120841, 7.0542556370641e-06 },
+ { 0.000225015702837188, 7.05228187923999e-06 },
+ { 0.000224953820261928, 7.05034239964525e-06 },
+ { 0.000224893017064143, 7.0484367491305e-06 },
+ { 0.00022483327906582, 7.04656448333854e-06 },
+ { 0.000224774592240197, 7.04472516265258e-06 },
+ { 0.00022471694271013, 7.0429183521451e-06 },
+ { 0.000224660316746486, 7.04114362152733e-06 },
+ { 0.000224604700766543, 7.03940054509932e-06 },
+ { 0.000224550081332424, 7.0376887017007e-06 },
+ { 0.000224496445149543, 7.03600767466198e-06 },
+ { 0.000224443779065066, 7.03435705175644e-06 },
+ { 0.000224392070066399, 7.03273642515265e-06 },
+ { 0.000224341305279693, 7.03114539136756e-06 },
+ { 0.00022429147196836, 7.02958355122011e-06 },
+ { 0.000224242557531616, 7.02805050978552e-06 },
+ { 0.000224194549503038, 7.02654587635001e-06 },
+ { 0.000224147435549135, 7.02506926436614e-06 },
+ { 0.000224101203467946, 7.02362029140872e-06 },
+ { 0.000224055841187646, 7.02219857913119e-06 },
+ { 0.000224011336765172, 7.02080375322257e-06 },
+ { 0.000223967678384865, 7.01943544336494e-06 },
+ { 0.000223924854357133, 7.01809328319141e-06 },
+ { 0.000223882853117125, 7.01677691024464e-06 },
+ { 0.000223841663223422, 7.01548596593582e-06 },
+ { 0.000223801273356745, 7.01422009550419e-06 },
+ { 0.000223761672318679, 7.01297894797702e-06 },
+ { 0.000223722849030413, 7.0117621761301e-06 },
+ { 0.000223684792531494, 7.01056943644869e-06 },
+ { 0.000223647491978595, 7.00940038908897e-06 },
+ { 0.000223610936644299, 7.00825469783991e-06 },
+ { 0.000223575115915903, 7.00713203008568e-06 },
+ { 0.000223540019294225, 7.00603205676844e-06 },
+ { 0.000223505636392438, 7.00495445235162e-06 },
+ { 0.000223471956934907, 7.00389889478363e-06 },
+ { 0.000223438970756052, 7.00286506546206e-06 },
+ { 0.000223406667799211, 7.0018526491982e-06 },
+ { 0.000223375038115529, 7.00086133418212e-06 },
+ { 0.000223344071862854, 6.99989081194811e-06 },
+ { 0.000223313759304649, 6.99894077734052e-06 },
+ { 0.000223284090808912, 6.99801092848006e-06 },
+ { 0.000223255056847118, 6.99710096673047e-06 },
+ { 0.000223226647993168, 6.99621059666565e-06 },
+ { 0.000223198854922349, 6.99533952603709e-06 },
+ { 0.000223171668410312, 6.99448746574181e-06 },
+ { 0.000223145079332057, 6.9936541297906e-06 },
+ { 0.000223119078660938, 6.9928392352767e-06 },
+ { 0.000223093657467669, 6.99204250234482e-06 },
+ { 0.000223068806919352, 6.99126365416057e-06 },
+ { 0.000223044518278512, 6.99050241688022e-06 },
+ { 0.000223020782902146, 6.98975851962088e-06 },
+ { 0.000222997592240777, 6.98903169443101e-06 },
+ { 0.000222974937837531, 6.98832167626126e-06 },
+ { 0.000222952811327217, 6.98762820293573e-06 },
+ { 0.000222931204435415, 6.98695101512352e-06 },
+ { 0.00022291010897759, 6.98628985631068e-06 },
+ { 0.000222889516858196, 6.98564447277244e-06 },
+ { 0.000222869420069809, 6.98501461354579e-06 },
+ { 0.000222849810692261, 6.98440003040248e-06 },
+ { 0.000222830680891787, 6.98380047782221e-06 },
+ { 0.000222812022920181, 6.98321571296625e-06 },
+ { 0.000222793829113966, 6.98264549565134e-06 },
+ { 0.000222776091893569, 6.9820895883239e-06 },
+ { 0.000222758803762509, 6.98154775603461e-06 },
+ { 0.000222741957306598, 6.9810197664132e-06 },
+ { 0.000222725545193143, 6.98050538964365e-06 },
+ { 0.000222709560170165, 6.98000439843966e-06 },
+ { 0.000222693995065629, 6.97951656802032e-06 },
+ { 0.000222678842786674, 6.97904167608631e-06 },
+ { 0.000222664096318863, 6.97857950279612e-06 },
+ { 0.000222649748725436, 6.97812983074274e-06 },
+ { 0.000222635793146573, 6.97769244493061e-06 },
+ { 0.000222622222798669, 6.97726713275278e-06 },
+ { 0.000222609030973612, 6.97685368396842e-06 },
+ { 0.000222596211038079, 6.97645189068058e-06 },
+ { 0.000222583756432828, 6.97606154731424e-06 },
+ { 0.000222571660672013, 6.97568245059462e-06 },
+ { 0.000222559917342496, 6.97531439952571e-06 },
+ { 0.000222548520103175, 6.97495719536918e-06 },
+ { 0.000222537462684313, 6.97461064162342e-06 },
+ { 0.000222526738886884, 6.97427454400296e-06 },
+ { 0.000222516342581918, 6.97394871041804e-06 },
+ { 0.000222506267709865, 6.97363295095449e-06 },
+ { 0.000222496508279953, 6.97332707785385e-06 },
+ { 0.000222487058369568, 6.97303090549378e-06 },
+ { 0.000222477912123634, 6.97274425036857e-06 },
+ { 0.000222469063753997, 6.97246693107012e-06 },
+ { 0.000222460507538829, 6.97219876826893e-06 },
+ { 0.000222452237822028, 6.97193958469549e-06 },
+ { 0.000222444249012631, 6.97168920512181e-06 },
+ { 0.000222436535584233, 6.97144745634325e-06 },
+ { 0.000222429092074413, 6.97121416716051e-06 },
+ { 0.00022242191308417, 6.97098916836191e-06 },
+ { 0.000222414993277359, 6.97077229270584e-06 },
+ { 0.000222408327380145, 6.97056337490348e-06 },
+ { 0.000222401910180452, 6.9703622516017e-06 },
+ { 0.000222395736527431, 6.97016876136623e-06 },
+ { 0.000222389801330924, 6.96998274466495e-06 },
+ { 0.000222384099560941, 6.96980404385152e-06 },
+ { 0.000222378626247142, 6.96963250314908e-06 },
+ { 0.000222373376478328, 6.96946796863433e-06 },
+ { 0.000222368345401933, 6.96931028822161e-06 },
+ { 0.000222363528223529, 6.96915931164736e-06 },
+ { 0.000222358920206333, 6.96901489045469e-06 },
+ { 0.000222354516670721, 6.96887687797819e-06 },
+ { 0.000222350312993751, 6.96874512932889e-06 },
+ { 0.000222346304608691, 6.9686195013795e-06 },
+ { 0.000222342487004547, 6.96849985274972e-06 },
+ { 0.000222338855725611, 6.96838604379187e-06 },
+ { 0.000222335406371001, 6.96827793657665e-06 },
+ { 0.000222332134594212, 6.96817539487904e-06 },
+ { 0.00022232903610268, 6.9680782841645e-06 },
+ { 0.000222326106657339, 6.96798647157525e-06 },
+ { 0.000222323342072192, 6.96789982591681e-06 },
+ { 0.00022232073821389, 6.96781821764464e-06 },
+ { 0.000222318291001307, 6.96774151885102e-06 },
+ { 0.000222315996405131, 6.96766960325212e-06 },
+ { 0.000222313850447455, 6.9676023461752e-06 },
+ { 0.000222311849201372, 6.96753962454597e-06 },
+ { 0.000222309988790583, 6.96748131687619e-06 },
+ { 0.000222308265389002, 6.96742730325142e-06 },
+ { 0.00022230667522037, 6.96737746531884e-06 },
+ { 0.000222305214557877, 6.96733168627542e-06 },
+ { 0.000222303879723785, 6.96728985085609e-06 },
+ { 0.000222302667089056, 6.96725184532218e-06 },
+ { 0.00022230157307299, 6.96721755744993e-06 },
+ { 0.000222300594142867, 6.96718687651929e-06 },
+ { 0.000222299726813584, 6.96715969330272e-06 },
+ { 0.000222298967647317, 6.96713590005431e-06 },
+ { 0.000222298313253165, 6.96711539049893e-06 },
+ { 0.000222297760286819, 6.96709805982159e-06 },
+ { 0.000222297305450222, 6.96708380465697e-06 },
+ { 0.000222296945491244, 6.96707252307908e-06 },
+ { 0.000222296677203351, 6.96706411459103e-06 },
+ { 0.000222296497425289, 6.96705848011506e-06 },
+ { 0.000222296403040767, 6.96705552198261e-06 },
+ { 0.000222296390978148, 6.96705514392459e-06 },
+ { 0.00022229645821014, 6.9670572510618e-06 },
+ { 0.000222296601753497, 6.96706174989544e-06 },
+ { 0.00022229681866872, 6.96706854829785e-06 },
+ { 0.000222297106059767, 6.96707755550335e-06 },
+ { 0.000222297461073765, 6.96708868209918e-06 },
+ { 0.000222297880900723, 6.96710184001666e-06 },
+ { 0.000222298362773258, 6.96711694252242e-06 },
+ { 0.000222298903966318, 6.96713390420982e-06 },
+ { 0.000222299501796913, 6.96715264099048e-06 },
+ { 0.000222300153623846, 6.96717307008593e-06 },
+ { 0.000222300856847458, 6.96719511001945e-06 },
+ { 0.000222301608909363, 6.96721868060799e-06 },
+ { 0.000222302407292202, 6.96724370295423e-06 },
+ { 0.000222303249519389, 6.96727009943883e-06 },
+ { 0.000222304133154872, 6.9672977937127e-06 },
+ { 0.000222305055802884, 6.96732671068952e-06 },
+ { 0.000222306015107718, 6.96735677653831e-06 },
+ { 0.000222307008753485, 6.96738791867615e-06 },
+ { 0.00022230803446389, 6.96742006576105e-06 },
+ { 0.000222309090002009, 6.96745314768489e-06 },
+ { 0.000222310173170065, 6.96748709556656e-06 },
+ { 0.000222311281809216, 6.96752184174516e-06 },
+ { 0.000222312413799341, 6.96755731977334e-06 },
+ { 0.000222313567058831, 6.9675934644108e-06 },
+ { 0.000222314739544384, 6.96763021161786e-06 },
+ { 0.000222315929250809, 6.9676674985492e-06 },
+ { 0.000222317134210823, 6.96770526354765e-06 },
+ { 0.000222318352494862, 6.96774344613821e-06 },
+ { 0.00022231958221089, 6.96778198702204e-06 },
+ { 0.000222320821504217, 6.96782082807073e-06 },
+ { 0.000222322068557312, 6.96785991232055e-06 },
+ { 0.00022232332158963, 6.96789918396693e-06 },
+ { 0.000222324578857435, 6.96793858835893e-06 },
+ { 0.000222325838653631, 6.96797807199396e-06 },
+ { 0.000222327099307595, 6.96801758251253e-06 },
+ { 0.000222328359185012, 6.96805706869312e-06 },
+ { 0.000222329616687717, 6.96809648044717e-06 },
+ { 0.000222330870253539, 6.96813576881426e-06 },
+ { 0.000222332118356149, 6.96817488595722e-06 },
+ { 0.000222333359504908, 6.96821378515757e-06 },
+ { 0.000222334592244728, 6.9682524208109e-06 },
+ { 0.000222335815155921, 6.96829074842245e-06 },
+ { 0.000222337026854071, 6.96832872460277e-06 },
+ { 0.000222338225989891, 6.96836630706349e-06 },
+ { 0.000222339411249095, 6.96840345461321e-06 },
+ { 0.000222340581352271, 6.96844012715348e-06 },
+ { 0.000222341735054754, 6.9684762856749e-06 },
+ { 0.000222342871146506, 6.96851189225336e-06 },
+ { 0.000222343988452, 6.96854691004629e-06 },
+ { 0.000222345085830103, 6.96858130328914e-06 },
+ { 0.000222346162173967, 6.96861503729185e-06 },
+ { 0.000222347216410921, 6.96864807843553e-06 },
+ { 0.000222348247502366, 6.96868039416915e-06 },
+ { 0.000222349254443676, 6.96871195300643e-06 },
+ { 0.000222350236264097, 6.96874272452272e-06 },
+ { 0.000222351192026658, 6.96877267935211e-06 },
+ { 0.000222352120828075, 6.96880178918454e-06 },
+ { 0.000222353021798667, 6.96883002676308e-06 },
+ { 0.00022235389410227, 6.96885736588125e-06 },
+ { 0.000222354736936155, 6.96888378138053e-06 },
+ { 0.000222355549530953, 6.96890924914787e-06 },
+ { 0.000222356331150578, 6.96893374611341e-06 },
+ { 0.000222357081092156, 6.96895725024817e-06 },
+ { 0.000222357798685959, 6.968979740562e-06 },
+ { 0.000222358483295338, 6.96900119710148e-06 },
+ { 0.000222359134316659, 6.96902160094803e-06 },
+ { 0.000222359751179253, 6.96904093421604e-06 },
+ { 0.00022236033334535, 6.96905918005118e-06 },
+ { 0.000222360880310035, 6.96907632262873e-06 },
+ { 0.000222361391601196, 6.9690923471521e-06 },
+ { 0.000222361866779477, 6.96910723985132e-06 },
+ { 0.00022236230543824, 6.9691209879818e-06 },
+ { 0.000222362707203519, 6.96913357982301e-06 },
+ { 0.000222363071733991, 6.96914500467741e-06 },
+ { 0.000222363398720938, 6.96915525286938e-06 },
+ { 0.000222363687888218, 6.9691643157443e-06 },
+ { 0.000222363938992241, 6.96917218566772e-06 },
+ { 0.000222364151821941, 6.96917885602458e-06 },
+ { 0.00022236432619876, 6.96918432121863e-06 },
+ { 0.000222364461976628, 6.96918857667186e-06 },
+ { 0.000222364559041949, 6.96919161882402e-06 },
+ { 0.000222364617313593, 6.96919344513236e-06 },
+ { 0.000222364636742882, 6.96919405407131e-06 }
+};
+
+static const double cumulative[][2] = { /* Expected-value Standard-error */
+ { 0, 0 },
+ { 0.000864844260437307, 3.2341771480318e-07 },
+ { 0.00344930442295799, 1.28922086184407e-06 },
+ { 0.00772342489639333, 2.88440311042538e-06 },
+ { 0.0136381440658139, 5.08839733657585e-06 },
+ { 0.0211265568432882, 7.87462036133179e-06 },
+ { 0.030105615859244, 1.12124077014868e-05 },
+ { 0.0404782086271475, 1.50691397344185e-05 },
+ { 0.0521355351853953, 1.94123434019322e-05 },
+ { 0.064959701316185, 2.42115614276198e-05 },
+ { 0.0788264368270804, 2.94398141358595e-05 },
+ { 0.0936078467237508, 3.50745339582566e-05 },
+ { 0.109175105365968, 4.10979224905411e-05 },
+ { 0.125401009650726, 4.74967542955343e-05 },
+ { 0.142162316497224, 5.42617187953981e-05 },
+ { 0.159341801859359, 6.13864407185916e-05 },
+ { 0.176829992489236, 6.88663433171346e-05 },
+ { 0.194526536975521, 7.66975149621118e-05 },
+ { 0.212341198407353, 8.4875712520328e-05 },
+ { 0.230194466607499, 9.33955923107457e-05 },
+ { 0.24801780252962, 0.000102250211571378 },
+ { 0.265753540505306, 0.000111430799564632 },
+ { 0.283354485055534, 0.000120926764190608 },
+ { 0.300783247582665, 0.000130725880067631 },
+ { 0.318011374214993, 0.000140814596964091 },
+ { 0.335018319317342, 0.000151178410498962 },
+ { 0.351790319779196, 0.000161802246533291 },
+ { 0.368319223346885, 0.000172670823165794 },
+ { 0.384601320283121, 0.00018376896701735 },
+ { 0.400636221901663, 0.000195081871806809 },
+ { 0.416425822478427, 0.000206595296209532 },
+ { 0.431973373145809, 0.000218295704393061 },
+ { 0.447282688098255, 0.000230170356552949 },
+ { 0.462357495207975, 0.000242207358540825 },
+ { 0.477200935359891, 0.000254395679712666 },
+ { 0.491815207784957, 0.000266725146938042 },
+ { 0.506201352653573, 0.000279186420862364 },
+ { 0.520359157352388, 0.000291770958567995 },
+ { 0.534287169299197, 0.000304470965219102 },
+ { 0.547982795865094, 0.000317279336409391 },
+ { 0.56144247091594, 0.000330189592836309 },
+ { 0.574661867547176, 0.000343195809435291 },
+ { 0.587636137613502, 0.000356292541885506 },
+ { 0.600360160462158, 0.000369474754049006 },
+ { 0.612828785672205, 0.000382737750106708 },
+ { 0.625037057372635, 0.000396077114756507 },
+ { 0.63698041067509, 0.000409488663894224 },
+ { 0.648654833727208, 0.000422968406925844 },
+ { 0.660056991728365, 0.000436512520552392 },
+ { 0.67118431182307, 0.00045011733278923 },
+ { 0.682035030008706, 0.000463779315283788 },
+ { 0.692608203010149, 0.000477495081697928 },
+ { 0.702903689447356, 0.00049126138993707 },
+ { 0.712922105558505, 0.000505075146206906 },
+ { 0.722664761256772, 0.000518933409153025 },
+ { 0.732133582433861, 0.000532833392642378 },
+ { 0.741331025230595, 0.000546772466092471 },
+ { 0.750259987532168, 0.000560748151683091 },
+ { 0.75892372228239, 0.000574758118312188 },
+ { 0.767325756405806, 0.000588800172740126 },
+ { 0.77546981824811, 0.000602872248904067 },
+ { 0.783359775543789, 0.000616972396742587 },
+ { 0.790999585049822, 0.000631098771943508 },
+ { 0.798393254182973, 0.000645249627770496 },
+ { 0.805544814298637, 0.000659423309594575 },
+ { 0.812458304673771, 0.000673618252086996 },
+ { 0.819137765816567, 0.000687832978404178 },
+ { 0.825587240428692, 0.00070206610027095 },
+ { 0.831810780184676, 0.000716316317748075 },
+ { 0.837812456461413, 0.000730582417656064 },
+ { 0.843596373230034, 0.000744863270040965 },
+ { 0.849166680493882, 0.000759157822573074 },
+ { 0.85452758689938, 0.000773465093222372 },
+ { 0.859683370431826, 0.000787784161846291 },
+ { 0.864638386419449, 0.000802114161410069 },
+ { 0.869397072377219, 0.00081645426946008 },
+ { 0.873963949511423, 0.000830803700256753 },
+ { 0.878343620960373, 0.000845161697746157 },
+ { 0.882540767052266, 0.000859527529385224 },
+ { 0.88656013801421, 0.000873900480786482 },
+ { 0.890406544662638, 0.000888279851206406 },
+ { 0.894084847647596, 0.000902664950019421 },
+ { 0.8975999458178, 0.000917055094424582 },
+ { 0.900956764229264, 0.000931449608650079 },
+ { 0.904160242246884, 0.000945847824815999 },
+ { 0.907215322098614, 0.000960249085393435 },
+ { 0.910126938145628, 0.000974652746914947 },
+ { 0.912900007038343, 0.000989058184337327 },
+ { 0.91553941884556, 0.00100346479531913 },
+ { 0.918050029175696, 0.00101787200371079 },
+ { 0.920436652259082, 0.00103227926176418 },
+ { 0.922704054924983, 0.00104668605089567 },
+ { 0.924856951387888, 0.00106109188118045 },
+ { 0.926899998747835, 0.00107549629001193 },
+ { 0.928837793104644, 0.0010898988404525 },
+ { 0.930674866185846, 0.00110429911971198 },
+ { 0.932415682382857, 0.00111869673796555 },
+ { 0.934064636084289, 0.00113309132745234 },
+ { 0.935626049185173, 0.00114748254158513 },
+ { 0.937104168637491, 0.00116187005372508 },
+ { 0.938503163898304, 0.00117625355535994 },
+ { 0.939827124123015, 0.00119063275363397 },
+ { 0.941080054954988, 0.00120500736843739 },
+ { 0.942265874777131, 0.00121937712948441 },
+ { 0.943388410319858, 0.00123374177391474 },
+ { 0.944451391565877, 0.00124810104491599 },
+ { 0.945458445950797, 0.00126245469169204 },
+ { 0.946413091930008, 0.00127680247084348 },
+ { 0.947318732058611, 0.00129114414894445 },
+ { 0.948178645806433, 0.00130547950586069 },
+ { 0.94899598239924, 0.00131980833819983 },
+ { 0.9497737540286, 0.00133413046224784 },
+ { 0.950514829803614, 0.0013484457158288 },
+ { 0.951221930820914, 0.00136275395871461 },
+ { 0.95189762670444, 0.00137705507147841 },
+ { 0.952544333909601, 0.00139134895298305 },
+ { 0.953164316006814, 0.00140563551696505 },
+ { 0.953759686055019, 0.00141991468835756 },
+ { 0.954332411060469, 0.001434186400043 },
+ { 0.954884318395864, 0.00144845059061537 },
+ { 0.955417103938939, 0.00146270720348639 },
+ { 0.955932341589961, 0.00147695618733997 },
+ { 0.956431493748457, 0.00149119749761648 },
+ { 0.956915922280999, 0.00150543109847399 },
+ { 0.957386899494419, 0.00151965696459107 },
+ { 0.957845618645373, 0.00153387508226248 },
+ { 0.958293203564012, 0.00154808544945412 },
+ { 0.95873071704446, 0.00156228807476128 },
+ { 0.959159167748055, 0.00157648297545728 },
+ { 0.959579515472819, 0.00159067017496462 },
+ { 0.95999267475144, 0.00160484970009607 },
+ { 0.96039951684733, 0.00161902157831515 },
+ { 0.960800870309794, 0.00163318583511642 },
+ { 0.961197520325387, 0.00164734249149334 },
+ { 0.961590207155522, 0.0016614915614119 },
+ { 0.961979623978106, 0.00167563304925737 },
+ { 0.962366414455474, 0.00168976694735972 },
+ { 0.962751170331964, 0.0017038932338655 },
+ { 0.963134429327794, 0.00171801187134215 },
+ { 0.963516673542005, 0.00173212280651286 },
+ { 0.963898328518127, 0.00174622597139297 },
+ { 0.964279763058726, 0.00176032128585476 },
+ { 0.964661289811319, 0.00177440866134504 },
+ { 0.965043166589692, 0.00178848800520305 },
+ { 0.965425598343577, 0.00180255922486943 },
+ { 0.96580873965189, 0.00181662223129111 },
+ { 0.966192697589875, 0.00183067694102797 },
+ { 0.966577534807986, 0.00184472327690428 },
+ { 0.966963272662575, 0.00185876116742914 },
+ { 0.967349894252373, 0.00187279054552704 },
+ { 0.967737347237796, 0.00188681134727247 },
+ { 0.968125546352698, 0.0019008235112651 },
+ { 0.96851437555474, 0.00191482697903286 },
+ { 0.968903689799959, 0.00192882169648674 },
+ { 0.969293316467073, 0.0019428076160933 },
+ { 0.969683056490542, 0.00195678469919398 },
+ { 0.970072685294235, 0.00197075291785552 },
+ { 0.97046195363683, 0.00198471225579347 },
+ { 0.970850588493419, 0.00199866270820161 },
+ { 0.971238294099558, 0.00201260428063239 },
+ { 0.971624753273908, 0.00202653698729763 },
+ { 0.972009629116019, 0.00204046084921118 },
+ { 0.972392567148178, 0.00205437589247977 },
+ { 0.972773197934457, 0.00206828214682375 },
+ { 0.973151140171804, 0.00208217964419359 },
+ { 0.973526004209467, 0.00209606841724322 },
+ { 0.973897395918181, 0.00210994849749593 },
+ { 0.974264920800317, 0.00212381991326614 },
+ { 0.974628188214181, 0.00213768268769865 },
+ { 0.974986815577298, 0.00215153683750943 },
+ { 0.975340432417114, 0.00216538237304278 },
+ { 0.975688684153943, 0.00217921930003463 },
+ { 0.976031235527663, 0.00219304762302002 },
+ { 0.976367773611921, 0.00220686734977916 },
+ { 0.976698010398196, 0.00222067849575036 },
+ { 0.977021684966998, 0.00223448108713146 },
+ { 0.977338565297302, 0.0022482751615428 },
+ { 0.977648449785131, 0.00226206076563903 },
+ { 0.976959698305536, 0.000719254180160381 },
+ { 0.977271116580268, 0.000729014429903263 },
+ { 0.977576967188632, 0.000738600181812663 },
+ { 0.977877374606276, 0.000748015337115725 },
+ { 0.978172459910358, 0.00075726369052647 },
+ { 0.978462340889919, 0.000766348933705155 },
+ { 0.978747132152104, 0.000775274658587222 },
+ { 0.979026945224402, 0.000784044360587866 },
+ { 0.979301888653079, 0.000792661441686746 },
+ { 0.979572068097951, 0.000801129213398638 },
+ { 0.979837586423683, 0.000809450899634553 },
+ { 0.980098543787712, 0.000817629639457557 },
+ { 0.980355037724988, 0.000825668489738588 },
+ { 0.980607163229618, 0.000833570427715265 },
+ { 0.980855012833574, 0.000841338353458721 },
+ { 0.981098676682566, 0.000848975092251657 },
+ { 0.981338242609211, 0.00085648339688133 },
+ { 0.981573796203589, 0.000863865949851062 },
+ { 0.98180542088131, 0.00087112536551353 },
+ { 0.982033197949185, 0.000878264192128858 },
+ { 0.982257206668591, 0.000885284913850685 },
+ { 0.982477524316635, 0.000892189952643032 },
+ { 0.982694226245188, 0.000898981670130554 },
+ { 0.982907385937888, 0.000905662369385131 },
+ { 0.983117075065182, 0.000912234296650864 },
+ { 0.983323363537495, 0.000918699643010445 },
+ { 0.983526319556571, 0.000925060545994409 },
+ { 0.983726009665104, 0.000931319091136429 },
+ { 0.983922498794673, 0.000937477313475817 },
+ { 0.984115850312084, 0.000943537199009889 },
+ { 0.984306126064161, 0.000949500686097735 },
+ { 0.984493386421052, 0.000955369666817512 },
+ { 0.984677690318101, 0.000961145988278837 },
+ { 0.984859095296345, 0.000966831453891858 },
+ { 0.985037657541685, 0.000972427824595134 },
+ { 0.985213431922783, 0.000977936820043089 },
+ { 0.985386472027721, 0.000983360119755297 },
+ { 0.985556830199487, 0.000988699364228364 },
+ { 0.985724557570317, 0.000993956156012382 },
+ { 0.98588970409493, 0.000999132060752665 },
+ { 0.986052318582724, 0.0010042286081985 },
+ { 0.986212448728929, 0.00100924729317987 },
+ { 0.986370141144792, 0.00101418957655327 },
+ { 0.986525441386809, 0.00101905688611793 },
+ { 0.986678393985039, 0.00102385061750325 },
+ { 0.986829042470546, 0.00102857213502882 },
+ { 0.986977429401977, 0.00103322277253745 },
+ { 0.987123596391332, 0.00103780383420282 },
+ { 0.987267584128935, 0.00104231659531205 },
+ { 0.987409432407642, 0.00104676230302451 },
+ { 0.987549180146316, 0.00105114217710745 },
+ { 0.987686865412579, 0.00105545741064923 },
+ { 0.987822525444893, 0.00105970917075113 },
+ { 0.987956196673962, 0.00106389859919834 },
+ { 0.9880879147435, 0.00106802681311081 },
+ { 0.988217714530384, 0.0010720949055747 },
+ { 0.988345630164196, 0.00107610394625509 },
+ { 0.988471695046199, 0.00108005498199061 },
+ { 0.988595941867753, 0.00108394903737053 },
+ { 0.988718402628182, 0.00108778711529487 },
+ { 0.98883910865213, 0.00109157019751832 },
+ { 0.988958090606404, 0.00109529924517815 },
+ { 0.989075378516341, 0.00109897519930698 },
+ { 0.989191001781683, 0.00110259898133069 },
+ { 0.989304989192021, 0.00110617149355206 },
+ { 0.989417368941773, 0.00110969361962051 },
+ { 0.989528168644758, 0.00111316622498862 },
+ { 0.989637415348332, 0.00111659015735544 },
+ { 0.989745135547152, 0.00111996624709756 },
+ { 0.989851355196528, 0.00112329530768784 },
+ { 0.989956099725412, 0.00112657813610242 },
+ { 0.99005939404903, 0.00112981551321654 },
+ { 0.99016126258115, 0.0011330082041891 },
+ { 0.990261729246017, 0.00113615695883677 },
+ { 0.990360817489959, 0.00113926251199766 },
+ { 0.99045855029267, 0.00114232558388501 },
+ { 0.990554950178194, 0.00114534688043129 },
+ { 0.990650039225593, 0.00114832709362277 },
+ { 0.990743839079339, 0.00115126690182508 },
+ { 0.990836370959422, 0.0011541669701 },
+ { 0.990927655671178, 0.00115702795051361 },
+ { 0.991017713614864, 0.00115985048243618 },
+ { 0.991106564794969, 0.00116263519283417 },
+ { 0.99119422882928, 0.00116538269655429 },
+ { 0.991280724957704, 0.00116809359660001 },
+ { 0.991366072050863, 0.00117076848440093 },
+ { 0.991450288618456, 0.00117340794007482 },
+ { 0.991533392817405, 0.00117601253268302 },
+ { 0.991615402459787, 0.00117858282047892 },
+ { 0.991696335020556, 0.00118111935115014 },
+ { 0.991776207645073, 0.00118362266205435 },
+ { 0.991855037156432, 0.00118609328044894 },
+ { 0.9919328400626, 0.00118853172371494 },
+ { 0.992009632563381, 0.00119093849957497 },
+ { 0.992085430557186, 0.00119331410630576 },
+ { 0.992160249647646, 0.00119565903294519 },
+ { 0.992234105150049, 0.00119797375949411 },
+ { 0.992307012097616, 0.00120025875711301 },
+ { 0.992378985247617, 0.00120251448831374 },
+ { 0.992450039087337, 0.00120474140714645 },
+ { 0.992520187839886, 0.00120693995938176 },
+ { 0.992589445469873, 0.0012091105826885 },
+ { 0.992657825688932, 0.00121125370680688 },
+ { 0.992725341961112, 0.00121336975371758 },
+ { 0.992792007508136, 0.00121545913780642 },
+ { 0.992857835314529, 0.00121752226602515 },
+ { 0.992922838132623, 0.00121955953804822 },
+ { 0.992987028487434, 0.0012215713464258 },
+ { 0.993050418681426, 0.00122355807673295 },
+ { 0.993113020799156, 0.00122552010771523 },
+ { 0.993174846711807, 0.00122745781143084 },
+ { 0.993235908081614, 0.00122937155338921 },
+ { 0.993296216366182, 0.00123126169268645 },
+ { 0.9933557828227, 0.00123312858213733 },
+ { 0.993414618512052, 0.00123497256840423 },
+ { 0.993472734302838, 0.00123679399212309 },
+ { 0.993530140875295, 0.00123859318802623 },
+ { 0.993586848725121, 0.00124037048506238 },
+ { 0.993642868167216, 0.00124212620651376 },
+ { 0.993698209339333, 0.00124386067011062 },
+ { 0.99375288220564, 0.00124557418814286 },
+ { 0.993806896560208, 0.00124726706756919 },
+ { 0.993860262030405, 0.00124893961012378 },
+ { 0.993912988080223, 0.00125059211242032 },
+ { 0.993965084013522, 0.00125222486605376 },
+ { 0.9940165589772, 0.00125383815769967 },
+ { 0.994067421964295, 0.0012554322692114 },
+ { 0.994117681817007, 0.0012570074777149 },
+ { 0.994167347229659, 0.00125856405570149 },
+ { 0.994216426751589, 0.00126010227111839 },
+ { 0.994264928789975, 0.00126162238745739 },
+ { 0.994312861612596, 0.00126312466384133 },
+ { 0.99436023335053, 0.00126460935510872 },
+ { 0.994407052000802, 0.0012660767118965 },
+ { 0.99445332542895, 0.00126752698072088 },
+ { 0.994499061371561, 0.00126896040405639 },
+ { 0.994544267438729, 0.00127037722041322 },
+ { 0.994588951116471, 0.00127177766441277 },
+ { 0.994633119769087, 0.00127316196686163 },
+ { 0.99467678064146, 0.00127453035482384 },
+ { 0.994719940861321, 0.00127588305169161 },
+ { 0.994762607441448, 0.00127722027725448 },
+ { 0.994804787281832, 0.00127854224776702 },
+ { 0.994846487171783, 0.00127984917601494 },
+ { 0.994887713791997, 0.00128114127137991 },
+ { 0.994928473716582, 0.00128241873990287 },
+ { 0.994968773415028, 0.00128368178434604 },
+ { 0.995008619254151, 0.00128493060425356 },
+ { 0.995048017499979, 0.00128616539601086 },
+ { 0.99508697431961, 0.00128738635290273 },
+ { 0.995125495783026, 0.0012885936651702 },
+ { 0.995163587864865, 0.00128978752006616 },
+ { 0.995201256446165, 0.00129096810190985 },
+ { 0.995238507316058, 0.00129213559214017 },
+ { 0.99527534617344, 0.00129329016936787 },
+ { 0.995311778628603, 0.00129443200942669 },
+ { 0.995347810204827, 0.00129556128542332 },
+ { 0.995383446339943, 0.00129667816778648 },
+ { 0.995418692387872, 0.00129778282431483 },
+ { 0.995453553620112, 0.00129887542022398 },
+ { 0.995488035227215, 0.00129995611819249 },
+ { 0.995522142320221, 0.00130102507840694 },
+ { 0.995555879932066, 0.00130208245860602 },
+ { 0.995589253018962, 0.00130312841412382 },
+ { 0.99562226646175, 0.00130416309793215 },
+ { 0.995654925067221, 0.00130518666068202 },
+ { 0.995687233569411, 0.00130619925074427 },
+ { 0.995719196630878, 0.00130720101424941 },
+ { 0.99575081884394, 0.00130819209512664 },
+ { 0.995782104731899, 0.00130917263514205 },
+ { 0.995813058750234, 0.00131014277393611 },
+ { 0.995843685287773, 0.00131110264906034 },
+ { 0.995873988667842, 0.00131205239601332 },
+ { 0.995903973149389, 0.00131299214827596 },
+ { 0.995933642928086, 0.00131392203734602 },
+ { 0.995963002137409, 0.00131484219277203 },
+ { 0.995992054849703, 0.00131575274218644 },
+ { 0.996020805077213, 0.00131665381133823 },
+ { 0.996049256773109, 0.0013175455241248 },
+ { 0.996077413832479, 0.00131842800262325 },
+ { 0.996105280093311, 0.00131930136712107 },
+ { 0.996132859337453, 0.00132016573614622 },
+ { 0.996160155291551, 0.0013210212264966 },
+ { 0.996187171627975, 0.001321867953269 },
+ { 0.996213911965722, 0.00132270602988748 },
+ { 0.996240379871305, 0.00132353556813114 },
+ { 0.996266578859623, 0.00132435667816142 },
+ { 0.996292512394815, 0.00132516946854891 },
+ { 0.996318183891097, 0.00132597404629953 },
+ { 0.996343596713584, 0.0013267705168803 },
+ { 0.996368754179095, 0.00132755898424465 },
+ { 0.996393659556946, 0.00132833955085711 },
+ { 0.996418316069724, 0.0013291123177177 },
+ { 0.996442726894046, 0.00132987738438574 },
+ { 0.996466895161311, 0.00133063484900327 },
+ { 0.996490823958429, 0.00133138480831802 },
+ { 0.99651451632854, 0.00133212735770592 },
+ { 0.996537975271721, 0.00133286259119325 },
+ { 0.996561203745678, 0.00133359060147833 },
+ { 0.996584204666426, 0.00133431147995281 },
+ { 0.996606980908954, 0.00133502531672257 },
+ { 0.996629535307884, 0.00133573220062829 },
+ { 0.996651870658108, 0.00133643221926551 },
+ { 0.996673989715425, 0.00133712545900449 },
+ { 0.996695895197154, 0.00133781200500953 },
+ { 0.996717589782748, 0.00133849194125813 },
+ { 0.996739076114386, 0.00133916535055958 },
+ { 0.996760356797563, 0.00133983231457342 },
+ { 0.99678143440166, 0.00134049291382743 },
+ { 0.996802311460516, 0.00134114722773534 },
+ { 0.996822990472979, 0.00134179533461424 },
+ { 0.996843473903448, 0.00134243731170162 },
+ { 0.996863764182414, 0.00134307323517218 },
+ { 0.996883863706982, 0.00134370318015424 },
+ { 0.996903774841386, 0.00134432722074599 },
+ { 0.996923499917498, 0.00134494543003131 },
+ { 0.996943041235328, 0.0013455578800954 },
+ { 0.996962401063505, 0.0013461646420401 },
+ { 0.996981581639767, 0.00134676578599895 },
+ { 0.997000585171427, 0.00134736138115199 },
+ { 0.997019413835838, 0.00134795149574025 },
+ { 0.997038069780848, 0.00134853619708009 },
+ { 0.997056555125248, 0.00134911555157714 },
+ { 0.997074871959213, 0.00134968962474014 },
+ { 0.99709302234473, 0.00135025848119448 },
+ { 0.997111008316029, 0.00135082218469548 },
+ { 0.997128831879991, 0.00135138079814143 },
+ { 0.997146495016567, 0.00135193438358652 },
+ { 0.997163999679176, 0.0013524830022534 },
+ { 0.9971813477951, 0.00135302671454561 },
+ { 0.997198541265877, 0.00135356558005975 },
+ { 0.997215581967679, 0.00135409965759752 },
+ { 0.997232471751692, 0.00135462900517744 },
+ { 0.997249212444483, 0.00135515368004645 },
+ { 0.997265805848362, 0.00135567373869132 },
+ { 0.997282253741743, 0.00135618923684981 },
+ { 0.997298557879491, 0.00135670022952165 },
+ { 0.99731471999327, 0.00135720677097941 },
+ { 0.99733074179188, 0.00135770891477908 },
+ { 0.997346624961591, 0.00135820671377056 },
+ { 0.997362371166473, 0.00135870022010791 },
+ { 0.997377982048715, 0.00135918948525947 },
+ { 0.997393459228944, 0.00135967456001779 },
+ { 0.997408804306538, 0.00136015549450941 },
+ { 0.99742401885993, 0.00136063233820447 },
+ { 0.99743910444691, 0.00136110513992612 },
+ { 0.997454062604925, 0.0013615739478599 },
+ { 0.997468894851365, 0.00136203880956278 },
+ { 0.997483602683853, 0.00136249977197222 },
+ { 0.997498187580529, 0.00136295688141498 },
+ { 0.997512651000322, 0.00136341018361582 },
+ { 0.99752699438323, 0.00136385972370609 },
+ { 0.997541219150581, 0.00136430554623207 },
+ { 0.997555326705303, 0.00136474769516333 },
+ { 0.997569318432181, 0.00136518621390082 },
+ { 0.997583195698114, 0.00136562114528491 },
+ { 0.997596959852367, 0.00136605253160325 },
+ { 0.997610612226813, 0.00136648041459855 },
+ { 0.997624154136186, 0.00136690483547618 },
+ { 0.997637586878312, 0.00136732583491172 },
+ { 0.997650911734349, 0.00136774345305833 },
+ { 0.997664129969019, 0.00136815772955396 },
+ { 0.997677242830833, 0.00136856870352863 },
+ { 0.99769025155232, 0.00136897641361135 },
+ { 0.997703157350246, 0.00136938089793712 },
+ { 0.99771596142583, 0.00136978219415371 },
+ { 0.997728664964961, 0.00137018033942841 },
+ { 0.997741269138407, 0.00137057537045457 },
+ { 0.997753775102023, 0.0013709673234582 },
+ { 0.997766183996954, 0.00137135623420426 },
+ { 0.997778496949839, 0.00137174213800304 },
+ { 0.997790715073005, 0.00137212506971632 },
+ { 0.997802839464665, 0.0013725050637635 },
+ { 0.997814871209107, 0.00137288215412757 },
+ { 0.997826811376886, 0.00137325637436108 },
+ { 0.997838661025005, 0.00137362775759191 },
+ { 0.997850421197104, 0.00137399633652903 },
+ { 0.997862092923634, 0.00137436214346816 },
+ { 0.997873677222041, 0.00137472521029731 },
+ { 0.997885175096933, 0.00137508556850223 },
+ { 0.99789658754026, 0.00137544324917186 },
+ { 0.997907915531475, 0.00137579828300356 },
+ { 0.997919160037707, 0.00137615070030844 },
+ { 0.997930322013926, 0.00137650053101638 },
+ { 0.997941402403097, 0.0013768478046812 },
+ { 0.997952402136348, 0.00137719255048561 },
+ { 0.99796332213312, 0.00137753479724613 },
+ { 0.997974163301328, 0.00137787457341793 },
+ { 0.997984926537508, 0.00137821190709959 },
+ { 0.997995612726967, 0.00137854682603784 },
+ { 0.998006222743936, 0.00137887935763213 },
+ { 0.998016757451707, 0.00137920952893922 },
+ { 0.998027217702786, 0.00137953736667767 },
+ { 0.998037604339025, 0.00137986289723225 },
+ { 0.998047918191767, 0.0013801861466583 },
+ { 0.998058160081979, 0.00138050714068603 },
+ { 0.998068330820393, 0.00138082590472476 },
+ { 0.998078431207631, 0.00138114246386705 },
+ { 0.998088462034341, 0.00138145684289283 },
+ { 0.998098424081326, 0.00138176906627344 },
+ { 0.998108318119668, 0.00138207915817561 },
+ { 0.998118144910857, 0.00138238714246542 },
+ { 0.998127905206912, 0.0013826930427121 },
+ { 0.998137599750504, 0.00138299688219193 },
+ { 0.998147229275075, 0.0013832986838919 },
+ { 0.998156794504957, 0.00138359847051352 },
+ { 0.998166296155486, 0.00138389626447637 },
+ { 0.998175734933122, 0.00138419208792176 },
+ { 0.998185111535555, 0.00138448596271626 },
+ { 0.998194426651824, 0.00138477791045518 },
+ { 0.99820368096242, 0.00138506795246602 },
+ { 0.998212875139399, 0.00138535610981187 },
+ { 0.998222009846487, 0.00138564240329474 },
+ { 0.998231085739184, 0.00138592685345889 },
+ { 0.998240103464871, 0.00138620948059404 },
+ { 0.99824906366291, 0.00138649030473861 },
+ { 0.998257966964743, 0.00138676934568283 },
+ { 0.998266813993996, 0.00138704662297191 },
+ { 0.998275605366572, 0.00138732215590909 },
+ { 0.998284341690753, 0.00138759596355864 },
+ { 0.998293023567288, 0.00138786806474889 },
+ { 0.998301651589494, 0.00138813847807512 },
+ { 0.998310226343345, 0.00138840722190251 },
+ { 0.998318748407564, 0.00138867431436896 },
+ { 0.998327218353711, 0.00138893977338796 },
+ { 0.998335636746276, 0.0013892036166513 },
+ { 0.998344004142763, 0.00138946586163188 },
+ { 0.998352321093777, 0.00138972652558637 },
+ { 0.998360588143109, 0.0013899856255579 },
+ { 0.998368805827821, 0.00139024317837868 },
+ { 0.998376974678328, 0.00139049920067259 },
+ { 0.99838509521848, 0.00139075370885775 },
+ { 0.998393167965641, 0.00139100671914903 },
+ { 0.998401193430769, 0.00139125824756055 },
+ { 0.998409172118498, 0.00139150830990812 },
+ { 0.998417104527209, 0.00139175692181167 },
+ { 0.99842499114911, 0.00139200409869764 },
+ { 0.998432832470311, 0.00139224985580131 },
+ { 0.998440628970895, 0.00139249420816918 },
+ { 0.998448381124998, 0.00139273717066119 },
+ { 0.998456089400872, 0.00139297875795302 },
+ { 0.998463754260965, 0.00139321898453833 },
+ { 0.998471376161982, 0.00139345786473094 },
+ { 0.998478955554965, 0.00139369541266698 },
+ { 0.998486492885351, 0.00139393164230709 },
+ { 0.998493988593046, 0.00139416656743848 },
+ { 0.99850144311249, 0.00139440020167702 },
+ { 0.998508856872721, 0.00139463255846934 },
+ { 0.998516230297441, 0.0013948636510948 },
+ { 0.998523563805079, 0.00139509349266753 },
+ { 0.998530857808857, 0.00139532209613839 },
+ { 0.998538112716847, 0.00139554947429694 },
+ { 0.998545328932037, 0.00139577563977332 },
+ { 0.998552506852391, 0.0013960006050402 },
+ { 0.998559646870905, 0.00139622438241462 },
+ { 0.99856674937567, 0.00139644698405984 },
+ { 0.99857381474993, 0.00139666842198719 },
+ { 0.998580843372135, 0.00139688870805785 },
+ { 0.998587835616004, 0.0013971078539846 },
+ { 0.998594791850576, 0.00139732587133364 },
+ { 0.99860171244027, 0.00139754277152627 },
+ { 0.998608597744933, 0.00139775856584062 },
+ { 0.998615448119901, 0.0013979732654133 },
+ { 0.998622263916045, 0.00139818688124114 },
+ { 0.998629045479829, 0.00139839942418276 },
+ { 0.998635793153361, 0.00139861090496021 },
+ { 0.99864250727444, 0.0013988213341606 },
+ { 0.998649188176612, 0.00139903072223766 },
+ { 0.998655836189216, 0.00139923907951329 },
+ { 0.998662451637433, 0.00139944641617912 },
+ { 0.998669034842338, 0.00139965274229802 },
+ { 0.998675586120944, 0.00139985806780559 },
+ { 0.998682105786251, 0.00140006240251168 },
+ { 0.998688594147294, 0.00140026575610181 },
+ { 0.998695051509186, 0.00140046813813864 },
+ { 0.998701478173166, 0.0014006695580634 },
+ { 0.998707874436645, 0.00140087002519728 },
+ { 0.998714240593246, 0.00140106954874283 },
+ { 0.99872057693285, 0.00140126813778533 },
+ { 0.998726883741643, 0.00140146580129416 },
+ { 0.998733161302152, 0.00140166254812412 },
+ { 0.998739409893293, 0.00140185838701677 },
+ { 0.998745629790408, 0.00140205332660173 },
+ { 0.998751821265312, 0.00140224737539795 },
+ { 0.998757984586326, 0.00140244054181503 },
+ { 0.998764120018323, 0.00140263283415441 },
+ { 0.998770227822767, 0.00140282426061069 },
+ { 0.99877630825775, 0.00140301482927281 },
+ { 0.99878236157803, 0.00140320454812524 },
+ { 0.998788388035074, 0.00140339342504925 },
+ { 0.99879438787709, 0.00140358146782403 },
+ { 0.998800361349069, 0.00140376868412787 },
+ { 0.998806308692817, 0.00140395508153934 },
+ { 0.998812230146997, 0.00140414066753839 },
+ { 0.998818125947161, 0.00140432544950751 },
+ { 0.998823996325784, 0.00140450943473283 },
+ { 0.998829841512304, 0.00140469263040522 },
+ { 0.998835661733154, 0.00140487504362135 },
+ { 0.998841457211795, 0.00140505668138479 },
+ { 0.998847228168752, 0.00140523755060708 },
+ { 0.998852974821647, 0.00140541765810874 },
+ { 0.998858697385229, 0.00140559701062034 },
+ { 0.998864396071411, 0.00140577561478348 },
+ { 0.9988700710893, 0.00140595347715183 },
+ { 0.998875722645229, 0.00140613060419214 },
+ { 0.998881350942787, 0.00140630700228517 },
+ { 0.998886956182854, 0.00140648267772672 },
+ { 0.998892538563627, 0.00140665763672855 },
+ { 0.998898098280653, 0.00140683188541938 },
+ { 0.998903635526858, 0.00140700542984578 },
+ { 0.99890915049258, 0.00140717827597309 },
+ { 0.99891464336559, 0.00140735042968641 },
+ { 0.998920114331131, 0.00140752189679142 },
+ { 0.99892556357194, 0.00140769268301534 },
+ { 0.998930991268277, 0.00140786279400777 },
+ { 0.998936397597955, 0.00140803223534159 },
+ { 0.998941782736366, 0.00140820101251383 },
+ { 0.998947146856509, 0.00140836913094649 },
+ { 0.998952490129017, 0.00140853659598742 },
+ { 0.998957812722183, 0.00140870341291114 },
+ { 0.998963114801987, 0.00140886958691965 },
+ { 0.998968396532119, 0.00140903512314329 },
+ { 0.998973658074012, 0.00140920002664148 },
+ { 0.998978899586859, 0.00140936430240358 },
+ { 0.998984121227642, 0.00140952795534964 },
+ { 0.99898932315116, 0.00140969099033118 },
+ { 0.998994505510046, 0.00140985341213198 },
+ { 0.998999668454797, 0.00141001522546881 },
+ { 0.999004812133799, 0.00141017643499223 },
+ { 0.999009936693344, 0.00141033704528726 },
+ { 0.99901504227766, 0.00141049706087418 },
+ { 0.999020129028932, 0.00141065648620924 },
+ { 0.999025197087324, 0.00141081532568536 },
+ { 0.999030246591001, 0.00141097358363284 },
+ { 0.999035277676155, 0.0014111312643201 },
+ { 0.999040290477024, 0.00141128837195431 },
+ { 0.999045285125915, 0.00141144491068214 },
+ { 0.999050261753224, 0.0014116008845904 },
+ { 0.99905522048746, 0.00141175629770673 },
+ { 0.999060161455266, 0.00141191115400023 },
+ { 0.999065084781436, 0.00141206545738217 },
+ { 0.999069990588942, 0.00141221921170659 },
+ { 0.999074878998948, 0.00141237242077097 },
+ { 0.999079750130834, 0.00141252508831683 },
+ { 0.999084604102217, 0.00141267721803041 },
+ { 0.999089441028966, 0.00141282881354325 },
+ { 0.999094261025228, 0.00141297987843281 },
+ { 0.999099064203442, 0.00141313041622307 },
+ { 0.999103850674359, 0.00141328043038515 },
+ { 0.999108620547065, 0.0014134299243379 },
+ { 0.999113373928994, 0.00141357890144846 },
+ { 0.999118110925949, 0.00141372736503288 },
+ { 0.999122831642124, 0.00141387531835665 },
+ { 0.999127536180115, 0.00141402276463531 },
+ { 0.999132224640943, 0.00141416970703497 },
+ { 0.999136897124069, 0.00141431614867291 },
+ { 0.999141553727416, 0.00141446209261808 },
+ { 0.999146194547378, 0.00141460754189169 },
+ { 0.999150819678847, 0.00141475249946771 },
+ { 0.999155429215223, 0.00141489696827342 },
+ { 0.999160023248433, 0.00141504095118993 },
+ { 0.999164601868947, 0.00141518445105272 },
+ { 0.999169165165795, 0.00141532747065211 },
+ { 0.999173713226586, 0.0014154700127338 },
+ { 0.999178246137516, 0.00141561207999939 },
+ { 0.999182763983395, 0.00141575367510684 },
+ { 0.999187266847651, 0.00141589480067096 },
+ { 0.999191754812356, 0.00141603545926396 },
+ { 0.999196227958234, 0.00141617565341585 },
+ { 0.999200686364681, 0.00141631538561497 },
+ { 0.999205130109776, 0.00141645465830845 },
+ { 0.999209559270299, 0.00141659347390267 },
+ { 0.999213973921745, 0.00141673183476372 },
+ { 0.999218374138337, 0.00141686974321787 },
+ { 0.999222759993043, 0.00141700720155202 },
+ { 0.999227131557588, 0.00141714421201412 },
+ { 0.99923148890247, 0.00141728077681367 },
+ { 0.999235832096973, 0.0014174168981221 },
+ { 0.999240161209179, 0.00141755257807323 },
+ { 0.999244476305986, 0.0014176878187637 },
+ { 0.999248777453117, 0.00141782262225338 },
+ { 0.999253064715139, 0.00141795699056582 },
+ { 0.999257338155468, 0.00141809092568863 },
+ { 0.99926159783639, 0.00141822442957392 },
+ { 0.99926584381907, 0.00141835750413868 },
+ { 0.999270076163568, 0.0014184901512652 },
+ { 0.999274294928845, 0.00141862237280149 },
+ { 0.999278500172784, 0.00141875417056161 },
+ { 0.999282691952196, 0.00141888554632615 },
+ { 0.999286870322837, 0.00141901650184251 },
+ { 0.999291035339416, 0.00141914703882539 },
+ { 0.999295187055611, 0.00141927715895711 },
+ { 0.999299325524078, 0.00141940686388796 },
+ { 0.999303450796465, 0.00141953615523665 },
+ { 0.99930756292342, 0.0014196650345906 },
+ { 0.999311661954608, 0.00141979350350635 },
+ { 0.999315747938718, 0.00141992156350989 },
+ { 0.999319820923479, 0.00142004921609706 },
+ { 0.999323880955664, 0.00142017646273383 },
+ { 0.999327928081108, 0.00142030330485674 },
+ { 0.999331962344717, 0.00142042974387316 },
+ { 0.999335983790477, 0.00142055578116168 },
+ { 0.999339992461466, 0.00142068141807244 },
+ { 0.999343988399866, 0.00142080665592747 },
+ { 0.999347971646972, 0.00142093149602099 },
+ { 0.999351942243203, 0.00142105593961979 },
+ { 0.999355900228111, 0.0014211799879635 },
+ { 0.999359845640395, 0.00142130364226497 },
+ { 0.999363778517906, 0.00142142690371053 },
+ { 0.999367698897662, 0.00142154977346033 },
+ { 0.999371606815854, 0.00142167225264869 },
+ { 0.999375502307859, 0.00142179434238434 },
+ { 0.999379385408247, 0.00142191604375077 },
+ { 0.999383256150793, 0.00142203735780652 },
+ { 0.999387114568486, 0.0014221582855855 },
+ { 0.999390960693537, 0.00142227882809723 },
+ { 0.999394794557389, 0.00142239898632722 },
+ { 0.999398616190729, 0.00142251876123719 },
+ { 0.999402425623492, 0.00142263815376539 },
+ { 0.999406222884875, 0.00142275716482686 },
+ { 0.999410008003344, 0.00142287579531377 },
+ { 0.999413781006642, 0.00142299404609562 },
+ { 0.9994175419218, 0.00142311191801959 },
+ { 0.999421290775143, 0.00142322941191076 },
+ { 0.999425027592302, 0.00142334652857243 },
+ { 0.999428752398221, 0.00142346326878633 },
+ { 0.999432465217163, 0.00142357963331296 },
+ { 0.999436166072722, 0.00142369562289178 },
+ { 0.999439854987832, 0.00142381123824153 },
+ { 0.99944353198477, 0.00142392648006044 },
+ { 0.999447197085171, 0.00142404134902654 },
+ { 0.99945085031003, 0.00142415584579787 },
+ { 0.999454491679713, 0.00142426997101273 },
+ { 0.999458121213966, 0.00142438372528998 },
+ { 0.999461738931922, 0.00142449710922923 },
+ { 0.999465344852105, 0.0014246101234111 },
+ { 0.999468938992444, 0.00142472276839749 },
+ { 0.999472521370276, 0.00142483504473178 },
+ { 0.999476092002357, 0.00142494695293909 },
+ { 0.999479650904866, 0.00142505849352651 },
+ { 0.999483198093414, 0.00142516966698334 },
+ { 0.999486733583054, 0.0014252804737813 },
+ { 0.999490257388284, 0.00142539091437477 },
+ { 0.999493769523054, 0.00142550098920105 },
+ { 0.999497270000779, 0.00142561069868051 },
+ { 0.99950075883434, 0.00142572004321686 },
+ { 0.999504236036093, 0.00142582902319741 },
+ { 0.999507701617878, 0.00142593763899318 },
+ { 0.999511155591023, 0.0014260458909592 },
+ { 0.999514597966351, 0.00142615377943473 },
+ { 0.999518028754189, 0.0014262613047434 },
+ { 0.999521447964373, 0.00142636846719348 },
+ { 0.999524855606255, 0.00142647526707807 },
+ { 0.999528251688709, 0.00142658170467531 },
+ { 0.999531636220139, 0.00142668778024857 },
+ { 0.999535009208483, 0.00142679349404666 },
+ { 0.999538370661222, 0.00142689884630404 },
+ { 0.999541720585385, 0.00142700383724101 },
+ { 0.999545058987556, 0.0014271084670639 },
+ { 0.999548385873878, 0.00142721273596527 },
+ { 0.999551701250063, 0.0014273166441241 },
+ { 0.999555005121394, 0.00142742019170599 },
+ { 0.999558297492733, 0.00142752337886335 },
+ { 0.999561578368529, 0.00142762620573556 },
+ { 0.999564847752819, 0.0014277286724492 },
+ { 0.999568105649239, 0.00142783077911818 },
+ { 0.999571352061026, 0.00142793252584398 },
+ { 0.999574586991025, 0.00142803391271578 },
+ { 0.999577810441698, 0.00142813493981068 },
+ { 0.999581022415122, 0.00142823560719385 },
+ { 0.999584222913003, 0.0014283359149187 },
+ { 0.999587411936675, 0.0014284358630271 },
+ { 0.999590589487111, 0.0014285354515495 },
+ { 0.999593755564924, 0.00142863468050511 },
+ { 0.999596910170374, 0.0014287335499021 },
+ { 0.999600053303375, 0.00142883205973773 },
+ { 0.999603184963496, 0.00142893020999856 },
+ { 0.999606305149971, 0.00142902800066056 },
+ { 0.999609413861703, 0.00142912543168932 },
+ { 0.999612511097266, 0.00142922250304018 },
+ { 0.999615596854915, 0.00142931921465842 },
+ { 0.999618671132586, 0.00142941556647937 },
+ { 0.999621733927906, 0.00142951155842864 },
+ { 0.999624785238193, 0.00142960719042221 },
+ { 0.999627825060466, 0.00142970246236661 },
+ { 0.999630853391445, 0.00142979737415908 },
+ { 0.99963387022756, 0.0014298919256877 },
+ { 0.999636875564953, 0.00142998611683157 },
+ { 0.999639869399485, 0.00143007994746093 },
+ { 0.999642851726736, 0.00143017341743733 },
+ { 0.999645822542017, 0.00143026652661376 },
+ { 0.999648781840369, 0.00143035927483479 },
+ { 0.999651729616569, 0.00143045166193676 },
+ { 0.999654665865136, 0.00143054368774783 },
+ { 0.999657590580332, 0.00143063535208823 },
+ { 0.999660503756171, 0.00143072665477033 },
+ { 0.999663405386421, 0.00143081759559877 },
+ { 0.999666295464607, 0.00143090817437066 },
+ { 0.999669173984018, 0.00143099839087567 },
+ { 0.99967204093771, 0.00143108824489614 },
+ { 0.99967489631851, 0.00143117773620729 },
+ { 0.999677740119022, 0.00143126686457729 },
+ { 0.999680572331628, 0.0014313556297674 },
+ { 0.999683392948495, 0.00143144403153212 },
+ { 0.999686201961578, 0.00143153206961931 },
+ { 0.999688999362625, 0.00143161974377031 },
+ { 0.999691785143178, 0.00143170705372008 },
+ { 0.99969455929458, 0.00143179399919731 },
+ { 0.99969732180798, 0.00143188057992455 },
+ { 0.999700072674333, 0.00143196679561834 },
+ { 0.999702811884406, 0.00143205264598932 },
+ { 0.999705539428784, 0.00143213813074236 },
+ { 0.999708255297868, 0.00143222324957667 },
+ { 0.999710959481885, 0.00143230800218595 },
+ { 0.999713651970889, 0.00143239238825846 },
+ { 0.999716332754765, 0.00143247640747715 },
+ { 0.99971900182323, 0.00143256005951981 },
+ { 0.999721659165843, 0.00143264334405915 },
+ { 0.999724304772002, 0.00143272626076292 },
+ { 0.999726938630952, 0.00143280880929403 },
+ { 0.999729560731786, 0.00143289098931064 },
+ { 0.99973217106345, 0.0014329728004663 },
+ { 0.999734769614746, 0.00143305424241006 },
+ { 0.999737356374334, 0.00143313531478654 },
+ { 0.99973993133074, 0.00143321601723607 },
+ { 0.999742494472354, 0.00143329634939478 },
+ { 0.999745045787435, 0.00143337631089474 },
+ { 0.999747585264116, 0.00143345590136401 },
+ { 0.999750112890407, 0.00143353512042679 },
+ { 0.999752628654196, 0.0014336139677035 },
+ { 0.999755132543256, 0.00143369244281086 },
+ { 0.999757624545242, 0.00143377054536207 },
+ { 0.999760104647703, 0.00143384827496681 },
+ { 0.999762572838077, 0.00143392563123141 },
+ { 0.999765029103698, 0.00143400261375891 },
+ { 0.9997674734318, 0.00143407922214919 },
+ { 0.999769905809518, 0.00143415545599902 },
+ { 0.99977232622389, 0.00143423131490221 },
+ { 0.999774734661864, 0.00143430679844967 },
+ { 0.999777131110298, 0.00143438190622949 },
+ { 0.999779515555963, 0.00143445663782708 },
+ { 0.999781887985548, 0.00143453099282524 },
+ { 0.999784248385659, 0.00143460497080421 },
+ { 0.999786596742827, 0.00143467857134184 },
+ { 0.999788933043508, 0.00143475179401362 },
+ { 0.999791257274084, 0.00143482463839279 },
+ { 0.99979356942087, 0.0014348971040504 },
+ { 0.999795869470113, 0.00143496919055546 },
+ { 0.999798157407999, 0.00143504089747496 },
+ { 0.999800433220649, 0.00143511222437399 },
+ { 0.999802696894131, 0.00143518317081583 },
+ { 0.999804948414453, 0.001435253736362 },
+ { 0.999807187767573, 0.00143532392057239 },
+ { 0.999809414939397, 0.00143539372300528 },
+ { 0.999811629915785, 0.00143546314321751 },
+ { 0.999813832682551, 0.00143553218076446 },
+ { 0.999816023225468, 0.00143560083520021 },
+ { 0.999818201530266, 0.00143566910607759 },
+ { 0.999820367582641, 0.00143573699294824 },
+ { 0.999822521368252, 0.00143580449536273 },
+ { 0.999824662872727, 0.00143587161287058 },
+ { 0.999826792081663, 0.00143593834502041 },
+ { 0.999828908980629, 0.00143600469135994 },
+ { 0.999831013555171, 0.00143607065143613 },
+ { 0.999833105790809, 0.00143613622479521 },
+ { 0.999835185673046, 0.00143620141098276 },
+ { 0.999837253187364, 0.00143626620954382 },
+ { 0.99983930831923, 0.00143633062002291 },
+ { 0.9998413510541, 0.00143639464196414 },
+ { 0.999843381377414, 0.00143645827491126 },
+ { 0.999845399274607, 0.00143652151840773 },
+ { 0.999847404731106, 0.00143658437199682 },
+ { 0.999849397732332, 0.00143664683522163 },
+ { 0.999851378263706, 0.00143670890762521 },
+ { 0.999853346310646, 0.00143677058875058 },
+ { 0.999855301858575, 0.00143683187814082 },
+ { 0.999857244892917, 0.00143689277533915 },
+ { 0.999859175399105, 0.00143695327988898 },
+ { 0.999861093362577, 0.00143701339133397 },
+ { 0.999862998768784, 0.00143707310921809 },
+ { 0.999864891603188, 0.00143713243308571 },
+ { 0.999866771851266, 0.00143719136248164 },
+ { 0.999868639498509, 0.00143724989695121 },
+ { 0.999870494530429, 0.00143730803604032 },
+ { 0.999872336932558, 0.00143736577929548 },
+ { 0.999874166690448, 0.00143742312626394 },
+ { 0.999875983789677, 0.00143748007649365 },
+ { 0.999877788215849, 0.00143753662953343 },
+ { 0.999879579954594, 0.00143759278493293 },
+ { 0.999881358991574, 0.00143764854224275 },
+ { 0.999883125312482, 0.00143770390101448 },
+ { 0.999884878903043, 0.00143775886080075 },
+ { 0.999886619749018, 0.0014378134211553 },
+ { 0.999888347836206, 0.00143786758163303 },
+ { 0.999890063150444, 0.00143792134179004 },
+ { 0.999891765677609, 0.00143797470118373 },
+ { 0.99989345540362, 0.00143802765937279 },
+ { 0.999895132314442, 0.00143808021591731 },
+ { 0.999896796396084, 0.00143813237037881 },
+ { 0.999898447634603, 0.00143818412232028 },
+ { 0.999900086016104, 0.00143823547130626 },
+ { 0.999901711526744, 0.00143828641690288 },
+ { 0.999903324152731, 0.00143833695867789 },
+ { 0.999904923880328, 0.00143838709620075 },
+ { 0.999906510695853, 0.00143843682904266 },
+ { 0.999908084585682, 0.00143848615677659 },
+ { 0.999909645536248, 0.00143853507897736 },
+ { 0.999911193534045, 0.00143858359522168 },
+ { 0.99991272856563, 0.00143863170508819 },
+ { 0.99991425061762, 0.00143867940815751 },
+ { 0.9999157596767, 0.00143872670401229 },
+ { 0.99991725572962, 0.00143877359223726 },
+ { 0.999918738763197, 0.00143882007241926 },
+ { 0.999920208764318, 0.0014388661441473 },
+ { 0.99992166571994, 0.00143891180701262 },
+ { 0.999923109617092, 0.00143895706060869 },
+ { 0.999924540442878, 0.00143900190453128 },
+ { 0.999925958184474, 0.00143904633837852 },
+ { 0.999927362829134, 0.00143909036175092 },
+ { 0.999928754364188, 0.0014391339742514 },
+ { 0.999930132777047, 0.00143917717548538 },
+ { 0.9999314980552, 0.00143921996506077 },
+ { 0.999932850186219, 0.00143926234258802 },
+ { 0.999934189157757, 0.00143930430768022 },
+ { 0.999935514957552, 0.00143934585995303 },
+ { 0.999936827573428, 0.00143938699902483 },
+ { 0.999938126993294, 0.0014394277245167 },
+ { 0.999939413205148, 0.00143946803605245 },
+ { 0.999940686197075, 0.00143950793325869 },
+ { 0.999941945957253, 0.00143954741576486 },
+ { 0.99994319247395, 0.00143958648320326 },
+ { 0.999944425735524, 0.00143962513520908 },
+ { 0.999945645730432, 0.00143966337142045 },
+ { 0.99994685244722, 0.00143970119147848 },
+ { 0.999948045874534, 0.00143973859502727 },
+ { 0.999949226001115, 0.00143977558171397 },
+ { 0.999950392815803, 0.0014398121511888 },
+ { 0.999951546307537, 0.0014398483031051 },
+ { 0.999952686465356, 0.00143988403711934 },
+ { 0.999953813278401, 0.00143991935289117 },
+ { 0.999954926735915, 0.00143995425008344 },
+ { 0.999956026827243, 0.00143998872836226 },
+ { 0.999957113541838, 0.001440022787397 },
+ { 0.999958186869253, 0.00144005642686033 },
+ { 0.999959246799153, 0.00144008964642826 },
+ { 0.999960293321307, 0.00144012244578017 },
+ { 0.999961326425593, 0.00144015482459881 },
+ { 0.999962346101998, 0.00144018678257039 },
+ { 0.99996335234062, 0.00144021831938454 },
+ { 0.999964345131669, 0.00144024943473441 },
+ { 0.999965324465463, 0.00144028012831661 },
+ { 0.999966290332437, 0.00144031039983133 },
+ { 0.999967242723139, 0.0014403402489823 },
+ { 0.999968181628229, 0.00144036967547687 },
+ { 0.999969107038487, 0.00144039867902599 },
+ { 0.999970018944804, 0.00144042725934424 },
+ { 0.999970917338193, 0.00144045541614991 },
+ { 0.999971802209782, 0.00144048314916496 },
+ { 0.999972673550819, 0.00144051045811507 },
+ { 0.99997353135267, 0.00144053734272967 },
+ { 0.999974375606823, 0.00144056380274197 },
+ { 0.999975206304887, 0.00144058983788897 },
+ { 0.999976023438591, 0.00144061544791148 },
+ { 0.999976826999788, 0.00144064063255415 },
+ { 0.999977616980455, 0.0014406653915655 },
+ { 0.999978393372691, 0.00144068972469794 },
+ { 0.99997915616872, 0.00144071363170775 },
+ { 0.999979905360893, 0.00144073711235519 },
+ { 0.999980640941686, 0.00144076016640443 },
+ { 0.9999813629037, 0.00144078279362362 },
+ { 0.999982071239665, 0.0014408049937849 },
+ { 0.99998276594244, 0.00144082676666443 },
+ { 0.99998344700501, 0.00144084811204238 },
+ { 0.999984114420491, 0.00144086902970297 },
+ { 0.999984768182127, 0.0014408895194345 },
+ { 0.999985408283294, 0.00144090958102933 },
+ { 0.999986034717498, 0.00144092921428395 },
+ { 0.999986647478377, 0.00144094841899893 },
+ { 0.999987246559699, 0.00144096719497902 },
+ { 0.999987831955368, 0.00144098554203309 },
+ { 0.999988403659418, 0.0014410034599742 },
+ { 0.999988961666017, 0.00144102094861957 },
+ { 0.999989505969469, 0.00144103800779063 },
+ { 0.999990036564209, 0.00144105463731305 },
+ { 0.999990553444811, 0.00144107083701668 },
+ { 0.99999105660598, 0.00144108660673566 },
+ { 0.999991546042562, 0.00144110194630836 },
+ { 0.999992021749534, 0.00144111685557744 },
+ { 0.999992483722013, 0.00144113133438981 },
+ { 0.999992931955252, 0.00144114538259672 },
+ { 0.999993366444643, 0.00144115900005371 },
+ { 0.999993787185713, 0.00144117218662063 },
+ { 0.999994194174129, 0.00144118494216168 },
+ { 0.999994587405698, 0.0014411972665454 },
+ { 0.999994966876362, 0.00144120915964467 },
+ { 0.999995332582207, 0.00144122062133677 },
+ { 0.999995684519455, 0.00144123165150332 },
+ { 0.99999602268447, 0.00144124225003034 },
+ { 0.999996347073756, 0.00144125241680826 },
+ { 0.999996657683955, 0.00144126215173188 },
+ { 0.999996954511853, 0.00144127145470043 },
+ { 0.999997237554376, 0.00144128032561758 },
+ { 0.999997506808591, 0.0014412887643914 },
+ { 0.999997762271707, 0.00144129677093441 },
+ { 0.999998003941074, 0.00144130434516356 },
+ { 0.999998231814184, 0.00144131148700027 },
+ { 0.999998445888673, 0.00144131819637042 },
+ { 0.999998646162317, 0.00144132447320431 },
+ { 0.999998832633036, 0.00144133031743676 },
+ { 0.999999005298892, 0.00144133572900703 },
+ { 0.999999164158091, 0.00144134070785888 },
+ { 0.99999930920898, 0.00144134525394053 },
+ { 0.999999440450052, 0.00144134936720471 },
+ { 0.99999955787994, 0.00144135304760864 },
+ { 0.999999661497424, 0.00144135629511401 },
+ { 0.999999751301425, 0.00144135910968703 },
+ { 0.999999827291008, 0.00144136149129841 },
+ { 0.999999889465382, 0.00144136343992335 },
+ { 0.9999999378239, 0.00144136495554157 },
+ { 0.999999972366058, 0.00144136603813729 },
+ { 0.999999993091496, 0.00144136668769923 },
+ { 1, 0.00144136690422063 }
+};
+
+static const double inverse_cumulative[] = {
+ 0, 0.00181900412026957, 0.00330980182852486, 0.00391849965097171,
+ 0.00452719747341855, 0.00513589529586539, 0.00574459311831223, 0.00632806291282084,
+ 0.00669612817511386, 0.00706419343740688, 0.0074322586996999, 0.00780032396199292,
+ 0.00816838922428594, 0.00853645448657896, 0.00890451974887198, 0.00927258501116501,
+ 0.00958338938434283, 0.00984936232879981, 0.0101153352732568, 0.0103813082177138,
+ 0.0106472811621708, 0.0109132541066277, 0.0111792270510847, 0.0114451999955417,
+ 0.0117111729399987, 0.0119771458844557, 0.0122431188289126, 0.0125090917733696,
+ 0.0127338510223064, 0.0129439296223883, 0.0131540082224701, 0.013364086822552,
+ 0.0135741654226339, 0.0137842440227157, 0.0139943226227976, 0.0142044012228795,
+ 0.0144144798229613, 0.0146245584230432, 0.0148346370231251, 0.0150447156232069,
+ 0.0152547942232888, 0.0154648728233706, 0.0156749514234525, 0.0158582448740068,
+ 0.0160334475617641, 0.0162086502495214, 0.0163838529372787, 0.0165590556250361,
+ 0.0167342583127934, 0.0169094610005507, 0.017084663688308, 0.0172598663760653,
+ 0.0174350690638226, 0.0176102717515799, 0.0177854744393372, 0.0179606771270945,
+ 0.0181358798148518, 0.0183110825026092, 0.0184862851903665, 0.0186614878781238,
+ 0.0188366905658811, 0.0189926185390339, 0.0191442831525329, 0.019295947766032,
+ 0.019447612379531, 0.01959927699303, 0.0197509416065291, 0.0199026062200281,
+ 0.0200542708335271, 0.0202059354470262, 0.0203576000605252, 0.0205092646740242,
+ 0.0206609292875233, 0.0208125939010223, 0.0209642585145213, 0.0211159231280204,
+ 0.0212675877415194, 0.0214192523550184, 0.0215709169685174, 0.0217225815820165,
+ 0.0218742461955155, 0.0220245057558316, 0.0221594556746887, 0.0222944055935459,
+ 0.0224293555124031, 0.0225643054312602, 0.0226992553501174, 0.0228342052689745,
+ 0.0229691551878317, 0.0231041051066889, 0.023239055025546, 0.0233740049444032,
+ 0.0235089548632603, 0.0236439047821175, 0.0237788547009747, 0.0239138046198318,
+ 0.024048754538689, 0.0241837044575461, 0.0243186543764033, 0.0244536042952605,
+ 0.0245885542141176, 0.0247235041329748, 0.0248584540518319, 0.0249934039706891,
+ 0.0251283538895463, 0.0252537132938116, 0.0253763844489637, 0.0254990556041159,
+ 0.025621726759268, 0.0257443979144202, 0.0258670690695723, 0.0259897402247245,
+ 0.0261124113798766, 0.0262350825350287, 0.0263577536901809, 0.026480424845333,
+ 0.0266030960004852, 0.0267257671556373, 0.0268484383107894, 0.0269711094659416,
+ 0.0270937806210937, 0.0272164517762459, 0.027339122931398, 0.0274617940865502,
+ 0.0275844652417023, 0.0277071363968544, 0.0278298075520066, 0.0279524787071587,
+ 0.0280751498623109, 0.028197821017463, 0.0283191496967392, 0.0284325978310814,
+ 0.0285460459654235, 0.0286594940997656, 0.0287729422341078, 0.0288863903684499,
+ 0.0289998385027921, 0.0291132866371342, 0.0292267347714763, 0.0293401829058185,
+ 0.0294536310401606, 0.0295670791745027, 0.0296805273088449, 0.029793975443187,
+ 0.0299074235775291, 0.0300208717118713, 0.0301343198462134, 0.0302477679805556,
+ 0.0303612161148977, 0.0304746642492398, 0.030588112383582, 0.0307015605179241,
+ 0.0308150086522662, 0.0309284567866084, 0.0310419049209505, 0.0311553530552927,
+ 0.0312688011896348, 0.0313822493239769, 0.0314927071947135, 0.0315991351528125,
+ 0.0317055631109115, 0.0318119910690105, 0.0319184190271095, 0.0320248469852085,
+ 0.0321312749433075, 0.0322377029014065, 0.0323441308595055, 0.0324505588176045,
+ 0.0325569867757035, 0.0326634147338025, 0.0327698426919015, 0.0328762706500005,
+ 0.0329826986080995, 0.0330891265661985, 0.0331955545242975, 0.0333019824823965,
+ 0.0334084104404955, 0.0335148383985945, 0.0336212663566935, 0.0337276943147925,
+ 0.0338341222728914, 0.0339405502309904, 0.0340469781890894, 0.0341534061471884,
+ 0.0342598341052874, 0.0343662620633864, 0.0344726900214854, 0.0345791179795844,
+ 0.0346808292760102, 0.0347818846582893, 0.0348829400405684, 0.0349839954228475,
+ 0.0350850508051266, 0.0351861061874057, 0.0352871615696848, 0.0353882169519639,
+ 0.035489272334243, 0.0355903277165221, 0.0356913830988012, 0.0357924384810803,
+ 0.0358934938633594, 0.0359945492456386, 0.0360956046279177, 0.0361966600101968,
+ 0.0362977153924759, 0.036398770774755, 0.0364998261570341, 0.0366008815393132,
+ 0.0367019369215923, 0.0368029923038714, 0.0369040476861505, 0.0370051030684296,
+ 0.0371061584507087, 0.0372072138329878, 0.0373082692152669, 0.037409324597546,
+ 0.0375103799798251, 0.0376114353621042, 0.0377124907443833, 0.0378104328067266,
+ 0.0379073861256615, 0.0380043394445963, 0.0381012927635312, 0.0381982460824661,
+ 0.038295199401401, 0.0383921527203359, 0.0384891060392707, 0.0385860593582056,
+ 0.0386830126771405, 0.0387799659960754, 0.0388769193150103, 0.0389738726339452,
+ 0.03907082595288, 0.0391677792718149, 0.0392647325907498, 0.0393616859096847,
+ 0.0394586392286196, 0.0395555925475544, 0.0396525458664893, 0.0397494991854242,
+ 0.0398464525043591, 0.039943405823294, 0.0400403591422289, 0.0401373124611637,
+ 0.0402342657800986, 0.0403312190990335, 0.0404281724179684, 0.0405251257369033,
+ 0.0406220790558382, 0.040719032374773, 0.0408159856937079, 0.0409119375132289,
+ 0.0410057938746412, 0.0410996502360535, 0.0411935065974657, 0.041287362958878,
+ 0.0413812193202903, 0.0414750756817026, 0.0415689320431148, 0.0416627884045271,
+ 0.0417566447659394, 0.0418505011273517, 0.041944357488764, 0.0420382138501762,
+ 0.0421320702115885, 0.0422259265730008, 0.0423197829344131, 0.0424136392958253,
+ 0.0425074956572376, 0.0426013520186499, 0.0426952083800622, 0.0427890647414744,
+ 0.0428829211028867, 0.042976777464299, 0.0430706338257113, 0.0431644901871235,
+ 0.0432583465485358, 0.0433522029099481, 0.0434460592713604, 0.0435399156327726,
+ 0.0436337719941849, 0.0437276283555972, 0.0438214847170095, 0.0439153410784217,
+ 0.044009197439834, 0.0441011860517888, 0.0441927577863295, 0.0442843295208702,
+ 0.0443759012554109, 0.0444674729899515, 0.0445590447244922, 0.0446506164590329,
+ 0.0447421881935736, 0.0448337599281142, 0.0449253316626549, 0.0450169033971956,
+ 0.0451084751317363, 0.045200046866277, 0.0452916186008176, 0.0453831903353583,
+ 0.045474762069899, 0.0455663338044397, 0.0456579055389803, 0.045749477273521,
+ 0.0458410490080617, 0.0459326207426024, 0.046024192477143, 0.0461157642116837,
+ 0.0462073359462244, 0.0462989076807651, 0.0463904794153058, 0.0464820511498464,
+ 0.0465736228843871, 0.0466651946189278, 0.0467567663534685, 0.0468483380880092,
+ 0.0469399098225498, 0.0470314815570905, 0.0471230532916312, 0.0472138560223102,
+ 0.0473038113130788, 0.0473937666038474, 0.047483721894616, 0.0475736771853846,
+ 0.0476636324761531, 0.0477535877669217, 0.0478435430576903, 0.0479334983484589,
+ 0.0480234536392275, 0.0481134089299961, 0.0482033642207646, 0.0482933195115332,
+ 0.0483832748023018, 0.0484732300930704, 0.048563185383839, 0.0486531406746076,
+ 0.0487430959653761, 0.0488330512561447, 0.0489230065469133, 0.0490129618376819,
+ 0.0491029171284505, 0.0491928724192191, 0.0492828277099876, 0.0493727830007562,
+ 0.0494627382915248, 0.0495526935822934, 0.049642648873062, 0.0497326041638306,
+ 0.0498225594545991, 0.0499125147453677, 0.0500024700361363, 0.0500924253269049,
+ 0.0501823806176735, 0.0502723359084421, 0.0503617438051086, 0.0504506399890131,
+ 0.0505395361729176, 0.0506284323568221, 0.0507173285407266, 0.0508062247246311,
+ 0.0508951209085356, 0.0509840170924401, 0.0510729132763446, 0.0511618094602491,
+ 0.0512507056441536, 0.0513396018280581, 0.0514284980119626, 0.0515173941958671,
+ 0.0516062903797716, 0.0516951865636761, 0.0517840827475806, 0.0518729789314851,
+ 0.0519618751153896, 0.052050771299294, 0.0521396674831985, 0.052228563667103,
+ 0.0523174598510075, 0.052406356034912, 0.0524952522188165, 0.052584148402721,
+ 0.0526730445866255, 0.05276194077053, 0.0528508369544345, 0.052939733138339,
+ 0.0530286293222435, 0.053117525506148, 0.0532064216900525, 0.053295317873957,
+ 0.0533842140578615, 0.0534730268681487, 0.0535613336417097, 0.0536496404152707,
+ 0.0537379471888318, 0.0538262539623928, 0.0539145607359538, 0.0540028675095148,
+ 0.0540911742830758, 0.0541794810566368, 0.0542677878301979, 0.0543560946037589,
+ 0.0544444013773199, 0.0545327081508809, 0.0546210149244419, 0.0547093216980029,
+ 0.054797628471564, 0.054885935245125, 0.054974242018686, 0.055062548792247,
+ 0.055150855565808, 0.055239162339369, 0.0553274691129301, 0.0554157758864911,
+ 0.0555040826600521, 0.0555923894336131, 0.0556806962071741, 0.0557690029807351,
+ 0.0558573097542961, 0.0559456165278572, 0.0560339233014182, 0.0561222300749792,
+ 0.0562105368485402, 0.0562988436221012, 0.0563871503956622, 0.0564754571692233,
+ 0.0565637639427843, 0.0566519695187876, 0.056740085333522, 0.0568282011482563,
+ 0.0569163169629907, 0.0570044327777251, 0.0570925485924594, 0.0571806644071938,
+ 0.0572687802219281, 0.0573568960366625, 0.0574450118513969, 0.0575331276661312,
+ 0.0576212434808656, 0.0577093592955999, 0.0577974751103343, 0.0578855909250687,
+ 0.057973706739803, 0.0580618225545374, 0.0581499383692718, 0.0582380541840061,
+ 0.0583261699987405, 0.0584142858134749, 0.0585024016282092, 0.0585905174429436,
+ 0.0586786332576779, 0.0587667490724123, 0.0588548648871467, 0.058942980701881,
+ 0.0590310965166154, 0.0591192123313497, 0.0592073281460841, 0.0592954439608185,
+ 0.0593835597755528, 0.0594716755902872, 0.0595597914050216, 0.0596479072197559,
+ 0.0597360230344903, 0.0598242633395279, 0.059912527134813, 0.0600007909300981,
+ 0.0600890547253831, 0.0601773185206682, 0.0602655823159533, 0.0603538461112383,
+ 0.0604421099065234, 0.0605303737018084, 0.0606186374970935, 0.0607069012923786,
+ 0.0607951650876636, 0.0608834288829487, 0.0609716926782338, 0.0610599564735188,
+ 0.0611482202688039, 0.0612364840640889, 0.061324747859374, 0.0614130116546591,
+ 0.0615012754499441, 0.0615895392452292, 0.0616778030405143, 0.0617660668357993,
+ 0.0618543306310844, 0.0619425944263694, 0.0620308582216545, 0.0621191220169396,
+ 0.0622073858122246, 0.0622956496075097, 0.0623839134027948, 0.0624721771980798,
+ 0.0625604409933649, 0.0626487047886499, 0.062736968583935, 0.0628252323792201,
+ 0.0629135887738314, 0.0630022885096577, 0.0630909882454839, 0.0631796879813101,
+ 0.0632683877171364, 0.0633570874529626, 0.0634457871887889, 0.0635344869246152,
+ 0.0636231866604414, 0.0637118863962677, 0.0638005861320939, 0.0638892858679202,
+ 0.0639779856037464, 0.0640666853395727, 0.0641553850753989, 0.0642440848112252,
+ 0.0643327845470514, 0.0644214842828777, 0.0645101840187039, 0.0645988837545302,
+ 0.0646875834903564, 0.0647762832261827, 0.0648649829620089, 0.0649536826978352,
+ 0.0650423824336614, 0.0651310821694877, 0.0652197819053139, 0.0653084816411402,
+ 0.0653971813769664, 0.0654858811127927, 0.0655745808486189, 0.0656632805844452,
+ 0.0657519803202714, 0.0658406800560977, 0.0659293797919239, 0.0660180795277502,
+ 0.0661072946220499, 0.0661966736476265, 0.066286052673203, 0.0663754316987796,
+ 0.0664648107243562, 0.0665541897499328, 0.0666435687755094, 0.066732947801086,
+ 0.0668223268266626, 0.0669117058522391, 0.0670010848778157, 0.0670904639033923,
+ 0.0671798429289689, 0.0672692219545455, 0.0673586009801221, 0.0674479800056987,
+ 0.0675373590312753, 0.0676267380568518, 0.0677161170824284, 0.067805496108005,
+ 0.0678948751335816, 0.0679842541591582, 0.0680736331847348, 0.0681630122103114,
+ 0.068252391235888, 0.0683417702614646, 0.0684311492870411, 0.0685205283126177,
+ 0.0686099073381943, 0.0686992863637709, 0.0687886653893475, 0.0688780444149241,
+ 0.0689674234405007, 0.0690568024660772, 0.0691461814916538, 0.0692360676941551,
+ 0.0693263297119362, 0.0694165917297173, 0.0695068537474984, 0.0695971157652796,
+ 0.0696873777830607, 0.0697776398008418, 0.069867901818623, 0.0699581638364041,
+ 0.0700484258541852, 0.0701386878719663, 0.0702289498897475, 0.0703192119075286,
+ 0.0704094739253097, 0.0704997359430908, 0.070589997960872, 0.0706802599786531,
+ 0.0707705219964342, 0.0708607840142153, 0.0709510460319965, 0.0710413080497776,
+ 0.0711315700675587, 0.0712218320853398, 0.071312094103121, 0.0714023561209021,
+ 0.0714926181386832, 0.0715828801564643, 0.0716731421742455, 0.0717634041920266,
+ 0.0718536662098077, 0.0719439282275889, 0.07203419024537, 0.0721244522631511,
+ 0.0722147142809322, 0.0723049762987134, 0.0723960101828217, 0.0724873233770361,
+ 0.0725786365712504, 0.0726699497654648, 0.0727612629596791, 0.0728525761538934,
+ 0.0729438893481078, 0.0730352025423221, 0.0731265157365365, 0.0732178289307508,
+ 0.0733091421249651, 0.0734004553191795, 0.0734917685133938, 0.0735830817076082,
+ 0.0736743949018225, 0.0737657080960368, 0.0738570212902512, 0.0739483344844655,
+ 0.0740396476786799, 0.0741309608728942, 0.0742222740671085, 0.0743135872613229,
+ 0.0744049004555372, 0.0744962136497516, 0.0745875268439659, 0.0746788400381802,
+ 0.0747701532323946, 0.0748614664266089, 0.0749527796208233, 0.0750440928150376,
+ 0.0751354060092519, 0.0752267192034663, 0.0753180323976806, 0.075409345591895,
+ 0.0755010094289928, 0.0755935101846347, 0.0756860109402766, 0.0757785116959184,
+ 0.0758710124515603, 0.0759635132072022, 0.076056013962844, 0.0761485147184859,
+ 0.0762410154741277, 0.0763335162297696, 0.0764260169854115, 0.0765185177410533,
+ 0.0766110184966952, 0.0767035192523371, 0.0767960200079789, 0.0768885207636208,
+ 0.0769810215192626, 0.0770735222749045, 0.0771660230305464, 0.0772585237861882,
+ 0.0773510245418301, 0.0774435252974719, 0.0775360260531138, 0.0776285268087557,
+ 0.0777210275643975, 0.0778135283200394, 0.0779060290756813, 0.0779985298313231,
+ 0.078091030586965, 0.0781835313426068, 0.0782760320982487, 0.0783685328538906,
+ 0.0784610336095324, 0.0785535343651743, 0.078646421750512, 0.0787402182702954,
+ 0.0788340147900788, 0.0789278113098621, 0.0790216078296455, 0.0791154043494289,
+ 0.0792092008692122, 0.0793029973889956, 0.079396793908779, 0.0794905904285623,
+ 0.0795843869483457, 0.0796781834681291, 0.0797719799879124, 0.0798657765076958,
+ 0.0799595730274791, 0.0800533695472625, 0.0801471660670459, 0.0802409625868293,
+ 0.0803347591066126, 0.080428555626396, 0.0805223521461793, 0.0806161486659627,
+ 0.0807099451857461, 0.0808037417055294, 0.0808975382253128, 0.0809913347450962,
+ 0.0810851312648795, 0.0811789277846629, 0.0812727243044463, 0.0813665208242296,
+ 0.081460317344013, 0.0815541138637964, 0.0816479103835797, 0.0817417069033631,
+ 0.0818365672265629, 0.0819317432475666, 0.0820269192685703, 0.0821220952895741,
+ 0.0822172713105778, 0.0823124473315815, 0.0824076233525853, 0.082502799373589,
+ 0.0825979753945927, 0.0826931514155965, 0.0827883274366002, 0.0828835034576039,
+ 0.0829786794786076, 0.0830738554996114, 0.0831690315206151, 0.0832642075416188,
+ 0.0833593835626226, 0.0834545595836263, 0.08354973560463, 0.0836449116256338,
+ 0.0837400876466375, 0.0838352636676412, 0.0839304396886449, 0.0840256157096487,
+ 0.0841207917306524, 0.0842159677516561, 0.0843111437726599, 0.0844063197936636,
+ 0.0845014958146673, 0.0845966718356711, 0.0846918478566748, 0.0847870238776785,
+ 0.0848821998986822, 0.0849784289019381, 0.085075047616302, 0.0851716663306659,
+ 0.0852682850450297, 0.0853649037593936, 0.0854615224737575, 0.0855581411881213,
+ 0.0856547599024852, 0.0857513786168491, 0.0858479973312129, 0.0859446160455768,
+ 0.0860412347599407, 0.0861378534743045, 0.0862344721886684, 0.0863310909030323,
+ 0.0864277096173961, 0.08652432833176, 0.0866209470461239, 0.0867175657604877,
+ 0.0868141844748516, 0.0869108031892155, 0.0870074219035793, 0.0871040406179432,
+ 0.0872006593323071, 0.0872972780466709, 0.0873938967610348, 0.0874905154753987,
+ 0.0875871341897625, 0.0876837529041264, 0.0877803716184903, 0.0878769903328541,
+ 0.087973609047218, 0.0880704987888095, 0.0881686069849526, 0.0882667151810957,
+ 0.0883648233772388, 0.0884629315733819, 0.088561039769525, 0.088659147965668,
+ 0.0887572561618111, 0.0888553643579542, 0.0889534725540973, 0.0890515807502404,
+ 0.0891496889463834, 0.0892477971425265, 0.0893459053386696, 0.0894440135348127,
+ 0.0895421217309558, 0.0896402299270989, 0.0897383381232419, 0.089836446319385,
+ 0.0899345545155281, 0.0900326627116712, 0.0901307709078143, 0.0902288791039574,
+ 0.0903269873001004, 0.0904250954962435, 0.0905232036923866, 0.0906213118885297,
+ 0.0907194200846728, 0.0908175282808159, 0.0909156364769589, 0.091013744673102,
+ 0.0911118528692451, 0.0912101564524853, 0.091309788819085, 0.0914094211856847,
+ 0.0915090535522844, 0.0916086859188841, 0.0917083182854838, 0.0918079506520835,
+ 0.0919075830186832, 0.0920072153852829, 0.0921068477518826, 0.0922064801184823,
+ 0.092306112485082, 0.0924057448516817, 0.0925053772182814, 0.0926050095848811,
+ 0.0927046419514808, 0.0928042743180805, 0.0929039066846802, 0.0930035390512799,
+ 0.0931031714178795, 0.0932028037844792, 0.0933024361510789, 0.0934020685176786,
+ 0.0935017008842783, 0.093601333250878, 0.0937009656174777, 0.0938005979840774,
+ 0.0939002303506771, 0.0939998627172768, 0.0940994950838765, 0.0941991274504762,
+ 0.0942987598170759, 0.0943992682225221, 0.0945004517019513, 0.0946016351813804,
+ 0.0947028186608096, 0.0948040021402388, 0.0949051856196679, 0.0950063690990971,
+ 0.0951075525785263, 0.0952087360579554, 0.0953099195373846, 0.0954111030168138,
+ 0.095512286496243, 0.0956134699756721, 0.0957146534551013, 0.0958158369345305,
+ 0.0959170204139596, 0.0960182038933888, 0.0961193873728179, 0.0962205708522471,
+ 0.0963217543316763, 0.0964229378111054, 0.0965241212905346, 0.0966253047699638,
+ 0.096726488249393, 0.0968276717288221, 0.0969288552082513, 0.0970300386876805,
+ 0.0971312221671096, 0.0972324056465388, 0.097333589125968, 0.0974347726053971,
+ 0.0975367201066298, 0.0976394781515203, 0.0977422361964109, 0.0978449942413014,
+ 0.0979477522861919, 0.0980505103310825, 0.098153268375973, 0.0982560264208636,
+ 0.0983587844657541, 0.0984615425106447, 0.0985643005555352, 0.0986670586004257,
+ 0.0987698166453163, 0.0988725746902068, 0.0989753327350974, 0.0990780907799879,
+ 0.0991808488248785, 0.099283606869769, 0.0993863649146595, 0.0994891229595501,
+ 0.0995918810044406, 0.0996946390493312, 0.0997973970942217, 0.0999001551391123,
+ 0.100002913184003, 0.100105671228893, 0.100208429273784, 0.100311187318674,
+ 0.100413945363565, 0.100516703408456, 0.100619461453346, 0.100723629254328,
+ 0.100827985831608, 0.100932342408888, 0.101036698986168, 0.101141055563448,
+ 0.101245412140728, 0.101349768718008, 0.101454125295288, 0.101558481872568,
+ 0.101662838449848, 0.101767195027128, 0.101871551604408, 0.101975908181688,
+ 0.102080264758968, 0.102184621336248, 0.102288977913528, 0.102393334490808,
+ 0.102497691068088, 0.102602047645368, 0.102706404222648, 0.102810760799928,
+ 0.102915117377208, 0.103019473954489, 0.103123830531769, 0.103228187109049,
+ 0.103332543686329, 0.103436900263609, 0.103541256840889, 0.103645613418169,
+ 0.103749969995449, 0.103855542256336, 0.103961525455448, 0.10406750865456,
+ 0.104173491853672, 0.104279475052784, 0.104385458251896, 0.104491441451008,
+ 0.10459742465012, 0.104703407849232, 0.104809391048344, 0.104915374247456,
+ 0.105021357446568, 0.10512734064568, 0.105233323844792, 0.105339307043904,
+ 0.105445290243016, 0.105551273442128, 0.10565725664124, 0.105763239840352,
+ 0.105869223039463, 0.105975206238575, 0.106081189437687, 0.106187172636799,
+ 0.106293155835911, 0.106399139035023, 0.106505122234135, 0.106611105433247,
+ 0.106717088632359, 0.106823071831471, 0.106929180224288, 0.107036825355525,
+ 0.107144470486762, 0.107252115617999, 0.107359760749236, 0.107467405880472,
+ 0.107575051011709, 0.107682696142946, 0.107790341274183, 0.10789798640542,
+ 0.108005631536657, 0.108113276667893, 0.10822092179913, 0.108328566930367,
+ 0.108436212061604, 0.108543857192841, 0.108651502324078, 0.108759147455314,
+ 0.108866792586551, 0.108974437717788, 0.109082082849025, 0.109189727980262,
+ 0.109297373111499, 0.109405018242735, 0.109512663373972, 0.109620308505209,
+ 0.109727953636446, 0.109835598767683, 0.109943243898919, 0.110050889030156,
+ 0.110160004550903, 0.110269356659303, 0.110378708767703, 0.110488060876102,
+ 0.110597412984502, 0.110706765092902, 0.110816117201301, 0.110925469309701,
+ 0.111034821418101, 0.111144173526501, 0.1112535256349, 0.1113628777433,
+ 0.1114722298517, 0.111581581960099, 0.111690934068499, 0.111800286176899,
+ 0.111909638285299, 0.112018990393698, 0.112128342502098, 0.112237694610498,
+ 0.112347046718897, 0.112456398827297, 0.112565750935697, 0.112675103044096,
+ 0.112784455152496, 0.112893807260896, 0.113003159369296, 0.113112511477695,
+ 0.113222046117384, 0.113333161880498, 0.113444277643611, 0.113555393406725,
+ 0.113666509169839, 0.113777624932953, 0.113888740696067, 0.113999856459181,
+ 0.114110972222295, 0.114222087985409, 0.114333203748523, 0.114444319511637,
+ 0.114555435274751, 0.114666551037865, 0.114777666800979, 0.114888782564093,
+ 0.114999898327207, 0.115111014090321, 0.115222129853435, 0.115333245616548,
+ 0.115444361379662, 0.115555477142776, 0.11566659290589, 0.115777708669004,
+ 0.115888824432118, 0.115999940195232, 0.116111055958346, 0.11622217172146,
+ 0.116333287484574, 0.116445873599659, 0.116558822617734, 0.116671771635809,
+ 0.116784720653884, 0.116897669671959, 0.117010618690034, 0.117123567708109,
+ 0.117236516726183, 0.117349465744258, 0.117462414762333, 0.117575363780408,
+ 0.117688312798483, 0.117801261816558, 0.117914210834633, 0.118027159852708,
+ 0.118140108870782, 0.118253057888857, 0.118366006906932, 0.118478955925007,
+ 0.118591904943082, 0.118704853961157, 0.118817802979232, 0.118930751997306,
+ 0.119043701015381, 0.119156650033456, 0.119269599051531, 0.119382548069606,
+ 0.119495497087681, 0.119610285849454, 0.119725151369885, 0.119840016890317,
+ 0.119954882410748, 0.12006974793118, 0.120184613451611, 0.120299478972043,
+ 0.120414344492474, 0.120529210012906, 0.120644075533337, 0.120758941053769,
+ 0.1208738065742, 0.120988672094632, 0.121103537615063, 0.121218403135495,
+ 0.121333268655926, 0.121448134176358, 0.121562999696789, 0.121677865217221,
+ 0.121792730737652, 0.121907596258083, 0.122022461778515, 0.122137327298946,
+ 0.122252192819378, 0.122367058339809, 0.122481923860241, 0.122596789380672,
+ 0.122712827616384, 0.122829706758501, 0.122946585900619, 0.123063465042737,
+ 0.123180344184855, 0.123297223326972, 0.12341410246909, 0.123530981611208,
+ 0.123647860753326, 0.123764739895444, 0.123881619037561, 0.123998498179679,
+ 0.124115377321797, 0.124232256463915, 0.124349135606032, 0.12446601474815,
+ 0.124582893890268, 0.124699773032386, 0.124816652174504, 0.124933531316621,
+ 0.125050410458739, 0.125167289600857, 0.125284168742975, 0.125401047885093,
+ 0.12551792702721, 0.125634806169328, 0.125751685311446, 0.125870001624282,
+ 0.125989005185262, 0.126108008746242, 0.126227012307222, 0.126346015868202,
+ 0.126465019429183, 0.126584022990163, 0.126703026551143, 0.126822030112123,
+ 0.126941033673104, 0.127060037234084, 0.127179040795064, 0.127298044356044,
+ 0.127417047917024, 0.127536051478005, 0.127655055038985, 0.127774058599965,
+ 0.127893062160945, 0.128012065721925, 0.128131069282906, 0.128250072843886,
+ 0.128369076404866, 0.128488079965846, 0.128607083526826, 0.128726087087807,
+ 0.128845090648787, 0.128964658385504, 0.12908591031452, 0.129207162243537,
+ 0.129328414172554, 0.129449666101571, 0.129570918030588, 0.129692169959604,
+ 0.129813421888621, 0.129934673817638, 0.130055925746655, 0.130177177675671,
+ 0.130298429604688, 0.130419681533705, 0.130540933462722, 0.130662185391739,
+ 0.130783437320756, 0.130904689249772, 0.131025941178789, 0.131147193107806,
+ 0.131268445036823, 0.131389696965839, 0.131510948894856, 0.131632200823873,
+ 0.13175345275289, 0.131874704681907, 0.131995956610923, 0.132117960580623,
+ 0.132241597208114, 0.132365233835605, 0.132488870463096, 0.132612507090587,
+ 0.132736143718078, 0.132859780345569, 0.13298341697306, 0.133107053600551,
+ 0.133230690228042, 0.133354326855533, 0.133477963483024, 0.133601600110515,
+ 0.133725236738006, 0.133848873365497, 0.133972509992989, 0.13409614662048,
+ 0.134219783247971, 0.134343419875462, 0.134467056502953, 0.134590693130444,
+ 0.134714329757935, 0.134837966385426, 0.134961603012917, 0.135085239640408,
+ 0.135208876267899, 0.135334741574242, 0.135460910678424, 0.135587079782606,
+ 0.135713248886787, 0.135839417990969, 0.13596558709515, 0.136091756199332,
+ 0.136217925303513, 0.136344094407695, 0.136470263511876, 0.136596432616058,
+ 0.136722601720239, 0.136848770824421, 0.136974939928602, 0.137101109032784,
+ 0.137227278136966, 0.137353447241147, 0.137479616345329, 0.13760578544951,
+ 0.137731954553692, 0.137858123657873, 0.137984292762055, 0.138110461866236,
+ 0.138236630970418, 0.138362800074599, 0.13849153947217, 0.13862039925771,
+ 0.13874925904325, 0.138878118828789, 0.139006978614329, 0.139135838399868,
+ 0.139264698185408, 0.139393557970948, 0.139522417756487, 0.139651277542027,
+ 0.139780137327567, 0.139908997113106, 0.140037856898646, 0.140166716684185,
+ 0.140295576469725, 0.140424436255265, 0.140553296040804, 0.140682155826344,
+ 0.140811015611884, 0.140939875397423, 0.141068735182963, 0.141197594968502,
+ 0.141326454754042, 0.141455314539582, 0.141585749009815, 0.141717467065314,
+ 0.141849185120812, 0.14198090317631, 0.142112621231808, 0.142244339287306,
+ 0.142376057342804, 0.142507775398303, 0.142639493453801, 0.142771211509299,
+ 0.142902929564797, 0.143034647620295, 0.143166365675793, 0.143298083731292,
+ 0.14342980178679, 0.143561519842288, 0.143693237897786, 0.143824955953284,
+ 0.143956674008782, 0.144088392064281, 0.144220110119779, 0.144351828175277,
+ 0.144483546230775, 0.144615264286273, 0.1447490339688, 0.144883786261577,
+ 0.145018538554355, 0.145153290847132, 0.145288043139909, 0.145422795432687,
+ 0.145557547725464, 0.145692300018242, 0.145827052311019, 0.145961804603797,
+ 0.146096556896574, 0.146231309189352, 0.146366061482129, 0.146500813774907,
+ 0.146635566067684, 0.146770318360462, 0.146905070653239, 0.147039822946016,
+ 0.147174575238794, 0.147309327531571, 0.147444079824349, 0.147578832117126,
+ 0.147713584409904, 0.147849427450957, 0.147987397410062, 0.148125367369167,
+ 0.148263337328272, 0.148401307287377, 0.148539277246481, 0.148677247205586,
+ 0.148815217164691, 0.148953187123796, 0.149091157082901, 0.149229127042006,
+ 0.149367097001111, 0.149505066960216, 0.14964303691932, 0.149781006878425,
+ 0.14991897683753, 0.150056946796635, 0.15019491675574, 0.150332886714845,
+ 0.15047085667395, 0.150608826633055, 0.150746796592159, 0.150884766551264,
+ 0.15102459740471, 0.151165975136252, 0.151307352867794, 0.151448730599335,
+ 0.151590108330877, 0.151731486062418, 0.15187286379396, 0.152014241525502,
+ 0.152155619257043, 0.152296996988585, 0.152438374720127, 0.152579752451668,
+ 0.15272113018321, 0.152862507914751, 0.153003885646293, 0.153145263377835,
+ 0.153286641109376, 0.153428018840918, 0.15356939657246, 0.153710774304001,
+ 0.153852152035543, 0.153993529767084, 0.154135997909478, 0.154280979582231,
+ 0.154425961254984, 0.154570942927738, 0.154715924600491, 0.154860906273244,
+ 0.155005887945997, 0.15515086961875, 0.155295851291504, 0.155440832964257,
+ 0.15558581463701, 0.155730796309763, 0.155875777982516, 0.156020759655269,
+ 0.156165741328023, 0.156310723000776, 0.156455704673529, 0.156600686346282,
+ 0.156745668019035, 0.156890649691789, 0.157035631364542, 0.157180613037295,
+ 0.15732792374043, 0.157476711173768, 0.157625498607107, 0.157774286040445,
+ 0.157923073473783, 0.158071860907122, 0.15822064834046, 0.158369435773798,
+ 0.158518223207137, 0.158667010640475, 0.158815798073813, 0.158964585507152,
+ 0.15911337294049, 0.159262160373828, 0.159410947807167, 0.159559735240505,
+ 0.159708522673843, 0.159857310107182, 0.16000609754052, 0.160154884973858,
+ 0.160303672407197, 0.160454370862285, 0.160607171342644, 0.160759971823002,
+ 0.16091277230336, 0.161065572783718, 0.161218373264077, 0.161371173744435,
+ 0.161523974224793, 0.161676774705151, 0.16182957518551, 0.161982375665868,
+ 0.162135176146226, 0.162287976626584, 0.162440777106943, 0.162593577587301,
+ 0.162746378067659, 0.162899178548017, 0.163051979028376, 0.163204779508734,
+ 0.163357579989092, 0.16351038046945, 0.163666965317135, 0.163823991662984,
+ 0.163981018008832, 0.164138044354681, 0.16429507070053, 0.164452097046379,
+ 0.164609123392228, 0.164766149738077, 0.164923176083925, 0.165080202429774,
+ 0.165237228775623, 0.165394255121472, 0.165551281467321, 0.16570830781317,
+ 0.165865334159018, 0.166022360504867, 0.166179386850716, 0.166336413196565,
+ 0.166493439542414, 0.166650465888263, 0.166811353257257, 0.166972824145877,
+ 0.167134295034498, 0.167295765923119, 0.16745723681174, 0.167618707700361,
+ 0.167780178588982, 0.167941649477603, 0.168103120366224, 0.168264591254845,
+ 0.168426062143466, 0.168587533032087, 0.168749003920708, 0.168910474809329,
+ 0.16907194569795, 0.169233416586571, 0.169394887475191, 0.169556358363812,
+ 0.169717829252433, 0.169881135986996, 0.170047276549132, 0.170213417111268,
+ 0.170379557673404, 0.17054569823554, 0.170711838797676, 0.170877979359812,
+ 0.171044119921948, 0.171210260484084, 0.17137640104622, 0.171542541608356,
+ 0.171708682170492, 0.171874822732628, 0.172040963294764, 0.1722071038569,
+ 0.172373244419036, 0.172539384981172, 0.172705525543308, 0.172871666105445,
+ 0.173040085999429, 0.173211128680302, 0.173382171361174, 0.173553214042047,
+ 0.17372425672292, 0.173895299403793, 0.174066342084665, 0.174237384765538,
+ 0.174408427446411, 0.174579470127283, 0.174750512808156, 0.174921555489029,
+ 0.175092598169902, 0.175263640850774, 0.175434683531647, 0.17560572621252,
+ 0.175776768893392, 0.175947811574265, 0.176119261994817, 0.17629544767239,
+ 0.176471633349963, 0.176647819027536, 0.176824004705109, 0.177000190382682,
+ 0.177176376060256, 0.177352561737829, 0.177528747415402, 0.177704933092975,
+ 0.177881118770548, 0.178057304448121, 0.178233490125694, 0.178409675803267,
+ 0.17858586148084, 0.178762047158413, 0.178938232835986, 0.179114418513559,
+ 0.179291846271207, 0.179473425615275, 0.179655004959343, 0.179836584303412,
+ 0.18001816364748, 0.180199742991548, 0.180381322335617, 0.180562901679685,
+ 0.180744481023753, 0.180926060367821, 0.18110763971189, 0.181289219055958,
+ 0.181470798400026, 0.181652377744095, 0.181833957088163, 0.182015536432231,
+ 0.182197115776299, 0.182378695120368, 0.182565429521855, 0.182752664571132,
+ 0.182939899620409, 0.183127134669687, 0.183314369718964, 0.183501604768241,
+ 0.183688839817518, 0.183876074866796, 0.184063309916073, 0.18425054496535,
+ 0.184437780014627, 0.184625015063905, 0.184812250113182, 0.184999485162459,
+ 0.185186720211736, 0.185373955261014, 0.185561877182958, 0.185755043112146,
+ 0.185948209041333, 0.18614137497052, 0.186334540899708, 0.186527706828895,
+ 0.186720872758082, 0.186914038687269, 0.187107204616457, 0.187300370545644,
+ 0.187493536474831, 0.187686702404018, 0.187879868333206, 0.188073034262393,
+ 0.18826620019158, 0.188459366120767, 0.188652532049955, 0.188850897795331,
+ 0.189050284840682, 0.189249671886032, 0.189449058931383, 0.189648445976733,
+ 0.189847833022084, 0.190047220067434, 0.190246607112785, 0.190445994158135,
+ 0.190645381203486, 0.190844768248836, 0.191044155294186, 0.191243542339537,
+ 0.191442929384887, 0.191642316430238, 0.191842120048372, 0.192048035558685,
+ 0.192253951068997, 0.19245986657931, 0.192665782089623, 0.192871697599936,
+ 0.193077613110249, 0.193283528620561, 0.193489444130874, 0.193695359641187,
+ 0.1939012751515, 0.194107190661812, 0.194313106172125, 0.194519021682438,
+ 0.194724937192751, 0.194930852703063, 0.195142196260036, 0.195354966840488,
+ 0.195567737420939, 0.195780508001391, 0.195993278581843, 0.196206049162294,
+ 0.196418819742746, 0.196631590323197, 0.196844360903649, 0.1970571314841,
+ 0.197269902064552, 0.197482672645003, 0.197695443225455, 0.197908213805906,
+ 0.198121069994851, 0.198341043713548, 0.198561017432244, 0.198780991150941,
+ 0.199000964869638, 0.199220938588335, 0.199440912307032, 0.199660886025729,
+ 0.199880859744426, 0.200100833463123, 0.20032080718182, 0.200540780900516,
+ 0.200760754619213, 0.20098072833791, 0.201200702056607, 0.201426098778158,
+ 0.201653647409568, 0.201881196040977, 0.202108744672387, 0.202336293303797,
+ 0.202563841935207, 0.202791390566617, 0.203018939198027, 0.203246487829437,
+ 0.203474036460846, 0.203701585092256, 0.203929133723666, 0.204156682355076,
+ 0.204384230986486, 0.204618921911524, 0.204854443196773, 0.205089964482023,
+ 0.205325485767273, 0.205561007052523, 0.205796528337772, 0.206032049623022,
+ 0.206267570908272, 0.206503092193521, 0.206738613478771, 0.206974134764021,
+ 0.207209656049271, 0.20744517733452, 0.207685264164212, 0.207929184075172,
+ 0.208173103986132, 0.208417023897092, 0.208660943808051, 0.208904863719011,
+ 0.209148783629971, 0.209392703540931, 0.209636623451891, 0.20988054336285,
+ 0.21012446327381, 0.21036838318477, 0.21061230309573, 0.210861988612869,
+ 0.211114763614686, 0.211367538616503, 0.21162031361832, 0.211873088620137,
+ 0.212125863621954, 0.212378638623771, 0.212631413625588, 0.212884188627405,
+ 0.213136963629222, 0.213389738631039, 0.213642513632856, 0.21389725328031,
+ 0.21415937259508, 0.214421491909849, 0.214683611224619, 0.214945730539388,
+ 0.215207849854158, 0.215469969168927, 0.215732088483697, 0.215994207798466,
+ 0.216256327113236, 0.216518446428005, 0.216780565742775, 0.217044786070963,
+ 0.217316773953234, 0.217588761835504, 0.217860749717775, 0.218132737600046,
+ 0.218404725482316, 0.218676713364587, 0.218948701246858, 0.219220689129129,
+ 0.219492677011399, 0.21976466489367, 0.220036652775941, 0.220315429127038,
+ 0.220597847169457, 0.220880265211875, 0.221162683254294, 0.221445101296713,
+ 0.221727519339132, 0.222009937381551, 0.222292355423969, 0.222574773466388,
+ 0.222857191508807, 0.223139609551226, 0.22342771767927, 0.223721167173466,
+ 0.224014616667663, 0.224308066161859, 0.224601515656055, 0.224894965150251,
+ 0.225188414644448, 0.225481864138644, 0.22577531363284, 0.226068763127036,
+ 0.226362212621233, 0.226664994482626, 0.226970118866384, 0.227275243250142,
+ 0.2275803676339, 0.227885492017658, 0.228190616401416, 0.228495740785174,
+ 0.228800865168932, 0.22910598955269, 0.229411113936448, 0.229722332589382,
+ 0.23003982001567, 0.230357307441958, 0.230674794868246, 0.230992282294534,
+ 0.231309769720823, 0.231627257147111, 0.231944744573399, 0.232262231999687,
+ 0.232579719425975, 0.232904907091642, 0.233235493158276, 0.233566079224911,
+ 0.233896665291545, 0.234227251358179, 0.234557837424813, 0.234888423491448,
+ 0.235219009558082, 0.235549595624716, 0.23588122654071, 0.23622569722098,
+ 0.236570167901249, 0.236914638581519, 0.237259109261789, 0.237603579942058,
+ 0.237948050622328, 0.238292521302597, 0.238636991982867, 0.238981462663137,
+ 0.239339863330258, 0.239699058144633, 0.240058252959007, 0.240417447773382,
+ 0.240776642587756, 0.241135837402131, 0.241495032216506, 0.24185422703088,
+ 0.242216406978558, 0.242591222445708, 0.242966037912857, 0.243340853380006,
+ 0.243715668847156, 0.244090484314305, 0.244465299781455, 0.244840115248604,
+ 0.245214930715753, 0.245603025218856, 0.245994418620466, 0.246385812022076,
+ 0.246777205423686, 0.247168598825296, 0.247559992226905, 0.247951385628515,
+ 0.248342779030125, 0.248747659098606, 0.249156652587053, 0.2495656460755,
+ 0.249974639563947, 0.250383633052394, 0.250792626540841, 0.251201620029289,
+ 0.251612058698921, 0.252039743769879, 0.252467428840838, 0.252895113911796,
+ 0.253322798982754, 0.253750484053712, 0.25417816912467, 0.254605854195628,
+ 0.255047923667439, 0.255495466011053, 0.255943008354667, 0.256390550698281,
+ 0.256838093041895, 0.257285635385509, 0.257733177729124, 0.258195443386208,
+ 0.258664088120685, 0.259132732855161, 0.259601377589638, 0.260070022324114,
+ 0.260538667058591, 0.261007311793068, 0.261498107058485, 0.261989184339014,
+ 0.262480261619543, 0.262971338900072, 0.263462416180601, 0.26395349346113,
+ 0.264458493569672, 0.264973424553304, 0.265488355536937, 0.266003286520569,
+ 0.266518217504202, 0.267033148487834, 0.267560171105367, 0.268100474238653,
+ 0.268640777371939, 0.269181080505224, 0.26972138363851, 0.270261686771796,
+ 0.270819705028464, 0.271387002608867, 0.271954300189269, 0.272521597769672,
+ 0.273088895350075, 0.273659435845581, 0.274255460789027, 0.274851485732473,
+ 0.275447510675919, 0.276043535619365, 0.276639560562811, 0.27726116998853,
+ 0.277887772713072, 0.278514375437614, 0.279140978162156, 0.279767580886698,
+ 0.280420811353434, 0.281079966661232, 0.281739121969031, 0.282398277276829,
+ 0.283059066113607, 0.283752879919502, 0.284446693725398, 0.285140507531294,
+ 0.28583432133719, 0.286547124650447, 0.287277840363085, 0.288008556075722,
+ 0.28873927178836, 0.28947827559471, 0.290248279904922, 0.291018284215134,
+ 0.291788288525346, 0.292563600337405, 0.293375428108293, 0.294187255879181,
+ 0.294999083650069, 0.295822183677325, 0.296678521560245, 0.297534859443166,
+ 0.298391197326086, 0.299275043092916, 0.300178731417868, 0.301082419742821,
+ 0.301991195383678, 0.302945227793297, 0.303899260202916, 0.304853292612535,
+ 0.305850371610192, 0.306857891831609, 0.307865412053027, 0.308911739467469,
+ 0.30997603455584, 0.311040329644211, 0.3121484923185, 0.313272981669674,
+ 0.314397471020849, 0.315581367988403, 0.316769587425637, 0.317977043703226,
+ 0.319232624005811, 0.320488204308396, 0.321799279628635, 0.323125919008203,
+ 0.324483261263213, 0.325884691519315, 0.327299200035216, 0.328779146439744,
+ 0.330262517515396, 0.331824652884333, 0.333389238077772, 0.335037131964496,
+ 0.336695746759716, 0.338432811211082, 0.340198496730592, 0.342027930528006,
+ 0.343913675793935, 0.345838409480119, 0.347856846578894, 0.3499197798127,
+ 0.352042579297134, 0.354259302490772, 0.356536561493589, 0.358881109319561,
+ 0.361313671166056, 0.363836817926778, 0.366439748491679, 0.369127446160857,
+ 0.371904231534573, 0.374773682388992, 0.377738570378694, 0.380800810162814,
+ 0.383961415989582, 0.387220461700673, 0.390577042394362, 0.394029239174462,
+ 0.397574091869165, 0.401207587569535, 0.404924674602348, 0.40871931155475,
+ 0.412593091812825, 0.416529405960117, 0.420518172148167, 0.424550658028915,
+ 0.428622797503118, 0.432718860047201, 0.43683110495589, 0.440952990102399,
+ 0.445076899215516, 0.449197788292571, 0.453311201371651, 0.45741409960577,
+ 0.461505869878849, 0.46558559365979, 0.469652236896929, 0.473708637399971,
+ 0.477756372989858, 0.481796989922385, 0.48583413706365, 0.48987125467134,
+ 0.493912219101465, 0.497962736080536, 0.502026812075268, 0.506109594319579,
+ 0.510221399822655, 0.514366957318452, 0.518552310031674, 0.522793051201349,
+ 0.527095750969031, 0.531466650081574, 0.535935589143574, 0.540497859381824,
+ 0.54518677008268, 0.55000657107477, 0.55499781241368, 0.570387005978552,
+ 0.575784020390147, 0.581355522358758, 0.587107695883691, 0.593047270300356,
+ 0.599186533270629, 0.605538121640565, 0.612115028481841, 0.61893061023499,
+ 0.626001861804575, 0.633353622260075, 0.640990719796521, 0.648946229610552,
+ 0.657230965238893, 0.665888971698384, 0.674935579636987, 0.68440554485823,
+ 0.694335038623836, 0.704766859548509, 0.71575271257307, 0.727336811019529,
+ 0.739584089095298, 0.752568375665671, 0.766367354784415, 0.781079093721498,
+ 0.79681569276495, 0.813711227439116, 0.831930890200451, 0.85166548254417,
+ 0.873163787875069, 0.896719943817702, 0.922723548624586, 0.951660429762437,
+ 0.984178161492999, 1.02116199287154, 1.06381685448612, 1.11388721526635,
+ 1.1739726045265, 1.2481155622603, 1.34292501514454, 1.46959617817339,
+ 1.64691705586599, 1.9024633637756, 2.27273568577832, 3.14159265358979
+};
+
+struct sampler_context {
+ struct geometry geometry;
+ double aspect_ratio;
+ double mean_radius;
+ double sigma;
+};
+
+static void
+get_material_property
+ (void* mtl,
+ const double wavelength,
+ struct sschiff_material_properties* props)
+{
+ (void)mtl, (void)wavelength;
+ props->medium_refractive_index = 1.33;
+ props->relative_imaginary_refractive_index = 1.7e-3/1.33;
+ props->relative_real_refractive_index = 1.39/1.33;
+}
+
+static res_T
+sample_cylinder
+ (struct ssp_rng* rng, struct s3d_shape* shape, void* sampler_context)
+{
+ struct sampler_context* sampler_ctx = sampler_context;
+ struct cylinder cylinder;
+ double sample;
+ (void)rng, (void)sampler_context;
+
+ sample = ssp_ran_lognormal(rng, log(sampler_ctx->mean_radius), log(sampler_ctx->sigma));
+ cylinder.geometry = &sampler_ctx->geometry;
+ cylinder.radius = (float)(sample / pow(3.0 / (2.0*sampler_ctx->aspect_ratio), 1.0/3.0));
+ cylinder.height = (float)(2.f * cylinder.radius / sampler_ctx->aspect_ratio);
+
+ return cylinder_setup_s3d_shape(&cylinder, shape);
+}
+
+struct cross_section_result {
+ double absorption_E;
+ double absorption_SE;
+ double extinction_E;
+ double extinction_SE;
+ double scattering_E;
+ double scattering_SE;
+};
+
+int
+main(int argc, char** argv)
+{
+ struct mem_allocator allocator;
+ struct sampler_context sampler_ctx;
+ struct sschiff_device* dev;
+ struct sschiff_geometry_distribution distrib = SSCHIFF_NULL_GEOMETRY_DISTRIBUTION;
+ struct sschiff_estimator* estimator;
+ struct sschiff_cross_section cross_section;
+ struct ssp_rng* rng;
+ struct sschiff_state result, result2;
+ const struct sschiff_state* val;
+ const struct sschiff_state* func = NULL;
+ const struct sschiff_state* cumul = NULL;
+ struct cross_section_result cross_section_result;
+ double* thetas = NULL;
+ double interval[2];
+ double n;
+ const double* angles = NULL;
+ const double wavelength = 0.5; /* In micron */
+ const size_t nscatt_angles = 1000;
+ const size_t ngeoms = 1000;
+ const size_t ndirs = 1000;
+ size_t count;
+ size_t ilimit_angle;
+ size_t i;
+ (void)argc, (void)argv;
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+ CHECK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng), RES_OK);
+ CHECK(sschiff_device_create
+ (NULL, &allocator, SSCHIFF_NTHREADS_DEFAULT, 1, NULL, &dev), RES_OK);
+
+ geometry_init_cylinder(&sampler_ctx.geometry, 64);
+
+ cross_section_result.extinction_E = 2.81307852441391;
+ cross_section_result.extinction_SE = 7.86230094748024e-4;
+ cross_section_result.scattering_E = 2.63488155160904;
+ cross_section_result.scattering_SE = 7.53366332231861e-4;
+ cross_section_result.absorption_E = 1.78192486614360e-1;
+ cross_section_result.absorption_SE = 3.44690633379987e-5;
+
+ sampler_ctx.aspect_ratio = 0.263;
+ sampler_ctx.mean_radius = 0.983;
+ sampler_ctx.sigma = 1.1374;
+
+ distrib.characteristic_length = 0.38190884533484676025;
+ distrib.material.get_property = get_material_property;
+ distrib.material.material = &sampler_ctx;
+ distrib.sample = sample_cylinder;
+ distrib.context = &sampler_ctx;
+
+ CHECK(sschiff_integrate(dev, rng, &distrib, &wavelength, 1,
+ sschiff_uniform_scattering_angles, nscatt_angles, ngeoms, ndirs,
+ &estimator), RES_OK);
+
+ CHECK(sschiff_estimator_get_cross_section
+ (estimator, 0, &cross_section), RES_OK);
+
+ printf("Wavelength = %g micron\n", wavelength);
+
+ result.E = cross_section_result.extinction_E;
+ result.SE = cross_section_result.extinction_SE;
+ val = &cross_section.extinction;
+ compute_estimation_intersection(interval, 4, &result, val);
+ printf(" Extinction = %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
+ result.E, result.SE, val->E, val->SE, interval[1]-interval[0]);
+ CHECK(interval[0] <= interval[1], 1);
+
+ result.E = cross_section_result.absorption_E;
+ result.SE = cross_section_result.absorption_SE;
+ val = &cross_section.absorption;
+ compute_estimation_intersection(interval, 4, &result, val);
+ printf(" Absorption = %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
+ result.E, result.SE, val->E, val->SE, interval[1]-interval[0]);
+ CHECK(interval[0] <= interval[1], 1);
+
+ result.E = cross_section_result.scattering_E;
+ result.SE = cross_section_result.scattering_SE;
+ val = &cross_section.scattering;
+ compute_estimation_intersection(interval, 4, &result, val);
+ printf(" Scattering = %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
+ result.E, result.SE, val->E, val->SE, interval[1]-interval[0]);
+ CHECK(interval[0] <= interval[1], 1);
+
+ printf(" Proj area ~ %9.3g +/- %9.3g\n",
+ cross_section.average_projected_area.E,
+ cross_section.average_projected_area.SE);
+
+ CHECK(sschiff_estimator_get_scattering_angles(estimator, &angles, &count), RES_OK);
+ CHECK(count, nscatt_angles);
+
+ #define LIMIT_ANGLE sschiff_estimator_get_limit_scattering_angle_index
+ CHECK(LIMIT_ANGLE(NULL, 1, NULL), RES_BAD_ARG);
+ CHECK(LIMIT_ANGLE(estimator, 1, NULL), RES_BAD_ARG);
+ CHECK(LIMIT_ANGLE(NULL, 0, NULL), RES_BAD_ARG);
+ CHECK(LIMIT_ANGLE(estimator, 0, NULL), RES_BAD_ARG);
+ CHECK(LIMIT_ANGLE(NULL, 1, &ilimit_angle), RES_BAD_ARG);
+ CHECK(LIMIT_ANGLE(estimator, 1, &ilimit_angle), RES_BAD_ARG);
+ CHECK(LIMIT_ANGLE(NULL, 0, &ilimit_angle), RES_BAD_ARG);
+ CHECK(LIMIT_ANGLE(estimator, 0, &ilimit_angle), RES_OK);
+ #undef LIMIT_ANGLE
+ CHECK(ilimit_angle < count, 1);
+ printf(" Limit angle = %g radians; ", angles[ilimit_angle]);
+
+ #define GET_N sschiff_estimator_get_wide_scattering_angle_model_parameter
+ CHECK(GET_N(NULL, 1, NULL), RES_BAD_ARG);
+ CHECK(GET_N(estimator, 1, NULL), RES_BAD_ARG);
+ CHECK(GET_N(NULL, 0, NULL), RES_BAD_ARG);
+ CHECK(GET_N(estimator, 0, NULL), RES_BAD_ARG);
+ CHECK(GET_N(NULL, 1, &n), RES_BAD_ARG);
+ CHECK(GET_N(estimator, 1, &n), RES_BAD_ARG);
+ CHECK(GET_N(NULL, 0, &n), RES_BAD_ARG);
+ CHECK(GET_N(estimator, 0, &n), RES_OK);
+ #undef GET_N
+ printf("n = %g\n", n);
+
+ #define DIFF_XSECTION sschiff_estimator_get_differential_cross_section
+ i = ilimit_angle;
+ CHECK(DIFF_XSECTION(NULL, 1, nscatt_angles, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(estimator, 1, nscatt_angles, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(NULL, 0, nscatt_angles, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(estimator, 0, nscatt_angles, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(NULL, 1, i, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(estimator, 1, i, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(NULL, 0, i, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(estimator, 0, i, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(NULL, 1, nscatt_angles, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(estimator, 1, nscatt_angles, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(NULL, 0, nscatt_angles, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(estimator, 0, nscatt_angles, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(NULL, 1, i, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(estimator, 1, i, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(NULL, 0, i, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION(estimator, 0, i, &result), RES_OK);
+ #undef DIFF_XSECTION
+
+ result2.E = 7.89191057312786e-2;
+ result2.SE = 2.47342639761112e-03;
+ compute_estimation_intersection(interval, 4, &result2, &result);
+ printf(" Ws = %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
+ result2.E, result2.SE, result.E, result.SE, interval[1] - interval[0]);
+ CHECK(interval[0] <= interval[1], 1);
+
+ #define DIFF_XSECTION_CUMUL \
+ sschiff_estimator_get_differential_cross_section_cumulative
+ CHECK(DIFF_XSECTION_CUMUL(NULL, 1, nscatt_angles, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(estimator, 1, nscatt_angles, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(NULL, 0, nscatt_angles, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(estimator, 0, nscatt_angles, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(NULL, 1, i, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(estimator, 1, i, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(NULL, 0, i, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(estimator, 0, i, NULL), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(NULL, 1, nscatt_angles, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(estimator, 1, nscatt_angles, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(NULL, 0, nscatt_angles, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(estimator, 0, nscatt_angles, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(NULL, 1, i, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(estimator, 1, i, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(NULL, 0, i, &result), RES_BAD_ARG);
+ CHECK(DIFF_XSECTION_CUMUL(estimator, 0, i, &result), RES_OK);
+ #undef DIFF_XSECTION_CUMUL
+
+ result2.E = 2.57417550513944;
+ result2.SE = 1.89515135143166e-3;
+ compute_estimation_intersection(interval, 4, &result2, &result);
+ printf(" Wc = %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
+ result2.E, result2.SE, result.E, result.SE, interval[1] - interval[0]);
+ CHECK(interval[0] <= interval[1], 1);
+
+ #define PHASE_FUNCTION sschiff_estimator_get_phase_function
+ CHECK(PHASE_FUNCTION(NULL, 1, NULL), RES_BAD_ARG);
+ CHECK(PHASE_FUNCTION(estimator, 1, NULL), RES_BAD_ARG);
+ CHECK(PHASE_FUNCTION(NULL, 0, NULL), RES_BAD_ARG);
+ CHECK(PHASE_FUNCTION(estimator, 0, NULL), RES_BAD_ARG);
+ CHECK(PHASE_FUNCTION(NULL, 1, &func), RES_BAD_ARG);
+ CHECK(PHASE_FUNCTION(estimator, 1, &func), RES_BAD_ARG);
+ CHECK(PHASE_FUNCTION(NULL, 0, &func), RES_BAD_ARG);
+ CHECK(PHASE_FUNCTION(estimator, 0, &func), RES_OK);
+ #undef PHASE_FUNCTION
+
+ printf("\n# Phase function\n");
+ FOR_EACH(i, 0, 1000) {
+ result.E = phase_func[i][0];
+ result.SE = phase_func[i][1];
+ compute_estimation_intersection(interval, 4, &result, &func[i]);
+ printf("PF(%9.3g) = %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
+ (double)i*(PI/999.0), result.E, result.SE, func[i].E, func[i].SE,
+ interval[1] - interval[0]);
+ /* Check up to the limit angle only. Wide angles are analytically computed
+ * and thus are widely affected by the estimation of the `n' parameter that
+ * is not sufficiently well estimated due to a limited number of
+ * realisations. */
+ if(i <= ilimit_angle) {
+ CHECK(interval[0] <= interval[1], 1);
+ }
+ }
+
+ #define CUMULATIVE sschiff_estimator_get_phase_function_cumulative
+ CHECK(CUMULATIVE(NULL, 1, NULL), RES_BAD_ARG);
+ CHECK(CUMULATIVE(estimator, 1, NULL), RES_BAD_ARG);
+ CHECK(CUMULATIVE(NULL, 0, NULL), RES_BAD_ARG);
+ CHECK(CUMULATIVE(estimator, 0, NULL), RES_BAD_ARG);
+ CHECK(CUMULATIVE(NULL, 1, &cumul), RES_BAD_ARG);
+ CHECK(CUMULATIVE(estimator, 1, &cumul), RES_BAD_ARG);
+ CHECK(CUMULATIVE(NULL, 0, &cumul), RES_BAD_ARG);
+ CHECK(CUMULATIVE(estimator, 0, &cumul), RES_OK);
+ #undef CUMULATIVE
+
+ printf("\n# Cumulative phase function\n");
+ FOR_EACH(i, 0, 1000) {
+ result.E = cumulative[i][0];
+ result.SE = cumulative[i][1];
+ compute_estimation_intersection(interval, 4, &result, &cumul[i]);
+ printf("CDF(%9.3g) = %9.3g +/- %9.3g ~ %9.3g +/- %9.3g (%9.3g)\n",
+ (double)i*(PI/999.0), result.E, result.SE, cumul[i].E, cumul[i].SE,
+ interval[1] - interval[0]);
+ /* Check up to the limit angle only. Wide angles are analytically computed
+ * and thus are widely affected by the estimation of the `n' parameter that
+ * is not sufficiently well estimated due to a limited number of
+ * realisations. */
+ if(i <= ilimit_angle) {
+ CHECK(interval[0] <= interval[1], 1);
+ }
+ }
+
+ NCHECK(sa_add(thetas, 2000), NULL);
+ #define INV_CUMULATIVE sschiff_estimator_inverse_cumulative_phase_function
+ CHECK(INV_CUMULATIVE(NULL, 1, NULL, 0), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(estimator, 1, NULL, 0), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(NULL, 0, NULL, 0), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(estimator, 0, NULL, 0), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(NULL, 1, thetas, 0), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(estimator, 1, thetas, 0), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(NULL, 0, thetas, 0), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(estimator, 0, thetas, 0), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(NULL, 1, NULL, 2), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(estimator, 1, NULL, 2), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(NULL, 0, NULL, 2), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(estimator, 0, NULL, 2), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(NULL, 1, thetas, 2), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(estimator, 1, thetas, 2), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(NULL, 0, thetas, 2), RES_BAD_ARG);
+ CHECK(INV_CUMULATIVE(estimator, 0, thetas, 2), RES_OK);
+ CHECK(eq_eps(thetas[0], 0, 1.e-6), 1);
+ CHECK(eq_eps(thetas[1], PI, 1.e-6), 1);
+ CHECK(INV_CUMULATIVE(estimator, 0, thetas, sa_size(thetas)), RES_OK);
+ #undef INV_CUMULATIVE
+
+ printf("\n# Inverse cumulative phase function\n");
+ FOR_EACH(i, 0, 2000) {
+ double error;
+ error = fabs(thetas[i] - inverse_cumulative[i]) / inverse_cumulative[i];
+ printf("CDF^-1(%9.3g) = %9.3g ~ %9.3g; err = %.3f%%\n",
+ (double)i*(1.0/1999.0), thetas[i], inverse_cumulative[i], error*100);
+ CHECK(interval[0] <= interval[1], 1);
+ }
+ sa_release(thetas);
+
+ CHECK(sschiff_estimator_ref_put(estimator), RES_OK);
+ CHECK(sschiff_device_ref_put(dev), RES_OK);
+ CHECK(ssp_rng_ref_put(rng), RES_OK);
+
+ geometry_release(&sampler_ctx.geometry);
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+ return 0;
+}
diff --git a/src/test_sschiff_estimator_sphere.c b/src/test_sschiff_estimator_sphere.c
@@ -1,30 +1,17 @@
-/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+/* Copyright (C) 2015-2016 CNRS
*
- * This software is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms. */
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "sschiff.h"
#include "test_sschiff_utils.h"
@@ -43,11 +30,6 @@ struct result {
double extinction_cross_section;
};
-struct geometry {
- float* vertices; /* List of float[3] */
- unsigned* indices; /* List of unsigned[3] */
-};
-
struct sampler_context {
struct geometry geometry;
double wavelength; /* In micron */
@@ -58,11 +40,6 @@ struct sampler_context {
double sigma;
};
-struct sphere {
- struct geometry* geometry;
- float radius; /* In micron */
-};
-
static void
get_material_property
(void* mtl,
@@ -82,153 +59,22 @@ get_material_property
ctx->relative_imaginary_refractive_index;
}
-static void
-get_indices(const unsigned itri, unsigned ids[3], void* ctx)
-{
- struct sphere* sphere = ctx;
- const size_t i = itri * 3;
-
- CHECK(sa_size(sphere->geometry->indices) % 3, 0);
- CHECK(itri < sa_size(sphere->geometry->indices) / 3, 1);
- ids[0] = sphere->geometry->indices[i + 0];
- ids[1] = sphere->geometry->indices[i + 1];
- ids[2] = sphere->geometry->indices[i + 2];
-}
-
-static INLINE void
-get_position(const unsigned ivert, float vertex[3], void* ctx)
-{
- struct sphere* sphere = ctx;
- const size_t i = ivert * 3;
-
- CHECK(sa_size(sphere->geometry->vertices) % 3, 0);
- CHECK(ivert < sa_size(sphere->geometry->vertices) / 3, 1);
- vertex[0] = sphere->geometry->vertices[i + 0] * sphere->radius;
- vertex[1] = sphere->geometry->vertices[i + 1] * sphere->radius;
- vertex[2] = sphere->geometry->vertices[i + 2] * sphere->radius;
-}
-
static res_T
sample_sphere
(struct ssp_rng* rng,
- struct sschiff_material* mtl,
struct s3d_shape* shape,
void* sampler_context)
{
- struct s3d_vertex_data attrib;
struct sampler_context* sampler_ctx = sampler_context;
struct sphere sphere;
- size_t nverts, nprims;
NCHECK(rng, NULL);
- NCHECK(mtl, NULL);
- NCHECK(shape, NULL);
sphere.geometry = &sampler_ctx->geometry;
sphere.radius = (float)ssp_ran_lognormal
(rng, log(sampler_ctx->mean_radius), log(sampler_ctx->sigma));
- attrib.usage = S3D_POSITION;
- attrib.type = S3D_FLOAT3;
- attrib.get = get_position;
-
- mtl->get_property = get_material_property;
- mtl->material = sampler_ctx;
-
- nverts = sa_size(sphere.geometry->vertices) / 3/*#coords*/;
- nprims = sa_size(sphere.geometry->indices) / 3/*#indices per prim*/;
-
- return s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprims,
- get_indices, (unsigned)nverts, &attrib, 1, &sphere);
-}
-
-static void
-sphere_init(struct geometry* sphere, const unsigned ntheta)
-{
- const unsigned nphi = (unsigned)(((double)ntheta + 0.5) / 2.0);
- const double step_theta = 2*PI / (double)ntheta;
- const double step_phi = PI / (double)nphi;
- double* cos_theta = NULL;
- double* sin_theta = NULL;
- double* cos_phi = NULL;
- double* sin_phi = NULL;
- unsigned itheta, iphi;
-
- NCHECK(sphere, NULL);
- NCHECK(ntheta, 0);
-
- sphere->vertices = NULL;
- sphere->indices = NULL;
-
- /* Precompute the cosine/sinus of the theta/phi angles */
- FOR_EACH(itheta, 0, ntheta) {
- const double theta = -PI + (double)itheta * step_theta;
- sa_push(cos_theta, cos(theta));
- sa_push(sin_theta, sin(theta));
- }
- FOR_EACH(iphi, 1, nphi) {
- const double phi = -PI/2 + (double)iphi * step_phi;
- sa_push(cos_phi, cos(phi));
- sa_push(sin_phi, sin(phi));
- }
- /* Compute the contour vertices */
- FOR_EACH(itheta, 0, ntheta) {
- FOR_EACH(iphi, 0, nphi-1) {
- sa_push(sphere->vertices, (float)(cos_theta[itheta]*cos_phi[iphi]));
- sa_push(sphere->vertices, (float)(sin_theta[itheta]*cos_phi[iphi]));
- sa_push(sphere->vertices, (float)sin_phi[iphi]);
- }
- }
- /* Compute the polar vertices */
- f3(sa_add(sphere->vertices, 3), 0.f, 0.f,-1.f);
- f3(sa_add(sphere->vertices, 3), 0.f, 0.f, 1.f);
-
- /* Define the indices of the contour primitives */
- FOR_EACH(itheta, 0, ntheta) {
- const unsigned itheta0 = itheta * (nphi - 1);
- const unsigned itheta1 = ((itheta + 1) % ntheta) * (nphi - 1);
- FOR_EACH(iphi, 0, nphi-2) {
- const unsigned iphi0 = iphi + 0;
- const unsigned iphi1 = iphi + 1;
-
- sa_push(sphere->indices, itheta0 + iphi0);
- sa_push(sphere->indices, itheta0 + iphi1);
- sa_push(sphere->indices, itheta1 + iphi0);
-
- sa_push(sphere->indices, itheta1 + iphi0);
- sa_push(sphere->indices, itheta0 + iphi1);
- sa_push(sphere->indices, itheta1 + iphi1);
- }
- }
-
- /* Define the indices of the polar primitives */
- FOR_EACH(itheta, 0, ntheta) {
- const unsigned itheta0 = itheta * (nphi - 1);
- const unsigned itheta1 = ((itheta + 1) % ntheta) * (nphi - 1);
-
- sa_push(sphere->indices, ntheta * (nphi - 1));
- sa_push(sphere->indices, itheta0);
- sa_push(sphere->indices, itheta1);
-
- sa_push(sphere->indices, ntheta * (nphi - 1) + 1);
- sa_push(sphere->indices, itheta1 + (nphi - 2));
- sa_push(sphere->indices, itheta0 + (nphi - 2));
- }
-
- /* Release the intermediary data structure */
- sa_release(cos_theta);
- sa_release(sin_theta);
- sa_release(cos_phi);
- sa_release(sin_phi);
-}
-
-static void
-sphere_release(struct geometry* sphere)
-{
- sa_release(sphere->vertices);
- sa_release(sphere->indices);
- sphere->vertices = NULL;
- sphere->indices = NULL;
+ return sphere_setup_s3d_shape(&sphere, shape);
}
static void
@@ -242,11 +88,11 @@ check_schiff_estimation
char buf[64];
struct sschiff_estimator* estimator;
struct sschiff_geometry_distribution distrib = SSCHIFF_NULL_GEOMETRY_DISTRIBUTION;
- struct sschiff_estimator_state state;
+ struct sschiff_cross_section cross_section;
struct time t0, t1;
size_t i;
- const size_t nscatt_angles = 1;
+ const size_t nscatt_angles = 1000;
const size_t ngeoms = 100;
const size_t ndirs = 100;
const double wavelength = sampler_ctx->wavelength;
@@ -255,6 +101,8 @@ check_schiff_estimation
NCHECK(results, NULL);
NCHECK(results, 0);
+ distrib.material.get_property = get_material_property;
+ distrib.material.material = sampler_ctx;
distrib.sample = sample_sphere;
distrib.context = sampler_ctx;
@@ -265,45 +113,42 @@ check_schiff_estimation
sampler_ctx->medium_refractive_index);
FOR_EACH(i, 0, nresults) {
- const struct sschiff_estimator_value* val;
+ const struct sschiff_state* val;
double dst;
sampler_ctx->mean_radius = results[i].mean_radius;
+ distrib.characteristic_length = sampler_ctx->mean_radius * 2.0;
time_current(&t0);
- CHECK(sschiff_integrate(dev, rng, &distrib, &wavelength, 1, nscatt_angles,
- ngeoms, ndirs, &estimator), RES_OK);
+ CHECK(sschiff_integrate(dev, rng, &distrib, &wavelength, 1,
+ sschiff_uniform_scattering_angles, nscatt_angles, ngeoms, ndirs, &estimator), RES_OK);
time_current(&t1);
time_sub(&t0, &t1, &t0);
time_dump(&t0, TIME_MIN|TIME_SEC|TIME_MSEC, NULL, buf, sizeof(buf));
printf("%d - mean radius: %5.2f micron - %s: \n", (int)i, results[i].mean_radius, buf);
- CHECK(sschiff_estimator_get_states(estimator, &state), RES_OK);
- CHECK(eq_eps(state.wavelength, wavelength, 1.e-12), 1);
+ CHECK(sschiff_estimator_get_cross_sections(estimator, &cross_section), RES_OK);
- val = state.values + SSCHIFF_EXTINCTION_CROSS_SECTION ;
+ val = &cross_section.extinction;
dst = val->E - results[i].extinction_cross_section;
printf(" Extinction cross section = %7.2f ~ %12.7f +/- %12.7f (%6.2f)\n",
results[i].extinction_cross_section, val->E, val->SE, dst / val->SE);
CHECK(eq_eps(val->E, results[i].extinction_cross_section, 4*val->SE), 1);
- val = state.values + SSCHIFF_ABSORPTION_CROSS_SECTION ;
+ val = &cross_section.absorption;
dst = val->E - results[i].absorption_cross_section;
printf(" Absorption cross section = %7.2f ~ %12.7f +/- %12.7f (%6.2f)\n",
results[i].absorption_cross_section, val->E, val->SE, dst / val->SE);
CHECK(eq_eps(val->E, results[i].absorption_cross_section, 4*val->SE), 1);
- val = state.values + SSCHIFF_SCATTERING_CROSS_SECTION;
+ val = &cross_section.scattering;
dst = val->E - results[i].scattering_cross_section;
printf(" Scattering cross section = %7.2f ~ %12.7f +/- %12.7f (%6.2f)\n",
results[i].scattering_cross_section, val->E, val->SE, dst / val->SE);
CHECK(eq_eps(val->E, results[i].scattering_cross_section, 4*val->SE), 1);
- /*s = log(sampler_ctx->sigma);
- r = sampler_ctx->mean_radius * exp(2.5 * s * s);
- r = PI * r * r * 1.e-12 */ /* Meter^2 to micron^2*/;
- val = state.values + SSCHIFF_AVERAGE_PROJECTED_AREA;
- printf(" Averavege projected area = %12.6g +/- %12.7g\n", val->E, val->SE);
+ val = &cross_section.average_projected_area;
+ printf(" Averavege projected area = %12.7g +/- %12.7g\n", val->E, val->SE);
CHECK(sschiff_estimator_ref_put(estimator), RES_OK);
}
@@ -317,7 +162,7 @@ main(int argc, char** argv)
struct sschiff_device* dev;
struct sschiff_geometry_distribution distrib = SSCHIFF_NULL_GEOMETRY_DISTRIBUTION;
struct sschiff_estimator* estimator;
- struct sschiff_estimator_state state;
+ struct sschiff_cross_section cross_section;
struct ssp_rng* rng;
const struct result results_n_r_1_01[] = {
{ 1.00, 0.484, 0.159, 0.643 },
@@ -344,16 +189,18 @@ main(int argc, char** argv)
{ 21.0, 1350, 1580, 2930 }
};
const double wlen = 0.6; /* Micron */
- size_t count;
+ double wlens[3] = { 0, 0, 0 };
+ const double* dbls = NULL;
+ size_t i, count;
(void)argc, (void)argv;
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
CHECK(ssp_rng_create(&allocator, &ssp_rng_threefry, &rng), RES_OK);
CHECK(sschiff_device_create
- (NULL, &allocator, SSCHIFF_NTHREADS_DEFAULT, 0, NULL, &dev), RES_OK);
+ (NULL, &allocator, SSCHIFF_NTHREADS_DEFAULT, 1, NULL, &dev), RES_OK);
- sphere_init(&sampler_ctx.geometry, 64);
+ geometry_init_sphere(&sampler_ctx.geometry, 64);
sampler_ctx.wavelength = wlen;
sampler_ctx.relative_real_refractive_index = 1.1;
@@ -362,95 +209,124 @@ main(int argc, char** argv)
sampler_ctx.mean_radius = 1.0;
sampler_ctx.sigma = 1.18;
+ distrib.material.get_property = get_material_property;
+ distrib.material.material = &sampler_ctx;
+ distrib.characteristic_length = 1;
distrib.sample = sample_sphere;
distrib.context = &sampler_ctx;
- CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, NULL, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 0, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, NULL, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, 1, 1, 1, NULL), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, NULL, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 0, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, NULL, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 1, 1, 1, 1, &estimator), RES_BAD_ARG);
- CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, 1, 1, 1, &estimator), RES_OK);
-
- CHECK(sschiff_estimator_get_wavelengths_count(NULL, NULL), RES_BAD_ARG);
- CHECK(sschiff_estimator_get_wavelengths_count(estimator, NULL), RES_BAD_ARG);
- CHECK(sschiff_estimator_get_wavelengths_count(NULL, &count), RES_BAD_ARG);
- CHECK(sschiff_estimator_get_wavelengths_count(estimator, &count), RES_OK);
+ CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, NULL, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 0, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, NULL, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, NULL, 1, 1, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, NULL, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 0, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, NULL, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, NULL, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, NULL, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, NULL, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, &distrib, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, &distrib, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, &distrib, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &distrib, NULL, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, NULL, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, NULL, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, NULL, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, NULL, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, NULL, &distrib, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, NULL, &distrib, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(NULL, rng, &distrib, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, NULL, 1, 1, 1, &estimator), RES_BAD_ARG);
+
+ CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1,
+ sschiff_uniform_scattering_angles, 1, 1, 1, &estimator), RES_BAD_ARG);
+ CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1,
+ sschiff_uniform_scattering_angles, 10, 1000, 1, &estimator), RES_OK);
+
+ CHECK(sschiff_estimator_get_wavelengths(NULL, NULL, NULL), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_wavelengths(estimator, NULL, NULL), RES_OK);/*Useless*/
+ CHECK(sschiff_estimator_get_wavelengths(NULL, NULL, &count), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_wavelengths(estimator, NULL, &count), RES_OK);
+ CHECK(count, 1);
+ CHECK(sschiff_estimator_get_wavelengths(NULL, &dbls, NULL), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_wavelengths(estimator, &dbls, NULL), RES_OK);
+ CHECK(dbls[0], wlen);
+ CHECK(sschiff_estimator_get_wavelengths(NULL, &dbls, &count), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_wavelengths(estimator, &dbls, &count), RES_OK);
+ CHECK(dbls[0], wlen);
CHECK(count, 1);
+ CHECK(sschiff_estimator_get_scattering_angles(NULL, NULL, NULL), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_scattering_angles(estimator, NULL, NULL), RES_OK); /* Useless */
+ CHECK(sschiff_estimator_get_scattering_angles(NULL, NULL, &count), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_scattering_angles(estimator, NULL, &count), RES_OK);
+ CHECK(count, 10);
+ CHECK(sschiff_estimator_get_scattering_angles(NULL, &dbls, NULL), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_scattering_angles(estimator, &dbls, NULL), RES_OK); /* Useless */
+ FOR_EACH(i, 0, count)
+ CHECK(eq_eps(dbls[i], (double)i*PI/((double)count-1), 1.e-6), 1);
+ CHECK(sschiff_estimator_get_scattering_angles(NULL, &dbls, &count), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_scattering_angles(estimator, &dbls, &count), RES_OK);
+ FOR_EACH(i, 0, count)
+ CHECK(eq_eps(dbls[i], (double)i*PI/((double)count-1), 1.e-6), 1);
+ CHECK(count, 10);
+
CHECK(sschiff_estimator_get_realisations_count(NULL, NULL), RES_BAD_ARG);
CHECK(sschiff_estimator_get_realisations_count(estimator, NULL), RES_BAD_ARG);
CHECK(sschiff_estimator_get_realisations_count(NULL, &count), RES_BAD_ARG);
CHECK(sschiff_estimator_get_realisations_count(estimator, &count), RES_OK);
- CHECK(count, 1);
+ CHECK(count, 1000);
- CHECK(sschiff_estimator_get_wavelength_state(NULL, 0, NULL), RES_BAD_ARG);
- CHECK(sschiff_estimator_get_wavelength_state(estimator, 0, NULL), RES_BAD_ARG);
- CHECK(sschiff_estimator_get_wavelength_state(NULL, wlen, NULL), RES_BAD_ARG);
- CHECK(sschiff_estimator_get_wavelength_state(estimator, wlen, NULL), RES_BAD_ARG);
- CHECK(sschiff_estimator_get_wavelength_state(NULL, 0, &state), RES_BAD_ARG);
- CHECK(sschiff_estimator_get_wavelength_state(estimator, 0, &state), RES_BAD_ARG);
- CHECK(sschiff_estimator_get_wavelength_state(NULL, wlen, &state), RES_BAD_ARG);
- CHECK(sschiff_estimator_get_wavelength_state(estimator, wlen, &state), RES_OK);
- CHECK(eq_eps(wlen, state.wavelength, 1.e-12), 1);
+ CHECK(sschiff_estimator_get_cross_section(NULL, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_cross_section(estimator, 1, NULL), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_cross_section(NULL, 1, &cross_section), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_cross_section(estimator, 1, &cross_section), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_cross_section(NULL, 0, NULL), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_cross_section(estimator, 0, NULL), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_cross_section(NULL, 0, &cross_section), RES_BAD_ARG);
+ CHECK(sschiff_estimator_get_cross_section(estimator, 0, &cross_section), RES_OK);
CHECK(sschiff_estimator_ref_get(NULL), RES_BAD_ARG);
CHECK(sschiff_estimator_ref_get(estimator), RES_OK);
@@ -458,10 +334,9 @@ main(int argc, char** argv)
CHECK(sschiff_estimator_ref_put(estimator), RES_OK);
CHECK(sschiff_estimator_ref_put(estimator), RES_OK);
- CHECK(sschiff_integrate(dev, rng, &distrib, &wlen, 1, 1, 10, 1, &estimator), RES_OK);
- CHECK(sschiff_estimator_get_realisations_count(estimator, &count), RES_OK);
- CHECK(count, 10);
- CHECK(sschiff_estimator_ref_put(estimator), RES_OK);
+ wlens[0] = 0.2, wlens[1] = 0.6, wlens[2] = 0.4;
+ CHECK(sschiff_integrate(dev, rng, &distrib, wlens, 3,
+ sschiff_uniform_scattering_angles, 10, 1000, 1, &estimator), RES_BAD_ARG);
sampler_ctx.relative_real_refractive_index = 1.1;
check_schiff_estimation(dev, rng, &sampler_ctx, results_n_r_1_1,
@@ -475,7 +350,7 @@ main(int argc, char** argv)
CHECK(sschiff_device_ref_put(dev), RES_OK);
CHECK(ssp_rng_ref_put(rng), RES_OK);
- sphere_release(&sampler_ctx.geometry);
+ geometry_release(&sampler_ctx.geometry);
check_memory_allocator(&allocator);
mem_shutdown_proxy_allocator(&allocator);
CHECK(mem_allocated_size(), 0);
diff --git a/src/test_sschiff_utils.h b/src/test_sschiff_utils.h
@@ -1,36 +1,337 @@
-/* Copyright (C) |Meso|Star> 2015 (contact@meso-star.com)
+/* Copyright (C) 2015-2016 CNRS
*
- * This software is governed by the CeCILL license under French law and
- * abiding by the rules of distribution of free software. You can use,
- * modify and/or redistribute the software under the terms of the CeCILL
- * license as circulated by CEA, CNRS and INRIA at the following URL
- * "http://www.cecill.info".
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
- * As a counterpart to the access to the source code and rights to copy,
- * modify and redistribute granted by the license, users are provided only
- * with a limited warranty and the software's author, the holder of the
- * economic rights, and the successive licensors have only limited
- * liability.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
*
- * In this respect, the user's attention is drawn to the risks associated
- * with loading, using, modifying and/or developing or reproducing the
- * software by the user in light of its specific status of free software,
- * that may mean that it is complicated to manipulate, and that also
- * therefore means that it is reserved for developers and experienced
- * professionals having in-depth computer knowledge. Users are therefore
- * encouraged to load and test the software's suitability as regards their
- * requirements in conditions enabling the security of their systems and/or
- * data to be ensured and, more generally, to use and operate it in the
- * same conditions as regards security.
- *
- * The fact that you are presently reading this means that you have had
- * knowledge of the CeCILL license and that you accept its terms. */
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef TEST_SSCHIFF_UTILS_H
#define TEST_SSCHIFF_UTILS_H
+#include <rsys/float3.h>
+#include <rsys/stretchy_array.h>
#include <rsys/mem_allocator.h>
+#include <star/s3d.h>
+
+/*******************************************************************************
+ * Helper geometry data structure
+ ******************************************************************************/
+struct geometry {
+ float* vertices; /* List of float[3] */
+ unsigned* indices; /* List of unsigned[3] */
+};
+
+static INLINE void
+geometry_init_sphere(struct geometry* sphere, const unsigned ntheta)
+{
+ const unsigned nphi = (unsigned)(((double)ntheta + 0.5) / 2.0);
+ const double step_theta = 2*PI / (double)ntheta;
+ const double step_phi = PI / (double)nphi;
+ double* cos_theta = NULL;
+ double* sin_theta = NULL;
+ double* cos_phi = NULL;
+ double* sin_phi = NULL;
+ unsigned itheta, iphi;
+
+ NCHECK(sphere, NULL);
+ NCHECK(ntheta, 0);
+
+ sphere->vertices = NULL;
+ sphere->indices = NULL;
+
+ /* Precompute the cosine/sinus of the theta/phi angles */
+ FOR_EACH(itheta, 0, ntheta) {
+ const double theta = -PI + (double)itheta * step_theta;
+ sa_push(cos_theta, cos(theta));
+ sa_push(sin_theta, sin(theta));
+ }
+ FOR_EACH(iphi, 1, nphi) {
+ const double phi = -PI/2 + (double)iphi * step_phi;
+ sa_push(cos_phi, cos(phi));
+ sa_push(sin_phi, sin(phi));
+ }
+ /* Compute the contour vertices */
+ FOR_EACH(itheta, 0, ntheta) {
+ FOR_EACH(iphi, 0, nphi-1) {
+ sa_push(sphere->vertices, (float)(cos_theta[itheta]*cos_phi[iphi]));
+ sa_push(sphere->vertices, (float)(sin_theta[itheta]*cos_phi[iphi]));
+ sa_push(sphere->vertices, (float)sin_phi[iphi]);
+ }
+ }
+ /* Compute the polar vertices */
+ f3(sa_add(sphere->vertices, 3), 0.f, 0.f,-1.f);
+ f3(sa_add(sphere->vertices, 3), 0.f, 0.f, 1.f);
+
+ /* Define the indices of the contour primitives */
+ FOR_EACH(itheta, 0, ntheta) {
+ const unsigned itheta0 = itheta * (nphi - 1);
+ const unsigned itheta1 = ((itheta + 1) % ntheta) * (nphi - 1);
+ FOR_EACH(iphi, 0, nphi-2) {
+ const unsigned iphi0 = iphi + 0;
+ const unsigned iphi1 = iphi + 1;
+
+ sa_push(sphere->indices, itheta0 + iphi0);
+ sa_push(sphere->indices, itheta0 + iphi1);
+ sa_push(sphere->indices, itheta1 + iphi0);
+
+ sa_push(sphere->indices, itheta1 + iphi0);
+ sa_push(sphere->indices, itheta0 + iphi1);
+ sa_push(sphere->indices, itheta1 + iphi1);
+ }
+ }
+
+ /* Define the indices of the polar primitives */
+ FOR_EACH(itheta, 0, ntheta) {
+ const unsigned itheta0 = itheta * (nphi - 1);
+ const unsigned itheta1 = ((itheta + 1) % ntheta) * (nphi - 1);
+
+ sa_push(sphere->indices, ntheta * (nphi - 1));
+ sa_push(sphere->indices, itheta0);
+ sa_push(sphere->indices, itheta1);
+
+ sa_push(sphere->indices, ntheta * (nphi - 1) + 1);
+ sa_push(sphere->indices, itheta1 + (nphi - 2));
+ sa_push(sphere->indices, itheta0 + (nphi - 2));
+ }
+
+ /* Release the intermediary data structure */
+ sa_release(cos_theta);
+ sa_release(sin_theta);
+ sa_release(cos_phi);
+ sa_release(sin_phi);
+}
+
+static INLINE void
+geometry_init_cylinder(struct geometry* geometry, const unsigned nsteps)
+{
+ const double step = 2*PI / (double)nsteps;
+ unsigned istep;
+
+ NCHECK(geometry, NULL);
+ NCHECK(nsteps, 0);
+
+ geometry->vertices = NULL;
+ geometry->indices = NULL;
+
+ /* Generate the vertex coordinates */
+ FOR_EACH(istep, 0, nsteps) {
+ const float theta = (float)(istep * step);
+ const float x = (float)cos(theta);
+ const float y = (float)sin(theta);
+ f3(sa_add(geometry->vertices, 3), x, y, -1.f);
+ f3(sa_add(geometry->vertices, 3), x, y, 0.f);
+ }
+
+ /* "Polar" vertices */
+ f3(sa_add(geometry->vertices, 3), 0.f, 0.f, -1.f);
+ f3(sa_add(geometry->vertices, 3), 0.f, 0.f, 0.f);
+
+ /* Contour primitives */
+ FOR_EACH(istep, 0, nsteps) {
+ const unsigned id = istep * 2;
+ unsigned* iprim;
+
+ iprim = sa_add(geometry->indices, 3);
+ iprim[0] = (id + 0);
+ iprim[1] = (id + 1);
+ iprim[2] = (id + 2) % (nsteps*2);
+
+ iprim = sa_add(geometry->indices, 3);
+ iprim[0] = (id + 2) % (nsteps*2);
+ iprim[1] = (id + 1);
+ iprim[2] = (id + 3) % (nsteps*2);
+ }
+
+ /* Cap primitives */
+ FOR_EACH(istep, 0, nsteps) {
+ const unsigned id = istep * 2;
+ unsigned* iprim;
+
+ iprim = sa_add(geometry->indices, 3);
+ iprim[0] = (nsteps * 2);
+ iprim[1] = (id + 0);
+ iprim[2] = (id + 2) % (nsteps*2);
+
+ iprim = sa_add(geometry->indices, 3);
+ iprim[0] = (nsteps * 2) + 1;
+ iprim[1] = (id + 3) % (nsteps*2);
+ iprim[2] = (id + 1);
+ }
+
+}
+
+static INLINE void
+geometry_release(struct geometry* geometry)
+{
+ NCHECK(geometry, NULL);
+ sa_release(geometry->vertices);
+ sa_release(geometry->indices);
+ geometry->vertices = NULL;
+ geometry->indices = NULL;
+}
+
+static INLINE void
+geometry_dump(struct geometry* geom, FILE* file)
+{
+ size_t i;
+ NCHECK(geom, NULL);
+ NCHECK(file, NULL);
+
+ CHECK(sa_size(geom->vertices)%3, 0); /* Ensure 3D position */
+ CHECK(sa_size(geom->indices)%3, 0); /* Ensure triangular primitives */
+
+ FOR_EACH(i, 0, sa_size(geom->vertices)/3) {
+ fprintf(file, "v %f %f %f\n",
+ geom->vertices[i*3+0],
+ geom->vertices[i*3+1],
+ geom->vertices[i*3+2]);
+ }
+ FOR_EACH(i, 0, sa_size(geom->indices)/3) {
+ fprintf(file, "f %d %d %d\n",
+ geom->indices[i*3+0] + 1,
+ geom->indices[i*3+1] + 1,
+ geom->indices[i*3+2] + 1);
+ }
+}
+
+/*******************************************************************************
+ * Cylinder shape
+ ******************************************************************************/
+struct cylinder {
+ struct geometry* geometry;
+ float radius;
+ float height;
+};
+
+static INLINE void
+cylinder_get_indices(const unsigned itri, unsigned ids[3], void* ctx)
+{
+ struct cylinder* cylinder = ctx;
+ const size_t i = itri * 3;
+
+ CHECK(sa_size(cylinder->geometry->indices) % 3, 0);
+ CHECK(itri < sa_size(cylinder->geometry->indices) / 3, 1);
+ ids[0] = cylinder->geometry->indices[i + 0];
+ ids[1] = cylinder->geometry->indices[i + 1];
+ ids[2] = cylinder->geometry->indices[i + 2];
+}
+
+static INLINE void
+cylinder_get_position(const unsigned ivert, float vertex[3], void* ctx)
+{
+ struct cylinder* cylinder = ctx;
+ const size_t i = ivert * 3;
+
+ CHECK(sa_size(cylinder->geometry->vertices) % 3, 0);
+ CHECK(ivert < sa_size(cylinder->geometry->vertices) / 3, 1);
+ vertex[0] = cylinder->geometry->vertices[i + 0] * cylinder->radius;
+ vertex[1] = cylinder->geometry->vertices[i + 1] * cylinder->radius;
+ vertex[2] = cylinder->geometry->vertices[i + 2] * cylinder->height;
+}
+
+static INLINE res_T
+cylinder_setup_s3d_shape(struct cylinder* cylinder, struct s3d_shape* shape)
+{
+ struct s3d_vertex_data attrib;
+ size_t nverts, nprims;
+
+ NCHECK(cylinder, NULL);
+ NCHECK(shape, NULL);
+
+ attrib.usage = S3D_POSITION;
+ attrib.type = S3D_FLOAT3;
+ attrib.get = cylinder_get_position;
+
+ nverts = sa_size(cylinder->geometry->vertices) / 3/*#coords*/;
+ nprims = sa_size(cylinder->geometry->indices) / 3/*#indices per prim*/;
+
+ return s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprims,
+ cylinder_get_indices, (unsigned)nverts, &attrib, 1, cylinder);
+}
+
+/*******************************************************************************
+ * Spherical shape
+ ******************************************************************************/
+struct sphere {
+ struct geometry* geometry;
+ float radius;
+};
+
+static INLINE void
+sphere_get_indices(const unsigned itri, unsigned ids[3], void* ctx)
+{
+ struct sphere* sphere = ctx;
+ const size_t i = itri * 3;
+
+ CHECK(sa_size(sphere->geometry->indices) % 3, 0);
+ CHECK(itri < sa_size(sphere->geometry->indices) / 3, 1);
+ ids[0] = sphere->geometry->indices[i + 0];
+ ids[1] = sphere->geometry->indices[i + 1];
+ ids[2] = sphere->geometry->indices[i + 2];
+}
+
+static INLINE void
+sphere_get_position(const unsigned ivert, float vertex[3], void* ctx)
+{
+ struct sphere* sphere = ctx;
+ const size_t i = ivert * 3;
+
+ CHECK(sa_size(sphere->geometry->vertices) % 3, 0);
+ CHECK(ivert < sa_size(sphere->geometry->vertices) / 3, 1);
+ vertex[0] = sphere->geometry->vertices[i + 0] * sphere->radius;
+ vertex[1] = sphere->geometry->vertices[i + 1] * sphere->radius;
+ vertex[2] = sphere->geometry->vertices[i + 2] * sphere->radius;
+}
+
+static INLINE res_T
+sphere_setup_s3d_shape(struct sphere* sphere, struct s3d_shape* shape)
+{
+ struct s3d_vertex_data attrib;
+ size_t nverts, nprims;
+
+ NCHECK(sphere, NULL);
+ NCHECK(shape, NULL);
+
+ attrib.usage = S3D_POSITION;
+ attrib.type = S3D_FLOAT3;
+ attrib.get = sphere_get_position;
+
+ nverts = sa_size(sphere->geometry->vertices) / 3/*#coords*/;
+ nprims = sa_size(sphere->geometry->indices) / 3/*#indices per prim*/;
+
+ return s3d_mesh_setup_indexed_vertices(shape, (unsigned)nprims,
+ sphere_get_indices, (unsigned)nverts, &attrib, 1, sphere);
+}
+
+/*******************************************************************************
+ * Miscellaneous functions
+ ******************************************************************************/
+static INLINE void
+compute_estimation_intersection
+ (double intersection[2],
+ const double scale,
+ const struct sschiff_state* state0,
+ const struct sschiff_state* state1)
+{
+ double interval0[2], interval1[2];
+ CHECK(scale > 0, 1);
+ interval0[0] = state0->E - scale*state0->SE;
+ interval0[1] = state0->E + scale*state0->SE;
+ interval1[0] = state1->E - scale*state1->SE;
+ interval1[1] = state1->E + scale*state1->SE;
+ intersection[0] = MMAX(interval0[0], interval1[0]);
+ intersection[1] = MMIN(interval0[1], interval1[1]);
+}
+
static void
check_memory_allocator(struct mem_allocator* allocator)
{