def f(params, r0, xx0, yy0, xx20, zz0):  # Minimization target
    '''
    :param params: [ds, theta_1, psi_1,..]
    :param ds: float
    :return:
    '''
    if len(params) % 2 == 1:
        ds = params[0]
        thetas = params[1::2]
        psis = params[2::2]
    else:
        raise ValueError

    rs = curve3d.build_curve(r0, ds, thetas, psis)  # reconstructed curve
    xx, yy, zz = rs.T

    xy_penalty = projection_penalty(xx, yy, xx0, yy0)
    xz_penalty = projection_penalty(xx, zz, xx20, zz0)
    # angle_penalty =
    # MAYBE: normalize by projection length?
    penalty = xy_penalty + xz_penalty
    return penalty
def f(params, r0, xx0, yy0, xx20, zz0, dxx0, dyy0, dxx20, dzz0, points_weight,
      smooth_weight, xy_weight_fraction, info):  # Minimization target
    '''
    :param params: [ds, theta_1, psi_1,..]
    :param points_weight: [1]
    :param smooth_weight: [1]
    :param xy_weight_fraction: from 0 to 1; 0.5 for equal treatment of xy and xz; best - set dependent on length ratio
    :param info: dict with fields 'print': True or False; 'num_evals' - set to zero
    :return:
    '''
    if len(params) % 2 == 1:
        ds = params[0]
        thetas = params[1::2]
        psis = params[2::2]
    else:
        raise ValueError

    rs = curve3d.build_curve(r0, ds, thetas, psis)  # reconstructed curve
    xx, yy, zz = rs.T
    length = ds * len(thetas)  # Use it to normalize projection penalties
    xy_penalty = projection_penalty(xx, yy, xx0, yy0, dxx0, dyy0,
                                    points_weight, length)
    xz_penalty = projection_penalty(xx, zz, xx20, zz0, dxx20, dzz0,
                                    points_weight, length)
    smooth_penalty = smooth_weight * smoothness_penalty(thetas, psis)
    penalty = xy_weight_fraction * xy_penalty + (
        1 - xy_weight_fraction) * xz_penalty + smooth_penalty

    ## Print info
    if info['print'] == True:
        info['num_evals'] += 1
        if info['num_evals'] == 1 or info['num_evals'] % 5000 == 0:
            print("{:<10}{}".format('num_evals', 'penalty'))
        if info['num_evals'] == 1 or info['num_evals'] % 500 == 0:
            print("{:<10}{:.3g}".format(info['num_evals'], penalty))
    return penalty
예제 #3
0
def get_rr(phi):
    basis = [b(phi) for b in basis_functions]
    psis = basis @ psi_coeffs
    thetas = basis @ theta_coeffs
    rr = curve3d.build_curve((0, 0, 0), ds, thetas, psis)
    return rr
        txs_new = pchip_interpolate(slist_new_real, txs_new, slist_new)
        tys_new = pchip_interpolate(slist_new_real, tys_new, slist_new)
        tzs_new = pchip_interpolate(slist_new_real, tzs_new, slist_new)

        # Reconstruct angles
        ds_theta_psi_new_list = np.array([
            curve3d.get_ds_angles(tx, ty, tz)
            for (tx, ty, tz) in zip(txs_new, tys_new, tzs_new)
        ])
        tangent_lengths, thetas_new, psis_new = ds_theta_psi_new_list.T

    if counter > 0:
        print("Counter:", counter)

    rr_new = curve3d.build_curve((0, 0, 0), ds_new, thetas_new, psis_new)
    xx_new, yy_new, zz_new = rr_new.T

    xlist_new.append(xx_new)
    ylist_new.append(yy_new)
    zlist_new.append(zz_new)
    thetas_new_list.append(thetas_new)
    psis_new_list.append(psis_new)

### Fix angle discontinuity
# Similar to unwrap
# For better Fourier expansion quality


def find_optimal_shift(val, val2, period=2 * pi):
    shifts = np.array([-1, 0, 1]) * period
                             {
                                 'num_evals': 0,
                                 'print': True
                             }),
                       tol=eps,
                       options={'disp': True},
                       method=method)
    time_spent = time.time() - start

    print("Time spent:", datetime.timedelta(seconds=time_spent))

    ds = res.x[0]
    thetas = res.x[1::2]
    psis = res.x[2::2]

    rr = curve3d.build_curve(r0, ds, thetas, psis)
    xx, yy, zz = rr.T

    x.append(xx)
    y.append(yy)
    z.append(zz)
    np.savetxt(os.path.join(output_folder, 'x-{}.dat'.format(iframe_raw)), xx)
    np.savetxt(os.path.join(output_folder, 'y-{}.dat'.format(iframe_raw)), yy)
    np.savetxt(os.path.join(output_folder, 'z-{}.dat'.format(iframe_raw)), zz)
    np.savetxt(
        os.path.join(output_folder_angles, 'ds-{}.dat'.format(iframe_raw)),
        [ds])
    np.savetxt(
        os.path.join(output_folder_angles, 'theta-{}.dat'.format(iframe_raw)),
        thetas)
    np.savetxt(
# ds0 = L_true / M * (1 + k * 2 * (random.random() - 0.5))
# params0 = [ds0]
# for n in range(M):
#     params0.append(sp.arctan(1 / 2) + k * 2 * (random.random() - 0.5)) # theta
#     params0.append(0 + k * 2 * (random.random() - 0.5)) # psi

## Initialize with initial curve + noise
rr0 = np.array((xx0, yy0, zz0)).T
_, ds0, thetas0, psis0 = curve3d.reconstruct_angles(rr0, M - 1)
params0 = [ds0 * (1 + k * 2 * (random.random() - 0.5))]
for theta, psi in zip(thetas0, psis0):
    params0.append(theta + k * 2 * (random.random() - 0.5)) # theta
    params0.append(psi + k * 2 * (random.random() - 0.5)) # psi


rr_init = curve3d.build_curve(r0, ds0, params0[1::2], params0[2::2])
xx_init, yy_init, zz_init = rr_init.T

print("Initial parameters:")
print(params0)

method = None  # "Powell"  #

start = time.time()
print("Optimization in progress...")
res = opt.minimize(f, params0, args=(r0, xx1, yy1, xx21, zz1), tol=10 ** -4, options={'disp': True}, method=method)
time_spent = time.time() - start

print("Done. Time spent:", datetime.timedelta(seconds=time_spent))

ds = res.x[0]