print 'initial lengths\n', cp.c_lengths
    print 'initial vectors\n', cp.c_vectors
    print 'initial G\n', cp.get_G(x0)
    print 'initial G_du\n', cp.get_G_du(x0)

    def f(x):
        x = x.reshape(cp.n_n, cp.n_d)
        X = cp.get_new_nodes(x)
        caf.X_arr = [X[1]]
        dist2 = np.linalg.norm(caf.d_arr)
        return dist2

    d0 = f(x0)
    eps = d0 * 1e-4

    x_sol = fmin_slsqp(f, x0, f_eqcons = cp.get_G, fprime_eqcons = cp.get_G_du, acc = 1e-8,
                       epsilon = eps)

    print 'x_sol', x_sol

    print 'dist', f(x_sol)
    print 'G', cp.get_G(x_sol)
    print 'lengths', cp.get_new_lengths(x_sol)
    print 'nodes', cp.get_new_nodes(x_sol)

    # 1) introduce the mapping association to the surface
    #    similar to cnstr_face
    # 2) define a rule for mountains and valley nodes.
    # 3) visualize attractor / control surface.
        x = x.reshape(cp.n_n, cp.n_d)
        X = cp.get_new_nodes(x)
        caf.X_arr = [X[2]]
        dist2 = np.linalg.norm(caf.d_arr)
        return dist2

    d0 = f(x0)
    eps = d0 * 1e-4

    x_sol = fmin_slsqp(f, x0, f_eqcons=cp.get_G, fprime_eqcons=cp.get_G_du, acc=1e-8, epsilon=eps)

    print "x_sol", x_sol

    print "dist", f(x_sol)
    print "G", cp.get_G(x_sol)
    print "lengths", cp.get_new_lengths(x_sol)
    print "nodes", cp.get_new_nodes(x_sol)

    # Visualization

    cp.add_fold_step(x_sol)

    cpv = CreasePatternView(data=cp, show_cnstr=True)

    cpv.configure_traits()

    # 1) introduce the mapping association to the surface
    #    similar to cnstr_face
    # 2) define a rule for mountains and valley nodes.
    # 3) visualize attractor / control surface.