static void admm_normaleq(void* _data, float* _dst, const float* _src) { struct admm_normaleq_data* data = _data; long dims[1] = { data->N }; //float* tmp = md_alloc_sameplace(1, dims, FL_SIZE, _src ); md_clear(1, dims, _dst, sizeof(float)); for (unsigned int i = 0; i < data->num_funs; i++) { data->ops[i].normal(data->ops[i].data, data->tmp, _src); if ((NULL != data->Aop) && (NULL != data->Aop_data)) md_axpy(1, dims, _dst, data->rho, data->tmp); else md_add(1, dims, _dst, _dst, data->tmp); } if ((NULL != data->Aop) && (NULL != data->Aop_data)) { data->Aop(data->Aop_data, data->tmp, _src); md_add(1, dims, _dst, _dst, data->tmp); } //md_free( tmp ); }
/** * Proximal function for f(z) = 0.5 || y - A z ||_2^2. * Solution is (A^H A + (1/mu) I)z = A^H y + (1/mu)(x_plus_u) * * @param prox_data should be of type prox_normaleq_data * @param mu proximal penalty * @param z output * @param x_plus_u input */ static void prox_normaleq_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u) { struct prox_normaleq_data* pdata = CAST_DOWN(prox_normaleq_data, prox_data); if (0 == mu) { md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE); } else { float rho = 1. / mu; float* b = md_alloc_sameplace(1, MD_DIMS(pdata->size), FL_SIZE, x_plus_u); md_copy(1, MD_DIMS(pdata->size), b, pdata->adj, FL_SIZE); md_axpy(1, MD_DIMS(pdata->size), b, rho, x_plus_u); if (NULL == pdata->op->norm_inv) { struct iter_conjgrad_conf* cg_conf = pdata->cgconf; cg_conf->l2lambda = rho; iter_conjgrad(CAST_UP(cg_conf), pdata->op->normal, NULL, pdata->size, z, (float*)b, NULL); } else { linop_norm_inv_iter((struct linop_s*)pdata->op, rho, z, b); } md_free(b); } }
static void normaleq_l2_apply(const void* _data, unsigned int N, void* args[N]) { const struct lsqr_data* data = _data; assert(2 == N); linop_normal_unchecked(data->model_op, args[0], args[1]); md_axpy(1, MD_DIMS(data->size), args[0], data->l2_lambda, args[1]); }
/** * Proximal function for f(z) = lambda / 2 || y - z ||_2^2. * Solution is z = (mu * lambda * y + x_plus_u) / (mu * lambda + 1) * * @param prox_data should be of type prox_leastsquares_data * @param mu proximal penalty * @param z output * @param x_plus_u input */ static void prox_leastsquares_fun(const operator_data_t* prox_data, float mu, float* z, const float* x_plus_u) { struct prox_leastsquares_data* pdata = CAST_DOWN(prox_leastsquares_data, prox_data); md_copy(1, MD_DIMS(pdata->size), z, x_plus_u, FL_SIZE); if (0 != mu) { if (NULL != pdata->y) md_axpy(1, MD_DIMS(pdata->size), z, pdata->lambda * mu, pdata->y); md_smul(1, MD_DIMS(pdata->size), z, z, 1. / (mu * pdata->lambda + 1)); } }