├── .idea ├── .name ├── dictionaries │ └── maxal.xml ├── scopes │ └── scope_settings.xml ├── encodings.xml ├── vcs.xml ├── modules.xml ├── misc.xml └── ScattPy.iml ├── scikits ├── scattpy │ ├── version.py │ ├── __init__.py │ ├── properties.py │ ├── doc_inherit.py │ ├── spheroidal_particles.py │ ├── spheroidal_functions.py │ ├── core.py │ ├── spheroidal_svm.py │ ├── spheroidal_ebcm.py │ ├── spheroidal.py │ ├── spheroidal_pmm.py │ └── spherical.py └── __init__.py ├── .gitignore ├── doc └── source │ ├── _themes │ ├── basic │ │ ├── static │ │ │ ├── jquery.js │ │ │ ├── file.png │ │ │ ├── minus.png │ │ │ ├── plus.png │ │ │ ├── doctools.js │ │ │ ├── basic.css │ │ │ └── searchtools.js │ │ ├── changes │ │ │ ├── frameset.html │ │ │ ├── rstsource.html │ │ │ └── versionchanges.html │ │ ├── opensearch.xml │ │ ├── genindex-split.html │ │ ├── defindex.html │ │ ├── genindex-single.html │ │ ├── search.html │ │ ├── modindex.html │ │ └── genindex.html │ └── github │ │ ├── static │ │ ├── jquery.js │ │ ├── file.png │ │ ├── minus.png │ │ ├── plus.png │ │ ├── doctools.js │ │ └── basic.css │ │ ├── page.html │ │ ├── theme.conf │ │ ├── changes │ │ ├── frameset.html │ │ ├── rstsource.html │ │ └── versionchanges.html │ │ ├── opensearch.xml │ │ ├── layout.html │ │ ├── layout.html.bak │ │ ├── genindex-split.html │ │ ├── defindex.html │ │ ├── genindex-single.html │ │ ├── search.html │ │ ├── modindex.html │ │ └── genindex.html │ ├── reference │ ├── laboratory.rst │ ├── methods.rst │ ├── shapes.rst │ ├── index.rst │ ├── all.rst │ └── particles.rst │ ├── contents.rst │ ├── user │ ├── index.rst │ ├── installation.rst │ └── getting_started.rst │ ├── index.rst │ ├── Makefile │ ├── _static │ └── scipy.css │ ├── _templates │ └── indexcontent.html │ ├── make.bat │ ├── sphinxext │ └── ipython_console_highlighting.py │ └── conf.py ├── test ├── test_import.py ├── test.py ├── pmm_test.py ├── ebcm_test.py ├── svm_test.py ├── draw_spheroidal.py ├── spheroidal_matrix_test.py └── spheroidal_test.py ├── README ├── setup.py └── src ├── sdmn.f └── radial.for /.idea/.name: -------------------------------------------------------------------------------- 1 | ScattPy -------------------------------------------------------------------------------- /scikits/scattpy/version.py: -------------------------------------------------------------------------------- 1 | __version__ = "0.1.2" 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.so 3 | *.h5 4 | *.log 5 | *.shelvedb 6 | *.swp 7 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/static/jquery.js: -------------------------------------------------------------------------------- 1 | ../../../../javascript/jquery/jquery.js -------------------------------------------------------------------------------- /doc/source/_themes/github/static/jquery.js: -------------------------------------------------------------------------------- 1 | ../../../../javascript/jquery/jquery.js -------------------------------------------------------------------------------- /scikits/__init__.py: -------------------------------------------------------------------------------- 1 | __import__('pkg_resources').declare_namespace(__name__) 2 | -------------------------------------------------------------------------------- /.idea/dictionaries/maxal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /doc/source/_themes/github/page.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% block body %} 3 | {{ body }} 4 | {% endblock %} 5 | -------------------------------------------------------------------------------- /doc/source/_themes/github/theme.conf: -------------------------------------------------------------------------------- 1 | [theme] 2 | inherit = basic 3 | stylesheet = basic.css 4 | pygments_style = friendly 5 | 6 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScattPy/scikits.scattpy/HEAD/doc/source/_themes/basic/static/file.png -------------------------------------------------------------------------------- /doc/source/_themes/basic/static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScattPy/scikits.scattpy/HEAD/doc/source/_themes/basic/static/minus.png -------------------------------------------------------------------------------- /doc/source/_themes/basic/static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScattPy/scikits.scattpy/HEAD/doc/source/_themes/basic/static/plus.png -------------------------------------------------------------------------------- /doc/source/_themes/github/static/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScattPy/scikits.scattpy/HEAD/doc/source/_themes/github/static/file.png -------------------------------------------------------------------------------- /doc/source/_themes/github/static/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScattPy/scikits.scattpy/HEAD/doc/source/_themes/github/static/minus.png -------------------------------------------------------------------------------- /doc/source/_themes/github/static/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ScattPy/scikits.scattpy/HEAD/doc/source/_themes/github/static/plus.png -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /doc/source/reference/laboratory.rst: -------------------------------------------------------------------------------- 1 | .. laboratory:: 2 | 3 | ######### 4 | Laboratory 5 | ######### 6 | 7 | .. currentmodule:: scikits.scattpy 8 | 9 | .. autoclass:: Lab 10 | :members: 11 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /doc/source/reference/methods.rst: -------------------------------------------------------------------------------- 1 | .. methods:: 2 | 3 | ###### 4 | Methods 5 | ###### 6 | 7 | .. currentmodule:: scikits.scattpy 8 | 9 | .. autosummary:: 10 | :toctree: generated/ 11 | 12 | svm 13 | ebcm 14 | pmm 15 | -------------------------------------------------------------------------------- /test/test_import.py: -------------------------------------------------------------------------------- 1 | __author__ = 'maxal' 2 | 3 | import f_radial 4 | 5 | 6 | kob = 0 7 | m = 1 8 | n = 2 9 | ksi = 1.4 10 | eps = 1E-8 11 | c = 2.0+0j 12 | R1f = 0 13 | R1d = 0 14 | R2f =0 15 | R2d = 0 16 | 17 | print f_radial.rad_fun(kob, m, n, c, ksi, eps)[0] -------------------------------------------------------------------------------- /doc/source/contents.rst: -------------------------------------------------------------------------------- 1 | ##################### 2 | ScattPy manual contents 3 | ##################### 4 | 5 | .. toctree:: 6 | 7 | user/index 8 | reference/index 9 | # dev/index 10 | # release 11 | # about 12 | # bugs 13 | # license 14 | # glossary 15 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | http://www.w3.org/1999/xhtml 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /doc/source/reference/shapes.rst: -------------------------------------------------------------------------------- 1 | .. _shapes: 2 | 3 | ###### 4 | Shapes 5 | ###### 6 | 7 | .. currentmodule:: scikits.scattpy 8 | 9 | A shape defines homogeneous particle surface or layers' surfaces of a multilayered particle. 10 | All shapes are classes derrived from the :autoclass:`Shape`. 11 | 12 | The following shapes are predefined: 13 | 14 | .. autosummary:: 15 | :toctree: generated/ 16 | 17 | ShapeSphere 18 | ShapeSpheroid 19 | ShapeChebyshev 20 | -------------------------------------------------------------------------------- /doc/source/reference/index.rst: -------------------------------------------------------------------------------- 1 | .. _reference: 2 | 3 | ############### 4 | ScattPy Reference 5 | ############### 6 | 7 | :Release: |version| 8 | :Date: |today| 9 | 10 | This reference manual details functions, modules, and objects 11 | included in ScattPy, describing what they are and what they do. 12 | For learning how to use ScattPy, see also :ref:`user`. 13 | 14 | .. toctree:: 15 | :maxdepth: 1 16 | 17 | shapes 18 | particles 19 | laboratory 20 | methods 21 | -------------------------------------------------------------------------------- /doc/source/user/index.rst: -------------------------------------------------------------------------------- 1 | .. _user: 2 | 3 | ################ 4 | ScattPy User Guide 5 | ################ 6 | 7 | This guide is intended as an introductory overview of ScattPy and 8 | explains how to install and make use of the most important features of 9 | ScattPy. For detailed reference documentation of the functions and 10 | classes contained in the package, see the :ref:`reference`. 11 | 12 | .. toctree:: 13 | :maxdepth: 1 14 | 15 | getting_started 16 | installation 17 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/changes/frameset.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | {% trans version=version|e, docstitle=docstitle|e %}Changes in Version {{ version }} — {{ docstitle }}{% endtrans %} 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/source/_themes/github/changes/frameset.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | {% trans version=version|e, docstitle=docstitle|e %}Changes in Version {{ version }} — {{ docstitle }}{% endtrans %} 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/changes/rstsource.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | {% trans filename=filename, docstitle=docstitle|e %}{{ filename }} — {{ docstitle }}{% endtrans %} 6 | 9 | 10 | 11 |
12 |       {{ text }}
13 |     
14 | 15 | 16 | -------------------------------------------------------------------------------- /doc/source/_themes/github/changes/rstsource.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | {% trans filename=filename, docstitle=docstitle|e %}{{ filename }} — {{ docstitle }}{% endtrans %} 6 | 9 | 10 | 11 |
12 |       {{ text }}
13 |     
14 | 15 | 16 | -------------------------------------------------------------------------------- /doc/source/index.rst: -------------------------------------------------------------------------------- 1 | .. ScattPy documentation master file, created by 2 | sphinx-quickstart on Sun Jan 9 00:56:54 2011. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to ScattPy's documentation! 7 | =================================== 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | Indices and tables 15 | ================== 16 | 17 | * :ref:`genindex` 18 | * :ref:`modindex` 19 | * :ref:`search` 20 | 21 | -------------------------------------------------------------------------------- /.idea/ScattPy.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /doc/source/reference/all.rst: -------------------------------------------------------------------------------- 1 | .. currentmodule:: scikits.scattpy 2 | 3 | .. autosummary:: 4 | :toctree: generated/ 5 | 6 | Shape 7 | ShapeSphere 8 | ShapeSpheroid 9 | ShapeChebyshev 10 | Particle 11 | HomogeneousParticle 12 | Sphere 13 | ProlateSpheroid 14 | OblateSpheroid 15 | ChebParticle 16 | LayeredParticle 17 | Layered_EqShape_Particle 18 | Layered_EqShapeEqVol_Particle 19 | LayeredConfocalSpheroid 20 | EMT_Particle 21 | EMT_MaxwellGarnett_Particle 22 | EMT_InvMaxwellGarnett_Particle 23 | EMT_Bruggeman_Particle 24 | Lab 25 | svm 26 | ebcm 27 | pmm 28 | 29 | 30 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/opensearch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ project|e }} 4 | {% trans docstitle=docstitle|e %}Search {{ docstitle }}{% endtrans %} 5 | utf-8 6 | 8 | {{ docstitle|e }} 9 | {% block extra %} {# Put e.g. an element here. #} {% endblock %} 10 | 11 | -------------------------------------------------------------------------------- /doc/source/_themes/github/opensearch.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ project|e }} 4 | {% trans docstitle=docstitle|e %}Search {{ docstitle }}{% endtrans %} 5 | utf-8 6 | 8 | {{ docstitle|e }} 9 | {% block extra %} {# Put e.g. an element here. #} {% endblock %} 10 | 11 | -------------------------------------------------------------------------------- /doc/source/user/installation.rst: -------------------------------------------------------------------------------- 1 | .. _installation: 2 | 3 | *************** 4 | Installation 5 | *************** 6 | 7 | To install ScattPy one needs: 8 | 9 | * Python 2.5 - 2.7 10 | * F2PY with a configured FORTRAN77 compiler 11 | * Python packages: 12 | 13 | - NumPy 14 | - SciPy 15 | - NumdiffTools 16 | 17 | Ubuntu 18 | ------ 19 | 20 | .. code-block:: bash 21 | 22 | $ sudo apt-get install python-numpy python-scipy python-dev python-setuptools ipython 23 | $ sudo easy_install numdifftools 24 | $ sudo easy_install scikits.scattpy 25 | 26 | Windows 27 | ------- 28 | 29 | Instructions for installing ScattPy under Windows operating system will be added later 30 | -------------------------------------------------------------------------------- /scikits/scattpy/__init__.py: -------------------------------------------------------------------------------- 1 | """ScattPy is a SciKits package providing numerical methods of solving 2 | light scattering by non-spherical particles problem.""" 3 | from methods import svm, ebcm, pmm 4 | from laboratory import\ 5 | Shape,\ 6 | ShapeSphere,\ 7 | ShapeSpheroid,\ 8 | ShapeChebyshev,\ 9 | Particle,\ 10 | HomogeneousParticle,\ 11 | Sphere,\ 12 | ProlateSpheroid,\ 13 | OblateSpheroid,\ 14 | ChebParticle,\ 15 | LayeredParticle,\ 16 | Layered_EqShape_Particle,\ 17 | Layered_EqShapeEqVol_Particle,\ 18 | LayeredConfocalSpheroid,\ 19 | EMT_Particle,\ 20 | EMT_MGarn_Particle,\ 21 | EMT_IMGarn_Particle,\ 22 | EMT_Brugg_Particle,\ 23 | Lab 24 | from version import __version__ 25 | 26 | -------------------------------------------------------------------------------- /doc/source/_themes/github/layout.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: nanohub 3 | title: {{title|e}} 4 | {%- if next %} 5 | 6 | next: 7 | title: {{ next.title }} 8 | url: {{ next.link|e }} 9 | {%- endif %} 10 | {%- if prev %} 11 | 12 | prev: 13 | title: {{ prev.title }} 14 | url: {{ prev.link|e }} 15 | {%- endif %} 16 | 17 | topnav: 18 | - title: Documentation 19 | url: /docs/ 20 | {%- for parent in parents %} 21 | 22 | - title: {{ parent.title }} 23 | url: {{ parent.link|e }} 24 | {%- endfor %} 25 | 26 | - title: {{ title }} 27 | url: # 28 | 29 | sidenav: ' 30 | {{toctree() }} 31 | ' 32 | --- 33 | 34 |
35 | {% block body %} {% endblock %} 36 |
37 | -------------------------------------------------------------------------------- /doc/source/_themes/github/layout.html.bak: -------------------------------------------------------------------------------- 1 | --- 2 | layout: nanohub 3 | title: {{docstitle|e}} 4 | {%- if next %} 5 | 6 | next: 7 | title: {{ next.title }} 8 | url: {{ next.link|e }} 9 | {%- endif %} 10 | {%- if prev %} 11 | 12 | prev: 13 | title: {{ prev.title }} 14 | url: {{ prev.link|e }} 15 | {%- endif %} 16 | 17 | topnav: 18 | - title: Documentation 19 | url: /docs/ 20 | {%- for parent in parents %} 21 | 22 | - title: {{ parent.title }} 23 | url: {{ parent.link|e }} 24 | {%- endfor %} 25 | 26 | - title: {{ title }} 27 | url: # 28 | 29 | sidenav: ' 30 | {{toctree() }} 31 | ' 32 | --- 33 | 34 |
35 | {% block body %} {% endblock %} 36 |
37 | -------------------------------------------------------------------------------- /scikits/scattpy/properties.py: -------------------------------------------------------------------------------- 1 | import spheroidal 2 | 3 | from numpy import pi, real, power, cos, absolute 4 | 5 | #according to (67) 6 | def getCext(particle, alpha, b, nmax): 7 | sum = 0 8 | k = particle.k 9 | for l in range(1, nmax+1): 10 | c = particle.c1 11 | cv = spheroidal.get_cv(1, l, c, particle.type) 12 | sum += power(1j, -l) * b[l-1] *\ 13 | spheroidal.ang1_cv(1, l, c, cv, particle.type, cos([alpha]))[0] 14 | return 4 * pi / (k * k) * real(sum) 15 | 16 | #according to (68) 17 | def getCsca(particle, b, nmax): 18 | sum = 0 19 | k = particle.k 20 | for i in range(nmax): 21 | sum += 2 * absolute(b[i] * b[i]) 22 | return pi / (k * k) * sum 23 | -------------------------------------------------------------------------------- /test/test.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | from scikits.scattpy import * 3 | P=ProlateSpheroid(ab=1.5,xv=1.0,m=1.33+0.07j) 4 | LAB=Lab(P, pi/4) 5 | RES=ebcm(LAB) 6 | 7 | Csca_tm,Qsca_tm = LAB.get_Csca(RES.c_sca_tm) 8 | print Csca_tm,Qsca_tm 9 | Theta = linspace(0,pi,1000) 10 | A = LAB.get_amplitude_matrix(RES.c_sca_tm,RES.c_sca_te,Theta,0) 11 | S11g,S21_S11 = LAB.get_int_plr(A) 12 | from matplotlib import pylab 13 | pylab.semilogy(Theta*180/pi, S11g) 14 | pylab.ylabel("S11/g") 15 | pylab.xlabel("Theta") 16 | pylab.title("Scattering field intencity") 17 | pylab.show() 18 | pylab.close() 19 | 20 | pylab.plot(Theta*180/pi, S21_S11); 21 | pylab.ylabel("S21/S11"); 22 | pylab.xlabel("Theta"); 23 | pylab.title("Scattering field degree of linear polarisation"); 24 | pylab.show() -------------------------------------------------------------------------------- /doc/source/_themes/basic/genindex-split.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Index') %} 3 | {% block body %} 4 | 5 |

{{ _('Index') }}

6 | 7 |

{{ _('Index pages by letter') }}:

8 | 9 |

{% for key, dummy in genindexentries -%} 10 | {{ key }} 11 | {% if not loop.last %}| {% endif %} 12 | {%- endfor %}

13 | 14 |

{{ _('Full index on one page') }} 15 | ({{ _('can be huge') }})

16 | 17 | {% endblock %} 18 | 19 | {% block sidebarrel %} 20 | {% if split_index %} 21 |

Index

22 |

{% for key, dummy in genindexentries -%} 23 | {{ key }} 24 | {% if not loop.last %}| {% endif %} 25 | {%- endfor %}

26 | 27 |

{{ _('Full index on one page') }}

28 | {% endif %} 29 | {{ super() }} 30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /doc/source/_themes/github/genindex-split.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Index') %} 3 | {% block body %} 4 | 5 |

{{ _('Index') }}

6 | 7 |

{{ _('Index pages by letter') }}:

8 | 9 |

{% for key, dummy in genindexentries -%} 10 | {{ key }} 11 | {% if not loop.last %}| {% endif %} 12 | {%- endfor %}

13 | 14 |

{{ _('Full index on one page') }} 15 | ({{ _('can be huge') }})

16 | 17 | {% endblock %} 18 | 19 | {% block sidebarrel %} 20 | {% if split_index %} 21 |

Index

22 |

{% for key, dummy in genindexentries -%} 23 | {{ key }} 24 | {% if not loop.last %}| {% endif %} 25 | {%- endfor %}

26 | 27 |

{{ _('Full index on one page') }}

28 | {% endif %} 29 | {{ super() }} 30 | {% endblock %} 31 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/changes/versionchanges.html: -------------------------------------------------------------------------------- 1 | {% macro entries(changes) %} 2 | 5 | {% endmacro -%} 6 | 8 | 9 | 10 | 11 | 12 | {% trans version=version|e, docstitle=docstitle|e %}Changes in Version {{ version }} — {{ docstitle }}{% endtrans %} 13 | 14 | 15 |
16 |
17 |

{% trans version=version|e %}Automatically generated list of changes in version {{ version }}{% endtrans %}

18 |

{{ _('Library changes') }}

19 | {% for modname, changes in libchanges %} 20 |

{{ modname }}

21 | {{ entries(changes) }} 22 | {% endfor %} 23 |

{{ _('C API changes') }}

24 | {{ entries(apichanges) }} 25 |

{{ _('Other changes') }}

26 | {% for (fn, title), changes in otherchanges %} 27 |

{{ title }} ({{ fn }})

28 | {{ entries(changes) }} 29 | {% endfor %} 30 |
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/source/_themes/github/changes/versionchanges.html: -------------------------------------------------------------------------------- 1 | {% macro entries(changes) %} 2 | 5 | {% endmacro -%} 6 | 8 | 9 | 10 | 11 | 12 | {% trans version=version|e, docstitle=docstitle|e %}Changes in Version {{ version }} — {{ docstitle }}{% endtrans %} 13 | 14 | 15 |
16 |
17 |

{% trans version=version|e %}Automatically generated list of changes in version {{ version }}{% endtrans %}

18 |

{{ _('Library changes') }}

19 | {% for modname, changes in libchanges %} 20 |

{{ modname }}

21 | {{ entries(changes) }} 22 | {% endfor %} 23 |

{{ _('C API changes') }}

24 | {{ entries(apichanges) }} 25 |

{{ _('Other changes') }}

26 | {% for (fn, title), changes in otherchanges %} 27 |

{{ title }} ({{ fn }})

28 | {{ entries(changes) }} 29 | {% endfor %} 30 |
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/defindex.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Overview') %} 3 | {% block body %} 4 |

{{ docstitle|e }}

5 |

6 | Welcome! This is 7 | {% block description %}the documentation for {{ project|e }} 8 | {{ release|e }}{% if last_updated %}, last updated {{ last_updated|e }}{% endif %}{% endblock %}. 9 |

10 | {% block tables %} 11 |

{{ _('Indices and tables:') }}

12 | 13 | 24 |
14 | 16 | 18 | 19 | 21 | 23 |
25 | {% endblock %} 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /doc/source/_themes/github/defindex.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Overview') %} 3 | {% block body %} 4 | 5 |

6 | Welcome! This is 7 | {% block description %}the documentation for {{ project|e }} 8 | {{ release|e }}{% if last_updated %}, last updated {{ last_updated|e }}{% endif %}{% endblock %}. 9 |

10 | {% block tables %} 11 |

{{ _('Indices and tables:') }}

12 | 13 | 24 |
14 | 16 | 18 | 19 | 21 | 23 |
25 | {% endblock %} 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /doc/source/reference/particles.rst: -------------------------------------------------------------------------------- 1 | .. _particles: 2 | 3 | ###### 4 | Particles 5 | ###### 6 | 7 | .. currentmodule:: scikits.scattpy 8 | 9 | A particle is defined by its surface shape and the complex refractive index of its medium. 10 | In the case of a multilayered particle, each layer's refractive index and surface shape 11 | should be defined. 12 | 13 | Homogeneous particles 14 | ===================== 15 | 16 | A homogeneous particle can be defined as an instance of the :class:`HomogeneousParticle`. 17 | There are also several predefined classes for the most often used partiles. 18 | 19 | .. autosummary:: 20 | :toctree: generated/ 21 | 22 | HomogeneousParticle 23 | Sphere 24 | ProlateSpheroid 25 | OblateSpheroid 26 | ChebParticle 27 | 28 | Layered particles 29 | ===================== 30 | 31 | A layered particle can be defined as an instance of the :class:`LayeredParticle`. 32 | There are also several predefined classes for the most often used multilayered partiles. 33 | 34 | .. autosummary:: 35 | :toctree: generated/ 36 | 37 | LayeredParticle 38 | Layered_EqShape_Particle 39 | Layered_EqShapeEqVol_Particle 40 | LayeredConfocalSpheroid 41 | 42 | Effective Medium Theory 43 | ===================== 44 | 45 | Inhomogeneous scatterers can also be treated with the effective medium theory (EMT). 46 | An EMT particle is an instance of a class derrivered from the :class:`EMT_Particle`. 47 | There are several classes implementing EMT with the most widely used EMT rules. 48 | 49 | .. autosummary:: 50 | :toctree: generated/ 51 | 52 | EMT_Particle 53 | EMT_MGarn_Particle 54 | EMT_IMGarn_Particle 55 | EMT_Brugg_Particle 56 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/genindex-single.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Index') %} 3 | {% block body %} 4 | 5 |

{% trans key=key %}Index – {{ key }}{% endtrans %}

6 | 7 |
8 |
9 | {%- set breakat = count // 2 %} 10 | {%- set numcols = 1 %} 11 | {%- set numitems = 0 %} 12 | {% for entryname, (links, subitems) in entries %} 13 |
{%- if links -%}{{ entryname|e }} 14 | {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor -%} 15 | {%- else -%} 16 | {{ entryname|e }} 17 | {%- endif -%}
18 | {%- if subitems %} 19 |
20 | {%- for subentryname, subentrylinks in subitems %} 21 |
{{ subentryname|e }} 22 | {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} 23 |
24 | {%- endfor %} 25 |
26 | {%- endif -%} 27 | {%- set numitems = numitems + 1 + (subitems|length) -%} 28 | {%- if numcols < 2 and numitems > breakat -%} 29 | {%- set numcols = numcols+1 -%} 30 |
31 | {%- endif -%} 32 | {%- endfor %} 33 |
34 | 35 | {% endblock %} 36 | 37 | {% block sidebarrel %} 38 |

Index

39 |

{% for key, dummy in genindexentries -%} 40 | {{ key }} 41 | {% if not loop.last %}| {% endif %} 42 | {%- endfor %}

43 | 44 |

{{ _('Full index on one page') }}

45 | {{ super() }} 46 | {% endblock %} 47 | -------------------------------------------------------------------------------- /doc/source/_themes/github/genindex-single.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Index') %} 3 | {% block body %} 4 | 5 |

{% trans key=key %}Index – {{ key }}{% endtrans %}

6 | 7 |
8 |
9 | {%- set breakat = count // 2 %} 10 | {%- set numcols = 1 %} 11 | {%- set numitems = 0 %} 12 | {% for entryname, (links, subitems) in entries %} 13 |
{%- if links -%}{{ entryname|e }} 14 | {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor -%} 15 | {%- else -%} 16 | {{ entryname|e }} 17 | {%- endif -%}
18 | {%- if subitems %} 19 |
20 | {%- for subentryname, subentrylinks in subitems %} 21 |
{{ subentryname|e }} 22 | {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} 23 |
24 | {%- endfor %} 25 |
26 | {%- endif -%} 27 | {%- set numitems = numitems + 1 + (subitems|length) -%} 28 | {%- if numcols < 2 and numitems > breakat -%} 29 | {%- set numcols = numcols+1 -%} 30 |
31 | {%- endif -%} 32 | {%- endfor %} 33 |
34 | 35 | {% endblock %} 36 | 37 | {% block sidebarrel %} 38 |

Index

39 |

{% for key, dummy in genindexentries -%} 40 | {{ key }} 41 | {% if not loop.last %}| {% endif %} 42 | {%- endfor %}

43 | 44 |

{{ _('Full index on one page') }}

45 | {{ super() }} 46 | {% endblock %} 47 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/search.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Search') %} 3 | {% set script_files = script_files + ['_static/searchtools.js'] %} 4 | {% block body %} 5 |

{{ _('Search') }}

6 |
7 | 8 |

9 | {% trans %}Please activate JavaScript to enable the search 10 | functionality.{% endtrans %} 11 |

12 |
13 |

14 | {% trans %}From here you can search these documents. Enter your search 15 | words into the box below and click "search". Note that the search 16 | function will automatically search for all of the words. Pages 17 | containing fewer words won't appear in the result list.{% endtrans %} 18 |

19 |
20 | 21 | 22 | 23 |
24 | {% if search_performed %} 25 |

{{ _('Search Results') }}

26 | {% if not search_results %} 27 |

{{ _('Your search did not match any results.') }}

28 | {% endif %} 29 | {% endif %} 30 |
31 | {% if search_results %} 32 | 39 | {% endif %} 40 |
41 | {% endblock %} 42 | {% block footer %} 43 | {{ super() }} 44 | 45 | {% endblock %} 46 | -------------------------------------------------------------------------------- /doc/source/_themes/github/search.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Search') %} 3 | {% set script_files = script_files + ['_static/searchtools.js'] %} 4 | {% block body %} 5 |

{{ _('Search') }}

6 |
7 | 8 |

9 | {% trans %}Please activate JavaScript to enable the search 10 | functionality.{% endtrans %} 11 |

12 |
13 |

14 | {% trans %}From here you can search these documents. Enter your search 15 | words into the box below and click "search". Note that the search 16 | function will automatically search for all of the words. Pages 17 | containing fewer words won't appear in the result list.{% endtrans %} 18 |

19 |
20 | 21 | 22 | 23 |
24 | {% if search_performed %} 25 |

{{ _('Search Results') }}

26 | {% if not search_results %} 27 |

{{ _('Your search did not match any results.') }}

28 | {% endif %} 29 | {% endif %} 30 |
31 | {% if search_results %} 32 | 39 | {% endif %} 40 |
41 | {% endblock %} 42 | {% block footer %} 43 | {{ super() }} 44 | 45 | {% endblock %} 46 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/modindex.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Global Module Index') %} 3 | {% block extrahead %} 4 | {{ super() }} 5 | {% if not embedded and collapse_modindex %} 6 | 9 | {% endif %} 10 | {% endblock %} 11 | {% block body %} 12 | 13 |

{{ _('Global Module Index') }}

14 | 15 | {%- for letter in letters %} 16 | {{ letter }} {% if not loop.last %}| {% endif %} 17 | {%- endfor %} 18 |
19 | 20 | 21 | {%- for modname, collapse, cgroup, indent, fname, synops, pform, dep, stripped in modindexentries %} 22 | {%- if not modname -%} 23 | 24 | 25 | {%- else -%} 26 | 27 | 31 | 38 | {%- endif -%} 39 | {% endfor %} 40 |
 
{{ fname }}
{% if collapse -%} 28 | 30 | {%- endif %}{% if indent %}   {% endif %} 32 | {% if fname %}{% endif -%} 33 | {{ stripped|e }}{{ modname|e }} 34 | {%- if fname %}{% endif %} 35 | {%- if pform and pform[0] %} ({{ pform|join(', ') }}){% endif -%} 36 | {% if dep %}{{ _('Deprecated')}}:{% endif %} 37 | {{ synops|e }}
41 | 42 | {% endblock %} 43 | -------------------------------------------------------------------------------- /doc/source/_themes/github/modindex.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Global Module Index') %} 3 | {% block extrahead %} 4 | {{ super() }} 5 | {% if not embedded and collapse_modindex %} 6 | 9 | {% endif %} 10 | {% endblock %} 11 | {% block body %} 12 | 13 |

{{ _('Global Module Index') }}

14 | 15 | {%- for letter in letters %} 16 | {{ letter }} {% if not loop.last %}| {% endif %} 17 | {%- endfor %} 18 |
19 | 20 | 21 | {%- for modname, collapse, cgroup, indent, fname, synops, pform, dep, stripped in modindexentries %} 22 | {%- if not modname -%} 23 | 24 | 25 | {%- else -%} 26 | 27 | 31 | 38 | {%- endif -%} 39 | {% endfor %} 40 |
 
{{ fname }}
{% if collapse -%} 28 | 30 | {%- endif %}{% if indent %}   {% endif %} 32 | {% if fname %}{% endif -%} 33 | {{ stripped|e }}{{ modname|e }} 34 | {%- if fname %}{% endif %} 35 | {%- if pform and pform[0] %} ({{ pform|join(', ') }}){% endif -%} 36 | {% if dep %}{{ _('Deprecated')}}:{% endif %} 37 | {{ synops|e }}
41 | 42 | {% endblock %} 43 | -------------------------------------------------------------------------------- /scikits/scattpy/doc_inherit.py: -------------------------------------------------------------------------------- 1 | """ 2 | doc_inherit decorator 3 | 4 | Usage: 5 | 6 | class Foo(object): 7 | def foo(self): 8 | "Frobber" 9 | pass 10 | 11 | class Bar(Foo): 12 | @doc_inherit 13 | def foo(self): 14 | pass 15 | 16 | Now, Bar.foo.__doc__ == Bar().foo.__doc__ == Foo.foo.__doc__ == "Frobber" 17 | """ 18 | 19 | from functools import wraps 20 | 21 | class DocInherit(object): 22 | """ 23 | Docstring inheriting method descriptor 24 | 25 | The class itself is also used as a decorator 26 | """ 27 | 28 | def __init__(self, mthd): 29 | self.mthd = mthd 30 | self.name = mthd.__name__ 31 | 32 | def __get__(self, obj, cls): 33 | if obj: 34 | return self.get_with_inst(obj, cls) 35 | else: 36 | return self.get_no_inst(cls) 37 | 38 | def get_with_inst(self, obj, cls): 39 | overridden = getattr(super(cls, obj), self.name, None) 40 | 41 | @wraps(self.mthd, assigned=('__name__', '__module__')) 42 | def f(*args, **kwargs): 43 | return self.mthd(obj, *args, **kwargs) 44 | 45 | return self.use_parent_doc(f, overridden) 46 | 47 | def get_no_inst(self, cls): 48 | for parent in cls.__mro__[1:]: 49 | overridden = getattr(parent, self.name, None) 50 | if overridden: break 51 | 52 | @wraps(self.mthd, assigned=('__name__', '__module__')) 53 | def f(*args, **kwargs): 54 | return self.mthd(*args, **kwargs) 55 | 56 | return self.use_parent_doc(f, overridden) 57 | 58 | def use_parent_doc(self, func, source): 59 | if source is None: 60 | raise NameError, ("Can't find '%s' in parents" % self.name) 61 | func.__doc__ = source.__doc__ 62 | return func 63 | 64 | doc_inherit = DocInherit 65 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | ScattPy is a scikits package providing numerical methods 2 | of solving light scattering by non-spherical particles. 3 | 4 | Installation from sources 5 | ========================= 6 | 7 | In the directory scattpy (the same as the file you are reading now), just do: 8 | 9 | python setup.py install 10 | 11 | Distribution 12 | ============ 13 | 14 | A scikit can be distributed by different means: 15 | 16 | Source distribution 17 | ------------------- 18 | 19 | To prepare a source distribution of the package: 20 | 21 | python setup.py sdist 22 | 23 | Eggs 24 | ---- 25 | 26 | Eggs are a format for easy distribution of packages. It is cross platform for 27 | packages without any C code, and platform specific otherwise. To build an egg: 28 | 29 | Binary installers 30 | ----------------- 31 | 32 | Binary installers are platform specific. On Windows, you can do: 33 | 34 | python setup.py bdist_wininst 35 | 36 | On Mac OS X (this requires an extension, bdist_mpkg, available on Pypi) 37 | 38 | python setup.py bdist_mpkg 39 | 40 | Pypi 41 | ==== 42 | 43 | Any scikits can also be registered to pypi, for source and eventually binary 44 | installer hosting. To register a package, and upload the sources at the same time: 45 | 46 | python setup.py register sdist upload 47 | 48 | This will register the package to pypi, prepare a tarball of the package, and 49 | upload it to pypi. You can also upload the files manually to pypi webpage. 50 | 51 | Other distributions can be uploaded to pypi. For example: 52 | 53 | python setup.py bdist_egg upload 54 | 55 | Once an egge is uploaded to scipy, people can simply install it with easy_install: 56 | 57 | easy_install scikits.example 58 | 59 | If you don't want to install as an egg, but from the sources: 60 | 61 | easy_install -eNb example scikits.example 62 | 63 | Will download the most recent sources, and extract them into the example 64 | directory. 65 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/genindex.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Index') %} 3 | {% block body %} 4 | 5 |

{{ _('Index') }}

6 | 7 | {% for key, dummy in genindexentries -%} 8 | {{ key }} {% if not loop.last %}| {% endif %} 9 | {%- endfor %} 10 | 11 |
12 | 13 | {% for key, entries in genindexentries %} 14 |

{{ key }}

15 |
16 |
17 | {%- set breakat = genindexcounts[loop.index0] // 2 %} 18 | {%- set numcols = 1 %} 19 | {%- set numitems = 0 %} 20 | {% for entryname, (links, subitems) in entries %} 21 |
{%- if links -%}{{ entryname|e }} 22 | {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor -%} 23 | {%- else -%} 24 | {{ entryname|e }} 25 | {%- endif -%}
26 | {%- if subitems %} 27 |
28 | {%- for subentryname, subentrylinks in subitems %} 29 |
{{ subentryname|e }} 30 | {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} 31 |
32 | {%- endfor %} 33 |
34 | {%- endif -%} 35 | {%- set numitems = numitems + 1 + (subitems|length) -%} 36 | {%- if numcols < 2 and numitems > breakat -%} 37 | {%- set numcols = numcols+1 -%} 38 |
39 | {%- endif -%} 40 | {%- endfor %} 41 |
42 | {% endfor %} 43 | 44 | {% endblock %} 45 | 46 | {% block sidebarrel %} 47 | {% if split_index %} 48 |

{{ _('Index') }}

49 |

{% for key, dummy in genindexentries -%} 50 | {{ key }} 51 | {% if not loop.last %}| {% endif %} 52 | {%- endfor %}

53 | 54 |

{{ _('Full index on one page') }}

55 | {% endif %} 56 | {{ super() }} 57 | {% endblock %} 58 | -------------------------------------------------------------------------------- /doc/source/_themes/github/genindex.html: -------------------------------------------------------------------------------- 1 | {% extends "layout.html" %} 2 | {% set title = _('Index') %} 3 | {% block body %} 4 | 5 |

{{ _('Index') }}

6 | 7 | {% for key, dummy in genindexentries -%} 8 | {{ key }} {% if not loop.last %}| {% endif %} 9 | {%- endfor %} 10 | 11 |
12 | 13 | {% for key, entries in genindexentries %} 14 |

{{ key }}

15 |
16 |
17 | {%- set breakat = genindexcounts[loop.index0] // 2 %} 18 | {%- set numcols = 1 %} 19 | {%- set numitems = 0 %} 20 | {% for entryname, (links, subitems) in entries %} 21 |
{%- if links -%}{{ entryname|e }} 22 | {%- for link in links[1:] %}, [{{ loop.index }}]{% endfor -%} 23 | {%- else -%} 24 | {{ entryname|e }} 25 | {%- endif -%}
26 | {%- if subitems %} 27 |
28 | {%- for subentryname, subentrylinks in subitems %} 29 |
{{ subentryname|e }} 30 | {%- for link in subentrylinks[1:] %}, [{{ loop.index }}]{% endfor -%} 31 |
32 | {%- endfor %} 33 |
34 | {%- endif -%} 35 | {%- set numitems = numitems + 1 + (subitems|length) -%} 36 | {%- if numcols < 2 and numitems > breakat -%} 37 | {%- set numcols = numcols+1 -%} 38 |
39 | {%- endif -%} 40 | {%- endfor %} 41 |
42 | {% endfor %} 43 | 44 | {% endblock %} 45 | 46 | {% block sidebarrel %} 47 | {% if split_index %} 48 |

{{ _('Index') }}

49 |

{% for key, dummy in genindexentries -%} 50 | {{ key }} 51 | {% if not loop.last %}| {% endif %} 52 | {%- endfor %}

53 | 54 |

{{ _('Full index on one page') }}

55 | {% endif %} 56 | {{ super() }} 57 | {% endblock %} 58 | -------------------------------------------------------------------------------- /scikits/scattpy/spheroidal_particles.py: -------------------------------------------------------------------------------- 1 | from scipy import * 2 | 3 | import spheroidal 4 | 5 | class Spheroid(object): 6 | 7 | def __init__(self,m,a_b,type): 8 | if type == 1: 9 | self.psi = a_b / sqrt(a_b * a_b - 1.0) 10 | elif type == -1: 11 | self.psi = 1.0 / sqrt(a_b * a_b - 1.0) 12 | else: 13 | print "Invalid value of type. Should be 1 or -1." 14 | 15 | self.spheroid = True 16 | 17 | self.m = m 18 | self.eps = sqrt(m) 19 | self.type = type 20 | self.k = 1.0 21 | 22 | def set_xl(self, xl): 23 | self.xl = xl 24 | if self.type == 1: 25 | self.c1 = xl / self.psi 26 | elif self.type == -1: 27 | self.c1 = xl / sqrt(self.psi * self.psi + 1.0) 28 | else: 29 | print "Invalid value of type. Should be 1 or -1. Current value is "+str(self.type) 30 | self.xv = self.c1 * pow(self.psi * (self.psi * self.psi - self.type),1.0/3.0) 31 | self.initialize() 32 | 33 | def set_xv(self,xv): 34 | self.xv = xv 35 | self.c1 = xv / pow(self.psi * (self.psi * self.psi - self.type),1.0/3.0) 36 | if self.type == 1: 37 | self.xl = self.c1 * self.psi 38 | elif self.type == -1: 39 | self.xl = self.c1 * sqrt(self.psi * self.psi + 1.0) 40 | else: 41 | print "Invalid value of type. Should be 1 or -1." 42 | self.initialize() 43 | 44 | def initialize(self): 45 | self.c2 = self.m * self.c1 46 | self.d = 2.0 * self.c1 47 | 48 | def function(self, nu): 49 | return self.psi 50 | 51 | def derivative(self, nu): 52 | return 0.0 53 | 54 | #Incedent waves 55 | class TEInputWave: 56 | alpha = 0 57 | 58 | def __init__(self, alpha): 59 | self.alpha = alpha 60 | 61 | #according to formulas 52 62 | def getB(self, particle, l): 63 | return 0 64 | 65 | def getA(self, particle, c, l): 66 | cv = spheroidal.get_cv(1, l, c, particle.type) 67 | return -2 * pow(1j, l) * spheroidal.ang1_cv(1, l, c, cv, particle.type, cos([self.alpha]))[0] 68 | 69 | 70 | class TMInputWave: 71 | alpha = 0 72 | 73 | def __init__(self, alpha): 74 | self.alpha = alpha 75 | 76 | #according to formulas 53 77 | def getB(self, particle, c, l): 78 | cv = spheroidal.get_cv(1, l, c, particle.type) 79 | return 2 * pow(1j, l) * spheroidal.ang1_cv(1, l, c, cv, particle.type, cos([self.alpha]))[0] 80 | 81 | def getA(self, particle, l): 82 | return 0.0 83 | -------------------------------------------------------------------------------- /scikits/scattpy/spheroidal_functions.py: -------------------------------------------------------------------------------- 1 | import scipy.special as special 2 | 3 | from numpy.lib.scimath import sqrt 4 | 5 | import f_spheroid 6 | import f_radial 7 | 8 | # ---- Calculation of norm for spheroidal angular functions ---- 9 | 10 | optimize_norm={} 11 | def get_norm_cv(m, n, c, cv, type): 12 | sum = 0 13 | k = 0 14 | key = str(m)+' '+str(n)+' '+str(c)+' '+str(cv) 15 | if key in optimize_norm: 16 | return optimize_norm[key] 17 | 18 | d = f_spheroid.sdmn(m, n, c, cv, type) 19 | isEven = (n - m) % 2 20 | if(isEven == 1): 21 | k = 1 22 | 23 | while (k < d.shape[0]): 24 | if (type == 1): 25 | value = d[k / 2] * d[k / 2] / (2.0 * k + 2.0 * m + 1.0) * get_norm_factorial(k, m) 26 | else: 27 | value = d[k / 2] * d[k / 2] / (2.0 * k + 2.0 * m + 1.0) * get_norm_factorial(k, m) 28 | sum += value 29 | k += 2 30 | 31 | sum = sqrt(2.0 * sum) 32 | optimize_norm[key] = sum 33 | return sum 34 | 35 | def get_norm_factorial(k, m): 36 | fact = 1l 37 | for i in range(1, 2 * m + 1): 38 | fact *= k + i 39 | return fact 40 | 41 | def get_pro_norm_cv(m, n, c, cv): 42 | return get_norm_cv(m, n, c, cv, 1) 43 | 44 | 45 | def get_obl_norm_cv(m, n, c, cv): 46 | return get_norm_cv(m, n, c, cv, -1) 47 | 48 | 49 | def get_pro_norm(m, n, c): 50 | return get_pro_norm_cv(m, n, c, special.pro_cv(m, n, c)) 51 | 52 | 53 | def get_obl_norm(m, n, c): 54 | return get_obl_norm_cv(m, n, c, special.obl_cv(m, n, c)) 55 | 56 | # ---- Shortcut for different types of spheroids 57 | 58 | def rad1_cv(m, n, c, type, x): 59 | eps = 10e-8; 60 | if type == 1: 61 | result = f_radial.rad_fun(0, m, n, c, x, eps) 62 | return result[0], result[1] 63 | elif type == -1: 64 | result = f_radial.rad_fun(1, m, n, c, x, eps) 65 | return result[0], result[1] 66 | 67 | 68 | def rad2_cv(m, n, c, type, x): 69 | eps = 10e-8; 70 | if type == 1: 71 | result = f_radial.rad_fun(0, m, n, c, x, eps) 72 | return result[2], result[3] 73 | elif type == -1: 74 | result = f_radial.rad_fun(1, m, n, c, x, eps) 75 | return result[2], result[3] 76 | 77 | 78 | def ang1_cv(m, n, c, cv, type, x): 79 | if type == 1: 80 | value = special.pro_ang1_cv(m, n, c, cv, x) 81 | elif type == -1: 82 | value = special.obl_ang1_cv(m, n, c, cv, x) 83 | return value / get_norm_cv(m, n, c, cv, type) 84 | 85 | 86 | def get_cv(m, n, c, type): 87 | if type == 1: 88 | return special.pro_cv(m, n, c) 89 | elif type == -1: 90 | return special.obl_cv(m, n, c) 91 | 92 | #according to 1.41 Komarov, Slavyanov "Spheroidal funtions" 93 | def rad3_cv(m, n, c, type, x): 94 | return [rad1_cv(m, n, c, type, x)[0] + 1j * rad2_cv(m, n, c, type, x)[0], 95 | rad1_cv(m, n, c, type, x)[1] + 1j * rad2_cv(m, n, c, type, x)[1]] 96 | 97 | def rad_cv(m, n, c, type, rank, x): 98 | if rank == 1: 99 | return rad1_cv(m, n, c, type, x) 100 | elif rank == 3: 101 | return rad3_cv(m, n, c, type, x) -------------------------------------------------------------------------------- /test/pmm_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from spheroidal_particles import * 4 | from properties import * 5 | 6 | #main integration tests for non-absorbing particle 7 | from spheroidal_pmm import SpheroidalPMM 8 | 9 | class testPMM(unittest.TestCase): 10 | 11 | def test_IntegrationCase1(self): 12 | alpha = pi / 4 13 | m=1.5;a_b=1.2;type=1 14 | particle = Spheroid(m,a_b,type) 15 | particle.set_xl(1) 16 | nmax = 6 17 | pmm = SpheroidalPMM(particle,nmax) 18 | b_sca = pmm.getSolution(TMInputWave(alpha))[0] 19 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 20 | C_sca = getCsca(particle, b_sca, nmax)[0] 21 | print C_ext, C_sca 22 | delta = (C_ext-C_sca)/(C_ext+C_sca) 23 | print delta 24 | self.assertAlmostEqual(delta,0,5) 25 | self.assertAlmostEqual(C_ext,C_sca,5) 26 | self.assertTrue(C_ext>0.) 27 | self.assertTrue(C_sca>0.) 28 | 29 | def test_IntegrationCase2(self): 30 | alpha = pi / 3 31 | m=1.3;a_b=1.1;type=-1 32 | particle = Spheroid(m,a_b,type) 33 | particle.set_xl(1) 34 | nmax = 6 35 | pmm = SpheroidalPMM(particle,nmax) 36 | b_sca = pmm.getSolution(TMInputWave(alpha))[0] 37 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 38 | C_sca = getCsca(particle, b_sca, nmax)[0] 39 | print C_ext, C_sca 40 | delta = (C_ext-C_sca)/(C_ext+C_sca) 41 | print delta 42 | self.assertAlmostEqual(delta,0,5) 43 | self.assertAlmostEqual(C_ext,C_sca,5) 44 | self.assertTrue(C_ext>0.) 45 | self.assertTrue(C_sca>0.) 46 | 47 | def test_IntegrationCase3(self): 48 | alpha = pi / 3 49 | m=1.3;a_b=1.2;type=1 50 | particle = Spheroid(m,a_b,type) 51 | particle.set_xl(1) 52 | nmax = 6 53 | pmm = SpheroidalPMM(particle,nmax) 54 | b_sca = pmm.getMatrixSolution(TMInputWave(alpha))[0] 55 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 56 | C_sca = getCsca(particle, b_sca, nmax)[0] 57 | print C_ext, C_sca 58 | delta = (C_ext-C_sca)/(C_ext+C_sca) 59 | print delta 60 | self.assertAlmostEqual(delta,0,5) 61 | self.assertAlmostEqual(C_ext,C_sca,5) 62 | self.assertTrue(C_ext>0.) 63 | self.assertTrue(C_sca>0.) 64 | 65 | def test_IntegrationCase4(self): 66 | alpha = pi / 3 67 | m=1.3;a_b=1.2;type=-1 68 | particle = Spheroid(m,a_b,type) 69 | particle.set_xl(1) 70 | nmax = 6 71 | pmm = SpheroidalPMM(particle,nmax) 72 | b_sca = pmm.getMatrixSolution(TMInputWave(alpha))[0] 73 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 74 | C_sca = getCsca(particle, b_sca, nmax)[0] 75 | print C_ext, C_sca 76 | delta = (C_ext-C_sca)/(C_ext+C_sca) 77 | print delta 78 | self.assertAlmostEqual(delta,0,5) 79 | self.assertAlmostEqual(C_ext,C_sca,5) 80 | self.assertTrue(C_ext>0.) 81 | self.assertTrue(C_sca>0.) 82 | 83 | if __name__ == '__main__': 84 | #import cProfile 85 | #cProfile.run('unittest.main()','profiler_results') 86 | unittest.main() 87 | 88 | 89 | -------------------------------------------------------------------------------- /test/ebcm_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from spheroidal_ebcm import SpheroidalEBCM 4 | from spheroidal_particles import * 5 | from properties import * 6 | 7 | #main integration tests for non-absorbing particle 8 | class testEBCM(unittest.TestCase): 9 | 10 | def test_IntegrationCase1(self): 11 | alpha = pi / 4 12 | m=1.5;a_b=1.1;type=-1 13 | particle = Spheroid(m,a_b,type) 14 | particle.set_xv(1) 15 | nmax = 6 16 | ebcm = SpheroidalEBCM(particle,nmax) 17 | b_sca = ebcm.getSolution(TMInputWave(alpha))[0] 18 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 19 | C_sca = getCsca(particle, b_sca, nmax)[0] 20 | print C_ext, C_sca 21 | delta = (C_ext-C_sca)/(C_ext+C_sca) 22 | print delta 23 | self.assertAlmostEqual(delta,0,5) 24 | self.assertAlmostEqual(C_ext,C_sca,5) 25 | self.assertTrue(C_ext>0.) 26 | self.assertTrue(C_sca>0.) 27 | 28 | def test_IntegrationCase2(self): 29 | alpha = pi / 3 30 | m=1.3;a_b=1.2;type=-1 31 | particle = Spheroid(m,a_b,type) 32 | particle.set_xl(1) 33 | nmax = 6 34 | ebcm = SpheroidalEBCM(particle,nmax) 35 | b_sca = ebcm.getSolution(TMInputWave(alpha))[0] 36 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 37 | C_sca = getCsca(particle, b_sca, nmax)[0] 38 | print C_ext, C_sca 39 | delta = (C_ext-C_sca)/(C_ext+C_sca) 40 | print delta 41 | self.assertAlmostEqual(delta,0,5) 42 | self.assertAlmostEqual(C_ext,C_sca,5) 43 | self.assertTrue(C_ext>0.) 44 | self.assertTrue(C_sca>0.) 45 | 46 | def test_IntegrationCase3(self): 47 | alpha = pi / 3 48 | m=1.3;a_b=1.2;type=1 49 | particle = Spheroid(m,a_b,type) 50 | particle.set_xl(1) 51 | nmax = 6 52 | ebcm = SpheroidalEBCM(particle,nmax) 53 | b_sca = ebcm.getMatrixSolution(TMInputWave(alpha))[0] 54 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 55 | C_sca = getCsca(particle, b_sca, nmax)[0] 56 | print C_ext, C_sca 57 | delta = (C_ext-C_sca)/(C_ext+C_sca) 58 | print delta 59 | self.assertAlmostEqual(delta,0,5) 60 | self.assertAlmostEqual(C_ext,C_sca,5) 61 | self.assertTrue(C_ext>0.) 62 | self.assertTrue(C_sca>0.) 63 | 64 | def test_IntegrationCase4(self): 65 | alpha = pi / 3 66 | m=1.3;a_b=1.2;type=-1 67 | particle = Spheroid(m,a_b,type) 68 | particle.set_xl(1) 69 | nmax = 6 70 | ebcm = SpheroidalEBCM(particle,nmax) 71 | b_sca = ebcm.getMatrixSolution(TMInputWave(alpha))[0] 72 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 73 | C_sca = getCsca(particle, b_sca, nmax)[0] 74 | print C_ext, C_sca 75 | delta = (C_ext-C_sca)/(C_ext+C_sca) 76 | print delta 77 | self.assertAlmostEqual(delta,0,5) 78 | self.assertAlmostEqual(C_ext,C_sca,5) 79 | self.assertTrue(C_ext>0.) 80 | self.assertTrue(C_sca>0.) 81 | 82 | if __name__ == '__main__': 83 | import cProfile 84 | cProfile.run('unittest.main()','profiler_results') 85 | unittest.main() 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /scikits/scattpy/core.py: -------------------------------------------------------------------------------- 1 | # Core functions 2 | from numpy import * 3 | from scipy.special import sph_jn, sph_jnyn, lpmn 4 | from scipy.misc.common import factorial 5 | from math import atan, acos, asin 6 | #from IPython.Debugger import Tracer; debug_here = Tracer() 7 | 8 | Pna = 0 9 | 10 | 11 | def get_Pmn(m, n, x): 12 | return array([lpmn(m, n, xl) for xl in x]) 13 | 14 | 15 | def norm(m, l): 16 | return sqrt((2 * l + 1) / 2. * factorial(l - m) / factorial(l + m)) 17 | 18 | 19 | def get_Pmn_normed(m, n, x): 20 | P = get_Pmn(m, n, x) 21 | for M in xrange(m + 1): 22 | for L in xrange(n + 1): 23 | P[:, :, M, L] = P[:, :, M, L] * norm(M, L) 24 | return P 25 | 26 | #------------- Returning vector fields ------------------------------------- 27 | 28 | def coord_cartesian2spherical(cPoint): 29 | x, y, z = list(cPoint) 30 | r = sqrt(x ** 2 + y ** 2 + z ** 2) 31 | if r == 0: 32 | t = p = 0.0 33 | else: 34 | t = acos(z / r) 35 | if x == 0: 36 | p = asin(sign(y)) 37 | else: 38 | p = atan(y / abs(x)) 39 | if x < 0: 40 | p = pi - p 41 | return array([r, t, p]) 42 | 43 | 44 | def coord_spherical2cartesian(sPoint): 45 | r, t, p = list(sPoint) 46 | x = r * sin(t) * cos(p) 47 | y = r * sin(t) * sin(p) 48 | z = r * cos(t) 49 | return array([x, y, z]) 50 | 51 | 52 | def vector_cartesian2spherical(cVec, sPoint): 53 | r, t, p = list(sPoint) 54 | matr = matrix(\ 55 | [[sin(t) * cos(p), sin(t) * sin(p), cos(t)],\ 56 | [cos(t) * cos(p), cos(t) * sin(p), -sin(t)],\ 57 | [-sin(p), cos(p), 0]]) 58 | sVec = array((matr * matrix(cVec).T).T)[0] 59 | return sVec 60 | 61 | 62 | def vector_spherical2cartesian(sVec, sPoint): 63 | r, t, p = list(sPoint) 64 | matr = matrix(\ 65 | [[sin(t) * cos(p), cos(t) * cos(p), -sin(p)],\ 66 | [sin(t) * sin(p), cos(t) * sin(p), cos(p)],\ 67 | [cos(t), sin(t), 0]]) 68 | cVec = array((matr * matrix(sVec).T).T)[0] 69 | return cVec 70 | 71 | 72 | def get_vector(cPoint, c_sca, k): 73 | sPoint = coord_cartesian2spherical(cPoint) 74 | r, t, p = list(sPoint) 75 | sVec = array([0., 0., 0.]) 76 | 77 | m = 1 78 | 79 | n = len(c_sca) / 2 + m - 1 80 | P, Pd = get_Pmn(m, n, [cos(t)])[0] 81 | Pml = P[m, m:n + 1] 82 | Pdml = Pd[m, m:n + 1] 83 | Bess, Hank = get_JnHn(n, [k * r]) 84 | Hankl = Hank[0, 0, m:] 85 | Hankdl = Hank[0, 1, m:] 86 | a = c_sca[:n - m + 1] 87 | b = c_sca[n - m + 1:] 88 | l = arange(m, n + 1) 89 | 90 | if t == 0 or t == pi: 91 | vec_r = vec_p = vec_t = 0 92 | else: 93 | vec_r = (1. / r * m * sin(m * p) * sum(a * Hankl * Pml) ).real 94 | vec_t = -(1. / (r * sin(t)) * m * sin(m * p)\ 95 | * sum((cos(t) * a + b) * Hankl * Pml) ).real 96 | vec_p = (-1. / r * sin(t) * cos(m * p)\ 97 | * sum(a * Pml * (Hankl + k * r * Hankdl))\ 98 | + sin(t) * cos(m * p) * sum(a * Hankl * Pml)\ 99 | - cos(m * p) * sum((cos(t) * a + b) * Hankl * Pdml) ).real 100 | 101 | sVec += array([vec_r, vec_t, vec_p]) 102 | cVec = vector_spherical2cartesian(sVec, sPoint) 103 | return cVec 104 | -------------------------------------------------------------------------------- /doc/source/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | 15 | .PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest 16 | 17 | help: 18 | @echo "Please use \`make ' where is one of" 19 | @echo " html to make standalone HTML files" 20 | @echo " dirhtml to make HTML files named index.html in directories" 21 | @echo " pickle to make pickle files" 22 | @echo " json to make JSON files" 23 | @echo " htmlhelp to make HTML files and a HTML help project" 24 | @echo " qthelp to make HTML files and a qthelp project" 25 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 26 | @echo " changes to make an overview of all changed/added/deprecated items" 27 | @echo " linkcheck to check all external links for integrity" 28 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 29 | 30 | clean: 31 | -rm -rf $(BUILDDIR)/* 32 | 33 | html: 34 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 35 | @echo 36 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 37 | 38 | dirhtml: 39 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 40 | @echo 41 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 42 | 43 | pickle: 44 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 45 | @echo 46 | @echo "Build finished; now you can process the pickle files." 47 | 48 | json: 49 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 50 | @echo 51 | @echo "Build finished; now you can process the JSON files." 52 | 53 | htmlhelp: 54 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 55 | @echo 56 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 57 | ".hhp project file in $(BUILDDIR)/htmlhelp." 58 | 59 | qthelp: 60 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 61 | @echo 62 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 63 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 64 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ScattPy.qhcp" 65 | @echo "To view the help file:" 66 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ScattPy.qhc" 67 | 68 | latex: 69 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 70 | @echo 71 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 72 | @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ 73 | "run these through (pdf)latex." 74 | 75 | changes: 76 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 77 | @echo 78 | @echo "The overview file is in $(BUILDDIR)/changes." 79 | 80 | linkcheck: 81 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 82 | @echo 83 | @echo "Link check complete; look for any errors in the above output " \ 84 | "or in $(BUILDDIR)/linkcheck/output.txt." 85 | 86 | doctest: 87 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 88 | @echo "Testing of doctests in the sources finished, look at the " \ 89 | "results in $(BUILDDIR)/doctest/output.txt." 90 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # Last Change: Sun Dec 19 11:00 AM 2010 J 3 | 4 | # Copyright (C) 2008 Alexander Vinokurov 5 | 6 | descr = """ScattPy package. 7 | 8 | ScattPy provides numerical methods for solving light scattering problem 9 | by non-spherical particles. 10 | """ 11 | 12 | import os 13 | import sys 14 | 15 | DISTNAME = 'scikits.scattpy' 16 | DESCRIPTION = 'Light Scattering methods for Python' 17 | LONG_DESCRIPTION = descr 18 | MAINTAINER = 'Alexander Vinokurov' 19 | MAINTAINER_EMAIL = 'scattpy@googlegroups.com' 20 | URL = 'http://scattpy.github.com' 21 | LICENSE = 'BSD' 22 | VERSION = '0.1.2' 23 | DOWNLOAD_URL = 'http://github.com/downloads/ScattPy/scikits.scattpy/scikits.scattpy-'+VERSION+'.tar.gz' 24 | 25 | import setuptools 26 | from numpy.distutils.core import setup 27 | 28 | def configuration(parent_package='', top_path=None, package_name=DISTNAME): 29 | if os.path.exists('MANIFEST'): os.remove('MANIFEST') 30 | 31 | from numpy.distutils.misc_util import Configuration 32 | config = Configuration(package_name, parent_package, top_path, 33 | version = VERSION, 34 | maintainer = MAINTAINER, 35 | maintainer_email = MAINTAINER_EMAIL, 36 | description = DESCRIPTION, 37 | license = LICENSE, 38 | url = URL, 39 | download_url = DOWNLOAD_URL, 40 | long_description = LONG_DESCRIPTION) 41 | 42 | config.set_options( 43 | ignore_setup_xxx_py = True, 44 | assume_default_configuration = True, 45 | delegate_options_to_subpackages = True, 46 | quiet = True, 47 | ) 48 | 49 | # config.add_subpackage("scikits") 50 | # config.add_data_files("scikits/__init__.py") 51 | 52 | # config.add_extension('f_utils', 53 | # sources=[os.path.join('src', 'f_utils.for')] 54 | # ) 55 | 56 | config.add_extension('f_utils', 57 | sources=[os.path.join('src', 'f_utils.for')] 58 | ) 59 | config.add_extension('f_spheroid', 60 | sources=[os.path.join('src', 'sdmn.f')] 61 | ) 62 | 63 | config.add_extension('f_radial', 64 | sources=[os.path.join('src', 'radial.for')], 65 | library_dirs=["lib"], 66 | libraries=["radial"] 67 | ) 68 | 69 | return config 70 | 71 | if __name__ == "__main__": 72 | setup(configuration = configuration, 73 | install_requires = 'numpy', 74 | namespace_packages = ['scikits'], 75 | packages = setuptools.find_packages(), 76 | include_package_data = True, 77 | #test_suite="tester", # for python setup.py test 78 | zip_safe = True, # the package can run out of an .egg file 79 | classifiers = 80 | [ 'Development Status :: 4 - Beta', 81 | 'Environment :: Console', 82 | 'Intended Audience :: Developers', 83 | 'Intended Audience :: Science/Research', 84 | 'Intended Audience :: Education', 85 | 'License :: OSI Approved :: BSD License', 86 | 'Topic :: Scientific/Engineering :: Mathematics', 87 | 'Topic :: Scientific/Engineering :: Physics', 88 | 'Topic :: Scientific/Engineering :: Astronomy', ]) 89 | -------------------------------------------------------------------------------- /doc/source/_static/scipy.css: -------------------------------------------------------------------------------- 1 | @import "default.css"; 2 | 3 | /** 4 | * Spacing fixes 5 | */ 6 | 7 | div.body p, div.body dd, div.body li { 8 | line-height: 125%; 9 | } 10 | 11 | ul.simple { 12 | margin-top: 0; 13 | margin-bottom: 0; 14 | padding-top: 0; 15 | padding-bottom: 0; 16 | } 17 | 18 | /* spacing around blockquoted fields in parameters/attributes/returns */ 19 | td.field-body > blockquote { 20 | margin-top: 0.1em; 21 | margin-bottom: 0.5em; 22 | } 23 | 24 | /* spacing around example code */ 25 | div.highlight > pre { 26 | padding: 2px 5px 2px 5px; 27 | } 28 | 29 | /* spacing in see also definition lists */ 30 | dl.last > dd { 31 | margin-top: 1px; 32 | margin-bottom: 5px; 33 | margin-left: 30px; 34 | } 35 | 36 | /** 37 | * Hide dummy toctrees 38 | */ 39 | 40 | ul { 41 | padding-top: 0; 42 | padding-bottom: 0; 43 | margin-top: 0; 44 | margin-bottom: 0; 45 | } 46 | ul li { 47 | padding-top: 0; 48 | padding-bottom: 0; 49 | margin-top: 0; 50 | margin-bottom: 0; 51 | } 52 | ul li a.reference { 53 | padding-top: 0; 54 | padding-bottom: 0; 55 | margin-top: 0; 56 | margin-bottom: 0; 57 | } 58 | 59 | /** 60 | * Make high-level subsections easier to distinguish from top-level ones 61 | */ 62 | div.body h3 { 63 | background-color: transparent; 64 | } 65 | 66 | div.body h4 { 67 | border: none; 68 | background-color: transparent; 69 | } 70 | 71 | /** 72 | * Scipy colors 73 | */ 74 | 75 | body { 76 | background-color: rgb(100,135,220); 77 | } 78 | 79 | div.document { 80 | background-color: rgb(230,230,230); 81 | } 82 | 83 | div.sphinxsidebar { 84 | background-color: rgb(230,230,230); 85 | } 86 | 87 | div.related { 88 | background-color: rgb(100,135,220); 89 | } 90 | 91 | div.sphinxsidebar h3 { 92 | color: rgb(0,102,204); 93 | } 94 | 95 | div.sphinxsidebar h3 a { 96 | color: rgb(0,102,204); 97 | } 98 | 99 | div.sphinxsidebar h4 { 100 | color: rgb(0,82,194); 101 | } 102 | 103 | div.sphinxsidebar p { 104 | color: black; 105 | } 106 | 107 | div.sphinxsidebar a { 108 | color: #355f7c; 109 | } 110 | 111 | div.sphinxsidebar ul.want-points { 112 | list-style: disc; 113 | } 114 | 115 | .field-list th { 116 | color: rgb(0,102,204); 117 | } 118 | 119 | /** 120 | * Extra admonitions 121 | */ 122 | 123 | div.tip { 124 | background-color: #ffffe4; 125 | border: 1px solid #ee6; 126 | } 127 | 128 | div.plot-output { 129 | clear-after: both; 130 | } 131 | 132 | div.plot-output .figure { 133 | float: left; 134 | text-align: center; 135 | margin-bottom: 0; 136 | padding-bottom: 0; 137 | } 138 | 139 | div.plot-output .caption { 140 | margin-top: 2; 141 | padding-top: 0; 142 | } 143 | 144 | div.plot-output p.admonition-title { 145 | display: none; 146 | } 147 | 148 | div.plot-output:after { 149 | content: ""; 150 | display: block; 151 | height: 0; 152 | clear: both; 153 | } 154 | 155 | 156 | /* 157 | div.admonition-example { 158 | background-color: #e4ffe4; 159 | border: 1px solid #ccc; 160 | }*/ 161 | 162 | 163 | /** 164 | * Styling for field lists 165 | */ 166 | 167 | table.field-list th { 168 | border-left: 1px solid #aaa !important; 169 | padding-left: 5px; 170 | } 171 | 172 | table.field-list { 173 | border-collapse: separate; 174 | border-spacing: 10px; 175 | } 176 | 177 | /** 178 | * Styling for footnotes 179 | */ 180 | 181 | table.footnote td, table.footnote th { 182 | border: none; 183 | } 184 | -------------------------------------------------------------------------------- /doc/source/_templates/indexcontent.html: -------------------------------------------------------------------------------- 1 | {% extends "defindex.html" %} 2 | {% block tables %} 3 |

Parts of the documentation:

4 | 5 | 17 |
6 |
18 | 63 | {% endblock %} 64 | -------------------------------------------------------------------------------- /doc/source/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | set SPHINXBUILD=sphinx-build 6 | set BUILDDIR=_build 7 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 8 | if NOT "%PAPER%" == "" ( 9 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 10 | ) 11 | 12 | if "%1" == "" goto help 13 | 14 | if "%1" == "help" ( 15 | :help 16 | echo.Please use `make ^` where ^ is one of 17 | echo. html to make standalone HTML files 18 | echo. dirhtml to make HTML files named index.html in directories 19 | echo. pickle to make pickle files 20 | echo. json to make JSON files 21 | echo. htmlhelp to make HTML files and a HTML help project 22 | echo. qthelp to make HTML files and a qthelp project 23 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 24 | echo. changes to make an overview over all changed/added/deprecated items 25 | echo. linkcheck to check all external links for integrity 26 | echo. doctest to run all doctests embedded in the documentation if enabled 27 | goto end 28 | ) 29 | 30 | if "%1" == "clean" ( 31 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 32 | del /q /s %BUILDDIR%\* 33 | goto end 34 | ) 35 | 36 | if "%1" == "html" ( 37 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 38 | echo. 39 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 40 | goto end 41 | ) 42 | 43 | if "%1" == "dirhtml" ( 44 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 45 | echo. 46 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 47 | goto end 48 | ) 49 | 50 | if "%1" == "pickle" ( 51 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 52 | echo. 53 | echo.Build finished; now you can process the pickle files. 54 | goto end 55 | ) 56 | 57 | if "%1" == "json" ( 58 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 59 | echo. 60 | echo.Build finished; now you can process the JSON files. 61 | goto end 62 | ) 63 | 64 | if "%1" == "htmlhelp" ( 65 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 66 | echo. 67 | echo.Build finished; now you can run HTML Help Workshop with the ^ 68 | .hhp project file in %BUILDDIR%/htmlhelp. 69 | goto end 70 | ) 71 | 72 | if "%1" == "qthelp" ( 73 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 74 | echo. 75 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 76 | .qhcp project file in %BUILDDIR%/qthelp, like this: 77 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\ScattPy.qhcp 78 | echo.To view the help file: 79 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\ScattPy.ghc 80 | goto end 81 | ) 82 | 83 | if "%1" == "latex" ( 84 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 85 | echo. 86 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 87 | goto end 88 | ) 89 | 90 | if "%1" == "changes" ( 91 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 92 | echo. 93 | echo.The overview file is in %BUILDDIR%/changes. 94 | goto end 95 | ) 96 | 97 | if "%1" == "linkcheck" ( 98 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 99 | echo. 100 | echo.Link check complete; look for any errors in the above output ^ 101 | or in %BUILDDIR%/linkcheck/output.txt. 102 | goto end 103 | ) 104 | 105 | if "%1" == "doctest" ( 106 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 107 | echo. 108 | echo.Testing of doctests in the sources finished, look at the ^ 109 | results in %BUILDDIR%/doctest/output.txt. 110 | goto end 111 | ) 112 | 113 | :end 114 | -------------------------------------------------------------------------------- /scikits/scattpy/spheroidal_svm.py: -------------------------------------------------------------------------------- 1 | from numpy import zeros, bmat, mat 2 | import scipy 3 | import scipy.linalg 4 | 5 | from spheroidal_functions import * 6 | 7 | import spheroidal 8 | 9 | 10 | class SpheroidalSVM: 11 | 12 | def __init__(self,particle,nmax): 13 | self.particle=particle 14 | self.c2 = particle.c2 15 | self.c1 = particle.c1 16 | self.nmax = nmax 17 | 18 | #according to (83) 19 | def get_A(self, c2,c1,rank): 20 | A = zeros((self.nmax, self.nmax),dtype=complex) 21 | type = self.particle.type 22 | m = 1 23 | for i in range(self.nmax): 24 | for k in range(self.nmax): 25 | l = i + m 26 | n = k + m 27 | cv_l = get_cv(m, l, c2, type) 28 | cv_n = get_cv(m, n, c1, type) 29 | if (self.particle.spheroid): 30 | func = lambda nu: ang1_cv(m, l, c2, cv_l, type, nu)[0] * ang1_cv(m, n, c1, cv_n, type, nu)[0] 31 | A[i][k] = spheroidal.quad(func, -1, 1) * rad_cv(m, l, c2, type, rank, self.particle.psi)[0] 32 | else: 33 | func = lambda nu: spheroidal.get_a_function(m, l, c2, rank, self.particle)(nu) * ang1_cv(m, n, c1, cv_n, type, nu)[0] 34 | A[i][k] = spheroidal.quad(func, -1, 1) 35 | return mat(A) 36 | 37 | #according to (84) 38 | def __get_Z(self,z_function,c2,c1, rank): 39 | Z = zeros((self.nmax, self.nmax),dtype=complex) 40 | type = self.particle.type 41 | m = 1 42 | for i in range(self.nmax): 43 | for k in range(self.nmax): 44 | l = i + m 45 | n = k + m 46 | cv_l = get_cv(m, l, c2, type) 47 | cv_n = get_cv(m, n, c1, type) 48 | func = lambda nu: z_function(m, l, c2, cv_l, rank, self.particle)(nu) *\ 49 | ang1_cv(m, n, c1, cv_n, type, nu)[0] * spheroidal.metric_phi(nu, self.particle)\ 50 | * spheroidal.get_integral_metric(self.particle)(nu) 51 | Z[i][k] = spheroidal.quad(func, -1, 1) 52 | return mat(Z) 53 | 54 | 55 | def get_C(self): 56 | return self.__get_Z(spheroidal.get_c_function, self.c2, self.c1, 1) 57 | 58 | 59 | def get_B(self, rank): 60 | return self.__get_Z(spheroidal.get_b_function, self.c1, self.c1, rank) 61 | 62 | # ---- Generation of A matrices 63 | 64 | #according to (86) 65 | def get_A11(self): 66 | return self.get_A(self.c1, self.c1, 3).T 67 | 68 | 69 | def get_A12(self): 70 | return -self.get_A(self.c2, self.c1, 1).T 71 | 72 | 73 | def get_A10(self): 74 | return -self.get_A(self.c1, self.c1, 1).T 75 | 76 | 77 | def get_A21(self): 78 | return self.get_B(3).T 79 | 80 | 81 | def get_A22(self): 82 | return -self.get_C().T 83 | 84 | 85 | def get_A20(self): 86 | return -self.get_B(1).T 87 | 88 | #according to (85) 89 | def get_fullB(self): 90 | return bmat([[self.get_A10()], [self.get_A20()]]) 91 | 92 | def get_fullA(self): 93 | A11 = self.get_A11() 94 | A12 = self.get_A12() 95 | A21 = self.get_A21() 96 | A22 = self.get_A22() 97 | return bmat([[A11, A12], [A21, A22]]) 98 | 99 | def getSolution(self,inputWave): 100 | A = self.get_fullA() 101 | B = self.get_fullB() * spheroidal.get_Bin(inputWave, self.particle, self.nmax) 102 | x = -scipy.linalg.solve(A, B) 103 | return (x[0:self.nmax + 1], x[self.nmax + 1:]) -------------------------------------------------------------------------------- /doc/source/user/getting_started.rst: -------------------------------------------------------------------------------- 1 | .. _getting_started: 2 | 3 | *************** 4 | Getting started 5 | *************** 6 | 7 | .. _getting_started_installation: 8 | 9 | Installation 10 | ============ 11 | 12 | To install ScattPy one needs: 13 | 14 | * Python 2.5 - 2.7 15 | * F2PY with a configured FORTRAN77 compiler 16 | * Python packages: 17 | 18 | - NumPy 19 | - SciPy 20 | - NumdiffTools 21 | 22 | Ubuntu 23 | ------ 24 | 25 | .. code-block:: bash 26 | 27 | $ sudo apt-get install python-numpy python-scipy python-dev python-setuptools ipython 28 | $ sudo easy_install numdifftools 29 | $ sudo easy_install scikits.scattpy 30 | 31 | Note: sudo apt-get install python-scipy doesn't work on Ubuntu 10.04. Please use, Ubuntu 10.10 or higher. 32 | 33 | Windows 34 | ------- 35 | 36 | Instructions for installing ScattPy under Windows operating system will be added later 37 | 38 | .. _getting_started_sample_session: 39 | 40 | Sample Session 41 | ============== 42 | 43 | The most simple way of trying ScattPy is to run an interactive python session with IPython. 44 | 45 | .. code-block:: bash 46 | 47 | $ ipython 48 | 49 | Import required packages. 50 | 51 | .. ipython:: 52 | 53 | In [1]: from numpy import * ; 54 | 55 | In [2]: from scikits.scattpy import * ; 56 | 57 | Define a prolate spheroidal particle with the size parameter :math:`x_{\rm V}=2`, aspect ratio :math:`a/b=4` and complex refractive index :math:`m`. 58 | 59 | .. ipython:: 60 | 61 | In [3]: P = ProlateSpheroid(ab=4., xv=2., m=1.33+0.2j) 62 | 63 | Define a laboratory object that desribes the incident wave and the scatterer. We will consider a plane wave propagating at the angle :math:`\alpha=\pi/4` to the particle symmetry axis. 64 | 65 | .. ipython:: 66 | 67 | In [1]: LAB = Lab(P, alpha=pi/4) 68 | 69 | Now we can use any of the ScattPy's numerical methods to obtain scattering properties of the defined model. In this example we apply the extended boundary conditions method (EBCM) that is best suited for homogeneous spheroids. 70 | 71 | .. ipython:: 72 | 73 | In [1]: RES = ebcm(LAB) 74 | 75 | The returned `RES` object contains the expansion coefficients of the scattered field for the TM and TE modes. These coefficients can be used to obtain optical characteristics such as scattering cross-sections and efficiency factors 76 | 77 | .. ipython:: 78 | 79 | In [1]: Csca_tm,Qsca_tm = LAB.get_Csca(RES.c_sca_tm) ; 80 | 81 | In [2]: print Csca_tm,Qsca_tm 82 | 83 | One can also calculate amplitude ans scattering matrix elements for defined ranges of scattering angles, e.g. :math:`\Theta\in[0,\pi],\;\varphi=0`: 84 | 85 | .. ipython:: 86 | 87 | In [2]: Theta = linspace(0,pi,1000) ; 88 | 89 | In [3]: A = LAB.get_amplitude_matrix(RES.c_sca_tm,RES.c_sca_te,Theta,0) ; 90 | 91 | In [4]: S11g,S21_S11 = LAB.get_int_plr(A) ; 92 | 93 | Using ScattPy together with Python data visualisation packages one can obtain plots of the scattering matrix elements. 94 | 95 | .. ipython:: 96 | 97 | In [1]: from matplotlib import pylab 98 | 99 | In [5]: pylab.semilogy(Theta*180/pi, S11g); 100 | 101 | In [5]: pylab.ylabel("S11/g"); 102 | 103 | In [5]: pylab.xlabel("Theta"); 104 | 105 | In [5]: pylab.title("Scattering field intencity"); 106 | 107 | @savefig pylab/getting_started_S11.png 108 | In [5]: pylab.show() 109 | 110 | .. ipython:: 111 | 112 | In [5]: pylab.close() 113 | 114 | In [5]: pylab.plot(Theta*180/pi, S21_S11); 115 | 116 | In [5]: pylab.ylabel("S21/S11"); 117 | 118 | In [5]: pylab.xlabel("Theta"); 119 | 120 | In [5]: pylab.title("Scattering field degree of linear polarisation"); 121 | 122 | @savefig pylab/getting_started_S21.png 123 | In [5]: pylab.show() 124 | -------------------------------------------------------------------------------- /scikits/scattpy/spheroidal_ebcm.py: -------------------------------------------------------------------------------- 1 | from numpy import zeros, asarray, mat 2 | import scipy 3 | import scipy.linalg 4 | 5 | from spheroidal_functions import * 6 | 7 | import spheroidal 8 | from spheroidal_svm import SpheroidalSVM 9 | 10 | 11 | class SpheroidalEBCM: 12 | def __init__(self, particle, nmax): 13 | self.particle = particle 14 | self.c2 = particle.c2 15 | self.c1 = particle.c1 16 | self.nmax = nmax 17 | 18 | #according to (88) 19 | def get_BSi(self): 20 | Bs = zeros((self.nmax, self.nmax), dtype=complex) 21 | type = self.particle.type 22 | m = 1 23 | for i in range(self.nmax): 24 | for k in range(self.nmax): 25 | n = i + m 26 | l = k + m 27 | cv_l = get_cv(m, l, self.c2, type) 28 | cv_n = get_cv(m, n, self.c1, type) 29 | func = lambda nu: (spheroidal.get_a_function(m, l, self.c2, cv_l, 1, self.particle)(nu) *\ 30 | spheroidal.get_b_function(m, n, self.c1, cv_n, 3, self.particle)(nu) -\ 31 | spheroidal.get_c_function(m, l, self.c2, cv_l, 1, self.particle)(nu) *\ 32 | spheroidal.get_a_function(m, n, self.c1, cv_n, 3, self.particle)(nu)) * spheroidal.metric_phi(nu, self.particle) \ 33 | * spheroidal.get_integral_metric(self.particle)(nu) 34 | 35 | Bs[i][k] = spheroidal.quad(func, -1, 1) 36 | return 1j * mat(Bs) 37 | 38 | #according to (88) 39 | def get_BRi(self): 40 | Br = zeros((self.nmax, self.nmax), dtype=complex) 41 | type = self.particle.type 42 | m = 1 43 | for i in range(self.nmax): 44 | for k in range(self.nmax): 45 | n = i + m 46 | l = k + m 47 | cv_l = get_cv(m, l, self.c2, type) 48 | cv_n = get_cv(m, n, self.c1, type) 49 | func = lambda nu: (spheroidal.get_a_function(m, l, self.c2, cv_l, 1, self.particle)(nu) * \ 50 | spheroidal.get_b_function(m, n, self.c1, cv_n, 1, self.particle)(nu) - \ 51 | spheroidal.get_c_function(m, l, self.c2, cv_l, 1, self.particle)(nu) * \ 52 | spheroidal.get_a_function(m, n, self.c1, cv_n, 1, self.particle)(nu)) * spheroidal.metric_phi(nu, self.particle)\ 53 | * spheroidal.get_integral_metric(self.particle)(nu) 54 | 55 | Br[i][k] = spheroidal.quad(func, -1, 1) 56 | return -1j * mat(Br) 57 | 58 | #according to (99) 59 | def get_BSm(self): 60 | svm = SpheroidalSVM(self.particle, self.nmax) 61 | Bs = 1j * ( svm.get_B(3) * svm.get_A(self.c2, self.c1, 1).T - 62 | svm.get_A(self.c1, self.c1, 3) * svm.get_C().T) 63 | return Bs 64 | 65 | #according to (99) 66 | def get_BRm(self): 67 | svm = SpheroidalSVM(self.particle, self.nmax) 68 | Br = -1j * ( svm.get_B(1) * svm.get_A(self.c2, self.c1, 1).T - 69 | svm.get_A(self.c1, self.c1, 1) * svm.get_C().T) 70 | return Br 71 | 72 | 73 | #Return b_sca and b_int. b_sca = result[0] and b_int = result[1] 74 | def getSolution(self, inputWave): 75 | b_in = spheroidal.get_Bin(inputWave, self.particle, self.nmax) 76 | b_int = scipy.linalg.solve(self.get_BSi(), -b_in) 77 | b_sca = asarray(self.get_BRi() * b_int) 78 | return (b_sca, b_int) 79 | 80 | def getMatrixSolution(self, inputWave): 81 | b_in = spheroidal.get_Bin(inputWave, self.particle, self.nmax) 82 | b_int = scipy.linalg.solve(self.get_BSm(), -b_in) 83 | b_sca = asarray(self.get_BRm() * b_int) 84 | return (b_sca, b_int) 85 | -------------------------------------------------------------------------------- /scikits/scattpy/spheroidal.py: -------------------------------------------------------------------------------- 1 | import scipy.integrate 2 | 3 | from scipy import * 4 | 5 | from spheroidal_svm import * 6 | 7 | #quad integration for complex numbers 8 | def quad(func, a, b, **kwargs): 9 | def real_func(x): 10 | return scipy.real(func(x)) 11 | def imag_func(x): 12 | return scipy.imag(func(x)) 13 | eps = 1E-18 14 | #real_integral = scipy.integrate.quadrature(real_func, a, b) 15 | #imag_integral = scipy.integrate.quadrature(imag_func, a, b) 16 | real_integral = scipy.integrate.quad(real_func, a, b,epsabs=eps) 17 | imag_integral = scipy.integrate.quad(imag_func, a, b,epsabs=eps) 18 | return real_integral[0] + 1j*imag_integral[0] 19 | 20 | #according to (81) 21 | def get_a_function(m, n, c, cv, rank, particle): 22 | type = particle.type 23 | return lambda nu: rad_cv(m, n, c, type, rank,particle.function(nu))[0] * ang1_cv(m, n, c, cv, type, nu)[0] 24 | 25 | #according to (81) 26 | def get_b_function(m, n, c, cv, rank, particle): 27 | type = particle.type 28 | return lambda nu: (metric_nu(nu, particle) / metric_psi(nu, particle) 29 | * rad_cv(m, n, c, type,rank, particle.function(nu))[1] * ang1_cv(m, n, c, cv, type, nu)[0] 30 | - particle.derivative(nu) * metric_psi(nu, particle) / metric_nu(nu, particle) 31 | * rad_cv(m, n, c, type,rank, particle.function(nu))[0] * ang1_cv(m, n, c, cv, type, nu)[1]) \ 32 | / get_integral_metric(particle)(nu) 33 | 34 | #according to (82) 35 | def get_c_function(m, n, c, cv, rank, particle): 36 | eps = particle.eps 37 | #according to (30) 38 | #is there a minus? 39 | delta = lambda nu: metric_phi(nu, particle) 40 | #according to (28) 41 | return lambda nu: get_b_function(m, n, c, cv, 1, particle)(nu) / eps -\ 42 | (1.0 / eps - 1.0) * IzIt(nu,particle) / delta(nu) * get_a_function(m, n, c, cv, 1, particle)(nu) 43 | 44 | #-------------------------Metric coefficients ------------------------------------------------ 45 | 46 | #according to (81) 47 | def get_integral_metric(particle): 48 | return lambda nu: sqrt(metric_nu(nu, particle) * metric_nu(nu, particle) 49 | + particle.derivative(nu) * particle.derivative(nu) * metric_psi(nu, particle) * metric_psi(nu, particle)) 50 | 51 | #according to formula 25 52 | def metric_psi(nu, particle): 53 | psi = particle.function(nu) 54 | return particle.d / 2.0 * sqrt((psi * psi - particle.type * nu * nu) / (psi * psi - particle.type)) 55 | 56 | 57 | def metric_nu(nu, particle): 58 | psi = particle.function(nu) 59 | return particle.d / 2.0 * sqrt((psi * psi - particle.type * nu * nu) / (1 - nu * nu)) 60 | 61 | 62 | def metric_phi(nu, particle): 63 | psi = particle.function(nu) 64 | return particle.d / 2.0 * sqrt((psi * psi - particle.type) * (1 - nu * nu)) 65 | 66 | def IzIt(nu,particle): 67 | return particle.d / 2.0 * (particle.derivative(nu) * nu + particle.function(nu))\ 68 | / get_integral_metric(particle)(nu) 69 | 70 | def IzIn(nu,particle): 71 | return particle.d / 2.0 * (nu * metric_nu(nu,particle) / metric_psi(nu,particle) - 72 | particle.derivative(nu) * particle.function(nu) * metric_psi(nu,particle) / metric_nu(nu,particle))\ 73 | / get_integral_metric(particle)(nu) 74 | 75 | def RIn(nu,particle): 76 | return (particle.d / 2.0)**2 * (particle.function(nu) * metric_nu(nu,particle) / metric_psi(nu,particle) - 77 | particle.type * nu *particle.derivative(nu) * metric_psi(nu,particle) / metric_nu(nu,particle)) \ 78 | / get_integral_metric(particle)(nu) 79 | def RIt(nu,particle): 80 | return (particle.d / 2.0)**2 * (particle.derivative(nu)*particle.function(nu)+particle.type*nu) / get_integral_metric(particle)(nu) 81 | 82 | #-------Solve equation and find solution of scattering 83 | 84 | def get_Bin(inputWave, particle,nmax): 85 | b = zeros((nmax, 1),dtype=complex) 86 | for i in range(nmax): 87 | l = i + 1 88 | b[i] = inputWave.getB(particle, particle.c1, l) 89 | return b 90 | 91 | #Return b_sca and b_int. b_sca = result[0] and b_int = result[1] 92 | def getSolution(method,particle, inputWave, nmax): 93 | A = method.get_fullA() 94 | B = method.get_fullB() * get_Bin(inputWave, particle, nmax) 95 | x = scipy.linalg.solve(A, B) 96 | return (x[0:nmax + 1], x[nmax + 1:]) -------------------------------------------------------------------------------- /src/sdmn.f: -------------------------------------------------------------------------------- 1 | C Shanjie Zhang and Jianming Jin 2 | C 3 | C Copyrighted but permission granted to use code in programs. 4 | C Buy their book "Computation of Special Functions", 1996, John Wiley & Sons, Inc. 5 | SUBROUTINE SDMN(M,N,C,CV,KD,DF) 6 | C 7 | C ===================================================== 8 | C Purpose: Compute the expansion coefficients of the 9 | C prolate and oblate spheroidal functions, dk 10 | C Input : m --- Mode parameter 11 | C n --- Mode parameter 12 | C c --- Spheroidal parameter 13 | C cv --- Characteristic value 14 | C KD --- Function code 15 | C KD=1 for prolate; KD=-1 for oblate 16 | C Output: DF(k) --- Expansion coefficients dk; 17 | C DF(1), DF(2), ... correspond to 18 | C d0, d2, ... for even n-m and d1, 19 | C d3, ... for odd n-m 20 | C ===================================================== 21 | C 22 | IMPLICIT DOUBLE PRECISION (A-H,O-Z) 23 | DIMENSION A(200),D(200),G(200),DF(200) 24 | cf2py intent(in) M, N, C, CV, KD 25 | cf2py intent(out) DF 26 | NM=25+INT(0.5*(N-M)+C) 27 | IF (C.LT.1.0D-10) THEN 28 | DO 5 I=1,NM 29 | 5 DF(I)=0D0 30 | DF((N-M)/2+1)=1.0D0 31 | RETURN 32 | ENDIF 33 | CS=C*C*KD 34 | IP=1 35 | K=0 36 | IF (N-M.EQ.2*INT((N-M)/2)) IP=0 37 | DO 10 I=1,NM+2 38 | IF (IP.EQ.0) K=2*(I-1) 39 | IF (IP.EQ.1) K=2*I-1 40 | DK0=M+K 41 | DK1=M+K+1 42 | DK2=2*(M+K) 43 | D2K=2*M+K 44 | A(I)=(D2K+2.0)*(D2K+1.0)/((DK2+3.0)*(DK2+5.0))*CS 45 | D(I)=DK0*DK1+(2.0*DK0*DK1-2.0*M*M-1.0)/((DK2-1.0) 46 | & *(DK2+3.0))*CS 47 | G(I)=K*(K-1.0)/((DK2-3.0)*(DK2-1.0))*CS 48 | 10 CONTINUE 49 | FS=1.0D0 50 | F1=0.0D0 51 | F0=1.0D-100 52 | KB=0 53 | DF(NM+1)=0.0D0 54 | FL=0.0D0 55 | DO 30 K=NM,1,-1 56 | F=-((D(K+1)-CV)*F0+A(K+1)*F1)/G(K+1) 57 | IF (DABS(F).GT.DABS(DF(K+1))) THEN 58 | DF(K)=F 59 | F1=F0 60 | F0=F 61 | IF (DABS(F).GT.1.0D+100) THEN 62 | DO 12 K1=K,NM 63 | 12 DF(K1)=DF(K1)*1.0D-100 64 | F1=F1*1.0D-100 65 | F0=F0*1.0D-100 66 | ENDIF 67 | ELSE 68 | KB=K 69 | FL=DF(K+1) 70 | F1=1.0D-100 71 | F2=-(D(1)-CV)/A(1)*F1 72 | DF(1)=F1 73 | IF (KB.EQ.1) THEN 74 | FS=F2 75 | ELSE IF (KB.EQ.2) THEN 76 | DF(2)=F2 77 | FS=-((D(2)-CV)*F2+G(2)*F1)/A(2) 78 | ELSE 79 | DF(2)=F2 80 | DO 20 J=3,KB+1 81 | F=-((D(J-1)-CV)*F2+G(J-1)*F1)/A(J-1) 82 | IF (J.LE.KB) DF(J)=F 83 | IF (DABS(F).GT.1.0D+100) THEN 84 | DO 15 K1=1,J 85 | 15 DF(K1)=DF(K1)*1.0D-100 86 | F=F*1.0D-100 87 | F2=F2*1.0D-100 88 | ENDIF 89 | F1=F2 90 | 20 F2=F 91 | FS=F 92 | ENDIF 93 | GO TO 35 94 | ENDIF 95 | 30 CONTINUE 96 | 35 SU1=0.0D0 97 | R1=1.0D0 98 | DO 40 J=M+IP+1,2*(M+IP) 99 | 40 R1=R1*J 100 | SU1=DF(1)*R1 101 | DO 45 K=2,KB 102 | R1=-R1*(K+M+IP-1.5D0)/(K-1.0D0) 103 | 45 SU1=SU1+R1*DF(K) 104 | SU2=0.0D0 105 | SW=0.0D0 106 | DO 50 K=KB+1,NM 107 | IF (K.NE.1) R1=-R1*(K+M+IP-1.5D0)/(K-1.0D0) 108 | SU2=SU2+R1*DF(K) 109 | IF (DABS(SW-SU2).LT.DABS(SU2)*1.0D-14) GOTO 55 110 | 50 SW=SU2 111 | 55 R3=1.0D0 112 | DO 60 J=1,(M+N+IP)/2 113 | 60 R3=R3*(J+0.5D0*(N+M+IP)) 114 | R4=1.0D0 115 | DO 65 J=1,(N-M-IP)/2 116 | 65 R4=-4.0D0*R4*J 117 | S0=R3/(FL*(SU1/FS)+SU2)/R4 118 | DO 70 K=1,KB 119 | 70 DF(K)=FL/FS*S0*DF(K) 120 | DO 75 K=KB+1,NM 121 | 75 DF(K)=S0*DF(K) 122 | RETURN 123 | END -------------------------------------------------------------------------------- /doc/source/sphinxext/ipython_console_highlighting.py: -------------------------------------------------------------------------------- 1 | """reST directive for syntax-highlighting ipython interactive sessions. 2 | 3 | XXX - See what improvements can be made based on the new (as of Sept 2009) 4 | 'pycon' lexer for the python console. At the very least it will give better 5 | highlighted tracebacks. 6 | """ 7 | 8 | #----------------------------------------------------------------------------- 9 | # Needed modules 10 | 11 | # Standard library 12 | import re 13 | 14 | # Third party 15 | from pygments.lexer import Lexer, do_insertions 16 | from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, 17 | PythonTracebackLexer) 18 | from pygments.token import Comment, Generic 19 | 20 | from sphinx import highlighting 21 | 22 | #----------------------------------------------------------------------------- 23 | # Global constants 24 | line_re = re.compile('.*?\n') 25 | 26 | #----------------------------------------------------------------------------- 27 | # Code begins - classes and functions 28 | 29 | class IPythonConsoleLexer(Lexer): 30 | """ 31 | For IPython console output or doctests, such as: 32 | 33 | .. sourcecode:: ipython 34 | 35 | In [1]: a = 'foo' 36 | 37 | In [2]: a 38 | Out[2]: 'foo' 39 | 40 | In [3]: print a 41 | foo 42 | 43 | In [4]: 1 / 0 44 | 45 | Notes: 46 | 47 | - Tracebacks are not currently supported. 48 | 49 | - It assumes the default IPython prompts, not customized ones. 50 | """ 51 | 52 | name = 'IPython console session' 53 | aliases = ['ipython'] 54 | mimetypes = ['text/x-ipython-console'] 55 | input_prompt = re.compile("(In \[[0-9]+\]: )|( \.\.\.+:)") 56 | output_prompt = re.compile("(Out\[[0-9]+\]: )|( \.\.\.+:)") 57 | continue_prompt = re.compile(" \.\.\.+:") 58 | tb_start = re.compile("\-+") 59 | 60 | def get_tokens_unprocessed(self, text): 61 | pylexer = PythonLexer(**self.options) 62 | tblexer = PythonTracebackLexer(**self.options) 63 | 64 | curcode = '' 65 | insertions = [] 66 | for match in line_re.finditer(text): 67 | line = match.group() 68 | input_prompt = self.input_prompt.match(line) 69 | continue_prompt = self.continue_prompt.match(line.rstrip()) 70 | output_prompt = self.output_prompt.match(line) 71 | if line.startswith("#"): 72 | insertions.append((len(curcode), 73 | [(0, Comment, line)])) 74 | elif input_prompt is not None: 75 | insertions.append((len(curcode), 76 | [(0, Generic.Prompt, input_prompt.group())])) 77 | curcode += line[input_prompt.end():] 78 | elif continue_prompt is not None: 79 | insertions.append((len(curcode), 80 | [(0, Generic.Prompt, continue_prompt.group())])) 81 | curcode += line[continue_prompt.end():] 82 | elif output_prompt is not None: 83 | # Use the 'error' token for output. We should probably make 84 | # our own token, but error is typicaly in a bright color like 85 | # red, so it works fine for our output prompts. 86 | insertions.append((len(curcode), 87 | [(0, Generic.Error, output_prompt.group())])) 88 | curcode += line[output_prompt.end():] 89 | else: 90 | if curcode: 91 | for item in do_insertions(insertions, 92 | pylexer.get_tokens_unprocessed(curcode)): 93 | yield item 94 | curcode = '' 95 | insertions = [] 96 | yield match.start(), Generic.Output, line 97 | if curcode: 98 | for item in do_insertions(insertions, 99 | pylexer.get_tokens_unprocessed(curcode)): 100 | yield item 101 | 102 | 103 | def setup(app): 104 | """Setup as a sphinx extension.""" 105 | 106 | # This is only a lexer, so adding it below to pygments appears sufficient. 107 | # But if somebody knows that the right API usage should be to do that via 108 | # sphinx, by all means fix it here. At least having this setup.py 109 | # suppresses the sphinx warning we'd get without it. 110 | pass 111 | 112 | #----------------------------------------------------------------------------- 113 | # Register the extension as a valid pygments lexer 114 | highlighting.lexers['ipython'] = IPythonConsoleLexer() 115 | -------------------------------------------------------------------------------- /test/svm_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | 3 | from spheroidal import * 4 | from spheroidal_particles import * 5 | from properties import * 6 | 7 | #main integration tests for non-absorbing particle 8 | class testSVM(unittest.TestCase): 9 | 10 | def __init__(self,methodName): 11 | unittest.TestCase.__init__(self,methodName) 12 | self.m = 1.3; self.a_b =1.4; self.type = 1; self.xl = 4 13 | self.particle = Spheroid(self.m,self.a_b,self.type) 14 | self.particle.set_xl(self.xl) 15 | 16 | #according to (100) 17 | #holds if k=1 so d should be 2 * c1 18 | def test_relation1(self): 19 | particle = self.particle 20 | nmax = 6 21 | svm = SpheroidalSVM(particle,nmax) 22 | c1 = particle.c1 23 | relation = svm.get_B(3) * svm.get_A(c1,c1,1).T - svm.get_A(c1,c1,3) * svm.get_B(1).T 24 | right_part = 1j*mat(eye(nmax)) 25 | for i in range(0,nmax): 26 | for k in range(0,nmax): 27 | self.assertAlmostEqual(relation[i,k],right_part[i,k]) 28 | 29 | def test_relation2(self): 30 | particle = self.particle 31 | nmax = 6 32 | svm = SpheroidalSVM(particle,nmax) 33 | c1 = particle.c1 34 | relation = svm.get_B(3) * svm.get_A(c1,c1,3).T - svm.get_A(c1,c1,3) * svm.get_B(3).T 35 | for i in range(0,nmax): 36 | for k in range(0,nmax): 37 | self.assertAlmostEqual(relation[i,k],0) 38 | 39 | def test_relation3(self): 40 | particle = self.particle 41 | nmax = 6 42 | svm = SpheroidalSVM(particle,nmax) 43 | c1 = particle.c1 44 | relation = svm.get_B(1) * svm.get_A(c1,c1,1).T - svm.get_A(c1,c1,1) * svm.get_B(1).T 45 | for i in range(0,nmax): 46 | for k in range(0,nmax): 47 | self.assertAlmostEqual(relation[i,k],0) 48 | 49 | def test_relation4(self): 50 | particle = self.particle 51 | nmax = 6 52 | svm = SpheroidalSVM(particle,nmax) 53 | c1 = particle.c1 54 | relation = svm.get_A(c1,c1,1).T * svm.get_B(3) - svm.get_A(c1,c1,3).T * svm.get_B(1) 55 | right_part = 1j*mat(eye(nmax)) 56 | for i in range(0,nmax): 57 | for k in range(0,nmax): 58 | self.assertAlmostEqual(relation[i,k],right_part[i,k]) 59 | 60 | def test_relation5(self): 61 | particle = self.particle 62 | nmax = 6 63 | svm = SpheroidalSVM(particle,nmax) 64 | c1 = particle.c1 65 | relation = svm.get_A(c1,c1,3).T * svm.get_A(c1,c1,1) - svm.get_A(c1,c1,1).T * svm.get_A(c1,c1,3) 66 | for i in range(0,nmax): 67 | for k in range(0,nmax): 68 | self.assertAlmostEqual(relation[i,k], 0) 69 | 70 | def test_relation6(self): 71 | particle = self.particle 72 | nmax = 6 73 | svm = SpheroidalSVM(particle,nmax) 74 | c1 = particle.c1 75 | relation = svm.get_B(3).T * svm.get_B(1) - svm.get_B(1).T * svm.get_B(3) 76 | for i in range(0,nmax): 77 | for k in range(0,nmax): 78 | self.assertAlmostEqual(relation[i,k], 0) 79 | 80 | def test_relation7(self): 81 | particle = self.particle 82 | nmax = 6 83 | svm = SpheroidalSVM(particle,nmax) 84 | c1 = particle.c1 85 | relation = svm.get_A(c1,c1,1) * svm.get_B(3).T - svm.get_B(1).T * svm.get_A(c1,c1,3) 86 | right_part = 1j*mat(eye(nmax)) 87 | for i in range(0,nmax): 88 | for k in range(0,nmax): 89 | self.assertAlmostEqual(relation[i,k], right_part[i,k]) 90 | 91 | 92 | def test_IntegrationCase1(self): 93 | alpha = pi / 4 94 | particle = self.particle 95 | particle.set_xl(1) 96 | print "c1=" + str(particle.c1) 97 | print "c2=" + str(particle.c2) 98 | print "d=" + str(particle.d) 99 | print "eps="+str(particle.eps) 100 | print "psi="+str(particle.psi) 101 | nmax = 8 102 | svm = SpheroidalSVM(particle,nmax) 103 | b_sca = svm.getSolution(TMInputWave(alpha))[0] 104 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 105 | C_sca = getCsca(particle, b_sca, nmax)[0] 106 | print C_ext, C_sca 107 | delta = (C_ext-C_sca)/(C_ext+C_sca) 108 | print delta 109 | self.assertAlmostEqual(delta,0,5) 110 | self.assertAlmostEqual(C_ext,C_sca,5) 111 | self.assertTrue(C_ext>0.) 112 | self.assertTrue(C_sca>0.) 113 | 114 | def test_IntegrationCase2(self): 115 | alpha = pi / 4 116 | particle = self.particle 117 | particle.set_xl(3.0) 118 | print " c1=" + str(particle.c1) + " c2=" + str(particle.c2) + " eps=" + str(particle.eps) + " psi=" + str(particle.psi) + " d="+str(particle.d) 119 | nmax = 6 120 | svm = SpheroidalSVM(particle,nmax) 121 | b_sca = svm.getSolution(TMInputWave(alpha))[0] 122 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 123 | C_sca = getCsca(particle, b_sca, nmax)[0] 124 | print C_ext, C_sca 125 | delta = (C_ext-C_sca)/(C_ext+C_sca) 126 | print delta 127 | self.assertAlmostEqual(delta,0,5) 128 | self.assertAlmostEqual(C_ext,C_sca,5) 129 | self.assertTrue(C_ext>0.) 130 | self.assertTrue(C_sca>0.) 131 | 132 | if __name__ == '__main__': 133 | #import cProfile 134 | #cProfile.run('unittest.main()','profiler_results') 135 | unittest.main() 136 | 137 | 138 | -------------------------------------------------------------------------------- /test/draw_spheroidal.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import matplotlib 4 | from spheroidal_ebcm import SpheroidalEBCM 5 | from spheroidal_pmm import SpheroidalPMM 6 | 7 | matplotlib.use('Agg') 8 | 9 | import matplotlib.pyplot as plt 10 | import numpy as np 11 | 12 | from pylab import load 13 | from pylab import save 14 | 15 | from spheroidal import * 16 | from spheroidal_particles import * 17 | from properties import * 18 | 19 | import sys 20 | 21 | m = 1.5 22 | alpha = pi / 4 23 | 24 | n_min = 6 25 | n_max = 52 26 | 27 | def generate_data(a_b,xl,type): 28 | y=[] 29 | execution_time=[] 30 | 31 | particle = Spheroid(m,a_b,type) 32 | particle.set_xl(xl) 33 | 34 | 35 | 36 | id = str(a_b) + " " + str(xl) + " " + str(type) 37 | 38 | for i in range(n_min,n_max,2): 39 | nmax = i 40 | print nmax 41 | start = time.time() 42 | svm = SpheroidalSVM(particle,nmax) 43 | b_sca = svm.getSolution(TMInputWave(alpha))[0] 44 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 45 | C_sca = getCsca(particle, b_sca, nmax)[0] 46 | delta=(C_ext-C_sca)/(C_ext+C_sca) 47 | execution_time.append(time.time() - start) 48 | y.append(delta) 49 | 50 | y= np.fabs(y) 51 | save("svm_delta"+id,y) 52 | save("svm_time"+id,execution_time) 53 | y=[] 54 | execution_time=[] 55 | 56 | for i in range(n_min,n_max,2): 57 | nmax = i 58 | print nmax 59 | start = time.time() 60 | ebcm = SpheroidalEBCM(particle,nmax) 61 | b_sca = ebcm.getMatrixSolution(TMInputWave(alpha))[0] 62 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 63 | C_sca = getCsca(particle, b_sca, nmax)[0] 64 | delta=(C_ext-C_sca)/(C_ext+C_sca) 65 | execution_time.append(time.time() - start) 66 | y.append(delta) 67 | 68 | y= np.fabs(y) 69 | save("ebcm_m_delta"+id,y) 70 | save("ebcm_m_time"+id,execution_time) 71 | y=[] 72 | execution_time=[] 73 | 74 | for i in range(n_min,n_max,2): 75 | nmax = i 76 | print nmax 77 | start = time.time() 78 | ebcm = SpheroidalEBCM(particle,nmax) 79 | b_sca = ebcm.getSolution(TMInputWave(alpha))[0] 80 | C_ext = getCext(particle, alpha, b_sca, nmax)[0] 81 | C_sca = getCsca(particle, b_sca, nmax)[0] 82 | delta=(C_ext-C_sca)/(C_ext+C_sca) 83 | execution_time.append(time.time() - start) 84 | y.append(delta) 85 | 86 | y= np.fabs(y) 87 | save("ebcm_delta"+id,y) 88 | save("ebcm_time"+id,execution_time) 89 | y=[] 90 | execution_time=[] 91 | 92 | # for i in range(n_min,n_max,2): 93 | # nmax = i 94 | # print nmax 95 | # start = time.time() 96 | # pmm = SpheroidalPMM(particle,c2,c1,nmax) 97 | # b_sca = pmm.getMatrixSolution(TMInputWave(alpha))[0] 98 | # C_ext = getCext(particle, alpha, k, b_sca, nmax)[0] 99 | # C_sca = getCsca(k, b_sca, nmax)[0] 100 | # delta=(C_ext-C_sca)/(C_ext+C_sca) 101 | # execution_time.append(time.time() - start) 102 | # y.append(delta) 103 | # 104 | # y= np.fabs(y) 105 | # save("pmm_m_delta",y) 106 | # save("pmm_m_time",execution_time) 107 | # y=[] 108 | # execution_time=[] 109 | # 110 | # for i in range(n_min,n_max,2): 111 | # nmax = i 112 | # print nmax 113 | # start = time.time() 114 | # pmm = SpheroidalPMM(particle,c2,c1,nmax) 115 | # b_sca = pmm.getSolution(TMInputWave(alpha))[0] 116 | # C_ext = getCext(particle, alpha, k, b_sca, nmax)[0] 117 | # C_sca = getCsca(k, b_sca, nmax)[0] 118 | # delta=(C_ext-C_sca)/(C_ext+C_sca) 119 | # execution_time.append(time.time() - start) 120 | # y.append(delta) 121 | # 122 | # y= np.fabs(y) 123 | # save("pmm_delta",y) 124 | # save("pmm_time",execution_time) 125 | 126 | def plot_graphics(a_b,xl,type): 127 | particle = Spheroid(m,a_b,type) 128 | particle.set_xl(xl) 129 | id = str(a_b) + " " + str(xl) + " " + str(type) 130 | 131 | svm_delta=load('svm_delta'+id+'.npy') 132 | svm_time=load('svm_time'+id+'.npy') 133 | ebcm_m_delta=load('ebcm_m_delta'+id+'.npy') 134 | ebcm_m_time=load('ebcm_m_time'+id+'.npy') 135 | ebcm_delta=load('ebcm_delta'+id+'.npy') 136 | ebcm_time=load('ebcm_time'+id+'.npy') 137 | x=np.arange(n_min,n_max,2) 138 | 139 | title = 'm = '+str(particle.m)+' a/b = ' + str(a_b) + ' type = '+str(type)+ ' xl = ' + str(xl) + ' xv = '+str(particle.xv) + ' alpha = ' + str(alpha) 140 | 141 | fig = plt.figure(figsize=(10,10)) 142 | plt.title(title) 143 | plt.grid(True) 144 | plt.plot(x,svm_delta,'k-',label='SVM') 145 | plt.plot(x,ebcm_m_delta,'b--',label='EBCMm') 146 | plt.plot(x,ebcm_delta,'r-.',label='EBCMi') 147 | plt.yscale('log') 148 | plt.xlabel('N') 149 | plt.ylabel('Error') 150 | plt.legend(loc=4) 151 | plt.savefig('comp_delta'+id+'.png') 152 | plt.clf() 153 | 154 | fig = plt.figure(figsize=(10,10)) 155 | plt.title(title) 156 | plt.grid(True) 157 | plt.plot(x,svm_time,'k-',label='SVM') 158 | plt.plot(x,ebcm_m_time,'b--',label='EBCMm') 159 | plt.plot(x,ebcm_time,'r-.',label='EBCMi') 160 | plt.yscale('log') 161 | plt.xlabel('N') 162 | plt.ylabel('Time') 163 | plt.legend(loc=4) 164 | plt.savefig('comp_time'+id+'.png') 165 | 166 | 167 | if __name__ == '__main__': 168 | a_b = float(sys.argv[1]) 169 | xl = float(sys.argv[2]) 170 | type = int(sys.argv[3]) 171 | generate_data(a_b,xl,type) 172 | plot_graphics(a_b,xl,type) 173 | 174 | 175 | -------------------------------------------------------------------------------- /src/radial.for: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | c**************************************************************************** 6 | c Radial spheroidal functions 7 | c 8 | c parameters: 9 | c kob - switch between prolate (0) and oblate (1) functions 10 | c m - index m 11 | c ne - maximum index n 12 | c c2 - argument c (complex*16) 13 | c ksi0 - argument xi (real*8) 14 | c eps - accuracy of getting eigenvalues 15 | c 16 | c results (all complex*16): 17 | c R1f(ne) - functions R^(1)_mn (c,xi), n = 1, ne 18 | c R1d(ne) - derivatives dR^(1)_mn (c,xi)/dxi, n = 1, ne 19 | c R2f(ne) - functions R^(2)_mn (c,xi), n = 1, ne 20 | c R2d(ne) - derivatives dR^(2)_mn (c,xi)/dxi, n = 1, ne 21 | c 22 | c 2005, Nov 23 | c**************************************************************************** 24 | 25 | SUBROUTINE rad_fun (kob, m, ne, C2, KSI0, EPS, R1f, R1d, R2f,R2d) 26 | parameter (nterms=330) 27 | IMPLICIT REAL*8 (A-H,O-Q,T-Z), COMPLEX*16 (R-S) 28 | REAL*8 C2, ksi0 29 | complex*16 R1f , R1d , R2f , R2d 30 | COMPLEX*16 bdc2 31 | DIMENSION RLC2(nterms), rDC2(4*nterms), bDC2(4*nterms) 32 | COMMON /K1/ S, S1, AKSI, AK, K, NK, nal 33 | COMMON /EPS1/ EPS1 34 | COMMON /EPS33/ EPS33 35 | COMMON /EPS3/ EPS3 36 | COMMON /FACT/ FACT(300) 37 | COMMON /PI/ PI 38 | cf2py intent(in) kob, m, ne, C2, KSI0, EPS 39 | cf2py intent(out) R1f, R1d, R2f, R2d 40 | c open(unit=07,file='sph_fun.out',status='unknown',access='append') 41 | 42 | NMAX = ne 43 | NMXE = nmax 44 | NK = NMAX+40 45 | IF (NK.LT.60) NK = 60 46 | IF (Ksi0.gt.1.5d0) NK = nk+40 47 | c NK=4*nterms 48 | IF (NK.GT.4*nterms) NK = 4*nterms 49 | 50 | k = kob 51 | IF(K) 5005,6,5005 52 | 5005 CONTINUE 53 | AK=-1D0 54 | GO TO 7 55 | 6 CONTINUE 56 | AK= 1D0 57 | 7 CONTINUE 58 | x = ksi0 59 | IF(K.eq.0) AKSI=X**2-1D0 60 | IF(K.eq.1) AKSI=X**2+1D0 61 | 62 | c if (k.eq.0 .and. x.lt.1.00001d0) then 63 | c write (*,2114) x 64 | c write (7,2114) x 65 | c end if 66 | 67 | c if (k.eq.1 .and. x.lt.0.00001d0) then 68 | c write (*,2115) x 69 | c write (7,2115) x 70 | c end if 71 | c 2114 FORMAT(1X,3('!'), ' Prolate x > 1 x = ',f5.3) 72 | c 2115 FORMAT(1X,3('!'), ' Oblate x > 0 x = ',f5.3) 73 | 74 | S=(0D0,0D0) 75 | S1=(0D0,1D0) 76 | nal = 1 77 | EPS=1D-15 78 | EPS1=1D-12 79 | * eps3 = 1d-80 80 | * eps3 = 1d-100 81 | eps3 = 1d-200 82 | eps33 = eps3 83 | pi = 4d0 * datan(1d0) 84 | 85 | c factorial 86 | FACT(1)=1D0 87 | FACT(2)=1D0 88 | DO 130 I=3,170 89 | 130 FACT(I)=FACT(I-1)*(I-1D0) 90 | FACT(170)=FACT(170)*(1.D-300) 91 | DO J = 170, 297 92 | FACT(J+1)=J*FACT(J) 93 | end do 94 | 95 | c----------------- 96 | 97 | c 112 FORMAT(1X,61('.')) 98 | c 202 FORMAT(1X,'homFUNq NN>nterms',5X,'NN=',I5) 99 | c 210 FORMAT(1X,'L=',I4,5X,'IER1,2,3,4,5=',5I5) 100 | c 212 FORMAT(1X,'I,L=',2I5,5X,'IER=',I5) 101 | 102 | W1=1D0/(C2*(ksi0**2-1D0+2*K)) 103 | ncc = real(c2) 104 | IF (NE-nterms) 40,40,41 105 | c 41 WRITE(7,202) NE 106 | c WRITE(*,202) NE 107 | 41 RETURN 108 | 40 CONTINUE 109 | RC1=c2 110 | 111 | c calc of lambda 112 | 113 | call lambda(K,M,ne,C2,EPS,rlc2,ie) 114 | if(ie.ne.0) return 115 | 116 | inum1 = nk 117 | if(nk.lt.inum1) inum1=nk+10 118 | 119 | if(k.eq.0) then 120 | ifun1 = 44 121 | IF(ksi0.GE.1.5D0) IFUN1 = 22 122 | end if 123 | 124 | if(k.eq.1) then 125 | ifun1 = 33 126 | IF(ksi0.GE.1.5D0) IFUN1 = 22 127 | end if 128 | 129 | c calc of Leg. functions 130 | 131 | CALL funlegnn (m, ksi0, inum1) 132 | 133 | c loop over l 134 | 135 | L = NE 136 | c DO 1 L=1,NE 137 | LM=L+M-1 138 | 139 | RL=RLC2(L) 140 | 141 | CALL cdcof4a(RL,RDC2,NK,BDC2,NK,2,rvn,1,M,LM,RC1,IER1) 142 | if(abs(bdc2(m+1)).le.eps33*1d20) eps33 = eps33 / 1d20 143 | 144 | if(k.eq.1.and.l.gt.ncc.and.ksi0.gt.0.25d0. 145 | * and.ksi0.lt.0.8d0) ifun1 = 11 146 | if(ifun1.eq.11) go to 11 147 | if(ifun1.eq.22) go to 22 148 | if(ifun1.eq.33) go to 33 149 | if(ifun1.eq.44) go to 44 150 | 151 | c LEG/LEG ifun1 = 11 152 | 11 CONTINUE 153 | CALL CDRF12cc(R1,R2,r3,r4,1,M,LM,RC1,RDC2,NK, 154 | * BDC2,NK,IER2) 155 | W = r1 * r4 - r2 * r3 156 | W2a = dabs(W / W1 - 1d0) 157 | c if(W2a.gt.eps1) write(*,99999) ifun1,l,W,W1,W2a 158 | if(W2a.gt.W0.and.k.eq.0) go to 13 159 | go to 5 160 | c99999 format(1x,'ifun=',i3,2x,'L=',i3,2x,'W=',1pd13.6,2x, 161 | c * 'W1=',d13.6,2x,'W2=',d13.6) 162 | 163 | c LEG/DIFF (JAF/DIFF) ifun1 = 13 164 | 13 CONTINUE 165 | IF(K.EQ.0) CALL cDRSF20(rr3,rr4,ksi0,R1,R2,m,rc1,rl,IER4) 166 | W = r1 * rr4 - r2 * rr3 167 | W2b = dabs(W / W1 - 1d0) 168 | ifu = 13 169 | if(ifun1.eq.22) ifu = 23 170 | if(ifun1.eq.44) ifu = 43 171 | c if(W2b.gt.eps1) write(*,99999) ifu,l,W,W1,W2b 172 | IF(W2b.lt.w0) then 173 | r3 = rr3 174 | r4 = rr4 175 | end if 176 | go to 5 177 | 178 | c BES/BES ifun1 = 22 179 | 22 CONTINUE 180 | CALL CDRB12cc (R1,R2,r3,r4,1,M,LM,RC1,ksi0,RDC2,NK,IER3) 181 | W = r1 * r4 - r2 * r3 182 | W2a = dabs(W / W1 - 1d0) 183 | if (W2a.le.eps1) go to 5 184 | if (k.eq.0) go to 13 185 | go to 5 186 | 187 | c DIFF/DIFF ifun1 = 33 188 | 33 CONTINUE 189 | CALL cDRSF212(R1,R2,r3,r4,2,m,LM,rc1,ksi0,rl, 190 | * RDC2,NK,BDC2,m+1,IER4) 191 | W = r1 * r4 - r2 * r3 192 | W2a = dabs(W / W1 - 1d0) 193 | if (W2a.gt.eps1) then 194 | c write(*,99999) ifun1,l,W,W1,W2a 195 | go to 11 196 | end if 197 | go to 5 198 | 199 | c JAF/JAF ifun1 = 44 200 | 44 CONTINUE 201 | CALL CDRG1cn(r1,r2,r3,r4,1,M,lm,rC1,ksi0, 202 | * RDC2,NK,bdc2,nk,rl,IER0) 203 | W = r1 * r4 - r2 * r3 204 | W0 = dabs(W / W1 - 1d0) 205 | ifun1 = 44 206 | c if (W0.gt.eps1) write(*,99999) ifun1,l,W,W1,W0 207 | if(W0.gt.eps1) go to 13 208 | 209 | c final results 210 | c 5 continue 211 | 5 R1f = r1 212 | R1d = r2 213 | R2f = r3 214 | R2d = r4 215 | 216 | c write(7,*) 'n ', l 217 | c write(7,*) 'R^(1) ',r1 218 | c write(7,*) 'R^(1)" ',r2 219 | c write(7,*) 'R^(2) ',r3 220 | c write(7,*) 'R^(2)" ', r4 221 | c W = r1 * r4 - r2 * r3 222 | c W2a = dabs(W / W1 - 1d0) 223 | c write(7,*) 'W, log W ',w2a, dlog10(W2a+1d-100) 224 | c write(*,*) 'W, log W ',w2a, dlog10(W2a+1d-100) 225 | c write(7,112) 226 | 227 | 1 CONTINUE 228 | RETURN 229 | END 230 | 231 | 232 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/static/doctools.js: -------------------------------------------------------------------------------- 1 | /// XXX: make it cross browser 2 | 3 | /** 4 | * make the code below compatible with browsers without 5 | * an installed firebug like debugger 6 | */ 7 | if (!window.console || !console.firebug) { 8 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", 9 | "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; 10 | window.console = {}; 11 | for (var i = 0; i < names.length; ++i) 12 | window.console[names[i]] = function() {} 13 | } 14 | 15 | /** 16 | * small helper function to urldecode strings 17 | */ 18 | jQuery.urldecode = function(x) { 19 | return decodeURIComponent(x).replace(/\+/g, ' '); 20 | } 21 | 22 | /** 23 | * small helper function to urlencode strings 24 | */ 25 | jQuery.urlencode = encodeURIComponent; 26 | 27 | /** 28 | * This function returns the parsed url parameters of the 29 | * current request. Multiple values per key are supported, 30 | * it will always return arrays of strings for the value parts. 31 | */ 32 | jQuery.getQueryParameters = function(s) { 33 | if (typeof s == 'undefined') 34 | s = document.location.search; 35 | var parts = s.substr(s.indexOf('?') + 1).split('&'); 36 | var result = {}; 37 | for (var i = 0; i < parts.length; i++) { 38 | var tmp = parts[i].split('=', 2); 39 | var key = jQuery.urldecode(tmp[0]); 40 | var value = jQuery.urldecode(tmp[1]); 41 | if (key in result) 42 | result[key].push(value); 43 | else 44 | result[key] = [value]; 45 | } 46 | return result; 47 | } 48 | 49 | /** 50 | * small function to check if an array contains 51 | * a given item. 52 | */ 53 | jQuery.contains = function(arr, item) { 54 | for (var i = 0; i < arr.length; i++) { 55 | if (arr[i] == item) 56 | return true; 57 | } 58 | return false; 59 | } 60 | 61 | /** 62 | * highlight a given string on a jquery object by wrapping it in 63 | * span elements with the given class name. 64 | */ 65 | jQuery.fn.highlightText = function(text, className) { 66 | function highlight(node) { 67 | if (node.nodeType == 3) { 68 | var val = node.nodeValue; 69 | var pos = val.toLowerCase().indexOf(text); 70 | if (pos >= 0 && !jQuery.className.has(node.parentNode, className)) { 71 | var span = document.createElement("span"); 72 | span.className = className; 73 | span.appendChild(document.createTextNode(val.substr(pos, text.length))); 74 | node.parentNode.insertBefore(span, node.parentNode.insertBefore( 75 | document.createTextNode(val.substr(pos + text.length)), 76 | node.nextSibling)); 77 | node.nodeValue = val.substr(0, pos); 78 | } 79 | } 80 | else if (!jQuery(node).is("button, select, textarea")) { 81 | jQuery.each(node.childNodes, function() { 82 | highlight(this) 83 | }); 84 | } 85 | } 86 | return this.each(function() { 87 | highlight(this); 88 | }); 89 | } 90 | 91 | /** 92 | * Small JavaScript module for the documentation. 93 | */ 94 | var Documentation = { 95 | 96 | init : function() { 97 | this.fixFirefoxAnchorBug(); 98 | this.highlightSearchWords(); 99 | this.initModIndex(); 100 | }, 101 | 102 | /** 103 | * i18n support 104 | */ 105 | TRANSLATIONS : {}, 106 | PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, 107 | LOCALE : 'unknown', 108 | 109 | // gettext and ngettext don't access this so that the functions 110 | // can savely bound to a different name (_ = Documentation.gettext) 111 | gettext : function(string) { 112 | var translated = Documentation.TRANSLATIONS[string]; 113 | if (typeof translated == 'undefined') 114 | return string; 115 | return (typeof translated == 'string') ? translated : translated[0]; 116 | }, 117 | 118 | ngettext : function(singular, plural, n) { 119 | var translated = Documentation.TRANSLATIONS[singular]; 120 | if (typeof translated == 'undefined') 121 | return (n == 1) ? singular : plural; 122 | return translated[Documentation.PLURALEXPR(n)]; 123 | }, 124 | 125 | addTranslations : function(catalog) { 126 | for (var key in catalog.messages) 127 | this.TRANSLATIONS[key] = catalog.messages[key]; 128 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); 129 | this.LOCALE = catalog.locale; 130 | }, 131 | 132 | /** 133 | * add context elements like header anchor links 134 | */ 135 | addContextElements : function() { 136 | $('div[id] > :header:first').each(function() { 137 | $('\u00B6'). 138 | attr('href', '#' + this.id). 139 | attr('title', _('Permalink to this headline')). 140 | appendTo(this); 141 | }); 142 | $('dt[id]').each(function() { 143 | $('\u00B6'). 144 | attr('href', '#' + this.id). 145 | attr('title', _('Permalink to this definition')). 146 | appendTo(this); 147 | }); 148 | }, 149 | 150 | /** 151 | * workaround a firefox stupidity 152 | */ 153 | fixFirefoxAnchorBug : function() { 154 | if (document.location.hash && $.browser.mozilla) 155 | window.setTimeout(function() { 156 | document.location.href += ''; 157 | }, 10); 158 | }, 159 | 160 | /** 161 | * highlight the search words provided in the url in the text 162 | */ 163 | highlightSearchWords : function() { 164 | var params = $.getQueryParameters(); 165 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; 166 | if (terms.length) { 167 | var body = $('div.body'); 168 | window.setTimeout(function() { 169 | $.each(terms, function() { 170 | body.highlightText(this.toLowerCase(), 'highlight'); 171 | }); 172 | }, 10); 173 | $('') 175 | .appendTo($('.sidebar .this-page-menu')); 176 | } 177 | }, 178 | 179 | /** 180 | * init the modindex toggle buttons 181 | */ 182 | initModIndex : function() { 183 | var togglers = $('img.toggler').click(function() { 184 | var src = $(this).attr('src'); 185 | var idnum = $(this).attr('id').substr(7); 186 | console.log($('tr.cg-' + idnum).toggle()); 187 | if (src.substr(-9) == 'minus.png') 188 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); 189 | else 190 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); 191 | }).css('display', ''); 192 | if (DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX) { 193 | togglers.click(); 194 | } 195 | }, 196 | 197 | /** 198 | * helper function to hide the search marks again 199 | */ 200 | hideSearchWords : function() { 201 | $('.sidebar .this-page-menu li.highlight-link').fadeOut(300); 202 | $('span.highlight').removeClass('highlight'); 203 | }, 204 | 205 | /** 206 | * make the url absolute 207 | */ 208 | makeURL : function(relativeURL) { 209 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; 210 | }, 211 | 212 | /** 213 | * get the current relative url 214 | */ 215 | getCurrentURL : function() { 216 | var path = document.location.pathname; 217 | var parts = path.split(/\//); 218 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { 219 | if (this == '..') 220 | parts.pop(); 221 | }); 222 | var url = parts.join('/'); 223 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); 224 | } 225 | }; 226 | 227 | // quick alias for translations 228 | _ = Documentation.gettext; 229 | 230 | $(document).ready(function() { 231 | Documentation.init(); 232 | }); 233 | -------------------------------------------------------------------------------- /doc/source/_themes/github/static/doctools.js: -------------------------------------------------------------------------------- 1 | /// XXX: make it cross browser 2 | 3 | /** 4 | * make the code below compatible with browsers without 5 | * an installed firebug like debugger 6 | */ 7 | if (!window.console || !console.firebug) { 8 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", 9 | "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; 10 | window.console = {}; 11 | for (var i = 0; i < names.length; ++i) 12 | window.console[names[i]] = function() {} 13 | } 14 | 15 | /** 16 | * small helper function to urldecode strings 17 | */ 18 | jQuery.urldecode = function(x) { 19 | return decodeURIComponent(x).replace(/\+/g, ' '); 20 | } 21 | 22 | /** 23 | * small helper function to urlencode strings 24 | */ 25 | jQuery.urlencode = encodeURIComponent; 26 | 27 | /** 28 | * This function returns the parsed url parameters of the 29 | * current request. Multiple values per key are supported, 30 | * it will always return arrays of strings for the value parts. 31 | */ 32 | jQuery.getQueryParameters = function(s) { 33 | if (typeof s == 'undefined') 34 | s = document.location.search; 35 | var parts = s.substr(s.indexOf('?') + 1).split('&'); 36 | var result = {}; 37 | for (var i = 0; i < parts.length; i++) { 38 | var tmp = parts[i].split('=', 2); 39 | var key = jQuery.urldecode(tmp[0]); 40 | var value = jQuery.urldecode(tmp[1]); 41 | if (key in result) 42 | result[key].push(value); 43 | else 44 | result[key] = [value]; 45 | } 46 | return result; 47 | } 48 | 49 | /** 50 | * small function to check if an array contains 51 | * a given item. 52 | */ 53 | jQuery.contains = function(arr, item) { 54 | for (var i = 0; i < arr.length; i++) { 55 | if (arr[i] == item) 56 | return true; 57 | } 58 | return false; 59 | } 60 | 61 | /** 62 | * highlight a given string on a jquery object by wrapping it in 63 | * span elements with the given class name. 64 | */ 65 | jQuery.fn.highlightText = function(text, className) { 66 | function highlight(node) { 67 | if (node.nodeType == 3) { 68 | var val = node.nodeValue; 69 | var pos = val.toLowerCase().indexOf(text); 70 | if (pos >= 0 && !jQuery.className.has(node.parentNode, className)) { 71 | var span = document.createElement("span"); 72 | span.className = className; 73 | span.appendChild(document.createTextNode(val.substr(pos, text.length))); 74 | node.parentNode.insertBefore(span, node.parentNode.insertBefore( 75 | document.createTextNode(val.substr(pos + text.length)), 76 | node.nextSibling)); 77 | node.nodeValue = val.substr(0, pos); 78 | } 79 | } 80 | else if (!jQuery(node).is("button, select, textarea")) { 81 | jQuery.each(node.childNodes, function() { 82 | highlight(this) 83 | }); 84 | } 85 | } 86 | return this.each(function() { 87 | highlight(this); 88 | }); 89 | } 90 | 91 | /** 92 | * Small JavaScript module for the documentation. 93 | */ 94 | var Documentation = { 95 | 96 | init : function() { 97 | this.fixFirefoxAnchorBug(); 98 | this.highlightSearchWords(); 99 | this.initModIndex(); 100 | }, 101 | 102 | /** 103 | * i18n support 104 | */ 105 | TRANSLATIONS : {}, 106 | PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, 107 | LOCALE : 'unknown', 108 | 109 | // gettext and ngettext don't access this so that the functions 110 | // can savely bound to a different name (_ = Documentation.gettext) 111 | gettext : function(string) { 112 | var translated = Documentation.TRANSLATIONS[string]; 113 | if (typeof translated == 'undefined') 114 | return string; 115 | return (typeof translated == 'string') ? translated : translated[0]; 116 | }, 117 | 118 | ngettext : function(singular, plural, n) { 119 | var translated = Documentation.TRANSLATIONS[singular]; 120 | if (typeof translated == 'undefined') 121 | return (n == 1) ? singular : plural; 122 | return translated[Documentation.PLURALEXPR(n)]; 123 | }, 124 | 125 | addTranslations : function(catalog) { 126 | for (var key in catalog.messages) 127 | this.TRANSLATIONS[key] = catalog.messages[key]; 128 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); 129 | this.LOCALE = catalog.locale; 130 | }, 131 | 132 | /** 133 | * add context elements like header anchor links 134 | */ 135 | addContextElements : function() { 136 | $('div[id] > :header:first').each(function() { 137 | $('\u00B6'). 138 | attr('href', '#' + this.id). 139 | attr('title', _('Permalink to this headline')). 140 | appendTo(this); 141 | }); 142 | $('dt[id]').each(function() { 143 | $('\u00B6'). 144 | attr('href', '#' + this.id). 145 | attr('title', _('Permalink to this definition')). 146 | appendTo(this); 147 | }); 148 | }, 149 | 150 | /** 151 | * workaround a firefox stupidity 152 | */ 153 | fixFirefoxAnchorBug : function() { 154 | if (document.location.hash && $.browser.mozilla) 155 | window.setTimeout(function() { 156 | document.location.href += ''; 157 | }, 10); 158 | }, 159 | 160 | /** 161 | * highlight the search words provided in the url in the text 162 | */ 163 | highlightSearchWords : function() { 164 | var params = $.getQueryParameters(); 165 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; 166 | if (terms.length) { 167 | var body = $('div.body'); 168 | window.setTimeout(function() { 169 | $.each(terms, function() { 170 | body.highlightText(this.toLowerCase(), 'highlight'); 171 | }); 172 | }, 10); 173 | $('') 175 | .appendTo($('.sidebar .this-page-menu')); 176 | } 177 | }, 178 | 179 | /** 180 | * init the modindex toggle buttons 181 | */ 182 | initModIndex : function() { 183 | var togglers = $('img.toggler').click(function() { 184 | var src = $(this).attr('src'); 185 | var idnum = $(this).attr('id').substr(7); 186 | console.log($('tr.cg-' + idnum).toggle()); 187 | if (src.substr(-9) == 'minus.png') 188 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); 189 | else 190 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); 191 | }).css('display', ''); 192 | if (DOCUMENTATION_OPTIONS.COLLAPSE_MODINDEX) { 193 | togglers.click(); 194 | } 195 | }, 196 | 197 | /** 198 | * helper function to hide the search marks again 199 | */ 200 | hideSearchWords : function() { 201 | $('.sidebar .this-page-menu li.highlight-link').fadeOut(300); 202 | $('span.highlight').removeClass('highlight'); 203 | }, 204 | 205 | /** 206 | * make the url absolute 207 | */ 208 | makeURL : function(relativeURL) { 209 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; 210 | }, 211 | 212 | /** 213 | * get the current relative url 214 | */ 215 | getCurrentURL : function() { 216 | var path = document.location.pathname; 217 | var parts = path.split(/\//); 218 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { 219 | if (this == '..') 220 | parts.pop(); 221 | }); 222 | var url = parts.join('/'); 223 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1); 224 | } 225 | }; 226 | 227 | // quick alias for translations 228 | _ = Documentation.gettext; 229 | 230 | $(document).ready(function() { 231 | Documentation.init(); 232 | }); 233 | -------------------------------------------------------------------------------- /scikits/scattpy/spheroidal_pmm.py: -------------------------------------------------------------------------------- 1 | from numpy import zeros, bmat, mat, conjugate 2 | import scipy 3 | import scipy.linalg 4 | 5 | from spheroidal_functions import * 6 | 7 | import spheroidal 8 | from spheroidal_svm import SpheroidalSVM 9 | 10 | 11 | class SpheroidalPMM: 12 | 13 | def __init__(self,particle,nmax): 14 | self.particle=particle 15 | self.c2 = particle.c2 16 | self.c1 = particle.c1 17 | self.nmax = nmax 18 | 19 | def get_A(self,function): 20 | A = zeros((self.nmax, self.nmax), dtype=complex) 21 | m = 1 22 | for i in range(self.nmax): 23 | for k in range(self.nmax): 24 | n = i + m 25 | l = k + m 26 | func = lambda nu: function(m, n,l)(nu) * \ 27 | spheroidal.metric_phi(nu, self.particle) *\ 28 | spheroidal.get_integral_metric(self.particle)(nu) 29 | 30 | A[i][k] = spheroidal.quad(func, -1, 1) 31 | return mat(A) 32 | 33 | # ---- Generation of A matrices 34 | 35 | def function_a11(self,m, n, l): 36 | cv_l = get_cv(m, l, self.c1, self.particle.type) 37 | cv_n = get_cv(m, n, self.c1, self.particle.type) 38 | return lambda nu: conjugate(spheroidal.get_a_function(m,n,self.c1,cv_n,3,self.particle)(nu)) *\ 39 | spheroidal.get_a_function(m,l,self.c1,cv_l,3,self.particle)(nu) +\ 40 | conjugate(spheroidal.get_b_function(m,n,self.c1,cv_n,3,self.particle)(nu)) *\ 41 | spheroidal.get_b_function(m,l,self.c1,cv_l,3,self.particle)(nu) 42 | 43 | def function_a12(self,m, n, l): 44 | cv_l = get_cv(m, l, self.c2, self.particle.type) 45 | cv_n = get_cv(m, n, self.c1, self.particle.type) 46 | return lambda nu: -(conjugate(spheroidal.get_a_function(m,n,self.c1,cv_n,3,self.particle)(nu)) *\ 47 | spheroidal.get_a_function(m,l,self.c2,cv_l,1,self.particle)(nu) +\ 48 | conjugate(spheroidal.get_b_function(m,n,self.c1,cv_n,3,self.particle)(nu)) *\ 49 | spheroidal.get_c_function(m,l,self.c2,cv_l,1,self.particle)(nu)) 50 | 51 | def function_a21(self,m, n, l): 52 | cv_l = get_cv(m, l, self.c1, self.particle.type) 53 | cv_n = get_cv(m, n, self.c2, self.particle.type) 54 | return lambda nu: -(conjugate(spheroidal.get_a_function(m,n,self.c2,cv_n,1,self.particle)(nu)) *\ 55 | spheroidal.get_a_function(m,l,self.c1,cv_l,3,self.particle)(nu) +\ 56 | conjugate(spheroidal.get_c_function(m,n,self.c2,cv_n,1,self.particle)(nu)) *\ 57 | spheroidal.get_b_function(m,l,self.c1,cv_l,3,self.particle)(nu)) 58 | 59 | def function_a22(self,m, n, l): 60 | cv_l = get_cv(m, l, self.c2, self.particle.type) 61 | cv_n = get_cv(m, n, self.c2, self.particle.type) 62 | return lambda nu: conjugate(spheroidal.get_a_function(m,n,self.c2,cv_n,1,self.particle)(nu)) *\ 63 | spheroidal.get_a_function(m,l,self.c2,cv_l,1,self.particle)(nu) +\ 64 | conjugate(spheroidal.get_c_function(m,n,self.c2,cv_n,1,self.particle)(nu)) *\ 65 | spheroidal.get_c_function(m,l,self.c2,cv_l,1,self.particle)(nu) 66 | 67 | def function_a10(self,m, n, l): 68 | cv_l = get_cv(m, l, self.c1, self.particle.type) 69 | cv_n = get_cv(m, n, self.c1, self.particle.type) 70 | return lambda nu: -(conjugate(spheroidal.get_a_function(m,n,self.c1,cv_n,3,self.particle)(nu)) *\ 71 | spheroidal.get_a_function(m,l,self.c1,cv_l,1,self.particle)(nu) +\ 72 | conjugate(spheroidal.get_b_function(m,n,self.c1,cv_n,3,self.particle)(nu)) *\ 73 | spheroidal.get_b_function(m,l,self.c1,cv_l,1,self.particle)(nu)) 74 | 75 | def function_a20(self,m, n, l): 76 | cv_l = get_cv(m, l, self.c1, self.particle.type) 77 | cv_n = get_cv(m, n, self.c2, self.particle.type) 78 | return lambda nu: conjugate(spheroidal.get_a_function(m,n,self.c2,cv_n,1,self.particle)(nu)) *\ 79 | spheroidal.get_a_function(m,l,self.c1,cv_l,1,self.particle)(nu) +\ 80 | conjugate(spheroidal.get_c_function(m,n,self.c2,cv_n,1,self.particle)(nu)) *\ 81 | spheroidal.get_b_function(m,l,self.c1,cv_l,1,self.particle)(nu) 82 | 83 | def get_A11i(self): 84 | return self.get_A(lambda m,n,l: self.function_a11(m,n,l)) 85 | 86 | def get_A12i(self): 87 | return self.get_A(lambda m,n,l: self.function_a12(m,n,l)) 88 | 89 | def get_A21i(self): 90 | return self.get_A(lambda m,n,l: self.function_a21(m,n,l)) 91 | 92 | def get_A22i(self): 93 | return self.get_A(lambda m,n,l: self.function_a22(m,n,l)) 94 | 95 | def get_A10i(self): 96 | return self.get_A(lambda m,n,l: self.function_a10(m,n,l)) 97 | 98 | def get_A20i(self): 99 | return self.get_A(lambda m,n,l: self.function_a20(m,n,l)) 100 | 101 | #according to (101) 102 | def get_A11m(self): 103 | svm = SpheroidalSVM(self.particle, self.nmax) 104 | return conjugate(svm.get_A(self.c1,self.c1,3)) * svm.get_A(self.c1,self.c1,3).T + \ 105 | conjugate(svm.get_B(3)) * svm.get_B(3).T 106 | 107 | 108 | def get_A12m(self): 109 | svm = SpheroidalSVM(self.particle, self.nmax) 110 | return -(conjugate(svm.get_A(self.c1,self.c1,3)) * svm.get_A(self.c2,self.c1,1).T +\ 111 | conjugate(svm.get_B(3)) * svm.get_C().T) 112 | 113 | 114 | def get_A21m(self): 115 | svm = SpheroidalSVM(self.particle, self.nmax) 116 | return -(conjugate(svm.get_A(self.c2,self.c1,1)) * svm.get_A(self.c1,self.c1,3).T +\ 117 | conjugate(svm.get_C()) * svm.get_B(3).T) 118 | 119 | def get_A22m(self): 120 | svm = SpheroidalSVM(self.particle, self.nmax) 121 | return conjugate(svm.get_A(self.c2,self.c1,1)) * svm.get_A(self.c2,self.c1,1).T +\ 122 | conjugate(svm.get_C()) * svm.get_C().T 123 | 124 | def get_A10m(self): 125 | svm = SpheroidalSVM(self.particle, self.nmax) 126 | return -(conjugate(svm.get_A(self.c1,self.c1,3)) * svm.get_A(self.c1,self.c1,1).T +\ 127 | conjugate(svm.get_B(3)) * svm.get_B(1).T) 128 | 129 | def get_A20m(self): 130 | svm = SpheroidalSVM(self.particle, self.nmax) 131 | return conjugate(svm.get_A(self.c2,self.c1,1)) * svm.get_A(self.c1,self.c1,1).T +\ 132 | conjugate(svm.get_C()) * svm.get_B(1).T 133 | 134 | def get_fullBm(self): 135 | return bmat([[self.get_A10m()], [self.get_A20m()]]) 136 | 137 | def get_fullAm(self): 138 | A11 = self.get_A11m() 139 | A12 = self.get_A12m() 140 | A21 = self.get_A21m() 141 | A22 = self.get_A22m() 142 | return bmat([[A11, A12], [A21, A22]]) 143 | 144 | def getMatrixSolution(self,inputWave): 145 | A = self.get_fullAm() 146 | B = self.get_fullBm() * spheroidal.get_Bin(inputWave, self.particle, self.nmax) 147 | x = -scipy.linalg.solve(A, B) 148 | return (x[0:self.nmax + 1], x[self.nmax + 1:]) 149 | 150 | def get_fullBi(self): 151 | return bmat([[self.get_A10i()], [self.get_A20i()]]) 152 | 153 | def get_fullAi(self): 154 | A11 = self.get_A11i() 155 | A12 = self.get_A12i() 156 | A21 = self.get_A21i() 157 | A22 = self.get_A22i() 158 | return bmat([[A11, A12], [A21, A22]]) 159 | 160 | def getSolution(self,inputWave): 161 | A = self.get_fullAi() 162 | B = self.get_fullBi() * spheroidal.get_Bin(inputWave, self.particle, self.nmax) 163 | x = -scipy.linalg.solve(A, B) 164 | return (x[0:self.nmax + 1], x[self.nmax + 1:]) -------------------------------------------------------------------------------- /doc/source/_themes/basic/static/basic.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Sphinx stylesheet -- basic theme 3 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 | */ 5 | 6 | /* -- main layout ----------------------------------------------------------- */ 7 | 8 | div.clearer { 9 | clear: both; 10 | } 11 | 12 | /* -- relbar ---------------------------------------------------------------- */ 13 | 14 | div.related { 15 | width: 100%; 16 | font-size: 90%; 17 | } 18 | 19 | div.related h3 { 20 | display: none; 21 | } 22 | 23 | div.related ul { 24 | margin: 0; 25 | padding: 0 0 0 10px; 26 | list-style: none; 27 | } 28 | 29 | div.related li { 30 | display: inline; 31 | } 32 | 33 | div.related li.right { 34 | float: right; 35 | margin-right: 5px; 36 | } 37 | 38 | /* -- sidebar --------------------------------------------------------------- */ 39 | 40 | div.sphinxsidebarwrapper { 41 | padding: 10px 5px 0 10px; 42 | } 43 | 44 | div.sphinxsidebar { 45 | float: left; 46 | width: 230px; 47 | margin-left: -100%; 48 | font-size: 90%; 49 | } 50 | 51 | div.sphinxsidebar ul { 52 | list-style: none; 53 | } 54 | 55 | div.sphinxsidebar ul ul, 56 | div.sphinxsidebar ul.want-points { 57 | margin-left: 20px; 58 | list-style: square; 59 | } 60 | 61 | div.sphinxsidebar ul ul { 62 | margin-top: 0; 63 | margin-bottom: 0; 64 | } 65 | 66 | div.sphinxsidebar form { 67 | margin-top: 10px; 68 | } 69 | 70 | div.sphinxsidebar input { 71 | border: 1px solid #98dbcc; 72 | font-family: sans-serif; 73 | font-size: 1em; 74 | } 75 | 76 | img { 77 | border: 0; 78 | } 79 | 80 | /* -- search page ----------------------------------------------------------- */ 81 | 82 | ul.search { 83 | margin: 10px 0 0 20px; 84 | padding: 0; 85 | } 86 | 87 | ul.search li { 88 | padding: 5px 0 5px 20px; 89 | background-image: url(file.png); 90 | background-repeat: no-repeat; 91 | background-position: 0 7px; 92 | } 93 | 94 | ul.search li a { 95 | font-weight: bold; 96 | } 97 | 98 | ul.search li div.context { 99 | color: #888; 100 | margin: 2px 0 0 30px; 101 | text-align: left; 102 | } 103 | 104 | ul.keywordmatches li.goodmatch a { 105 | font-weight: bold; 106 | } 107 | 108 | /* -- index page ------------------------------------------------------------ */ 109 | 110 | table.contentstable { 111 | width: 90%; 112 | } 113 | 114 | table.contentstable p.biglink { 115 | line-height: 150%; 116 | } 117 | 118 | a.biglink { 119 | font-size: 1.3em; 120 | } 121 | 122 | span.linkdescr { 123 | font-style: italic; 124 | padding-top: 5px; 125 | font-size: 90%; 126 | } 127 | 128 | /* -- general index --------------------------------------------------------- */ 129 | 130 | table.indextable td { 131 | text-align: left; 132 | vertical-align: top; 133 | } 134 | 135 | table.indextable dl, table.indextable dd { 136 | margin-top: 0; 137 | margin-bottom: 0; 138 | } 139 | 140 | table.indextable tr.pcap { 141 | height: 10px; 142 | } 143 | 144 | table.indextable tr.cap { 145 | margin-top: 10px; 146 | background-color: #f2f2f2; 147 | } 148 | 149 | img.toggler { 150 | margin-right: 3px; 151 | margin-top: 3px; 152 | cursor: pointer; 153 | } 154 | 155 | /* -- general body styles --------------------------------------------------- */ 156 | 157 | a.headerlink { 158 | visibility: hidden; 159 | } 160 | 161 | h1:hover > a.headerlink, 162 | h2:hover > a.headerlink, 163 | h3:hover > a.headerlink, 164 | h4:hover > a.headerlink, 165 | h5:hover > a.headerlink, 166 | h6:hover > a.headerlink, 167 | dt:hover > a.headerlink { 168 | visibility: visible; 169 | } 170 | 171 | div.body p.caption { 172 | text-align: inherit; 173 | } 174 | 175 | div.body td { 176 | text-align: left; 177 | } 178 | 179 | .field-list ul { 180 | padding-left: 1em; 181 | } 182 | 183 | .first { 184 | margin-top: 0 !important; 185 | } 186 | 187 | p.rubric { 188 | margin-top: 30px; 189 | font-weight: bold; 190 | } 191 | 192 | /* -- sidebars -------------------------------------------------------------- */ 193 | 194 | div.sidebar { 195 | margin: 0 0 0.5em 1em; 196 | border: 1px solid #ddb; 197 | padding: 7px 7px 0 7px; 198 | background-color: #ffe; 199 | width: 40%; 200 | float: right; 201 | } 202 | 203 | p.sidebar-title { 204 | font-weight: bold; 205 | } 206 | 207 | /* -- topics ---------------------------------------------------------------- */ 208 | 209 | div.topic { 210 | border: 1px solid #ccc; 211 | padding: 7px 7px 0 7px; 212 | margin: 10px 0 10px 0; 213 | } 214 | 215 | p.topic-title { 216 | font-size: 1.1em; 217 | font-weight: bold; 218 | margin-top: 10px; 219 | } 220 | 221 | /* -- admonitions ----------------------------------------------------------- */ 222 | 223 | div.admonition { 224 | margin-top: 10px; 225 | margin-bottom: 10px; 226 | padding: 7px; 227 | } 228 | 229 | div.admonition dt { 230 | font-weight: bold; 231 | } 232 | 233 | div.admonition dl { 234 | margin-bottom: 0; 235 | } 236 | 237 | p.admonition-title { 238 | margin: 0px 10px 5px 0px; 239 | font-weight: bold; 240 | } 241 | 242 | div.body p.centered { 243 | text-align: center; 244 | margin-top: 25px; 245 | } 246 | 247 | /* -- tables ---------------------------------------------------------------- */ 248 | 249 | table.docutils { 250 | border: 0; 251 | border-collapse: collapse; 252 | } 253 | 254 | table.docutils td, table.docutils th { 255 | padding: 1px 8px 1px 0; 256 | border-top: 0; 257 | border-left: 0; 258 | border-right: 0; 259 | border-bottom: 1px solid #aaa; 260 | } 261 | 262 | table.field-list td, table.field-list th { 263 | border: 0 !important; 264 | } 265 | 266 | table.footnote td, table.footnote th { 267 | border: 0 !important; 268 | } 269 | 270 | th { 271 | text-align: left; 272 | padding-right: 5px; 273 | } 274 | 275 | /* -- other body styles ----------------------------------------------------- */ 276 | 277 | dl { 278 | margin-bottom: 15px; 279 | } 280 | 281 | dd p { 282 | margin-top: 0px; 283 | } 284 | 285 | dd ul, dd table { 286 | margin-bottom: 10px; 287 | } 288 | 289 | dd { 290 | margin-top: 3px; 291 | margin-bottom: 10px; 292 | margin-left: 30px; 293 | } 294 | 295 | dt:target, .highlight { 296 | background-color: #fbe54e; 297 | } 298 | 299 | dl.glossary dt { 300 | font-weight: bold; 301 | font-size: 1.1em; 302 | } 303 | 304 | .field-list ul { 305 | margin: 0; 306 | padding-left: 1em; 307 | } 308 | 309 | .field-list p { 310 | margin: 0; 311 | } 312 | 313 | .refcount { 314 | color: #060; 315 | } 316 | 317 | .optional { 318 | font-size: 1.3em; 319 | } 320 | 321 | .versionmodified { 322 | font-style: italic; 323 | } 324 | 325 | .system-message { 326 | background-color: #fda; 327 | padding: 5px; 328 | border: 3px solid red; 329 | } 330 | 331 | .footnote:target { 332 | background-color: #ffa 333 | } 334 | 335 | .line-block { 336 | display: block; 337 | margin-top: 1em; 338 | margin-bottom: 1em; 339 | } 340 | 341 | .line-block .line-block { 342 | margin-top: 0; 343 | margin-bottom: 0; 344 | margin-left: 1.5em; 345 | } 346 | 347 | /* -- code displays --------------------------------------------------------- */ 348 | 349 | pre { 350 | overflow: auto; 351 | } 352 | 353 | td.linenos pre { 354 | padding: 5px 0px; 355 | border: 0; 356 | background-color: transparent; 357 | color: #aaa; 358 | } 359 | 360 | table.highlighttable { 361 | margin-left: 0.5em; 362 | } 363 | 364 | table.highlighttable td { 365 | padding: 0 0.5em 0 0.5em; 366 | } 367 | 368 | tt.descname { 369 | background-color: transparent; 370 | font-weight: bold; 371 | font-size: 1.2em; 372 | } 373 | 374 | tt.descclassname { 375 | background-color: transparent; 376 | } 377 | 378 | tt.xref, a tt { 379 | background-color: transparent; 380 | font-weight: bold; 381 | } 382 | 383 | h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { 384 | background-color: transparent; 385 | } 386 | 387 | /* -- math display ---------------------------------------------------------- */ 388 | 389 | img.math { 390 | vertical-align: middle; 391 | } 392 | 393 | div.body div.math p { 394 | text-align: center; 395 | } 396 | 397 | span.eqno { 398 | float: right; 399 | } 400 | 401 | /* -- printout stylesheet --------------------------------------------------- */ 402 | 403 | @media print { 404 | div.document, 405 | div.documentwrapper, 406 | div.bodywrapper { 407 | margin: 0 !important; 408 | width: 100%; 409 | } 410 | 411 | div.sphinxsidebar, 412 | div.related, 413 | div.footer, 414 | #top-link { 415 | display: none; 416 | } 417 | } 418 | -------------------------------------------------------------------------------- /doc/source/_themes/github/static/basic.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Sphinx stylesheet -- basic theme 3 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 | */ 5 | 6 | /* -- main layout ----------------------------------------------------------- */ 7 | 8 | div.clearer { 9 | clear: both; 10 | } 11 | 12 | /* -- relbar ---------------------------------------------------------------- */ 13 | 14 | div.related { 15 | width: 100%; 16 | font-size: 90%; 17 | } 18 | 19 | div.related h3 { 20 | display: none; 21 | } 22 | 23 | div.related ul { 24 | margin: 0; 25 | padding: 0 0 0 10px; 26 | list-style: none; 27 | } 28 | 29 | div.related li { 30 | display: inline; 31 | } 32 | 33 | div.related li.right { 34 | float: right; 35 | margin-right: 5px; 36 | } 37 | 38 | /* -- sidebar --------------------------------------------------------------- */ 39 | 40 | div.sphinxsidebarwrapper { 41 | padding: 10px 5px 0 10px; 42 | } 43 | 44 | div.sphinxsidebar { 45 | float: left; 46 | width: 230px; 47 | margin-left: -100%; 48 | font-size: 90%; 49 | } 50 | 51 | div.sphinxsidebar ul { 52 | list-style: none; 53 | } 54 | 55 | div.sphinxsidebar ul ul, 56 | div.sphinxsidebar ul.want-points { 57 | margin-left: 20px; 58 | list-style: square; 59 | } 60 | 61 | div.sphinxsidebar ul ul { 62 | margin-top: 0; 63 | margin-bottom: 0; 64 | } 65 | 66 | div.sphinxsidebar form { 67 | margin-top: 10px; 68 | } 69 | 70 | div.sphinxsidebar input { 71 | border: 1px solid #98dbcc; 72 | font-family: sans-serif; 73 | font-size: 1em; 74 | } 75 | 76 | img { 77 | border: 0; 78 | } 79 | 80 | /* -- search page ----------------------------------------------------------- */ 81 | 82 | ul.search { 83 | margin: 10px 0 0 20px; 84 | padding: 0; 85 | } 86 | 87 | ul.search li { 88 | padding: 5px 0 5px 20px; 89 | background-image: url(file.png); 90 | background-repeat: no-repeat; 91 | background-position: 0 7px; 92 | } 93 | 94 | ul.search li a { 95 | font-weight: bold; 96 | } 97 | 98 | ul.search li div.context { 99 | color: #888; 100 | margin: 2px 0 0 30px; 101 | text-align: left; 102 | } 103 | 104 | ul.keywordmatches li.goodmatch a { 105 | font-weight: bold; 106 | } 107 | 108 | /* -- index page ------------------------------------------------------------ */ 109 | 110 | table.contentstable { 111 | width: 90%; 112 | } 113 | 114 | table.contentstable p.biglink { 115 | line-height: 150%; 116 | } 117 | 118 | a.biglink { 119 | font-size: 1.3em; 120 | } 121 | 122 | span.linkdescr { 123 | font-style: italic; 124 | padding-top: 5px; 125 | font-size: 90%; 126 | } 127 | 128 | /* -- general index --------------------------------------------------------- */ 129 | 130 | table.indextable td { 131 | text-align: left; 132 | vertical-align: top; 133 | } 134 | 135 | table.indextable dl, table.indextable dd { 136 | margin-top: 0; 137 | margin-bottom: 0; 138 | } 139 | 140 | table.indextable tr.pcap { 141 | height: 10px; 142 | } 143 | 144 | table.indextable tr.cap { 145 | margin-top: 10px; 146 | background-color: #f2f2f2; 147 | } 148 | 149 | img.toggler { 150 | margin-right: 3px; 151 | margin-top: 3px; 152 | cursor: pointer; 153 | } 154 | 155 | /* -- general body styles --------------------------------------------------- */ 156 | 157 | a.headerlink { 158 | visibility: hidden; 159 | } 160 | 161 | h1:hover > a.headerlink, 162 | h2:hover > a.headerlink, 163 | h3:hover > a.headerlink, 164 | h4:hover > a.headerlink, 165 | h5:hover > a.headerlink, 166 | h6:hover > a.headerlink, 167 | dt:hover > a.headerlink { 168 | visibility: visible; 169 | } 170 | 171 | div.body p.caption { 172 | text-align: inherit; 173 | } 174 | 175 | div.body td { 176 | text-align: left; 177 | } 178 | 179 | .field-list ul { 180 | padding-left: 1em; 181 | } 182 | 183 | .first { 184 | margin-top: 0 !important; 185 | } 186 | 187 | p.rubric { 188 | margin-top: 30px; 189 | font-weight: bold; 190 | } 191 | 192 | /* -- sidebars -------------------------------------------------------------- */ 193 | 194 | div.sidebar { 195 | margin: 0 0 0.5em 1em; 196 | border: 1px solid #ddb; 197 | padding: 7px 7px 0 7px; 198 | background-color: #ffe; 199 | width: 40%; 200 | float: right; 201 | } 202 | 203 | p.sidebar-title { 204 | font-weight: bold; 205 | } 206 | 207 | /* -- topics ---------------------------------------------------------------- */ 208 | 209 | div.topic { 210 | border: 1px solid #ccc; 211 | padding: 7px 7px 0 7px; 212 | margin: 10px 0 10px 0; 213 | } 214 | 215 | p.topic-title { 216 | font-size: 1.1em; 217 | font-weight: bold; 218 | margin-top: 10px; 219 | } 220 | 221 | /* -- admonitions ----------------------------------------------------------- */ 222 | 223 | div.admonition { 224 | margin-top: 10px; 225 | margin-bottom: 10px; 226 | padding: 7px; 227 | } 228 | 229 | div.admonition dt { 230 | font-weight: bold; 231 | } 232 | 233 | div.admonition dl { 234 | margin-bottom: 0; 235 | } 236 | 237 | p.admonition-title { 238 | margin: 0px 10px 5px 0px; 239 | font-weight: bold; 240 | } 241 | 242 | div.body p.centered { 243 | text-align: center; 244 | margin-top: 25px; 245 | } 246 | 247 | /* -- tables ---------------------------------------------------------------- */ 248 | 249 | table.docutils { 250 | border: 0; 251 | border-collapse: collapse; 252 | } 253 | 254 | table.docutils td, table.docutils th { 255 | padding: 1px 8px 1px 0; 256 | border-top: 0; 257 | border-left: 0; 258 | border-right: 0; 259 | border-bottom: 1px solid #aaa; 260 | } 261 | 262 | table.field-list td, table.field-list th { 263 | border: 0 !important; 264 | } 265 | 266 | table.footnote td, table.footnote th { 267 | border: 0 !important; 268 | } 269 | 270 | th { 271 | text-align: left; 272 | padding-right: 5px; 273 | } 274 | 275 | /* -- other body styles ----------------------------------------------------- */ 276 | 277 | dl { 278 | margin-bottom: 15px; 279 | } 280 | 281 | dd p { 282 | margin-top: 0px; 283 | } 284 | 285 | dd ul, dd table { 286 | margin-bottom: 10px; 287 | } 288 | 289 | dd { 290 | margin-top: 3px; 291 | margin-bottom: 10px; 292 | margin-left: 30px; 293 | } 294 | 295 | dt:target, .highlight { 296 | background-color: #fbe54e; 297 | } 298 | 299 | dl.glossary dt { 300 | font-weight: bold; 301 | font-size: 1.1em; 302 | } 303 | 304 | .field-list ul { 305 | margin: 0; 306 | padding-left: 1em; 307 | } 308 | 309 | .field-list p { 310 | margin: 0; 311 | } 312 | 313 | .refcount { 314 | color: #060; 315 | } 316 | 317 | .optional { 318 | font-size: 1.3em; 319 | } 320 | 321 | .versionmodified { 322 | font-style: italic; 323 | } 324 | 325 | .system-message { 326 | background-color: #fda; 327 | padding: 5px; 328 | border: 3px solid red; 329 | } 330 | 331 | .footnote:target { 332 | background-color: #ffa 333 | } 334 | 335 | .line-block { 336 | display: block; 337 | margin-top: 1em; 338 | margin-bottom: 1em; 339 | } 340 | 341 | .line-block .line-block { 342 | margin-top: 0; 343 | margin-bottom: 0; 344 | margin-left: 1.5em; 345 | } 346 | 347 | /* -- code displays --------------------------------------------------------- */ 348 | 349 | pre { 350 | overflow: auto; 351 | } 352 | 353 | td.linenos pre { 354 | padding: 5px 0px; 355 | border: 0; 356 | background-color: transparent; 357 | color: #aaa; 358 | } 359 | 360 | table.highlighttable { 361 | margin-left: 0.5em; 362 | } 363 | 364 | table.highlighttable td { 365 | padding: 0 0.5em 0 0.5em; 366 | } 367 | 368 | tt.descname { 369 | background-color: transparent; 370 | font-weight: bold; 371 | font-size: 1.2em; 372 | } 373 | 374 | tt.descclassname { 375 | background-color: transparent; 376 | } 377 | 378 | tt.xref, a tt { 379 | background-color: transparent; 380 | font-weight: bold; 381 | } 382 | 383 | h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { 384 | background-color: transparent; 385 | } 386 | 387 | /* -- math display ---------------------------------------------------------- */ 388 | 389 | img.math { 390 | vertical-align: middle; 391 | } 392 | 393 | div.body div.math p { 394 | text-align: center; 395 | } 396 | 397 | span.eqno { 398 | float: right; 399 | } 400 | 401 | /* -- printout stylesheet --------------------------------------------------- */ 402 | 403 | @media print { 404 | div.document, 405 | div.documentwrapper, 406 | div.bodywrapper { 407 | margin: 0 !important; 408 | width: 100%; 409 | } 410 | 411 | div.sphinxsidebar, 412 | div.related, 413 | div.footer, 414 | #top-link { 415 | display: none; 416 | } 417 | } 418 | -------------------------------------------------------------------------------- /test/spheroidal_matrix_test.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from spheroidal import * 3 | 4 | #tests without using derivatives 5 | #prolate spheroid 6 | from spheroidal_particles import TMInputWave, Spheroid 7 | from spheroidal_svm import * 8 | 9 | class testSpheroidalMatrixA(unittest.TestCase): 10 | 11 | def __init__(self,methodName): 12 | unittest.TestCase.__init__(self,methodName) 13 | self.m = 1; self.a_b =10; self.type = 1; self.xl = 4 14 | self.particle = Spheroid(self.m,self.a_b,self.type) 15 | self.particle.set_xl(self.xl) 16 | 17 | def test_getA11Simplest(self): 18 | particle = self.particle 19 | nmax = 3 20 | svm = SpheroidalSVM(particle,nmax) 21 | c = particle.c1 22 | psi = particle.psi 23 | A = svm.get_A11() 24 | cv = get_cv(1,1,c,particle.type) 25 | self.assertAlmostEqual(A[0,0],rad3_cv(1,1,c,particle.type,psi)[0]) 26 | cv = get_cv(1,2,c,particle.type) 27 | self.assertAlmostEqual(A[1,1],rad3_cv(1,2,c,particle.type,psi)[0]) 28 | cv = get_cv(1,3,c,particle.type) 29 | self.assertAlmostEqual(A[2,2],rad3_cv(1,3,c,particle.type,psi)[0]) 30 | self.assertAlmostEqual(A[1,0], 0) 31 | self.assertAlmostEqual(A[0,1], 0) 32 | self.assertAlmostEqual(A[0,2], 0) 33 | self.assertAlmostEqual(A[2,0], 0) 34 | self.assertAlmostEqual(A[2,1], 0) 35 | self.assertAlmostEqual(A[1,2], 0) 36 | 37 | def test_getA12Simplest(self): 38 | particle = self.particle 39 | nmax = 3 40 | svm = SpheroidalSVM(particle,nmax) 41 | c = particle.c1 42 | psi = particle.psi 43 | A = svm.get_A12() 44 | cv = get_cv(1,1,c,particle.type) 45 | self.assertAlmostEqual(A[0,0],-rad1_cv(1,1,c,particle.type,psi)[0]) 46 | cv = get_cv(1,2,c,particle.type) 47 | self.assertAlmostEqual(A[1,1],-rad1_cv(1,2,c,particle.type,psi)[0]) 48 | cv = get_cv(1,3,c,particle.type) 49 | self.assertAlmostEqual(A[2,2],-rad1_cv(1,3,c,particle.type,psi)[0]) 50 | self.assertAlmostEqual(A[1,0], 0) 51 | self.assertAlmostEqual(A[0,1], 0) 52 | self.assertAlmostEqual(A[0,2], 0) 53 | self.assertAlmostEqual(A[2,0], 0) 54 | self.assertAlmostEqual(A[2,1], 0) 55 | self.assertAlmostEqual(A[1,2], 0) 56 | 57 | def test_getA21Simplest(self): 58 | particle = self.particle 59 | nmax = 3 60 | svm = SpheroidalSVM(particle,nmax) 61 | c = particle.c1 62 | psi = particle.psi 63 | A = svm.get_A21() 64 | cv = get_cv(1,1,c,particle.type) 65 | coeff = lambda nu: metric_phi(nu,particle) * metric_nu(nu,particle) / metric_psi(nu,particle) * ang1_cv(1, 1, c, cv, particle.type, nu)[0] * ang1_cv(1, 1, c, cv, particle.type, nu)[0] 66 | coeff = quad(coeff,-1,1) 67 | self.assertAlmostEqual(A[0,0],rad3_cv(1,1,c,particle.type,psi)[1] * coeff) 68 | cv = get_cv(1,2,c,particle.type) 69 | self.assertAlmostEqual(A[1,1],rad3_cv(1,2,c,particle.type,psi)[1] * coeff) 70 | cv = get_cv(1,3,c,particle.type) 71 | self.assertAlmostEqual(A[2,2],rad3_cv(1,3,c,particle.type,psi)[1] * coeff) 72 | self.assertAlmostEqual(A[1,0], 0) 73 | self.assertAlmostEqual(A[0,1], 0) 74 | self.assertAlmostEqual(A[0,2], 0) 75 | self.assertAlmostEqual(A[2,0], 0) 76 | self.assertAlmostEqual(A[2,1], 0) 77 | self.assertAlmostEqual(A[1,2], 0) 78 | 79 | def test_getA22Simplest(self): 80 | particle = self.particle 81 | nmax = 3 82 | svm = SpheroidalSVM(particle,nmax) 83 | c = particle.c1 84 | psi = particle.psi 85 | A = svm.get_A22() 86 | cv = get_cv(1,1,c,particle.type) 87 | coeff = lambda nu: metric_phi(nu,particle) * metric_nu(nu,particle) / metric_psi(nu,particle) * ang1_cv(1, 1, c, cv, particle.type, nu)[0] * ang1_cv(1, 1, c, cv, particle.type, nu)[0] 88 | coeff = - quad(coeff,-1,1) 89 | self.assertAlmostEqual(A[0,0],rad1_cv(1,1,c,particle.type,psi)[1] * coeff) 90 | cv = get_cv(1,2,c,particle.type) 91 | self.assertAlmostEqual(A[1,1],rad1_cv(1,2,c,particle.type,psi)[1] * coeff) 92 | cv = get_cv(1,3,c,particle.type) 93 | self.assertAlmostEqual(A[2,2],rad1_cv(1,3,c,particle.type,psi)[1] * coeff) 94 | self.assertAlmostEqual(A[1,0], 0) 95 | self.assertAlmostEqual(A[0,1], 0) 96 | self.assertAlmostEqual(A[0,2], 0) 97 | self.assertAlmostEqual(A[2,0], 0) 98 | self.assertAlmostEqual(A[2,1], 0) 99 | self.assertAlmostEqual(A[1,2], 0) 100 | 101 | def test_getA10Simplest(self): 102 | particle = self.particle 103 | nmax = 3 104 | svm = SpheroidalSVM(particle,nmax) 105 | c = particle.c1 106 | psi = particle.psi 107 | A = svm.get_A10() 108 | cv = get_cv(1,1,c,particle.type) 109 | self.assertAlmostEqual(A[0,0],-rad1_cv(1,1,c,particle.type,psi)[0]) 110 | cv = get_cv(1,2,c,particle.type) 111 | self.assertAlmostEqual(A[1,1],-rad1_cv(1,2,c,particle.type,psi)[0]) 112 | cv = get_cv(1,3,c,particle.type) 113 | self.assertAlmostEqual(A[2,2],-rad1_cv(1,3,c,particle.type,psi)[0]) 114 | self.assertAlmostEqual(A[1,0], 0) 115 | self.assertAlmostEqual(A[0,1], 0) 116 | self.assertAlmostEqual(A[0,2], 0) 117 | self.assertAlmostEqual(A[2,0], 0) 118 | self.assertAlmostEqual(A[2,1], 0) 119 | self.assertAlmostEqual(A[1,2], 0) 120 | 121 | def test_getA20Simplest(self): 122 | particle = self.particle 123 | nmax = 3 124 | svm = SpheroidalSVM(particle,nmax) 125 | c = particle.c1 126 | psi = particle.psi 127 | A = svm.get_A20() 128 | cv = get_cv(1,1,c,particle.type) 129 | coeff = lambda nu: metric_phi(nu,particle) * metric_nu(nu,particle) / metric_psi(nu,particle) * ang1_cv(1, 1, c, cv, particle.type, nu)[0] * ang1_cv(1, 1, c, cv, particle.type, nu)[0] 130 | coeff = - quad(coeff,-1,1) 131 | self.assertAlmostEqual(A[0,0],rad1_cv(1,1,c,particle.type,psi)[1] * coeff) 132 | cv = get_cv(1,2,c,particle.type) 133 | self.assertAlmostEqual(A[1,1],rad1_cv(1,2,c,particle.type,psi)[1] * coeff) 134 | cv = get_cv(1,3,c,particle.type) 135 | self.assertAlmostEqual(A[2,2],rad1_cv(1,3,c,particle.type,psi)[1] * coeff) 136 | self.assertAlmostEqual(A[1,0], 0) 137 | self.assertAlmostEqual(A[0,1], 0) 138 | self.assertAlmostEqual(A[0,2], 0) 139 | self.assertAlmostEqual(A[2,0], 0) 140 | self.assertAlmostEqual(A[2,1], 0) 141 | self.assertAlmostEqual(A[1,2], 0) 142 | 143 | def test_get_fullA1(self): 144 | particle = self.particle 145 | nmax = 1 146 | svm = SpheroidalSVM(particle,nmax) 147 | A = svm.get_fullA() 148 | self.assertAlmostEqual(A[0, 0], svm.get_A11()) 149 | self.assertAlmostEqual(A[0, 1], svm.get_A12()) 150 | self.assertAlmostEqual(A[1, 0], svm.get_A21()) 151 | self.assertAlmostEqual(A[1, 1], svm.get_A22()) 152 | 153 | def test_get_fullA2(self): 154 | particle = self.particle 155 | nmax = 2 156 | svm = SpheroidalSVM(particle,nmax) 157 | c = particle.c1 158 | psi = particle.psi 159 | A = svm.get_fullA() 160 | A11 = svm.get_A11() 161 | A12 = svm.get_A12() 162 | A21 = svm.get_A21() 163 | A22 = svm.get_A22() 164 | self.assertAlmostEqual(A[0, 0], A11[0, 0]) 165 | self.assertAlmostEqual(A[0, 1], A11[0, 1]) 166 | self.assertAlmostEqual(A[1, 0], A11[1, 0]) 167 | self.assertAlmostEqual(A[1, 1], A11[1, 1]) 168 | self.assertAlmostEqual(A[0, 2], A12[0, 0]) 169 | self.assertAlmostEqual(A[0, 3], A12[0, 1]) 170 | self.assertAlmostEqual(A[1, 2], A12[1, 0]) 171 | self.assertAlmostEqual(A[1, 3], A12[1, 1]) 172 | self.assertAlmostEqual(A[2, 0], A21[0, 0]) 173 | self.assertAlmostEqual(A[2, 1], A21[0, 1]) 174 | self.assertAlmostEqual(A[3, 0], A21[1, 0]) 175 | self.assertAlmostEqual(A[3, 1], A21[1, 1]) 176 | self.assertAlmostEqual(A[2, 2], A22[0, 0]) 177 | self.assertAlmostEqual(A[2, 3], A22[0, 1]) 178 | self.assertAlmostEqual(A[3, 2], A22[1, 0]) 179 | self.assertAlmostEqual(A[3, 3], A22[1, 1]) 180 | 181 | 182 | class testSpheroidalMatrixZ(unittest.TestCase): 183 | 184 | def __init__(self,methodName): 185 | unittest.TestCase.__init__(self,methodName) 186 | self.m = 1 187 | self.a_b =2 188 | self.type = 1 189 | self.xl = 1.5 190 | self.particle = Spheroid(self.m,self.a_b,self.type) 191 | self.particle.set_xl(self.xl) 192 | 193 | def test_getFullB1(self): 194 | particle = self.particle 195 | nmax = 1 196 | svm = SpheroidalSVM(particle,nmax) 197 | B = svm.get_fullB() 198 | self.assertAlmostEqual(B[0], svm.get_A10()) 199 | self.assertAlmostEqual(B[1], svm.get_A20()) 200 | 201 | def test_getFullB2(self): 202 | particle = self.particle 203 | nmax = 2 204 | svm = SpheroidalSVM(particle,nmax) 205 | B = svm.get_fullB() 206 | B1 = svm.get_A10() 207 | B2 = svm.get_A20() 208 | self.assertAlmostEqual(B[0, 0], B1[0, 0]) 209 | self.assertAlmostEqual(B[0, 1], B1[0, 1]) 210 | self.assertAlmostEqual(B[1, 0], B1[1, 0]) 211 | self.assertAlmostEqual(B[1, 1], B1[1, 1]) 212 | self.assertAlmostEqual(B[2, 0], B2[0, 0]) 213 | self.assertAlmostEqual(B[2, 1], B2[0, 1]) 214 | self.assertAlmostEqual(B[3, 0], B2[1, 0]) 215 | self.assertAlmostEqual(B[3, 1], B2[1, 1]) -------------------------------------------------------------------------------- /test/spheroidal_test.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import unittest 3 | import scipy.linalg 4 | 5 | from scipy.special import * 6 | 7 | from spheroidal import * 8 | from spheroidal_particles import Spheroid 9 | 10 | class testSpheroidalProlateNorm(unittest.TestCase): 11 | numpy.seterr('print') 12 | def test_norm5(self): 13 | c = 5 14 | for n in range(1,12): 15 | for m in range(1,n+1): 16 | self.check_norm(m, n, c) 17 | m = 0 18 | 19 | #def test_norm_minus5(self): 20 | # c = -5 21 | # for n in range(1,4): 22 | # for m in range(1,n+1): 23 | # self.check_norm(m, n, c) 24 | # m = 0 25 | def test_axinorm1(self): 26 | c=1; m=1; n=5 27 | self.check_norm(m,n,c) 28 | 29 | def test_axinorm5(self): 30 | c=5; m=1; n=10 31 | self.check_norm(m,n,c) 32 | 33 | def test_axinorm5(self): 34 | c=10; m=1; n=20 35 | self.check_norm(m,n,c) 36 | 37 | def test_norm1(self): 38 | c = 1 39 | for n in range(1,5): 40 | for m in range(1,n+1): 41 | self.check_norm(m, n, c) 42 | m = 0 43 | 44 | def test_norm20(self): 45 | self.check_norm(3, 20, 10) 46 | 47 | def test_norm02(self): 48 | c = 0.2 49 | for n in range(1,5): 50 | for m in range(1,n+1): 51 | self.check_norm(m, n, c) 52 | m = 0 53 | 54 | def check_norm(self, m, n, c): 55 | norm = get_pro_norm(m,n,c) 56 | func = lambda x: power(pro_ang1(m, n, c, x)[0], 2) 57 | self.assertAlmostEqual((quad(func, -1, 1, limit = 300, epsabs=10e-10,epsrel=10e-10))/(norm*norm), 1, places = 7) 58 | 59 | class testSpheroidalOblateNorm(testSpheroidalProlateNorm): 60 | def check_norm(self, m, n, c): 61 | norm = get_obl_norm(m,n,c) 62 | func = lambda x: power(obl_ang1(m, n, c, x)[0] / norm, 2) 63 | self.assertAlmostEqual((quad(func, -1, 1, limit = 300,epsabs=10e-10,epsrel=10e-10)), 1, places = 7) 64 | 65 | class testAngularRelationsProlate(unittest.TestCase): 66 | def testEven1(self): 67 | m = 1; n = 2; c = 2; x = 0.5 68 | self.assertAlmostEqual(pro_ang1(m, n, c, x)[0],pow(-1,n-m) * pro_ang1(m, n, c, -x)[0]) 69 | self.assertAlmostEqual(obl_ang1(m, n, c, x)[0],pow(-1,n-m) * obl_ang1(m, n, c, -x)[0]) 70 | 71 | def testEven2(self): 72 | m = 1; n = 3; c = 2; x = -0.5 73 | self.assertAlmostEqual(pro_ang1(m, n, c, x)[0],pow(-1,n-m) * pro_ang1(m, n, c, -x)[0]) 74 | self.assertAlmostEqual(obl_ang1(m, n, c, x)[0],pow(-1,n-m) * obl_ang1(m, n, c, -x)[0]) 75 | 76 | def testSimplestCaseProlate1(self): 77 | m = 1; n = 2; c = numpy.pi * n / 2; type = 1; x = 0.5 78 | cv = get_cv(m, n, c, type) 79 | norm = get_norm_cv(m, n, c, cv, type) 80 | self.assertAlmostEqual(ang1_cv(m, n, c,cv,type, x)[0] * norm, - 2 / (n * numpy.pi) * scipy.special.lpmn(1,n,0)[1][m][n] /sqrt(1-x*x) * sin(numpy.pi * n * x/2)) 81 | 82 | def testSimplestCaseProlate2(self): 83 | m = 1; n = 3; c = numpy.pi * n / 2; type = 1; x = 0.3 84 | cv = get_cv(m, n, c, type) 85 | norm = get_norm_cv(m, n, c, cv, type) 86 | self.assertAlmostEqual(ang1_cv(m, n, c,cv,type, x)[0] * norm, - scipy.special.lpmv(1,n,0) /sqrt(1-x*x) * cos(numpy.pi * n * x/2)) 87 | 88 | def testSimplestCaseProlate3(self): 89 | m = 1; n = 4; c = numpy.pi * n / 2; type = 1; x = -0.5 90 | cv = get_cv(m, n, c, type) 91 | norm = get_norm_cv(m, n, c, cv, type) 92 | self.assertAlmostEqual(ang1_cv(m, n, c,cv,type, x)[0] * norm, 2 / (n * numpy.pi) * scipy.special.lpmn(1,n,0)[1][m][n] /sqrt(1-x*x) * sin(numpy.pi * n * x/2)) 93 | 94 | def testSimplestCaseProlate4(self): 95 | m = 1; n = 5; c = numpy.pi * n / 2; type = 1; x = -0.3 96 | cv = get_cv(m, n, c, type) 97 | norm = get_norm_cv(m, n, c, cv, type) 98 | self.assertAlmostEqual(ang1_cv(m, n, c,cv,type, x)[0] * norm, - scipy.special.lpmv(1,n,0) /sqrt(1-x*x) * cos(numpy.pi * n * x/2)) 99 | 100 | def testSimplestCaseProlate5(self): 101 | m = 1; n = 6; c = numpy.pi * n / 2; type = 1; x = -0.3 102 | cv = get_cv(m, n, c, type) 103 | norm = get_norm_cv(m, n, c, cv, type) 104 | self.assertAlmostEqual(ang1_cv(m, n, c,cv,type, x)[0] * norm, - 2 / (n * numpy.pi) * scipy.special.lpmn(1,n,0)[1][m][n] /sqrt(1-x*x) * sin(numpy.pi * n * x/2)) 105 | 106 | def testSimplestCaseProlate6(self): 107 | m = 1; n = 7; c = numpy.pi * n / 2; type = 1; x = -0.3 108 | cv = get_cv(m, n, c, type) 109 | norm = get_norm_cv(m, n, c, cv, type) 110 | self.assertAlmostEqual(ang1_cv(m, n, c,cv,type, x)[0] * norm, - scipy.special.lpmv(1,n,0) /sqrt(1-x*x) * cos(numpy.pi * n * x/2)) 111 | 112 | class testRadialRelations(unittest.TestCase): 113 | 114 | psi = 1.4 115 | 116 | def testR1R2Wronskian1(self): 117 | m=1;n=1;c = 2; psi = self.psi 118 | [R1,dR1] = rad1_cv(m,n,c,1,psi) 119 | [R2,dR2] = rad2_cv(m,n,c,1,psi) 120 | W = scipy.mat([[R1, dR1],[R2, dR2]]) 121 | self.assertAlmostEqual(scipy.linalg.det(W),1/(c*(psi * psi-1.0))) 122 | 123 | def testR1R2Wronskian2(self): 124 | m=1;n=2;c = 3.0; psi = self.psi 125 | [R1,dR1] = rad1_cv(m,n,c,-1,psi) 126 | [R2,dR2] = rad2_cv(m,n,c,-1,psi) 127 | W = scipy.mat([[R1, dR1],[R2, dR2]]) 128 | self.assertAlmostEqual(scipy.linalg.det(W),1/(c*(psi**2+1))) 129 | 130 | def testR1R3Wronskian1(self): 131 | m=1;n=3;c = 2; psi = self.psi 132 | type = 1 133 | [R1,dR1] = rad1_cv(m,n,c,1,psi) 134 | [R3,dR3] = rad3_cv(m,n,c,type,psi) 135 | W = scipy.mat([[R1, dR1],[R3, dR3]]) 136 | self.assertAlmostEqual(scipy.linalg.det(W),1j/(c*(psi**2-1))) 137 | 138 | def testR1R3Wronskian2(self): 139 | m=1;n=2;c = 3.0; psi = self.psi 140 | type = -1 141 | [R1,dR1] = rad1_cv(m,n,c,-1,psi) 142 | [R3,dR3] = rad3_cv(m,n,c,type,psi) 143 | W = scipy.mat([[R1, dR1],[R3, dR3]]) 144 | self.assertAlmostEqual(scipy.linalg.det(W),1j/(c*(psi**2+1))) 145 | 146 | 147 | 148 | class testMetricCoefficients(unittest.TestCase): 149 | 150 | def testDelta1(self): 151 | m=1.5;a_b=3;type=1 152 | particle = Spheroid(m,a_b,type) 153 | particle.set_xl(1.5) 154 | nu = 0.5 155 | self.assertAlmostEquals(IzIn(nu,particle)*RIt(nu,particle)-IzIt(nu,particle)*RIn(nu,particle),-metric_phi(nu,particle)) 156 | 157 | def testDelta2(self): 158 | m=1.5;a_b=3;type=-1 159 | particle = Spheroid(m,a_b,type) 160 | particle.set_xl(1.5) 161 | nu = -0.3 162 | self.assertAlmostEquals(IzIn(nu,particle)*RIt(nu,particle)-IzIt(nu,particle)*RIn(nu,particle),-metric_phi(nu,particle)) 163 | 164 | def testDelta3(self): 165 | m=2;a_b=2;type=1 166 | particle = Spheroid(m,a_b,type) 167 | particle.set_xl(1.5) 168 | nu = -0.5 169 | self.assertAlmostEquals(IzIn(nu,particle)*RIt(nu,particle)-IzIt(nu,particle)*RIn(nu,particle),-metric_phi(nu,particle)) 170 | 171 | def testDelta4(self): 172 | m=2;a_b=2;type=-1 173 | particle = Spheroid(m,a_b,type) 174 | particle.set_xl(1.5) 175 | nu = 0.3 176 | self.assertAlmostEquals(IzIn(nu,particle)*RIt(nu,particle)-IzIt(nu,particle)*RIn(nu,particle),-metric_phi(nu,particle)) 177 | 178 | class testDeltaAngularFunctions(unittest.TestCase): 179 | def testDelta_n_equal(self): 180 | m=1; 181 | c1 = 2; n1 = 3 182 | c2 = 2; n2 = 3; 183 | norm1 = get_pro_norm(m,n1,c1) 184 | norm2 = get_pro_norm(m,n2,c2) 185 | func = lambda x: pro_ang1(m, n1, c1, x)[0] / norm1 * pro_ang1(m, n2, c2, x)[0] / norm2 186 | self.assertAlmostEqual((quad(func, -1, 1)), 1, places = 7) 187 | 188 | def testDelta_n_different1(self): 189 | m=1; 190 | c1 = 2; n1 = 4 191 | c2 = 2; n2 = 3; 192 | func = lambda x: pro_ang1(m, n1, c1, x)[0] * pro_ang1(m, n2, c2, x)[0] 193 | self.assertAlmostEqual((quad(func, -1, 1)), 0, places = 7) 194 | 195 | def testDelta_n_different2(self): 196 | m=1; type = 1 197 | c1 = 10; n1 = 1 198 | c2 = 10; n2 = 3 199 | cv1 = get_cv(m,n1,c1,type) 200 | cv2 = get_cv(m,n2,c2,type) 201 | func = lambda x: ang1_cv(m, n1, c1,cv1,type, x)[0] * ang1_cv(m, n2, c2,cv2,type, x)[0] 202 | self.assertAlmostEqual((quad(func, -1, 1,epsabs=1e-12,epsrel=1e-12)), 0, places = 8) 203 | 204 | def testDelta_n_different(self): 205 | m=1; type = 1 206 | c1 = 2; n1 = 4 207 | c2 = 2; n2 = 2; 208 | cv1 = get_cv(m,n1,c1,type) 209 | cv2 = get_cv(m,n2,c2,type) 210 | func = lambda x: ang1_cv(m, n1, c1,cv1,type, x)[0] * ang1_cv(m, n2, c2,cv2,type, x)[0] 211 | self.assertAlmostEqual((quad(func, -1, 1)), 0, places = 7) 212 | 213 | def testDelta_simmetric(self): 214 | m=1; 215 | c1 = 2; n1 = 4 216 | c2 = 3; n2 = 4; 217 | func = lambda x: pro_ang1(m, n1, c1, x)[0] * numpy.conjugate(pro_ang1(m, n2, c2, x)[0]) 218 | func2 = lambda x: pro_ang1(m, n2, c2, x)[0] * numpy.conjugate(pro_ang1(m, n1, c1, x)[0]) 219 | self.assertAlmostEqual(quad(func, -1, 1), quad(func2, -1, 1), places = 7) 220 | 221 | class testFactorial(unittest.TestCase): 222 | 223 | def test_factorial(self): 224 | self.assertEqual(get_norm_factorial(1,0), 1) 225 | self.assertEqual(get_norm_factorial(5,0), 1) 226 | self.assertEqual(get_norm_factorial(0,0), 1) 227 | 228 | self.assertEqual(get_norm_factorial(3,1), 20) 229 | self.assertEqual(get_norm_factorial(2,2), 360) 230 | 231 | 232 | if __name__ == '__main__': 233 | unittest.main() 234 | -------------------------------------------------------------------------------- /doc/source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # ScattPy documentation build configuration file, created by 4 | # sphinx-quickstart on Sun Jan 9 00:56:54 2011. 5 | # 6 | # This file is execfile()d with the current directory set to its containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | import sys, os 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | sys.path.append(os.path.abspath('sphinxext')) 20 | 21 | # -- General configuration ----------------------------------------------------- 22 | 23 | # Add any Sphinx extension module names here, as strings. They can be extensions 24 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 25 | #extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.coverage', 'sphinx.ext.pngmath'] 26 | extensions = [ 27 | 'sphinx.ext.autodoc', 28 | 'sphinx.ext.pngmath', 29 | 'sphinx.ext.intersphinx', 30 | 'sphinx.ext.coverage', 31 | 'sphinx.ext.doctest', 32 | 'sphinx.ext.autosummary', 33 | # 'numpydoc.plot_directive', 34 | 'matplotlib.sphinxext.only_directives', 35 | 'matplotlib.sphinxext.plot_directive', 36 | # 'matplotlib.sphinxext.ipython_directive', 37 | 'ipython_directive', 38 | 'ipython_console_highlighting', 39 | 'numpydoc', 40 | 'sphinxtogithub' 41 | ] 42 | 43 | # Add any paths that contain templates here, relative to this directory. 44 | templates_path = ['_templates'] 45 | 46 | # The suffix of source filenames. 47 | source_suffix = '.rst' 48 | 49 | # The encoding of source files. 50 | #source_encoding = 'utf-8' 51 | 52 | # The master toctree document. 53 | #master_doc = 'index' 54 | 55 | # General information about the project. 56 | project = u'ScattPy' 57 | copyright = u'2011, Alexander Vinokurov' 58 | 59 | # The version info for the project you're documenting, acts as replacement for 60 | # |version| and |release|, also used in various other places throughout the 61 | # built documents. 62 | # 63 | # The short X.Y version. 64 | version = '0.1.0' 65 | # The full version, including alpha/beta/rc tags. 66 | release = '0.1.0' 67 | 68 | # The language for content autogenerated by Sphinx. Refer to documentation 69 | # for a list of supported languages. 70 | #language = None 71 | 72 | # There are two options for replacing |today|: either, you set today to some 73 | # non-false value, then it is used: 74 | #today = '' 75 | # Else, today_fmt is used as the format for a strftime call. 76 | today_fmt = '%B %d, %Y' 77 | 78 | # List of documents that shouldn't be included in the build. 79 | #unused_docs = [] 80 | 81 | # List of directories, relative to source directory, that shouldn't be searched 82 | # for source files. 83 | exclude_trees = ['_build'] 84 | 85 | # The reST default role (used for this markup: `text`) to use for all documents. 86 | #default_role = None 87 | 88 | # If true, '()' will be appended to :func: etc. cross-reference text. 89 | #add_function_parentheses = True 90 | 91 | # If true, the current module name will be prepended to all description 92 | # unit titles (such as .. function::). 93 | #add_module_names = True 94 | 95 | # If true, sectionauthor and moduleauthor directives will be shown in the 96 | # output. They are ignored by default. 97 | #show_authors = False 98 | 99 | # The name of the Pygments (syntax highlighting) style to use. 100 | pygments_style = 'sphinx' 101 | 102 | # A list of ignored prefixes for module index sorting. 103 | #modindex_common_prefix = [] 104 | 105 | 106 | # -- Options for HTML output --------------------------------------------------- 107 | 108 | # The theme to use for HTML and HTML Help pages. Major themes that come with 109 | # Sphinx are currently 'default' and 'sphinxdoc'. 110 | html_theme = 'github' 111 | html_style = 'scipy.css' 112 | 113 | # Theme options are theme-specific and customize the look and feel of a theme 114 | # further. For a list of options available for each theme, see the 115 | # documentation. 116 | #html_theme_options = {} 117 | 118 | # Add any paths that contain custom themes here, relative to this directory. 119 | html_theme_path = ['_themes'] 120 | 121 | # The name for this set of Sphinx documents. If None, it defaults to 122 | # " v documentation". 123 | html_title = "%s v%s Manual (DRAFT)" % (project, version) 124 | 125 | # A shorter title for the navigation bar. Default is the same as html_title. 126 | #html_short_title = None 127 | 128 | # The name of an image file (relative to this directory) to place at the top 129 | # of the sidebar. 130 | #html_logo = None 131 | 132 | # The name of an image file (within the static path) to use as favicon of the 133 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 134 | # pixels large. 135 | #html_favicon = None 136 | 137 | # Add any paths that contain custom static files (such as style sheets) here, 138 | # relative to this directory. They are copied after the builtin static files, 139 | # so a file named "default.css" will overwrite the builtin "default.css". 140 | html_static_path = ['_static'] 141 | 142 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 143 | # using the given strftime format. 144 | html_last_updated_fmt = '%b %d, %Y' 145 | 146 | # If true, SmartyPants will be used to convert quotes and dashes to 147 | # typographically correct entities. 148 | #html_use_smartypants = True 149 | 150 | # Custom sidebar templates, maps document names to template names. 151 | #html_sidebars = {} 152 | 153 | # Additional templates that should be rendered to pages, maps page names to 154 | # template names. 155 | html_additional_pages = { 156 | 'index':'indexcontent.html' 157 | } 158 | 159 | # If false, no module index is generated. 160 | html_use_modindex = True 161 | 162 | # If false, no index is generated. 163 | #html_use_index = True 164 | 165 | # If true, the index is split into individual pages for each letter. 166 | #html_split_index = False 167 | 168 | # If true, links to the reST sources are added to the pages. 169 | #html_show_sourcelink = True 170 | 171 | # If true, an OpenSearch description file will be output, and all pages will 172 | # contain a tag referring to it. The value of this option must be the 173 | # base URL from which the finished HTML is served. 174 | #html_use_opensearch = '' 175 | 176 | # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). 177 | #html_file_suffix = '' 178 | 179 | # Output file base name for HTML help builder. 180 | htmlhelp_basename = 'ScattPydoc' 181 | 182 | 183 | # -- Options for LaTeX output -------------------------------------------------- 184 | 185 | # The paper size ('letter' or 'a4'). 186 | #latex_paper_size = 'letter' 187 | 188 | # The font size ('10pt', '11pt' or '12pt'). 189 | #latex_font_size = '10pt' 190 | 191 | # Grouping the document tree into LaTeX files. List of tuples 192 | # (source start file, target name, title, author, documentclass [howto/manual]). 193 | _stdauthor = 'Alexander Vinokurov' 194 | #latex_documents = [ 195 | # ('reference/index', 'numpy-ref.tex', 'ScattPy Reference', 196 | # _stdauthor, 'manual'), 197 | # ('user/index', 'numpy-user.tex', 'ScattPy User Guide', 198 | # _stdauthor, 'manual'), 199 | #] 200 | latex_documents = [('contents','scattpy-doc.tex','ScattPy Documentation', 201 | _stdauthor, 'manual')] 202 | 203 | # The name of an image file (relative to this directory) to place at the top of 204 | # the title page. 205 | #latex_logo = None 206 | 207 | # For "manual" documents, if this is true, then toplevel headings are parts, 208 | # not chapters. 209 | #latex_use_parts = False 210 | 211 | # Additional stuff for the LaTeX preamble. 212 | #latex_preamble = '' 213 | latex_preamble = r''' 214 | \usepackage{amsmath} 215 | \DeclareUnicodeCharacter{00A0}{\nobreakspace} 216 | 217 | % In the parameters section, place a newline after the Parameters 218 | % header 219 | \usepackage{expdlist} 220 | \let\latexdescription=\description 221 | \def\description{\latexdescription{}{} \breaklabel} 222 | 223 | % Make Examples/etc section headers smaller and more compact 224 | \makeatletter 225 | \titleformat{\paragraph}{\normalsize\py@HeaderFamily}% 226 | {\py@TitleColor}{0em}{\py@TitleColor}{\py@NormalColor} 227 | \titlespacing*{\paragraph}{0pt}{1ex}{0pt} 228 | \makeatother 229 | 230 | % Fix footer/header 231 | \renewcommand{\chaptermark}[1]{\markboth{\MakeUppercase{\thechapter.\ #1}}{}} 232 | \renewcommand{\sectionmark}[1]{\markright{\MakeUppercase{\thesection.\ #1}}} 233 | ''' 234 | 235 | # Documents to append as an appendix to all manuals. 236 | #latex_appendices = [] 237 | 238 | # If false, no module index is generated. 239 | latex_use_modindex = True 240 | 241 | 242 | # Example configuration for intersphinx: refer to the Python standard library. 243 | intersphinx_mapping = {'http://docs.python.org/': None} 244 | 245 | 246 | # ----------------------------------------------------------------------------- 247 | # Numpy extensions 248 | # ----------------------------------------------------------------------------- 249 | 250 | # If we want to do a phantom import from an XML file for all autodocs 251 | phantom_import_file = 'dump.xml' 252 | 253 | # Make numpydoc to generate plots for example sections 254 | numpydoc_use_plots = True 255 | 256 | # ----------------------------------------------------------------------------- 257 | # Autosummary 258 | # ----------------------------------------------------------------------------- 259 | 260 | import glob 261 | autosummary_generate = glob.glob("reference/*.rst") 262 | 263 | # ----------------------------------------------------------------------------- 264 | # Coverage checker 265 | # ----------------------------------------------------------------------------- 266 | coverage_ignore_modules = r""" 267 | """.split() 268 | coverage_ignore_functions = r""" 269 | test($|_) (some|all)true bitwise_not cumproduct pkgload 270 | generic\. 271 | """.split() 272 | coverage_ignore_classes = r""" 273 | """.split() 274 | 275 | coverage_c_path = [] 276 | coverage_c_regexes = {} 277 | coverage_ignore_c_items = {} 278 | 279 | 280 | # ----------------------------------------------------------------------------- 281 | # Plots 282 | # ----------------------------------------------------------------------------- 283 | plot_pre_code = """ 284 | import numpy as np 285 | np.random.seed(0) 286 | """ 287 | plot_include_source = True 288 | plot_formats = [('png', 100), 'pdf'] 289 | 290 | import math 291 | phi = (math.sqrt(5) + 1)/2 292 | 293 | import matplotlib 294 | matplotlib.rcParams.update({ 295 | 'font.size': 8, 296 | 'axes.titlesize': 8, 297 | 'axes.labelsize': 8, 298 | 'xtick.labelsize': 8, 299 | 'ytick.labelsize': 8, 300 | 'legend.fontsize': 8, 301 | 'figure.figsize': (3*phi, 3), 302 | 'figure.subplot.bottom': 0.2, 303 | 'figure.subplot.left': 0.2, 304 | 'figure.subplot.right': 0.9, 305 | 'figure.subplot.top': 0.85, 306 | 'figure.subplot.wspace': 0.4, 307 | 'text.usetex': False, 308 | }) 309 | -------------------------------------------------------------------------------- /scikits/scattpy/spherical.py: -------------------------------------------------------------------------------- 1 | from numpy import * 2 | from scipy.special.orthogonal import ps_roots 3 | from scipy import special 4 | import f_utils 5 | 6 | # (r, theta, phi) 7 | class spherical_utilities(object): 8 | def __init__(self, ng, n, lab): 9 | self.n = n 10 | self.ng = ng 11 | self.set_ngauss() 12 | self.set_funcs_ang() 13 | self.set_all_layers(lab) 14 | 15 | def set_ngauss(self): 16 | k, w = ps_roots(self.ng) 17 | self.knots, self.weights = k * pi, w * pi 18 | self.thetas = self.knots 19 | self.sint = sin(self.thetas) 20 | self.cost = cos(self.thetas) 21 | self.tgt = tan(self.thetas) 22 | self.ctgt = 1 / self.tgt 23 | 24 | def set_funcs_ang(self): 25 | P = array([special.lpmn(self.n, self.n, ct) for ct in self.cost]) 26 | self.data_Ang, self.data_Angd = P[:, 0, :, :], P[:, 1, :, :] 27 | 28 | def set_all_layers(self, lab): 29 | self.data_layers = [0] 30 | for bnd in lab.boundaries(): 31 | r, rd, rdd = bnd.shape.R(self.knots) 32 | rdr = rd / r 33 | r2rd2 = r ** 2 + rd ** 2 34 | Rad = [0, {}, {}] 35 | Radd = [0, {}, {}] 36 | kis = [0, bnd.k1, bnd.k2] 37 | for i in [1, 2]: 38 | krs = kis[i] * r 39 | JY = array([special.sph_jnyn(self.n, kr) for kr in krs])[:, :, :] 40 | Rad[i] = {'j': JY[:, 0, :], 'h': JY[:, 0, :] + 1j * JY[:, 2, :]} 41 | Radd[i] = {'j': JY[:, 1, :], 'h': JY[:, 1, :] + 1j * JY[:, 3, :]} 42 | 43 | self.data_layers.append({'ki': kis,\ 44 | 'r': r,\ 45 | 'rd': rd,\ 46 | 'rdd': rdd,\ 47 | 'rdr': rdr,\ 48 | 'r2rd2': r2rd2,\ 49 | 'Rad': Rad,\ 50 | 'Radd': Radd}) 51 | 52 | def set_layer_no(self, lay): 53 | self._lay = lay 54 | 55 | def _get_const(self, name): 56 | return self.data_layers[self._lay][name] 57 | 58 | def _get_r(self): return self._get_const("r") 59 | 60 | r = property(fget=_get_r) 61 | 62 | def _get_rd(self): return self._get_const("rd") 63 | 64 | rd = property(_get_rd) 65 | 66 | def _get_rdd(self): return self._get_const("rdd") 67 | 68 | rdd = property(_get_rdd) 69 | 70 | def _get_rdr(self): return self._get_const("rdr") 71 | 72 | rdr = property(_get_rdr) 73 | 74 | def _get_r2rd2(self): return self._get_const("r2rd2") 75 | 76 | r2rd2 = property(_get_r2rd2) 77 | 78 | def _get_ki(self): return self._get_const("ki") 79 | 80 | ki = property(_get_ki) 81 | 82 | def Rad(self, m, ij, i): 83 | return self.data_layers[self._lay]['Rad'][i][ij][:, m:] 84 | 85 | def Radd(self, m, ij, i): 86 | return self.data_layers[self._lay]['Radd'][i][ij][:, m:] 87 | 88 | def Ang(self, m): 89 | return self.data_Ang[:, m, m:] 90 | 91 | def Angd(self, m): 92 | return self.data_Angd[:, m, m:] 93 | 94 | 95 | def get_Jn(n, x): 96 | return array([special.sph_jn(n, xl) for xl in x]) 97 | 98 | 99 | def get_JnHn(n, x): 100 | JnYn = array([special.sph_jnyn(n, xl) for xl in x]) 101 | return JnYn[:, :2, :], JnYn[:, :2, :] + 1j * JnYn[:, 2:, :] 102 | 103 | 104 | def matA0(C, m, jh, i, coef): 105 | Rad = C.Rad(m, jh, i) 106 | Angm = C.Ang(m) 107 | #func = lambda k: outer( Rad[k]*Angm[k], coef[k]*Angm[k]) 108 | #return mat_integrate(func) 109 | return f_utils.mat_a0(Rad, Angm, coef, C.weights) 110 | 111 | 112 | def matA(C, m, jh, i): 113 | return matA0(C, m, jh, i, coef=C.sint) 114 | 115 | 116 | def matB(C, m, jh, i): 117 | ki = C.ki[i] 118 | Rad = C.Rad(m, jh, i) 119 | Radd = C.Radd(m, jh, i) 120 | Angm = C.Ang(m) 121 | Angmd = C.Angd(m) 122 | #func = lambda k: \ 123 | # outer(ki*r[k]*Radd[k]*Angm[k]+rdr[k]*sint[k]*Rad[k]*Angmd[k],\ 124 | # sint[k]*Angm[k] ) 125 | #return mat_integrate(func) 126 | return f_utils.mat_b(ki, Rad, Radd, Angm, Angmd, C.r, C.rdr, C.sint, C.weights) 127 | 128 | 129 | def matC(C, m, jh, i, e12, B=None): 130 | ki = C.ki[i] 131 | if B is None: B = matB(n, m, fRad, fAng, ki) 132 | ff = (1. - C.ctgt * C.rdr) * C.sint 133 | A = matA0(C, m, jh, i, coef=ff) 134 | return e12 * B + (e12 - 1.) * A 135 | 136 | 137 | def matD0(C, m, jh, i, coef): 138 | ki = C.ki[i] 139 | Rad = C.Rad(m, jh, i) 140 | Radd = C.Radd(m, jh, i) 141 | Angm = C.Ang(m) 142 | Angmd = C.Angd(m) 143 | #func = lambda k: \ 144 | # outer(ki*r[k]*cost[k]*Radd[k]*Angm[k]+sint[k]**2*Rad[k]*Angmd[k],\ 145 | # Angm[k]*coef[k] ) 146 | #return mat_integrate(func) 147 | return f_utils.mat_d0\ 148 | (ki, Rad, Radd, Angm, Angmd, C.r, C.sint, C.cost, coef, C.weights) 149 | 150 | 151 | def matE0(C, m, jh, i, coef): 152 | ki = C.ki[i] 153 | Rad = C.Rad(m, jh, i) 154 | Radd = C.Radd(m, jh, i) 155 | Angm = C.Ang(m) 156 | Angmd = C.Angd(m) 157 | #func = lambda k: \ 158 | # outer((ki*r[k]*Radd[k]+Rad[k])*Angm[k], Angm[k]*coef[k] ) 159 | #return mat_integrate(func) 160 | return f_utils.mat_e0(ki, Rad, Radd, Angm, C.r, coef, C.weights) 161 | 162 | 163 | def matG0(C, m, jh, i, coef): 164 | ki = C.ki[i] 165 | Rad = C.Rad(m, jh, i) 166 | Radd = C.Radd(m, jh, i) 167 | Angm = C.Ang(m) 168 | Angmd = C.Angd(m) 169 | #func = lambda k: \ 170 | # outer(ki*rd[k]*Radd[k]*Angm[k] - sint[k]*Rad[k]*Angmd[k],\ 171 | # Angm[k]*coef[k] ) 172 | #return mat_integrate(func) 173 | return f_utils.mat_g0(ki, Rad, Radd, Angm, Angmd, C.r, C.rd, C.sint, coef, C.weights) 174 | 175 | 176 | def matD(C, m, jh, i, e12, B=None): 177 | if B is None: B = matB(C, m, jh, i) 178 | fd = C.rdr 179 | D0 = matD0(C, m, jh, i, coef=fd) 180 | return B + (e12 - 1.) * D0 181 | 182 | 183 | def matE(C, m, jh, i, e12): 184 | fe = C.rd 185 | E0 = matE0(C, m, jh, i, coef=fe) 186 | return (e12 - 1.) * E0 187 | 188 | 189 | def matF(C, m, jh, i, e12): 190 | fd = (C.rd * C.cost - C.r * C.sint) / C.r ** 2 191 | D0 = matD0(C, m, jh, i, coef=fd) 192 | return -(e12 - 1.) * D0 193 | 194 | 195 | def matG(C, m, jh, i, e12, B=None): 196 | if B is None: B = matB(C, m, jh, i) 197 | fe = (C.rd * C.cost - C.r * C.sint) / C.r 198 | E0 = matE0(C, m, jh, i, coef=fe) 199 | return B - (e12 - 1.) * E0 200 | 201 | 202 | def matA12(C, m, jh, i, e21, A=None): 203 | if A is None: A = matA(C, m, jh, i) 204 | fa = C.r * (C.rd * C.cost - C.r * C.sint) / C.r2rd2 205 | A0 = matA0(C, m, jh, i, coef=fa) 206 | return A - (e21 - 1) * A0 207 | 208 | 209 | def matA14(C, m, jh, i, e21): 210 | fa = (C.r ** 2 * C.rd) / C.r2rd2 211 | A0 = matA0(C, m, jh, i, coef=fa) 212 | return -(e21 - 1) * A0 213 | 214 | 215 | def matA32(C, m, jh, i, e21): 216 | fa = (C.rd * C.sint + C.r * C.cost) * (C.rd * C.cost - C.r * C.sint) / (C.r * C.r2rd2) 217 | A0 = matA0(C, m, jh, i, coef=fa) 218 | return (e21 - 1) * A0 219 | 220 | 221 | def matA34(C, m, jh, i, e21, A=None): 222 | if A is None: A = matA(C, m, jh, i) 223 | fa = C.rd * (C.rd * C.sint + C.r * C.cost) / C.r2rd2 224 | A0 = matA0(C, m, jh, i, coef=fa) 225 | return A + (e21 - 1) * A0 226 | 227 | 228 | def matA22(C, m, jh, i, e21, B=None): 229 | if B is None: B = matB(C, m, jh, i) 230 | fg = C.rd * (C.rd * C.cost - C.r * C.sint) / C.r2rd2 231 | fa = (C.r ** 2 - C.r * C.rdd + 2 * C.rd ** 2)\ 232 | * ( C.r * (C.rd * C.cost - C.r * C.sint) + C.rd * (C.rd * C.sint + C.r * C.cost) )\ 233 | / (C.r2rd2) ** 2 234 | #fa = f_utils.f1(r,rd,rdd,sint,cost) 235 | A0 = matA0(C, m, jh, i, coef=fa) 236 | G0 = matG0(C, m, jh, i, coef=fg) 237 | return B - (e21 - 1) * (G0 - A0) 238 | 239 | 240 | def matA24(C, m, jh, i, e21): 241 | fg = C.r * C.rd ** 2 / C.r2rd2 242 | fa = C.rd * (C.r ** 4 - 2 * C.r ** 3 * C.rdd + 2 * C.r ** 2 * C.rd ** 2 - C.rd ** 4)\ 243 | / (C.r2rd2) ** 2 244 | #fa = f_utils.f2(r,rd,rdd) * rd 245 | A0 = matA0(C, m, jh, i, coef=fa) 246 | G0 = matG0(C, m, jh, i, coef=fg) 247 | return -(e21 - 1) * (G0 - A0) 248 | 249 | 250 | def matA42(C, m, jh, i, e21): 251 | fg = (C.rd * C.cost - C.r * C.sint) ** 2 / (C.r * C.r2rd2) 252 | fa = 2 * (C.r ** 2 - C.r * C.rdd + 2 * C.rd ** 2)\ 253 | * (C.rd * C.cost - C.r * C.sint) * (C.rd * C.sint + C.r * C.cost)\ 254 | / (C.r * C.r2rd2 ** 2) 255 | #fa = f_utils.f3(r,rd,rdd,sint,cost) / r 256 | A0 = matA0(C, m, jh, i, coef=fa) 257 | G0 = matG0(C, m, jh, i, coef=fg) 258 | return (e21 - 1) * (G0 - A0) 259 | 260 | 261 | def matA44(C, m, jh, i, e21, B=None): 262 | if B is None: B = matB(C, m, jh, i) 263 | fg = C.rd * (C.rd * C.cost - C.r * C.sint) / C.r2rd2 264 | fa = ((C.r ** 3 * C.rdd + C.r ** 2 * C.rd ** 2 - C.r * C.rd ** 2 * C.rdd + 3 * C.rd ** 4) * C.sint\ 265 | + C.rdr * C.cost * (C.r ** 4 - 2 * C.r ** 3 * C.rdd + 2 * C.r ** 2 * C.rd ** 2 - C.rd ** 4))\ 266 | / (C.r2rd2) ** 2 267 | #fa = f_utils.f4(r,rd,rdd,sint,cost) 268 | A0 = matA0(C, m, jh, i, coef=fa) 269 | G0 = matG0(C, m, jh, i, coef=fg) 270 | return B + (e21 - 1) * (G0 - A0) 271 | 272 | ############### EBCM ############################# 273 | 274 | def mat_ebcm_axi_tm(C, m, jh1, jh2, e12, e21): 275 | k1 = C.ki[1] 276 | k2 = C.ki[2] 277 | Rad1 = C.Rad(m, jh1, 1) 278 | Radd1 = C.Radd(m, jh1, 1) 279 | Rad2 = C.Rad(m, jh2, 2) 280 | Radd2 = C.Radd(m, jh2, 2) 281 | Angm = C.Ang(m) 282 | Angmd = C.Angd(m) 283 | return f_utils.axitm(Rad1, Radd1, Rad2, Radd2, Angm, Angmd,\ 284 | C.r, C.rd, C.sint, C.cost, k1, k2, e12, C.weights) 285 | 286 | 287 | def mat_ebcm_axi_te(C, m, jh1, jh2, e12, e21): 288 | k1 = C.ki[1] 289 | k2 = C.ki[2] 290 | Rad1 = C.Rad(m, jh1, 1) 291 | Radd1 = C.Radd(m, jh1, 1) 292 | Rad2 = C.Rad(m, jh2, 2) 293 | Radd2 = C.Radd(m, jh2, 2) 294 | Angm = C.Ang(m) 295 | Angmd = C.Angd(m) 296 | return f_utils.axite(Rad1, Radd1, Rad2, Radd2, Angm, Angmd,\ 297 | C.r, C.rd, C.sint, C.cost, k1, k2, C.weights) 298 | 299 | 300 | def mat_ebcm_naxi_tm(C, m, jh1, jh2, e12, e21): 301 | k1 = C.ki[1] 302 | k2 = C.ki[2] 303 | Rad1 = C.Rad(m, jh1, 1) 304 | Radd1 = C.Radd(m, jh1, 1) 305 | Rad2 = C.Rad(m, jh2, 2) 306 | Radd2 = C.Radd(m, jh2, 2) 307 | Angm = C.Ang(m) 308 | Angmd = C.Angd(m) 309 | return f_utils.naxitm(m, Rad1, Radd1, Rad2, Radd2, Angm, Angmd,\ 310 | C.r, C.rd, C.sint, C.cost, k1, k2, e12, e21, C.weights) 311 | 312 | 313 | def mat_ebcm_naxi_te(C, m, jh1, jh2, e12, e21): 314 | k1 = C.ki[1] 315 | k2 = C.ki[2] 316 | Rad1 = C.Rad(m, jh1, 1) 317 | Radd1 = C.Radd(m, jh1, 1) 318 | Rad2 = C.Rad(m, jh2, 2) 319 | Radd2 = C.Radd(m, jh2, 2) 320 | Angm = C.Ang(m) 321 | Angmd = C.Angd(m) 322 | return f_utils.naxite(m, Rad1, Radd1, Rad2, Radd2, Angm, Angmd,\ 323 | C.r, C.rd, C.rdd, C.sint, C.cost, k1, k2, e12, e21, C.weights) 324 | 325 | ################### PMM #################################### 326 | 327 | def mat_pmm_axi_tm(C, e12, xv): 328 | m = 1 329 | k1 = C.ki[1] 330 | k2 = C.ki[2] 331 | Radj1 = C.Rad(1, 'j', 1) 332 | Raddj1 = C.Radd(1, 'j', 1) 333 | Radj2 = C.Rad(1, 'j', 2) 334 | Raddj2 = C.Radd(1, 'j', 2) 335 | Radh1 = C.Rad(1, 'h', 1) 336 | Raddh1 = C.Radd(1, 'h', 1) 337 | Angm = C.Ang(1) 338 | Angmd = C.Angd(1) 339 | #RadjR = get_Jn(C.n,[xv*k2])[0,0,m:] 340 | #RadhR = get_JnHn(C.n,[xv*k1])[1][0,0,m:] 341 | RadjR = ones(shape(Radj1[1])) 342 | RadhR = ones(shape(Radj1[1])) 343 | return f_utils.pmmaxitm(Radj1, Raddj1, Radj2, Raddj2, Radh1, Raddh1, Angm, Angmd,\ 344 | RadjR, RadhR, C.r, C.rd, C.sint, C.ctgt, k1, k2, e12, C.weights) 345 | 346 | 347 | def mat_pmm_naxi_tm(C, m, e12, xv): 348 | k1 = C.ki[1] 349 | k2 = C.ki[2] 350 | Radj1 = C.Rad(m, 'j', 1) 351 | Raddj1 = C.Radd(m, 'j', 1) 352 | Radj2 = C.Rad(m, 'j', 2) 353 | Raddj2 = C.Radd(m, 'j', 2) 354 | Radh1 = C.Rad(m, 'h', 1) 355 | Raddh1 = C.Radd(m, 'h', 1) 356 | Angm = C.Ang(m) 357 | Angmd = C.Angd(m) 358 | #RadjR = get_Jn(C.n,[xv*k2])[0,0,m:] 359 | #RadhR = get_JnHn(C.n,[xv*k1])[1][0,0,m:] 360 | RadjR = ones(shape(Radj1[1])) 361 | RadhR = ones(shape(Radj1[1])) 362 | return f_utils.pmmnaxitm(Radj1, Raddj1, Radj2, Raddj2, Radh1, Raddh1, Angm, Angmd,\ 363 | RadjR, RadhR, C.r, C.rd, C.sint, C.cost, k1, k2, e12, C.weights) 364 | 365 | -------------------------------------------------------------------------------- /doc/source/_themes/basic/static/searchtools.js: -------------------------------------------------------------------------------- 1 | /** 2 | * helper function to return a node containing the 3 | * search summary for a given text. keywords is a list 4 | * of stemmed words, hlwords is the list of normal, unstemmed 5 | * words. the first one is used to find the occurance, the 6 | * latter for highlighting it. 7 | */ 8 | 9 | jQuery.makeSearchSummary = function(text, keywords, hlwords) { 10 | var textLower = text.toLowerCase(); 11 | var start = 0; 12 | $.each(keywords, function() { 13 | var i = textLower.indexOf(this.toLowerCase()); 14 | if (i > -1) 15 | start = i; 16 | }); 17 | start = Math.max(start - 120, 0); 18 | var excerpt = ((start > 0) ? '...' : '') + 19 | $.trim(text.substr(start, 240)) + 20 | ((start + 240 - text.length) ? '...' : ''); 21 | var rv = $('
').text(excerpt); 22 | $.each(hlwords, function() { 23 | rv = rv.highlightText(this, 'highlight'); 24 | }); 25 | return rv; 26 | } 27 | 28 | /** 29 | * Porter Stemmer 30 | */ 31 | var PorterStemmer = function() { 32 | 33 | var step2list = { 34 | ational: 'ate', 35 | tional: 'tion', 36 | enci: 'ence', 37 | anci: 'ance', 38 | izer: 'ize', 39 | bli: 'ble', 40 | alli: 'al', 41 | entli: 'ent', 42 | eli: 'e', 43 | ousli: 'ous', 44 | ization: 'ize', 45 | ation: 'ate', 46 | ator: 'ate', 47 | alism: 'al', 48 | iveness: 'ive', 49 | fulness: 'ful', 50 | ousness: 'ous', 51 | aliti: 'al', 52 | iviti: 'ive', 53 | biliti: 'ble', 54 | logi: 'log' 55 | }; 56 | 57 | var step3list = { 58 | icate: 'ic', 59 | ative: '', 60 | alize: 'al', 61 | iciti: 'ic', 62 | ical: 'ic', 63 | ful: '', 64 | ness: '' 65 | }; 66 | 67 | var c = "[^aeiou]"; // consonant 68 | var v = "[aeiouy]"; // vowel 69 | var C = c + "[^aeiouy]*"; // consonant sequence 70 | var V = v + "[aeiou]*"; // vowel sequence 71 | 72 | var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 73 | var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 74 | var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 75 | var s_v = "^(" + C + ")?" + v; // vowel in stem 76 | 77 | this.stemWord = function (w) { 78 | var stem; 79 | var suffix; 80 | var firstch; 81 | var origword = w; 82 | 83 | if (w.length < 3) 84 | return w; 85 | 86 | var re; 87 | var re2; 88 | var re3; 89 | var re4; 90 | 91 | firstch = w.substr(0,1); 92 | if (firstch == "y") 93 | w = firstch.toUpperCase() + w.substr(1); 94 | 95 | // Step 1a 96 | re = /^(.+?)(ss|i)es$/; 97 | re2 = /^(.+?)([^s])s$/; 98 | 99 | if (re.test(w)) 100 | w = w.replace(re,"$1$2"); 101 | else if (re2.test(w)) 102 | w = w.replace(re2,"$1$2"); 103 | 104 | // Step 1b 105 | re = /^(.+?)eed$/; 106 | re2 = /^(.+?)(ed|ing)$/; 107 | if (re.test(w)) { 108 | var fp = re.exec(w); 109 | re = new RegExp(mgr0); 110 | if (re.test(fp[1])) { 111 | re = /.$/; 112 | w = w.replace(re,""); 113 | } 114 | } 115 | else if (re2.test(w)) { 116 | var fp = re2.exec(w); 117 | stem = fp[1]; 118 | re2 = new RegExp(s_v); 119 | if (re2.test(stem)) { 120 | w = stem; 121 | re2 = /(at|bl|iz)$/; 122 | re3 = new RegExp("([^aeiouylsz])\\1$"); 123 | re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 124 | if (re2.test(w)) 125 | w = w + "e"; 126 | else if (re3.test(w)) { 127 | re = /.$/; 128 | w = w.replace(re,""); 129 | } 130 | else if (re4.test(w)) 131 | w = w + "e"; 132 | } 133 | } 134 | 135 | // Step 1c 136 | re = /^(.+?)y$/; 137 | if (re.test(w)) { 138 | var fp = re.exec(w); 139 | stem = fp[1]; 140 | re = new RegExp(s_v); 141 | if (re.test(stem)) 142 | w = stem + "i"; 143 | } 144 | 145 | // Step 2 146 | re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; 147 | if (re.test(w)) { 148 | var fp = re.exec(w); 149 | stem = fp[1]; 150 | suffix = fp[2]; 151 | re = new RegExp(mgr0); 152 | if (re.test(stem)) 153 | w = stem + step2list[suffix]; 154 | } 155 | 156 | // Step 3 157 | re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; 158 | if (re.test(w)) { 159 | var fp = re.exec(w); 160 | stem = fp[1]; 161 | suffix = fp[2]; 162 | re = new RegExp(mgr0); 163 | if (re.test(stem)) 164 | w = stem + step3list[suffix]; 165 | } 166 | 167 | // Step 4 168 | re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; 169 | re2 = /^(.+?)(s|t)(ion)$/; 170 | if (re.test(w)) { 171 | var fp = re.exec(w); 172 | stem = fp[1]; 173 | re = new RegExp(mgr1); 174 | if (re.test(stem)) 175 | w = stem; 176 | } 177 | else if (re2.test(w)) { 178 | var fp = re2.exec(w); 179 | stem = fp[1] + fp[2]; 180 | re2 = new RegExp(mgr1); 181 | if (re2.test(stem)) 182 | w = stem; 183 | } 184 | 185 | // Step 5 186 | re = /^(.+?)e$/; 187 | if (re.test(w)) { 188 | var fp = re.exec(w); 189 | stem = fp[1]; 190 | re = new RegExp(mgr1); 191 | re2 = new RegExp(meq1); 192 | re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); 193 | if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) 194 | w = stem; 195 | } 196 | re = /ll$/; 197 | re2 = new RegExp(mgr1); 198 | if (re.test(w) && re2.test(w)) { 199 | re = /.$/; 200 | w = w.replace(re,""); 201 | } 202 | 203 | // and turn initial Y back to y 204 | if (firstch == "y") 205 | w = firstch.toLowerCase() + w.substr(1); 206 | return w; 207 | } 208 | } 209 | 210 | 211 | /** 212 | * Search Module 213 | */ 214 | var Search = { 215 | 216 | _index : null, 217 | _queued_query : null, 218 | _pulse_status : -1, 219 | 220 | init : function() { 221 | var params = $.getQueryParameters(); 222 | if (params.q) { 223 | var query = params.q[0]; 224 | $('input[name="q"]')[0].value = query; 225 | this.performSearch(query); 226 | } 227 | }, 228 | 229 | /** 230 | * Sets the index 231 | */ 232 | setIndex : function(index) { 233 | var q; 234 | this._index = index; 235 | if ((q = this._queued_query) !== null) { 236 | this._queued_query = null; 237 | Search.query(q); 238 | } 239 | }, 240 | 241 | hasIndex : function() { 242 | return this._index !== null; 243 | }, 244 | 245 | deferQuery : function(query) { 246 | this._queued_query = query; 247 | }, 248 | 249 | stopPulse : function() { 250 | this._pulse_status = 0; 251 | }, 252 | 253 | startPulse : function() { 254 | if (this._pulse_status >= 0) 255 | return; 256 | function pulse() { 257 | Search._pulse_status = (Search._pulse_status + 1) % 4; 258 | var dotString = ''; 259 | for (var i = 0; i < Search._pulse_status; i++) 260 | dotString += '.'; 261 | Search.dots.text(dotString); 262 | if (Search._pulse_status > -1) 263 | window.setTimeout(pulse, 500); 264 | }; 265 | pulse(); 266 | }, 267 | 268 | /** 269 | * perform a search for something 270 | */ 271 | performSearch : function(query) { 272 | // create the required interface elements 273 | this.out = $('#search-results'); 274 | this.title = $('

' + _('Searching') + '

').appendTo(this.out); 275 | this.dots = $('').appendTo(this.title); 276 | this.status = $('

').appendTo(this.out); 277 | this.output = $('