Index: sasmodels/models/guinier_porod.py
===================================================================
--- sasmodels/models/guinier_porod.py	(revision cc3fac6c527f2d51c2acdc5679ef024eb46ddf95)
+++ sasmodels/models/guinier_porod.py	(revision cc3fac6c527f2d51c2acdc5679ef024eb46ddf95)
@@ -0,0 +1,130 @@
+# pylint: disable=line-too-long
+r"""
+Calculates the scattering for a generalized Guinier/power law object.
+This is an empirical model that can be used to determine the size
+and dimensionality of scattering objects, including asymmetric objects
+such as rods or platelets, and shapes intermediate between spheres
+and rods or between rods and platelets.
+
+Definition
+----------
+
+The following functional form is used
+
+.. math::
+    I(q) = \frac{G}{Q^s} \ \exp{\left[ \frac{-Q^2R_g^2}{3-s} \right]} \textrm{ for } Q \leq Q_1
+    \\
+    I(q) = D / Q^m \textrm{ for } Q \geq Q_1
+
+This is based on the generalized Guinier law for such elongated objects
+(see the Glatter reference below). For 3D globular objects (such as spheres), $s = 0$
+and one recovers the standard Guinier formula.
+For 2D symmetry (such as for rods) $s = 1$,
+and for 1D symmetry (such as for lamellae or platelets) $s = 2$.
+A dimensionality parameter ($3-s$) is thus defined, and is 3 for spherical objects,
+2 for rods, and 1 for plates.
+
+Enforcing the continuity of the Guinier and Porod functions and their derivatives yields
+
+.. math::
+    Q_1 = \frac{1}{R_g} \sqrt{(m-s)(3-s)/2}
+
+and
+
+.. math::
+    D = G \ \exp{ \left[ \frac{-Q_1^2 R_g^2}{3-s} \right]} \ Q_1^{m-s}
+      = \frac{G}{R_g^{m-s}} \ \exp{\left[  -\frac{m-s}{2} \right]} \left( \frac{(m-s)(3-s)}{2} \right)^{\frac{m-s}{2}}
+
+
+Note that the radius-of-gyration for a sphere of radius R is given by $R_g = R \sqrt(3/5)$.
+
+The cross-sectional radius-of-gyration for a randomly oriented cylinder
+of radius R is given by $R_g = R / \sqrt(2)$.
+
+The cross-sectional radius-of-gyration of a randomly oriented lamella
+of thickness $T$ is given by $R_g = T / \sqrt(12)$.
+
+For 2D data: The 2D scattering intensity is calculated in the same way as 1D,
+where the q vector is defined as
+
+.. math::
+    q = \sqrt{q_x^2+q_y^2}
+
+.. image:: img/guinier_porod_model.jpg
+
+    Figure 1: Guinier-Porod model for $R_g=100$ |Ang|, $s=1$, $m=3$, and $background=0.1$.
+
+
+Reference
+---------
+
+A Guinier, G Fournet, Small-Angle Scattering of X-Rays, John Wiley and Sons, New York, (1955)
+
+O Glatter, O Kratky, Small-Angle X-Ray Scattering, Academic Press (1982)
+Check out Chapter 4 on Data Treatment, pages 155-156.
+"""
+
+from numpy import inf, sqrt, power, exp
+
+name = "guinier_porod"
+title = "Guinier-Porod function"
+description = """\
+         I(q) = scale/q^s* exp ( - R_g^2 q^2 / (3-s) ) for q<= ql
+         = scale/q^m*exp((-ql^2*Rg^2)/(3-s))*ql^(m-s) for q>=ql
+                        where ql = sqrt((m-s)(3-s)/2)/Rg.
+                        List of parameters:
+                        scale = Guinier Scale
+                        s = Dimension Variable
+                        Rg = Radius of Gyration [A] 
+                        m = Porod Exponent
+                        background  = Background [1/cm]"""
+
+category = "shape-independent"
+
+# pylint: disable=bad-whitespace, line-too-long
+#             ["name", "units", default, [lower, upper], "type","description"],
+parameters = [["rg", "Ang", 60.0, [0, inf], "", "Radius of gyration"],
+              ["s",  "",    1.0,  [0, inf], "", "Dimension variable"],
+              ["m",  "",    3.0,  [0, inf], "", "Porod exponent"]]
+# pylint: enable=bad-whitespace, line-too-long
+
+
+def Iq(q, rg, s, m):
+    """
+    @param q: Input q-value
+    """
+    n = 3.0 - s
+
+    # Take care of the singular points
+    if rg <= 0.0:
+        return 0.0
+    if (n-3.0+m) <= 0.0:
+        return 0.0
+
+    # Do the calculation and return the function value
+    q1 = sqrt((n-3.0+m)*n/2.0)/rg
+    if q < q1:
+        F = (1.0/power(q,(3.0-n)))*exp((-q*q*rg*rg)/n) 
+    else:
+        F = (1.0/power(q, m))*exp(-(n-3.0+m)/2.0)*power(((n-3.0+m)*n/2.0),
+                                    ((n-3.0+m)/2.0))/power(rg,(n-3.0+m))
+    return F
+
+Iq.vectorized = False  # Iq accepts an array of q values
+
+def Iqxy(qx, qy, *args):
+    """
+    @param qx:   Input q_x-value
+    @param qy:   Input q_y-value
+    @param args: Remaining arguments
+    """
+    return Iq(sqrt(qx ** 2 + qy ** 2), *args)
+
+Iqxy.vectorized = False # Iqxy accepts an array of qx, qy values
+
+demo = dict(scale=1.5, background=0.5, rg=60, s=1.0, m=3.0)
+
+oldname = "GuinierPorodModel"
+oldpars = dict(scale='scale', background='background', s='dim', m='m', rg='rg')
+
+tests = [[{'scale': 1.5, 'background':0.5}, 0.04, 5.290096890253155]]
Index: sasmodels/models/porod.py
===================================================================
--- sasmodels/models/porod.py	(revision 16bb4337d95ce5f999aec885781f06ccb80925c0)
+++ sasmodels/models/porod.py	(revision cc3fac6c527f2d51c2acdc5679ef024eb46ddf95)
@@ -13,5 +13,5 @@
 of the sample, and $\Delta\rho$ is the contrast factor.
 
-For 2D data: The 2D scattering intensity is calculated in the same way as 1D, 
+For 2D data: The 2D scattering intensity is calculated in the same way as 1D,
 where the q vector is defined as
 
