Difference between revisions of "Source Inversion (FEniCS/Casadi)"

From mintOC
Jump to: navigation, search
(Solution)
Line 251: Line 251:
  
 
<pre>
 
<pre>
# x        u         u0
+
#       x        u       u0       u_d
         0    19.845  18.7521
+
         0    19.845  18.7521   18.7182
0.0078125  20.0001  18.8986
+
0.0078125  20.0001  18.8986   18.8645
  0.015625  20.1551  19.0451
+
  0.015625  20.1551  19.0451   19.0107
0.0234375  20.3101  19.1916
+
0.0234375  20.3101  19.1916   19.1569
   0.03125  20.4652  19.3381
+
   0.03125  20.4652  19.3381   19.3032
0.0390625  20.6202  19.4846
+
0.0390625  20.6202  19.4846   19.4494
  0.046875  20.7752  19.6311
+
  0.046875  20.7752  19.6311   19.5956
0.0546875  20.9303  19.7776
+
0.0546875  20.9303  19.7776   19.7419
   0.0625  21.0853  19.9241
+
   0.0625  21.0853  19.9241   19.8881
0.0703125  21.2403  20.0706
+
0.0703125  21.2403  20.0706   20.0343
  0.078125  21.3953  20.2171
+
  0.078125  21.3953  20.2171   20.1806
0.0859375  21.5503  20.3635
+
0.0859375  21.5503  20.3635   20.3268
   0.09375  21.7053    20.51
+
   0.09375  21.7053    20.51   20.473
  0.101562  21.8603  20.6565
+
  0.101562  21.8603  20.6565   20.6193
  0.109375  22.0153  20.8029
+
  0.109375  22.0153  20.8029   20.7655
  0.117188  22.1702  20.9494
+
  0.117188  22.1702  20.9494   20.9117
     0.125  22.3251  21.0958
+
     0.125  22.3251  21.0958   21.0579
  0.132812  22.4799  21.2422
+
  0.132812  22.4799  21.2422   21.2042
  0.140625  22.6347  21.3886
+
  0.140625  22.6347  21.3886   21.3504
  0.148438  22.7894  21.5349
+
  0.148438  22.7894  21.5349   21.4966
   0.15625    22.944  21.6812
+
   0.15625    22.944  21.6812   21.6428
  0.164062  23.0985  21.8275
+
  0.164062  23.0985  21.8275   21.7889
  0.171875  23.2528  21.9737
+
  0.171875  23.2528  21.9737   21.9351
  0.179688    23.407  22.1197
+
  0.179688    23.407  22.1197   22.0812
   0.1875    23.561  22.2657
+
   0.1875    23.561  22.2657   22.2273
  0.195312  23.7146  22.4116
+
  0.195312  23.7146  22.4116   22.3733
  0.203125    23.868  22.5573
+
  0.203125    23.868  22.5573   22.5193
  0.210938  24.0209  22.7028
+
  0.210938  24.0209  22.7028   22.6652
   0.21875  24.1734    22.848
+
   0.21875  24.1734    22.848   22.811
  0.226562  24.3254    22.993
+
  0.226562  24.3254    22.993   22.9567
  0.234375  24.4766  23.1377
+
  0.234375  24.4766  23.1377   23.1022
  0.242188  24.6271    23.282
+
  0.242188  24.6271    23.282   23.2476
     0.25  24.7767  23.4259
+
     0.25  24.7767  23.4259   23.3927
  0.257812  24.9252  23.5692
+
  0.257812  24.9252  23.5692   23.5376
  0.265625  25.0725  23.7119
+
  0.265625  25.0725  23.7119   23.6822
  0.273438  25.2184    23.854
+
  0.273438  25.2184    23.854   23.8263
   0.28125  25.3627  23.9952
+
   0.28125  25.3627  23.9952     23.97
  0.289062  25.5052  24.1355
+
  0.289062  25.5052  24.1355   24.1131
  0.296875  25.6457  24.2748
+
  0.296875  25.6457  24.2748   24.2556
  0.304688  25.7839    24.413
+
  0.304688  25.7839    24.413   24.3972
   0.3125  25.9196  24.5498
+
   0.3125  25.9196  24.5498   24.538
  0.320312  26.0525  24.6852
+
  0.320312  26.0525  24.6852   24.6777
  0.328125  26.1823  24.8189
+
  0.328125  26.1823  24.8189   24.8162
  0.335938  26.3088  24.9509
+
  0.335938  26.3088  24.9509   24.9533
   0.34375  26.4316  25.0809
+
   0.34375  26.4316  25.0809   25.0889
  0.351562  26.5505  25.2087
+
  0.351562  26.5505  25.2087   25.2226
  0.359375  26.6651  25.3342
+
  0.359375  26.6651  25.3342   25.3542
  0.367188  26.7753  25.4572
+
  0.367188  26.7753  25.4572   25.4836
     0.375  26.8807  25.5774
+
     0.375  26.8807  25.5774   25.6105
  0.382812  26.9811  25.6947
+
  0.382812  26.9811  25.6947   25.7346
  0.390625  27.0762  25.8089
+
  0.390625  27.0762  25.8089   25.8556
  0.398438  27.1659  25.9198
+
  0.398438  27.1659  25.9198   25.9733
   0.40625  27.2499  26.0271
+
   0.40625  27.2499  26.0271   26.0873
  0.414062  27.3281  26.1308
+
  0.414062  27.3281  26.1308   26.1973
  0.421875  27.4004  26.2305
+
  0.421875  27.4004  26.2305   26.3032
  0.429688  27.4666  26.3262
+
  0.429688  27.4666  26.3262   26.4046
   0.4375  27.5268  26.4177
+
   0.4375  27.5268  26.4177   26.5012
  0.445312  27.5809  26.5047
+
  0.445312  27.5809  26.5047   26.5927
  0.453125  27.6289  26.5873
+
  0.453125  27.6289  26.5873   26.6791
  0.460938  27.6708  26.6652
+
  0.460938  27.6708  26.6652   26.7599
   0.46875  27.7069  26.7384
+
   0.46875  27.7069  26.7384   26.8351
  0.476562  27.7371  26.8066
+
  0.476562  27.7371  26.8066   26.9045
  0.484375  27.7617    26.87
+
  0.484375  27.7617    26.87   26.968
  0.492188  27.7808  26.9283
+
  0.492188  27.7808  26.9283   27.0255
       0.5  27.7947  26.9816
+
       0.5  27.7947  26.9816   27.0768
  0.507812  27.8035  27.0298
+
  0.507812  27.8035  27.0298   27.1221
  0.515625  27.8076  27.0729
+
  0.515625  27.8076  27.0729   27.1613
  0.523438  27.8072  27.1109
+
  0.523438  27.8072  27.1109   27.1945
   0.53125  27.8026  27.1438
+
   0.53125  27.8026  27.1438   27.2217
  0.539062    27.794  27.1718
+
  0.539062    27.794  27.1718   27.2431
  0.546875  27.7818  27.1948
+
  0.546875  27.7818  27.1948   27.2589
  0.554688  27.7662    27.213
+
  0.554688  27.7662    27.213   27.2692
   0.5625  27.7476  27.2264
+
   0.5625  27.7476  27.2264   27.2743
  0.570312  27.7261  27.2352
+
  0.570312  27.7261  27.2352   27.2743
  0.578125  27.7021  27.2395
+
  0.578125  27.7021  27.2395   27.2696
  0.585938  27.6759  27.2394
+
  0.585938  27.6759  27.2394   27.2603
   0.59375  27.6476  27.2351
+
   0.59375  27.6476  27.2351   27.2469
  0.601562  27.6174  27.2269
+
  0.601562  27.6174  27.2269   27.2295
  0.609375  27.5857  27.2147
+
  0.609375  27.5857  27.2147   27.2084
  0.617188  27.5525    27.199
+
  0.617188  27.5525    27.199   27.184
     0.625  27.5181  27.1797
+
     0.625  27.5181  27.1797   27.1565
  0.632812  27.4826  27.1573
+
  0.632812  27.4826  27.1573   27.1261
  0.640625  27.4461  27.1317
+
  0.640625  27.4461  27.1317   27.0932
  0.648438  27.4087  27.1032
+
  0.648438  27.4087  27.1032   27.058
   0.65625  27.3706  27.0721
+
   0.65625  27.3706  27.0721   27.0207
  0.664062  27.3318  27.0385
+
  0.664062  27.3318  27.0385   26.9815
  0.671875  27.2924  27.0025
+
  0.671875  27.2924  27.0025   26.9406
  0.679688  27.2525  26.9644
+
  0.679688  27.2525  26.9644   26.8983
   0.6875  27.2119  26.9242
+
   0.6875  27.2119  26.9242   26.8545
  0.695312  27.1709  26.8821
+
  0.695312  27.1709  26.8821   26.8096
  0.703125  27.1293  26.8383
+
  0.703125  27.1293  26.8383   26.7635
  0.710938  27.0871  26.7928
+
  0.710938  27.0871  26.7928   26.7164
   0.71875  27.0443  26.7457
+
   0.71875  27.0443  26.7457   26.6683
  0.726562  27.0008  26.6971
+
  0.726562  27.0008  26.6971   26.6193
  0.734375  26.9566  26.6469
+
  0.734375  26.9566  26.6469   26.5693
  0.742188  26.9115  26.5953
+
  0.742188  26.9115  26.5953   26.5184
     0.75  26.8654  26.5422
+
     0.75  26.8654  26.5422   26.4666
  0.757812  26.8183  26.4875
+
  0.757812  26.8183  26.4875   26.4137
  0.765625  26.7699  26.4312
+
  0.765625  26.7699  26.4312   26.3598
  0.773438    26.72  26.3732
+
  0.773438    26.72  26.3732   26.3046
   0.78125  26.6686  26.3135
+
   0.78125  26.6686  26.3135   26.2481
  0.789062  26.6153  26.2517
+
  0.789062  26.6153  26.2517   26.1902
  0.796875    26.56    26.188
+
  0.796875    26.56    26.188   26.1306
  0.804688  26.5024  26.1219
+
  0.804688  26.5024  26.1219   26.0691
   0.8125  26.4423  26.0534
+
   0.8125  26.4423  26.0534   26.0057
  0.820312  26.3794  25.9822
+
  0.820312  26.3794  25.9822   25.9399
  0.828125  26.3134  25.9082
+
  0.828125  26.3134  25.9082   25.8717
  0.835938    26.244  25.8311
+
  0.835938    26.244  25.8311   25.8007
   0.84375    26.171  25.7506
+
   0.84375    26.171  25.7506   25.7267
  0.851562    26.094  25.6665
+
  0.851562    26.094  25.6665   25.6494
  0.859375  26.0129  25.5785
+
  0.859375  26.0129  25.5785   25.5685
  0.867188  25.9272  25.4865
+
  0.867188  25.9272  25.4865   25.4837
     0.875  25.8368  25.3902
+
     0.875  25.8368  25.3902   25.3947
  0.882812  25.7413  25.2893
+
  0.882812  25.7413  25.2893   25.3013
  0.890625  25.6406  25.1837
+
  0.890625  25.6406  25.1837   25.2032
  0.898438  25.5345  25.0732
+
  0.898438  25.5345  25.0732   25.1002
   0.90625  25.4227  24.9576
+
   0.90625  25.4227  24.9576   24.9919
  0.914062    25.305  24.8368
+
  0.914062    25.305  24.8368   24.8782
  0.921875  25.1815  24.7107
+
  0.921875  25.1815  24.7107   24.7589
  0.929688  25.0519  24.5791
+
  0.929688  25.0519  24.5791   24.6338
   0.9375  24.9162  24.4421
+
   0.9375  24.9162  24.4421   24.5029
  0.945312  24.7745  24.2996
+
  0.945312  24.7745  24.2996   24.3659
  0.953125  24.6267  24.1516
+
  0.953125  24.6267  24.1516   24.2228
  0.960938  24.4728  23.9982
+
  0.960938  24.4728  23.9982   24.0737
   0.96875    24.313  23.8395
+
   0.96875    24.313  23.8395   23.9184
  0.976562  24.1474  23.6756
+
  0.976562  24.1474  23.6756   23.7572
  0.984375  23.9762  23.5067
+
  0.984375  23.9762  23.5067   23.5899
  0.992188  23.7995  23.3328
+
  0.992188  23.7995  23.3328   23.4169
         1  23.6175  23.1542
+
         1  23.6175  23.1542   23.2381
 
</pre>
 
</pre>
 
   
 
   
 
[[Category:Casadi]]
 
[[Category:Casadi]]

Revision as of 23:41, 12 January 2016

This page contains a discretized version of the mixed integer PDE constrained optimization problem Source Inversion in CasADi 2.4.3 format. The weak version of the problem was discretized using finite element methods (via FEniCS) using first-degree Lagrangian elements on an equidistant mesh with 128 cells.

CasADi

from dolfin import *
 
import math
import numpy
import scipy, scipy.sparse
import casadi
 
 
# Simple Branch and Bound solver
def solve_bnb(solver, root, integers):
    # Initialize the node queue
    Q = [(numpy.inf, root)]
 
    # Global solution data
    x_opt = None
    f_opt = numpy.inf
 
    # Continuous solution data
    x0 = None
    f0 = numpy.inf
 
    # Main loop
    seqnum = 0
    while Q:
        seqnum += 1
 
        # Extract node with lowest lower bound and check if fathoming is necessary
        # (should not happen)
        node = Q.pop()
        if f_opt < numpy.inf and node[0] >= f_opt:
            print "Node %4d (%4d left): %9g >= %9g - PRE-FATHOM" % (seqnum, len(Q), node[0], f_opt)
            continue
        node = node[1]
 
        # Solve the node
        result = solver(node)
 
        # Local solution data
        x = result['x']
        f = result['f'].get()[0]
 
        # Store continuous solution data if none has been stored yet
        if x0 is None:
            x0 = casadi.DMatrix(x)
            f0 = f
 
        # Check if branch can be fathomed
        if f >= f_opt:
            print "Node %4d (%4d left): %9g >= %9g - POST-FATHOM" % (seqnum, len(Q), f, f_opt)
            continue
 
        # Check for violations of integrality (fixed tolerance 1e-5)
        viol = [abs(casadi.floor(x[i] + 0.5) - x[i]) for i in integers]
        idx  = [(integers[i], viol[i]) for i in range(len(integers)) if viol[i] > 1e-5]
        if not idx:
            # Register new global solution
            x_opt = x
            f_opt = f
 
            # Cull the branch and bound tree
            pre  = len(Q)
            Q    = [n for n in Q if n[0] < f_opt]
            post = len(Q)
 
            print "Node %4d (%4d left): f_opt = %9g - *** SOLUTION *** (%d culled)" % (seqnum, len(Q), f, pre - post)
        else:
            # Branch on first violation
            idx = idx[0][0]
 
            # Generate two new nodes (could reuse node structure)
            ln = {
                'x0':     casadi.DMatrix(x),
                'lbx':    node['lbx'],
                'ubx':    casadi.DMatrix(node['ubx']),
                'lbg':    node['lbg'],
                'ubg':    node['ubg'],
                'lam_x0': casadi.DMatrix(result['lam_x']),
                'lam_g0': casadi.DMatrix(result['lam_g'])
            }
            un = {
                'x0':     casadi.DMatrix(x),
                'lbx':    casadi.DMatrix(node['lbx']),
                'ubx':    node['ubx'],
                'lbg':    node['lbg'],
                'ubg':    node['ubg'],
                'lam_x0': casadi.DMatrix(result['lam_x']),
                'lam_g0': casadi.DMatrix(result['lam_g'])
            }
 
            ln['ubx'][idx] = casadi.floor(x[idx])
            un['lbx'][idx] = casadi.ceil(x[idx])
 
            lower_node = (f, ln)
            upper_node = (f, un)
 
            # Insert new nodes in queue (inefficient for large queues)
            Q.extend([lower_node, upper_node])
            Q.sort(cmp=lambda x,y: cmp(y[0], x[0]))
            print "Node %4d (%4d left): %9g - BRANCH ON %d" % (seqnum, len(Q), f, idx)
 
    return {
        'x0': x0,
        'f0': f0,
        'x': x_opt,
        'f': f_opt
    }
 
 
# Converts FEniCS matrix to scipy.sparse.coo_matrix
def matrix_to_coo(A, shape=None):
    nnz = A.nnz()
    col = numpy.empty(nnz, dtype='uint64')
    row = numpy.empty(nnz, dtype='uint64')
    val = numpy.empty(nnz)
 
    if shape is None:
        shape = (A.size(0), A.size(1))
 
    it = 0
    for i in range(A.size(0)):
        col_local, val_local = A.getrow(i)
        nnz_local = col_local.shape[0]
 
        col[it:it+nnz_local] = col_local[:]
        row[it:it+nnz_local] = i
        val[it:it+nnz_local] = val_local[:]
        it                  += nnz_local
 
    return scipy.sparse.coo_matrix((val, (row, col)), shape=shape)
 
 
# Returns FEniCS expression for elementary source term
def source_term(x0):
    return Expression("100.0 * exp(-pow(x[0] - x0, 2) / 0.02)", x0=x0)
 
# Grid resolutions
nx = 128
nu = 8
 
# Generate mesh and function space
mesh = UnitIntervalMesh(nx)
V    = FunctionSpace(mesh, 'CG', 1)
 
# Define the bilinear form and assemble it
u = TrialFunction(V)
v = TestFunction(V)
a = inner(grad(u), grad(v)) * dx + u * v * ds
A = assemble(a)
 
# Create the linear form for the exact source term and perform assembly
f = source_term(3.0 / math.pi) + source_term(0.5)
L = f * v * dx
b = assemble(L)
 
# Solve for the reference solution
u_ref = Function(V)
solve(A, u_ref.vector(), b)
 
# Define the control grid and the elementary source terms
ctrl_grid = numpy.linspace(0.0, 1.0, num=nu+1)[:-1]
ctrl_grid += 0.5 * ctrl_grid[1]
src_expr  = [source_term(x0) for x0 in ctrl_grid]
 
# Assemble the linear forms corresponding to the elementary source terms and
# construct the second half of the coefficient matrix
b = [assemble(-f * v * dx) for f in src_expr]
B = scipy.column_stack([v.array() for v in b])
 
# Construct the full coefficient matrix
C = scipy.sparse.vstack([
    scipy.sparse.hstack([matrix_to_coo(A), B]),
    scipy.sparse.coo_matrix(([1.0]*nu, ([0]*nu, [V.dim() + i for i in range(nu)])), shape=(1, V.dim() + nu))
])
 
# Transfer the optimization constraints to CasADi
C  = casadi.DMatrix(C)
lb = casadi.DMatrix.zeros(C.shape[0], 1)
ub = casadi.DMatrix.zeros(C.shape[0], 1)
 
lb[-1] = 0.0
ub[-1] = 5.0
 
lbx = numpy.array([-numpy.inf]*V.dim() + [0.0]*nu)
ubx = numpy.array([ numpy.inf]*V.dim() + [1.0]*nu)
 
# Define the objective functional and assemble it
u     = Function(V)
J     = (u_ref - u)**2 * dx
dJdu  = derivative(J, u)
dJdu2 = derivative(dJdu, u)
 
H = casadi.DMatrix(matrix_to_coo(assemble(dJdu2), shape=(V.dim() + nu, V.dim() + nu)))
g = casadi.DMatrix(numpy.concatenate((assemble(dJdu).array(), [0.0]*nu)))
c = assemble(J)
 
# Build the CasADi NLP
x   = casadi.MX.sym('X', V.dim() + nu)
nlp = casadi.MXFunction('nlp',
    casadi.nlpIn(x=x),
    casadi.nlpOut(
        f=0.5*casadi.quad_form(x, H) + casadi.inner_prod(g, x) + c,
        g=casadi.mul(C, x)
    ))
 
# Build NLP solver
solver = casadi.NlpSolver('solver', 'ipopt', nlp, {
    'print_level': 0,
    'print_time':  False
})
result = solve_bnb(solver, {
    'lbx': lbx,
    'ubx': ubx,
    'lbg': lb,
    'ubg': ub
}, range(V.dim(), V.dim() + nu))
 
# Evaluate result
print ""
print "----------------------------"
print " f = %g" % result['f']
 
u.vector()[:] = result['x'][:V.dim()].toArray()[:,0]

Results

Node solutions are calculated using IPOPT (3.12, default settings, using linear solver MUMPS on Ubuntu 15.10 for x86-64 with Linux 4.2.0-19-generic, Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz, 16 GB RAM). The objective function value is 0.858837. The integer solution is found after processing 25 nodes.

Solution

The following is a Gnuplot compatible tabular version of the control data determined by the solver:

# x       w         w0
   0.0625         0 2.91549e-08
   0.1875         0 2.75108e-08
   0.3125         0 6.746e-08
   0.4375         1   0.46917
   0.5625         0  0.543817
   0.6875         0 1.33205e-07
   0.8125         0 1.51069e-07
   0.9375         1  0.897707

The following is a Gnuplot compatible tabular version of the solution found using FEM approximations:

#       x         u        u0       u_d
        0    19.845   18.7521   18.7182
0.0078125   20.0001   18.8986   18.8645
 0.015625   20.1551   19.0451   19.0107
0.0234375   20.3101   19.1916   19.1569
  0.03125   20.4652   19.3381   19.3032
0.0390625   20.6202   19.4846   19.4494
 0.046875   20.7752   19.6311   19.5956
0.0546875   20.9303   19.7776   19.7419
   0.0625   21.0853   19.9241   19.8881
0.0703125   21.2403   20.0706   20.0343
 0.078125   21.3953   20.2171   20.1806
0.0859375   21.5503   20.3635   20.3268
  0.09375   21.7053     20.51    20.473
 0.101562   21.8603   20.6565   20.6193
 0.109375   22.0153   20.8029   20.7655
 0.117188   22.1702   20.9494   20.9117
    0.125   22.3251   21.0958   21.0579
 0.132812   22.4799   21.2422   21.2042
 0.140625   22.6347   21.3886   21.3504
 0.148438   22.7894   21.5349   21.4966
  0.15625    22.944   21.6812   21.6428
 0.164062   23.0985   21.8275   21.7889
 0.171875   23.2528   21.9737   21.9351
 0.179688    23.407   22.1197   22.0812
   0.1875    23.561   22.2657   22.2273
 0.195312   23.7146   22.4116   22.3733
 0.203125    23.868   22.5573   22.5193
 0.210938   24.0209   22.7028   22.6652
  0.21875   24.1734    22.848    22.811
 0.226562   24.3254    22.993   22.9567
 0.234375   24.4766   23.1377   23.1022
 0.242188   24.6271    23.282   23.2476
     0.25   24.7767   23.4259   23.3927
 0.257812   24.9252   23.5692   23.5376
 0.265625   25.0725   23.7119   23.6822
 0.273438   25.2184    23.854   23.8263
  0.28125   25.3627   23.9952     23.97
 0.289062   25.5052   24.1355   24.1131
 0.296875   25.6457   24.2748   24.2556
 0.304688   25.7839    24.413   24.3972
   0.3125   25.9196   24.5498    24.538
 0.320312   26.0525   24.6852   24.6777
 0.328125   26.1823   24.8189   24.8162
 0.335938   26.3088   24.9509   24.9533
  0.34375   26.4316   25.0809   25.0889
 0.351562   26.5505   25.2087   25.2226
 0.359375   26.6651   25.3342   25.3542
 0.367188   26.7753   25.4572   25.4836
    0.375   26.8807   25.5774   25.6105
 0.382812   26.9811   25.6947   25.7346
 0.390625   27.0762   25.8089   25.8556
 0.398438   27.1659   25.9198   25.9733
  0.40625   27.2499   26.0271   26.0873
 0.414062   27.3281   26.1308   26.1973
 0.421875   27.4004   26.2305   26.3032
 0.429688   27.4666   26.3262   26.4046
   0.4375   27.5268   26.4177   26.5012
 0.445312   27.5809   26.5047   26.5927
 0.453125   27.6289   26.5873   26.6791
 0.460938   27.6708   26.6652   26.7599
  0.46875   27.7069   26.7384   26.8351
 0.476562   27.7371   26.8066   26.9045
 0.484375   27.7617     26.87    26.968
 0.492188   27.7808   26.9283   27.0255
      0.5   27.7947   26.9816   27.0768
 0.507812   27.8035   27.0298   27.1221
 0.515625   27.8076   27.0729   27.1613
 0.523438   27.8072   27.1109   27.1945
  0.53125   27.8026   27.1438   27.2217
 0.539062    27.794   27.1718   27.2431
 0.546875   27.7818   27.1948   27.2589
 0.554688   27.7662    27.213   27.2692
   0.5625   27.7476   27.2264   27.2743
 0.570312   27.7261   27.2352   27.2743
 0.578125   27.7021   27.2395   27.2696
 0.585938   27.6759   27.2394   27.2603
  0.59375   27.6476   27.2351   27.2469
 0.601562   27.6174   27.2269   27.2295
 0.609375   27.5857   27.2147   27.2084
 0.617188   27.5525    27.199    27.184
    0.625   27.5181   27.1797   27.1565
 0.632812   27.4826   27.1573   27.1261
 0.640625   27.4461   27.1317   27.0932
 0.648438   27.4087   27.1032    27.058
  0.65625   27.3706   27.0721   27.0207
 0.664062   27.3318   27.0385   26.9815
 0.671875   27.2924   27.0025   26.9406
 0.679688   27.2525   26.9644   26.8983
   0.6875   27.2119   26.9242   26.8545
 0.695312   27.1709   26.8821   26.8096
 0.703125   27.1293   26.8383   26.7635
 0.710938   27.0871   26.7928   26.7164
  0.71875   27.0443   26.7457   26.6683
 0.726562   27.0008   26.6971   26.6193
 0.734375   26.9566   26.6469   26.5693
 0.742188   26.9115   26.5953   26.5184
     0.75   26.8654   26.5422   26.4666
 0.757812   26.8183   26.4875   26.4137
 0.765625   26.7699   26.4312   26.3598
 0.773438     26.72   26.3732   26.3046
  0.78125   26.6686   26.3135   26.2481
 0.789062   26.6153   26.2517   26.1902
 0.796875     26.56    26.188   26.1306
 0.804688   26.5024   26.1219   26.0691
   0.8125   26.4423   26.0534   26.0057
 0.820312   26.3794   25.9822   25.9399
 0.828125   26.3134   25.9082   25.8717
 0.835938    26.244   25.8311   25.8007
  0.84375    26.171   25.7506   25.7267
 0.851562    26.094   25.6665   25.6494
 0.859375   26.0129   25.5785   25.5685
 0.867188   25.9272   25.4865   25.4837
    0.875   25.8368   25.3902   25.3947
 0.882812   25.7413   25.2893   25.3013
 0.890625   25.6406   25.1837   25.2032
 0.898438   25.5345   25.0732   25.1002
  0.90625   25.4227   24.9576   24.9919
 0.914062    25.305   24.8368   24.8782
 0.921875   25.1815   24.7107   24.7589
 0.929688   25.0519   24.5791   24.6338
   0.9375   24.9162   24.4421   24.5029
 0.945312   24.7745   24.2996   24.3659
 0.953125   24.6267   24.1516   24.2228
 0.960938   24.4728   23.9982   24.0737
  0.96875    24.313   23.8395   23.9184
 0.976562   24.1474   23.6756   23.7572
 0.984375   23.9762   23.5067   23.5899
 0.992188   23.7995   23.3328   23.4169
        1   23.6175   23.1542   23.2381