void KronekerProductVectorMatrix(dvector* v, matrix* m, array* t) { size_t i, j, k; double res; for(i = 0; i < v->size; i++){ for(j = 0; j < m->row; j++){ for(k = 0; k < m->col; k++){ res = getDVectorValue(v, i)*getMatrixValue(m, j, k); if(_isnan_(res) || _isinf_(res)){ setArrayValue(t, k, i, j, 0.f); } else{ setArrayValue(t, k, i, j, res); } } } } }
void MatrixOpData::cleanUp(double offsetScale) { const ArrayDouble & a = getArray(); const ArrayDouble::Values & m = a.getValues(); const unsigned long dim = a.getLength(); // Estimate the magnitude of the matrix. double max_val = 0.; for (unsigned long i = 0; i<dim; ++i) { for (unsigned long j = 0; j<dim; ++j) { const double val = fabs(m[i * dim + j]); max_val = max_val > val ? max_val : val; } } // Determine an absolute tolerance. // TODO: For double matrices a smaller tolerance could be used. However we // have matrices that may have been quantized to less than double precision // either from being written to files or via the factories that take float // args. In any case, the tolerance is small enough to pick up anything // that would be significant in the context of color management. const double scale = max_val > 1e-4 ? max_val : 1e-4; const double abs_tol = scale * 1e-6; // Replace values that are close to integers by exact values. for (unsigned long i = 0; i<dim; ++i) { for (unsigned long j = 0; j<dim; ++j) { const double val = m[i * dim + j]; const double round_val = round(val); const double diff = fabs(val - round_val); if (diff < abs_tol) { setArrayValue(i * dim + j, round_val); } } } // Do likewise for the offsets. const double scale2 = offsetScale > 1e-4 ? offsetScale : 1e-4; const double abs_tol2 = scale2 * 1e-6; for (unsigned long i = 0; i<dim; ++i) { const double val = getOffsets()[i]; const double round_val = round(val); const double diff = fabs(val - round_val); if (diff < abs_tol2) { setOffsetValue(i, round_val); } } }
void ArrayCopy(array* asrc, array** adst) { size_t i, j, k; if((*adst)->m == NULL){ (*adst)->order = asrc->order; (*adst)->m = xmalloc(sizeof(matrix*)*asrc->order); for(k = 0; k < asrc->order; k++){ NewMatrix(&((*adst)->m[k]), asrc->m[k]->row, asrc->m[k]->col); } } else{ if(asrc->order != (*adst)->order){ /* resize the order */ (*adst)->m = xrealloc((*adst)->m, sizeof(array*)*asrc->order); } /*chek and resize the matrix for each order if is necessary */ for(k = 0; k < asrc->order; k++){ if(asrc->m[k]->row != (*adst)->m[k]->row || asrc->m[k]->col != (*adst)->m[k]->col){ (*adst)->m[k]->row = asrc->m[k]->row; (*adst)->m[k]->col = asrc->m[k]->col; (*adst)->m[k]->data = xrealloc((*adst)->m[k]->data, sizeof(double*)*asrc->m[k]->row); for(i = 0; i < asrc->m[k]->row; i++){ (*adst)->m[k]->data[i] = xrealloc((*adst)->m[k]->data[i], sizeof(double)*asrc->m[k]->col); } } } } /*copy the data...*/ for(k = 0; k < asrc->order; k++){ for(i = 0; i < asrc->m[k]->row; i++){ for(j = 0; j < asrc->m[k]->col; j++){ setArrayValue((*adst), k, i, j, getArrayValue(asrc, k, i, j)); } } } }