Spline::Spline(const Point input[], int inputLength) : params(new Param[inputLength]), c(¶ms[0]), paramsLength(inputLength) { assert(inputLength > 2); std::vector<double> dxs(inputLength - 1); std::vector<double> ms(inputLength - 1); // Get consecutive differences and slopes for (int i = 0; i < inputLength - 1; i++) { assert(input[i].x < input[i + 1].x); const double dx = input[i + 1].x - input[i].x; const double dy = input[i + 1].y - input[i].y; dxs[i] = dx; ms[i] = dy/dx; } // Get degree-1 coefficients params[0].c = ms[0]; for (int i = 1; i < inputLength - 1; i++) { const double m = ms[i - 1]; const double mNext = ms[i]; if (m * mNext <= 0) { params[i].c = 0.0; } else { const double dx = dxs[i - 1]; const double dxNext = dxs[i]; const double common = dx + dxNext; params[i].c = 3.0 * common / ((common + dxNext) / m + (common + dx) / mNext); } } params[inputLength - 1].c = ms[inputLength - 2]; // Get degree-2 and degree-3 coefficients for (int i = 0; i < inputLength - 1; i++) { params[i].x1 = input[i].x; params[i].x2 = input[i + 1].x; params[i].d = input[i].y; const double c1 = params[i].c; const double m = ms[i]; const double invDx = 1.0 / dxs[i]; const double common = c1 + params[i + 1].c - m - m; params[i].b = (m - c1 - common) * invDx; params[i].a = common * invDx * invDx; } // Fix the value ranges, because we interpolate outside original bounds if necessary. params[0].x1 = std::numeric_limits<double>::min(); params[inputLength - 2].x2 = std::numeric_limits<double>::max(); }
arma::field<arma::Cube<double>> Softmax::backProp(const arma::field<arma::Cube<double>>& deltas) { arma::field<arma::Cube<double>> dxs(deltas.size()); for (unsigned int i=0; i<deltas.size(); ++i) { const arma::Col<double>& y = mYs[i]; arma::Mat<double> jacobian = -y*y.t(); jacobian.diag() = y%(1.0-y); arma::Col<double> delta = deltas[i]; arma::Col<double> dx = jacobian*delta; dxs[i] = arma::Cube<double>((const double*) dx.begin(), 1, 1, dx.size()); } return dxs; }