# Path: bssrdf_estimate/tools/solvers/polyfit.py
# def cubic_fitting(ps):
#     n_div = 5
# 
#     x0 = ps.copy()
# 
#     # Linear interpolation
#     ps = map(lambda p0, p1: linear_interpolation(p0, p1, n_div), ps, ps[1:])
#     ps = np.array(list(chain(*ps)))
# 
#     def func(x, ps = ps):
#         w_d = 1.0
#         w_p = 10.0
#         w_s = 1.0e-4
# 
#         # Hermite interpolation
#         _ , xs = spline_interpolate(x, n_div)
# 
#         cost = 0.0
# 
#         # Error between original
#         cost += w_d * sum(map(lambda x, p: (x - p) ** 2.0, xs, ps))
# 
#         # Penalize increase
#         cost += w_p * sum(map(lambda x0, x1: (x0 - x1) ** 2.0 if x0 - x1 < 0.0 else 0.0, xs, xs[1:]))
#         cost += w_p * xs[-1] * xs[-1] if xs[-1] < 0.0 else 0.0
# 
#         # Penalize smoothness
#         cost += w_s * sum(map(lambda x0, x1, x2: (x0 - 2.0 * x1 + x2) ** 2.0, xs, xs[1:], xs[2:]))
# 
#         return cost
# 
#     opt = { 'maxiter': 2000, 'disp': False }
#     res = sp.optimize.minimize(func, x0, method='L-BFGS-B', options=opt)
# 
#     if not res.success:
#         print('[ERROR] failed: %s' % res.message)
#     else:
#         print('[INFO] L-BFGS-B Success!!')
# 
#     return res.x


import numpy as np
import scipy as sp
import scipy.sparse
import scipy.sparse.linalg
import matplotlib.pyplot as plt
from .polyfit import cubic_fitting
#-*- coding: utf-8 -*-




class SolveUnc(object):
    def __init__(self, A, b):
        ATA = np.dot(A.T, A)
        ATb = np.dot(A.T, b)

        self.xx = np.zeros(ATb.shape)
        for c in range(ATb.shape[1]):
            self.xx[:,c] = sp.sparse.linalg.qmr(ATA, ATb[:,c])[0]

        self.save_curve_figure('result/Rd_curve_before_smoothing.png', self.xx)

        for c in range(ATb.shape[1]):

# Path: bssrdf_estimate/tools/solvers/polyfit.py
# def cubic_fitting(ps):
#     n_div = 5
# 
#     x0 = ps.copy()
# 
#     # Linear interpolation
#     ps = map(lambda p0, p1: linear_interpolation(p0, p1, n_div), ps, ps[1:])
#     ps = np.array(list(chain(*ps)))
# 
#     def func(x, ps = ps):
#         w_d = 1.0
#         w_p = 10.0
#         w_s = 1.0e-4
# 
#         # Hermite interpolation
#         _ , xs = spline_interpolate(x, n_div)
# 
#         cost = 0.0
# 
#         # Error between original
#         cost += w_d * sum(map(lambda x, p: (x - p) ** 2.0, xs, ps))
# 
#         # Penalize increase
#         cost += w_p * sum(map(lambda x0, x1: (x0 - x1) ** 2.0 if x0 - x1 < 0.0 else 0.0, xs, xs[1:]))
#         cost += w_p * xs[-1] * xs[-1] if xs[-1] < 0.0 else 0.0
# 
#         # Penalize smoothness
#         cost += w_s * sum(map(lambda x0, x1, x2: (x0 - 2.0 * x1 + x2) ** 2.0, xs, xs[1:], xs[2:]))
# 
#         return cost
# 
#     opt = { 'maxiter': 2000, 'disp': False }
#     res = sp.optimize.minimize(func, x0, method='L-BFGS-B', options=opt)
# 
#     if not res.success:
#         print('[ERROR] failed: %s' % res.message)
#     else:
#         print('[INFO] L-BFGS-B Success!!')
# 
#     return res.x


# Path: bssrdf_estimate/tools/solvers/solve_unc.py
import numpy as np
import scipy as sp
import scipy.sparse
import scipy.sparse.linalg
import matplotlib.pyplot as plt
from .polyfit import cubic_fitting

#-*- coding: utf-8 -*-




class SolveUnc(object):
    def __init__(self, A, b):
        ATA = np.dot(A.T, A)
        ATb = np.dot(A.T, b)

        self.xx = np.zeros(ATb.shape)
        for c in range(ATb.shape[1]):
            self.xx[:,c] = sp.sparse.linalg.qmr(ATA, ATb[:,c])[0]

        self.save_curve_figure('result/Rd_curve_before_smoothing.png', self.xx)

        for c in range(ATb.shape[1]):

            self.xx[:,c] = cubic_fitting(self.xx[:,c])