T LpIneq(size_t m, size_t n) { std::vector<T> A(m * n); std::vector<T> x(n); std::vector<T> y(m); std::default_random_engine generator; std::uniform_real_distribution<T> u_dist(static_cast<T>(0), static_cast<T>(1)); // Generate A according to: // A = [-1 / n *rand(m - n, n); -eye(n)] for (unsigned int i = 0; i < (m - n) * n; ++i) A[i] = -static_cast<T>(1) / static_cast<T>(n) * u_dist(generator); for (unsigned int i = static_cast<unsigned int>((m - n) * n); i < m * n; ++i) A[i] = (i - (m - n) * n) % (n + 1) == 0 ? -1 : 0; PogsData<T, T*> pogs_data(A.data(), m, n); pogs_data.x = x.data(); pogs_data.y = y.data(); // Generate b according to: // b = A * rand(n, 1) + 0.2 * rand(m, 1) pogs_data.f.reserve(m); for (unsigned int i = 0; i < m; ++i) { T b_i = static_cast<T>(0); for (unsigned int j = 0; j < n; ++j) b_i += A[i * n + j] * u_dist(generator); b_i += static_cast<T>(0.2) * u_dist(generator); pogs_data.f.emplace_back(kIndLe0, static_cast<T>(1), b_i); } // Generate c according to: // c = rand(n, 1) pogs_data.g.reserve(n); for (unsigned int i = 0; i < n; ++i) pogs_data.g.emplace_back(kIdentity, u_dist(generator)); T t = timer<T>(); Pogs(&pogs_data); return timer<T>() - t; }
void SolverWrap(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { size_t m = mxGetM(prhs[0]); size_t n = mxGetN(prhs[0]); // Convert column major (matlab) to row major (c++). T* A = new T[m * n]; ColToRowMajor(reinterpret_cast<T*>(mxGetPr(prhs[0])), m, n, A); // Initialize Pogs data structure PogsData<T, T*> pogs_data(A, m, n); pogs_data.f.reserve(m); pogs_data.g.reserve(n); pogs_data.x = reinterpret_cast<T*>(mxGetPr(plhs[0])); if (nlhs >= 2) pogs_data.y = reinterpret_cast<T*>(mxGetPr(plhs[1])); // Populate parameters. int err = 0; if (nrhs == 4) err = PopulateParams(prhs[3], &pogs_data); // Populate function objects. if (err == 0) err = PopulateFunctionObj("f", prhs[1], m, &pogs_data.f); if (err == 0) err = PopulateFunctionObj("g", prhs[2], n, &pogs_data.g); // Run solver. if (err == 0) Pogs(&pogs_data); if (nlhs >= 3) reinterpret_cast<T*>(mxGetPr(plhs[2]))[0] = pogs_data.optval; delete [] A; }
double Logistic(size_t m, size_t n) { std::vector<T> A(m * (n + 1)); std::vector<T> d(m); std::vector<T> x(n + 1); std::vector<T> y(m); std::default_random_engine generator; std::uniform_real_distribution<T> u_dist(static_cast<T>(0), static_cast<T>(1)); std::normal_distribution<T> n_dist(static_cast<T>(0), static_cast<T>(1)); for (unsigned int i = 0; i < m; ++i) { for (unsigned int j = 0; j < n; ++j) A[i * (n + 1) + j] = n_dist(generator); A[i * (n + 1) + n] = 1; } std::vector<T> x_true(n + 1); for (unsigned int i = 0; i < n; ++i) x_true[i] = u_dist(generator) < 0.8 ? 0 : n_dist(generator) / n; x_true[n] = n_dist(generator) / n; #pragma omp parallel for for (unsigned int i = 0; i < m; ++i) { d[i] = 0; for (unsigned int j = 0; j < n + 1; ++j) // u += A[i + j * m] * x_true[j]; d[i] += A[i * n + j] * x_true[j]; } for (unsigned int i = 0; i < m; ++i) d[i] = 1 / (1 + std::exp(-d[i])) > u_dist(generator); T lambda_max = static_cast<T>(0); #pragma omp parallel for reduction(max : lambda_max) for (unsigned int j = 0; j < n; ++j) { T u = 0; for (unsigned int i = 0; i < m; ++i) // u += A[i * n + j] * (static_cast<T>(0.5) - d[i]); u += A[i + j * m] * (static_cast<T>(0.5) - d[i]); lambda_max = std::max(lambda_max, std::abs(u)); } Dense<T, ROW> A_(A.data()); PogsData<T, Dense<T, ROW>> pogs_data(A_, m, n + 1); pogs_data.x = x.data(); pogs_data.y = y.data(); pogs_data.f.reserve(m); for (unsigned int i = 0; i < m; ++i) pogs_data.f.emplace_back(kLogistic, 1, 0, 1, -d[i]); pogs_data.g.reserve(n + 1); for (unsigned int i = 0; i < n; ++i) pogs_data.g.emplace_back(kAbs, static_cast<T>(0.5) * lambda_max); pogs_data.g.emplace_back(kZero); double t = timer<double>(); Pogs(&pogs_data); return timer<double>() - t; }