/** * Create the augmented knots vector and fill in matrix Xt with the spline basis vectors */ void basis_splines_endreps_local_v2(float *knots, int n_knots, int order, int *boundaries, int n_boundaries, Eigen::MatrixXf &Xt) { assert(n_boundaries == 2 && boundaries[0] < boundaries[1]); int n_rows = boundaries[1] - boundaries[0]; // this is frames so evaluate at each frame we'll need int n_cols = n_knots + order; // number of basis vectors we'll have at end Xt.resize(n_cols, n_rows); // swapped to transpose later. This order lets us use it as a scratch space Xt.fill(0); int n_std_knots = n_knots + 2 * order; float std_knots[n_std_knots]; // Repeat the boundary knots on there to ensure linear out side of knots for (int i = 0; i < order; i++) { std_knots[i] = boundaries[0]; } // Our original boundary knots here for (int i = 0; i < n_knots; i++) { std_knots[i+order] = knots[i]; } // Repeat the boundary knots on there to ensure linear out side of knots for (int i = 0; i < order; i++) { std_knots[i+order+n_knots] = boundaries[1]; } // Evaluate our basis splines at each frame. for (int i = boundaries[0]; i < boundaries[1]; i++) { int idx = -1; // find index such that i >= knots[idx] && i < knots[idx+1] float *val = std::upper_bound(std_knots, std_knots + n_std_knots - 1, 1.0f * i); idx = val - std_knots - 1; assert(idx >= 0); float *f = Xt.data() + i * n_cols + idx - (order - 1); //column offset basis_spline_xi_v2(std_knots, n_std_knots, order, idx, i, f); } // Put in our conventional format where each column is a basis vector Xt.transposeInPlace(); }
void VertexBufferObject::update(const Eigen::MatrixXf& M) { assert(id != 0); glBindBuffer(GL_ARRAY_BUFFER, id); glBufferData(GL_ARRAY_BUFFER, sizeof(float)*M.size(), M.data(), GL_DYNAMIC_DRAW); rows = M.rows(); cols = M.cols(); check_gl_error(); }
void PlotBorderPixels(Eigen::MatrixXf& mat, const Graph& graph, WeightMap weights, BorderPixelMap border_pixels) { float* p = mat.data(); for(auto eid : as_range(boost::edges(graph))) { float v = weights[eid]; for(unsigned int pid : boost::get(border_pixels, eid)) { p[pid] = v; } } }
void run () { const double tol = argument[2]; #ifdef MRTRIX_UPDATED_API const Eigen::MatrixXf in1 = load_matrix<float> (argument[0]); const Eigen::MatrixXf in2 = load_matrix<float> (argument[1]); if (in1.rows() != in2.rows() || in1.cols() != in2.cols()) throw Exception ("matrices \"" + Path::basename (argument[0]) + "\" and \"" + Path::basename (argument[1]) + "\" do not have matching sizes" " (" + str(in1.rows()) + "x" + str(in1.cols()) + " vs " + str(in2.rows()) + "x" + str(in2.cols()) + ")"); const size_t numel = in1.size(); for (size_t i = 0; i != numel; ++i) { if (std::abs (*(in1.data()+i) - *(in2.data()+i)) > tol) throw Exception ("matrices \"" + Path::basename (argument[0]) + "\" and \"" + Path::basename (argument[1]) + " do not match within specified precision of " + str(tol) + " (" + str(*(in1.data()+i)) + " vs " + str(*(in2.data()+i)) + ")"); } #else Math::Matrix<float> in1, in2; in1.load (argument[0]); in2.load (argument[1]); if (in1.rows() != in2.rows() || in1.columns() != in2.columns()) throw Exception ("matrices \"" + Path::basename (argument[0]) + "\" and \"" + Path::basename (argument[1]) + "\" do not have matching sizes" " (" + str(in1.rows()) + "x" + str(in1.columns()) + " vs " + str(in2.rows()) + "x" + str(in2.columns()) + ")"); const size_t numel = in1.rows() * in1.columns(); for (size_t i = 0; i != numel; ++i) { if (std::abs (*(in1.ptr()+i) - *(in2.ptr()+i)) > tol) throw Exception ("matrices \"" + Path::basename (argument[0]) + "\" and \"" + Path::basename (argument[1]) + " do not match within specified precision of " + str(tol) + " (" + str(*(in1.ptr()+i)) + " vs " + str(*(in2.ptr()+i)) + ")"); } #endif CONSOLE ("data checked OK"); }
void load( Archive & ar, Eigen::MatrixXf & t, const unsigned int file_version ) { int n0; ar >> BOOST_SERIALIZATION_NVP( n0 ); int n1; ar >> BOOST_SERIALIZATION_NVP( n1 ); t.resize( n0, n1 ); ar >> make_array( t.data(), t.rows()*t.cols() ); }
void save( Archive & ar, const Eigen::MatrixXf & t, const unsigned int file_version ) { int n0 = t.rows(); ar << BOOST_SERIALIZATION_NVP( n0 ); int n1 = t.cols(); ar << BOOST_SERIALIZATION_NVP( n1 ); ar << boost::serialization::make_array( t.data(), t.rows()*t.cols() ); }
void AdaptClusterRadiusBySaliency(ImagePoints& points, const Eigen::MatrixXf& saliency, const Parameters& opt) { // FIXME what is base? const float base = 0.5f; auto it_p = points.begin(); auto it_p_end = points.end(); auto it_s = saliency.data(); for(; it_p!=it_p_end; ++it_p, ++it_s) { it_p->cluster_radius_px *= std::pow(base, -*it_s); } }
void run () { const Eigen::MatrixXf in1 = load_matrix<float> (argument[0]); const Eigen::MatrixXf in2 = load_matrix<float> (argument[1]); if (in1.rows() != in2.rows() || in1.cols() != in2.cols()) throw Exception ("matrices \"" + Path::basename (argument[0]) + "\" and \"" + Path::basename (argument[1]) + "\" do not have matching sizes" " (" + str(in1.rows()) + "x" + str(in1.cols()) + " vs " + str(in2.rows()) + "x" + str(in2.cols()) + ")"); const size_t numel = in1.size(); auto opt = get_options ("frac"); if (opt.size()) { const double tol = opt[0][0]; for (size_t i = 0; i != numel; ++i) { if (std::abs ((*(in1.data()+i) - *(in2.data()+i)) / (0.5 * (*(in1.data()+i) + *(in2.data()+i)))) > tol) throw Exception ("matrices \"" + Path::basename (argument[0]) + "\" and \"" + Path::basename (argument[1]) + " do not match within fractional precision of " + str(tol) + " (" + str(*(in1.data()+i)) + " vs " + str(*(in2.data()+i)) + ")"); } } else { double tol = 0.0; opt = get_options ("abs"); if (opt.size()) tol = opt[0][0]; for (size_t i = 0; i != numel; ++i) { if (std::abs (*(in1.data()+i) - *(in2.data()+i)) > tol) throw Exception ("matrices \"" + Path::basename (argument[0]) + "\" and \"" + Path::basename (argument[1]) + " do not match within absolute precision of " + str(tol) + " (" + str(*(in1.data()+i)) + " vs " + str(*(in2.data()+i)) + ")"); } } CONSOLE ("data checked OK"); }
void FiffStreamThread::sendRawBuffer(Eigen::MatrixXf m_matRawData) { if(m_bIsSendingRawBuffer) { // qDebug() << "Send RawBuffer to client"; m_qMutex.lock(); FiffStream t_FiffStreamOut(&m_qSendBlock, QIODevice::WriteOnly); t_FiffStreamOut.write_float(FIFF_DATA_BUFFER,m_matRawData.data(),m_matRawData.rows()*m_matRawData.cols()); m_qMutex.unlock(); } // else // { // qDebug() << "Send RawBuffer is not activated"; // } }
void readLDRFile(const std::string& file, Eigen::MatrixXf& data) { std::ifstream in(file.c_str(), std::ios::in | std::ios::binary); in.seekg(0, std::ios::end); int size = in.tellg(); in.seekg(0, std::ios::beg); int num_floats = size / (sizeof(float) / sizeof (char)); int num_rows = num_floats / 6; data.resize(6, num_rows); float* row_arr = new float[num_floats]; in.read((char*)(row_arr), size); float* data_arr = data.data(); for (int k = 0; k < num_floats; k++) data_arr[k] = row_arr[k]; data.transposeInPlace(); in.close(); }
int main(int argc, char* argv[]) { try { // Select a device and display arrayfire info int device = argc > 1 ? std::atoi(argv[1]) : 0; af::setDevice(device); af::info(); Eigen::MatrixXf C = Eigen::MatrixXf::Random(1e4, 50); // host array af::array in(1e4, 50, C.data()); // copy host data to device af::array u, s_vec, vt; svd(u, s_vec, vt, in); } catch (af::exception& e) { std::cout << e.what() << '\n'; return 1; } return 0; }
void CloudAnalyzer2D::examinePointEvidence() { pointEvidence.clear(); for (int r = 0; r < R->size(); ++r) { Eigen::MatrixXf total = Eigen::MatrixXf::Zero(newRows, newCols); #pragma omp parallel for schedule(static) for (int i = 0; i < total.cols(); ++i) { for (int j = 0; j < total.rows(); ++j) { for (int k = 0; k < numZ; ++k) { const Eigen::Vector3d coord(i, j, k); const Eigen::Vector3i src = (R->at(r) * (coord - newZZ) + zeroZero) .unaryExpr([](auto v) { return std::round(v); }) .cast<int>(); if (src[0] < 0 || src[0] >= numX || src[1] < 0 || src[1] >= numY || src[2] < 0 || src[2] >= numZ) continue; if (pointInVoxel->at(src)) ++total(j, i); } } } double average, sigma; const float *dataPtr = total.data(); std::tie(average, sigma) = place::aveAndStdev( dataPtr, dataPtr + total.size(), [](auto v) { return v; }, [](auto v) -> bool { return v; }); cv::Mat heatMap(newRows, newCols, CV_8UC1, cv::Scalar::all(255)); for (int j = 0; j < heatMap.rows; ++j) { uchar *dst = heatMap.ptr<uchar>(j); for (int i = 0; i < heatMap.cols; ++i) { const double count = total(j, i); if (count > 0) { const int gray = cv::saturate_cast<uchar>( 255.0 * ((count - average - sigma) / (3.0 * sigma) - 0.0 * sigma)); dst[i] = 255 - gray; } } } if (FLAGS_preview && doors->size()) { std::cout << "Number of doors: " << doors->size() << std::endl; cv::Mat out; cv::cvtColor(heatMap, out, CV_GRAY2BGR); cv::Mat_<cv::Vec3b> _out = out; for (auto &d : *doors) { Eigen::Vector3d bl = d.corner * FLAGS_scale; bl[1] *= -1.0; bl = R->at(r).inverse() * bl; Eigen::Vector3d xAxis = d.xAxis; xAxis[1] *= -1.0; xAxis = R->at(r).inverse() * xAxis; Eigen::Vector3d zAxis = d.zAxis; zAxis[1] *= -1.0; zAxis = R->at(r).inverse() * zAxis; double w = d.w * FLAGS_scale; auto color = randomColor(); for (int i = 0; i < w; ++i) { Eigen::Vector3d pix = (bl + i * xAxis + i * zAxis + newZZ).unaryExpr([](auto v) { return std::round(v); }); if (pix[0] < 0 || pix[0] >= out.cols || pix[1] < 0 || pix[1] >= out.rows) continue; _out(pix[1], pix[0]) = color; } } cv::rectshow(out); } pointEvidence.push_back(heatMap); if (FLAGS_preview) cv::rectshow(heatMap); } }
std::vector<EigenComponent> solver_magma(const Eigen::MatrixXf& A, unsigned int num_ev) { static MagmaSpectralSolver magma; magma_int_t N = A.rows(); std::cout << "MAGMA Solver N=" << N << std::endl; magma_timestr_t start, end; float gpu_time; start = get_current_time(); magma_int_t info; const float *h_A = A.data(); float *h_R, *h_work; float *w1; magma_int_t *iwork; const char *uplo = MagmaLowerStr; const char *jobz = MagmaVecStr; /* Query for workspace sizes */ float aux_work[1]; magma_int_t aux_iwork[1]; std::cout << "Querying workspace size" << std::endl; magma_ssyevd( jobz[0], uplo[0], N, h_R, N, w1, aux_work, -1, aux_iwork, -1, &info ); magma_int_t lwork = (magma_int_t) aux_work[0]; magma_int_t liwork = aux_iwork[0]; std::cout << lwork << " " << liwork << std::endl; std::cout << "Allocating" << std::endl; w1 = magma.malloc<float>(N ); h_R = magma.hostmalloc<float>(N*N); h_work = magma.hostmalloc<float>(lwork); iwork = magma.malloc<magma_int_t>(liwork); std::cout << "Copying" << std::endl; slacpy_( MagmaUpperLowerStr, &N, &N, h_A, &N, h_R, &N ); std::cout << "Solving" << std::endl; magma_ssyevd(jobz[0], uplo[0], N, h_R, N, w1, h_work, lwork, iwork, liwork, &info); std::cout << "Collecting" << std::endl; // save eigenvectors and eigenvalues std::vector<EigenComponent> solution(std::min<int>(N, num_ev)); for(unsigned int i=0; i<solution.size(); i++) { solution[i].eigenvalue = w1[i+1]; Eigen::VectorXf ev(N); for(unsigned int j=0; j<N; j++) { ev[j] = *(h_R + i*N + j); } solution[i].eigenvector = ev; } std::cout << "Freeing" << std::endl; magma.free(w1); magma.hostfree(h_R); magma.hostfree(h_work); magma.free(iwork); end = get_current_time(); gpu_time = GetTimerValue(start,end)/1000.; std::cout << "Time: " << gpu_time << std::endl; return solution; }
//input vectors as columns (Eigen defaults to column major storage) void calcMeanAndCovarWeighed(const Eigen::MatrixXf &input, const Eigen::VectorXd &inputWeights, Eigen::MatrixXf &out_covMat, Eigen::VectorXf &out_mean) { calcMeanAndCovarWeighed(input.data(),inputWeights.data(),input.rows(),input.cols(),out_covMat,out_mean); }
//input vectors as columns (Eigen defaults to column major storage) void calcMeanWeighed(const Eigen::MatrixXf &input, const Eigen::VectorXd &inputWeights, Eigen::VectorXf &out_mean) { AALTO_ASSERT1(!input.IsRowMajor); calcMeanWeighed(input.data(),inputWeights.data(),input.rows(),input.cols(),out_mean); }
// Compute d/df a^T*K*b Eigen::MatrixXf kernelGradient( const Eigen::MatrixXf & a, const Eigen::MatrixXf & b ) const { Eigen::MatrixXf g = 0*f_; lattice_.gradient( g.data(), a.data(), b.data(), a.rows() ); return g; }
Eigen::MatrixXf PointDensityImpl(const std::vector<T>& seeds, const Eigen::MatrixXf& target, Fx fx, Fy fy) { // radius of box in which to average cluster density constexpr int RHO_R = 3; constexpr float cMagicSoftener = 0.5f; // 0.62f; constexpr float cRangeLossMult = 1.001f; constexpr float cRange = 1.3886f; const int rows = target.rows(); const int cols = target.cols(); // range of kernel s.t. 99.9% of mass is covered Eigen::MatrixXf density = Eigen::MatrixXf::Zero(rows, cols); for(const T& s : seeds) { const int sx = std::round(fx(s)); const int sy = std::round(fy(s)); // compute point density as average over a box float rho_sum = 0.0f; unsigned int rho_num = 0; for(int i=-RHO_R; i<=+RHO_R; ++i) { for(int j=-RHO_R; j<=+RHO_R; ++j) { const int sxj = sx + j; const int syi = sy + i; if( 0 <= sxj && sxj < rows && 0 <= syi && syi < cols) { rho_sum += target(sxj, syi); rho_num ++; } } } if(rho_sum == 0.0f || rho_num == 0) { continue; } const float rho = rho_sum / static_cast<float>(rho_num); // seed corresponds to a kernel at position (x,y) // with sigma = 1/sqrt(pi*rho) // i.e. 1/sigma^2 = pi*rho // factor pi is already compensated in kernel const float sxf = fx(s); const float syf = fy(s); const float rho_soft = cMagicSoftener * rho; // kernel influence range const int R = static_cast<int>(std::ceil(cRange / std::sqrt(rho_soft))); const int xmin = std::max<int>(sx - R, 0); const int xmax = std::min<int>(sx + R, int(rows) - 1); const int ymin = std::max<int>(sy - R, 0); const int ymax = std::min<int>(sy + R, int(cols) - 1); for(int yi=ymin; yi<=ymax; yi++) { for(int xi=xmin; xi<=xmax; xi++) { float dx = static_cast<float>(xi) - sxf; float dy = static_cast<float>(yi) - syf; float d2 = dx*dx + dy*dy; float delta = rho_soft * KernelSquare(rho_soft*d2); density(xi, yi) += delta; } } } { const float* psrc = target.data(); const float* psrc_end = psrc + rows*cols; float* pdst = density.data(); for(; psrc!=psrc_end; ++psrc, ++pdst) { if(*psrc == 0.0f) { *pdst = 0.0f; } } } return cRangeLossMult * density; }
void TraceStoreCol::SplineLossyCompress(const std::string &strategy, int order, char *bad_wells, float *mad) { Eigen::MatrixXf Basis; vector<float> knots; FillInKnots(strategy, mFrames, knots); // Eigen::Map<Eigen::MatrixXf, Eigen::Aligned> Basis(, compressed.n_frames, compressed.n_basis); if (!knots.empty()) { int boundaries[2]; boundaries[0] = 0; boundaries[1] = mFrames; basis_splines_endreps_local_v2(&knots[0], knots.size(), order, boundaries, sizeof(boundaries)/sizeof(boundaries[0]), Basis); } Eigen::MatrixXf SX = (Basis.transpose() * Basis).inverse() * Basis.transpose(); Eigen::MatrixXf Y(mFlowFrameStride, mFrames); // Eigen::MatrixXf FlowMeans(mFlows, mFrames); // FlowMeans.setZero(); int good_wells = 0; char *bad_start = bad_wells; char *bad_end = bad_start + mFrameStride; while(bad_start != bad_end) { if (*bad_start++ == 0) { good_wells++; } } // if nothing good then skip it if (good_wells < MIN_SAMPLE_WELL) { return; } std::vector<ChipReduction> smoothed_avg(mFlows); int x_clip = mCols; int y_clip = mRows; if (mUseMeshNeighbors == 0) { x_clip = THUMBNAIL_SIZE; y_clip = THUMBNAIL_SIZE; } for (size_t flow_ix = 0; flow_ix < mFlows; flow_ix++) { smoothed_avg[flow_ix].Init(mRows, mCols, mFrames, SMOOTH_REDUCE_STEP, SMOOTH_REDUCE_STEP, y_clip, x_clip, SMOOTH_REDUCE_STEP * SMOOTH_REDUCE_STEP * .4); for (size_t frame_ix = 0; frame_ix < mFrames; frame_ix++) { smoothed_avg[flow_ix].ReduceFrame(&mData[0] + flow_ix * mFrameStride + frame_ix * mFlowFrameStride, bad_wells, frame_ix); } smoothed_avg[flow_ix].SmoothBlocks(SMOOTH_REDUCE_REGION, SMOOTH_REDUCE_REGION); } float *y_start = Y.data(); float *y_end = Y.data() + mData.size(); int16_t *trace_start = &mData[0]; while(y_start != y_end) { *y_start++ = *trace_start++; } // // get the flow means per frame. // for (size_t frame_ix = 0; frame_ix < mFrames; frame_ix++) { // for(size_t flow_ix = 0; flow_ix < mFlows; flow_ix++) { // float *start = Y.data() + mFlowFrameStride * frame_ix + flow_ix * mFrameStride; // float *end = start + mFrameStride; // float *sum = &FlowMeans(flow_ix, frame_ix); // char *bad = bad_wells; // while (start != end) { // if (*bad == 0) { // *sum += *start; // } // start++; // bad++; // } // *sum /= good_wells; // } // } // subtract off flow,frame avg for (size_t frame_ix = 0; frame_ix < mFrames; frame_ix++) { for(size_t flow_ix = 0; flow_ix < mFlows; flow_ix++) { float *start = Y.data() + mFlowFrameStride * frame_ix + flow_ix * mFrameStride; float *end = start + mFrameStride; for (size_t row = 0; row < mRows; row++) { for (size_t col = 0; col < mCols; col++) { float avg = smoothed_avg[flow_ix].GetSmoothEst(row, col, frame_ix); *start++ -= avg; } } } } // // subtract them off // Eigen::VectorXf col_mean = Y.colwise().sum(); // col_mean /= Y.rows(); // for (int i = 0; i < Y.cols(); i++) { // Y.col(i).array() -= col_mean.coeff(i); // } // Get coefficients to solve Eigen::MatrixXf B = Y * SX.transpose(); // Uncompress data into yhat matrix Eigen::MatrixXf Yhat = B * Basis.transpose(); // add the flow/frame averages back for (size_t frame_ix = 0; frame_ix < mFrames; frame_ix++) { for(size_t flow_ix = 0; flow_ix < mFlows; flow_ix++) { float *start = Y.data() + mFlowFrameStride * frame_ix + flow_ix * mFrameStride; float *end = start + mFrameStride; float *hstart = Yhat.data() + mFlowFrameStride * frame_ix + flow_ix * mFrameStride; for (size_t row = 0; row < mRows; row++) { for (size_t col = 0; col < mCols; col++) { float avg = smoothed_avg[flow_ix].GetSmoothEst(row, col, frame_ix); *start++ += avg; *hstart++ += avg; } } } } // for (size_t frame_ix = 0; frame_ix < mFrames; frame_ix++) { // for(size_t flow_ix = 0; flow_ix < mFlows; flow_ix++) { // float *start = Y.data() + mFlowFrameStride * frame_ix + flow_ix * mFrameStride; // float *hstart = Yhat.data() + mFlowFrameStride * frame_ix + flow_ix * mFrameStride; // float *end = start + mFrameStride; // float avg = FlowMeans(flow_ix, frame_ix); // while (start != end) { // *start++ += avg; // *hstart++ += avg; // } // } // } // for (int i = 0; i < Yhat.cols(); i++) { // Yhat.col(i).array() += col_mean.coeff(i); // Y.col(i).array() += col_mean.coeff(i); // } float *yhat_start = Yhat.data(); float *yhat_end = Yhat.data() + mData.size(); trace_start = &mData[0]; while(yhat_start != yhat_end) { *trace_start++ = (int)(*yhat_start + .5); yhat_start++; } Y = Y - Yhat; Eigen::VectorXf M = Y.rowwise().squaredNorm(); for (size_t flow_ix = 0; flow_ix < mFlows; flow_ix++) { float *mad_start = mad; float *mad_end = mad_start + mFrameStride; float *m_start = M.data() + flow_ix * mFrameStride; while (mad_start != mad_end) { *mad_start += *m_start; mad_start++; m_start++; } } float *mad_start = mad; float *mad_end = mad + mFrameStride; int norm_factor = mFlows * mFrames; while (mad_start != mad_end) { *mad_start /= norm_factor; mad_start++; } }
bool TraceStoreCol::PcaLossyCompressChunk(int row_start, int row_end, int col_start, int col_end, int num_rows, int num_cols, int num_frames, int frame_stride, int flow_ix, int flow_frame_stride, short *data, bool replace, float *ssq, char *filters, int row_step, int col_step, int num_pca) { Eigen::MatrixXf Ysub, Y, S, Basis; int loc_num_wells = (col_end - col_start) * (row_end - row_start); int loc_num_cols = col_end - col_start; // Take a sample of the data at rate step, avoiding flagged wells // Count the good rows int sample_wells = 0; for (int row_ix = row_start; row_ix < row_end; row_ix+= row_step) { char *filt_start = filters + row_ix * num_cols + col_start; char *filt_end = filt_start + loc_num_cols; while (filt_start < filt_end) { if (*filt_start == 0) { sample_wells++; } filt_start += col_step; } } // try backing off to every well rather than just sampled if we didn't get enough if (sample_wells < MIN_SAMPLE_WELL) { row_step = 1; col_step = 1; int sample_wells = 0; for (int row_ix = row_start; row_ix < row_end; row_ix+= row_step) { char *filt_start = filters + row_ix * num_cols + col_start; char *filt_end = filt_start + loc_num_cols; while (filt_start < filt_end) { if (*filt_start == 0) { sample_wells++; } filt_start += col_step; } } } if (sample_wells < MIN_SAMPLE_WELL) { return false; // just give up } // Got enough data to work with, zero out the ssq array for accumulation for (int row_ix = row_start; row_ix < row_end; row_ix++) { float *ssq_start = ssq + row_ix * num_cols + col_start; float *ssq_end = ssq_start + loc_num_cols; while (ssq_start != ssq_end) { *ssq_start++ = 0; } } // Copy the sampled data in Matrix, frame major Ysub.resize(sample_wells, num_frames); for (int frame_ix = 0; frame_ix < (int)num_frames; frame_ix++) { int sample_offset = 0; for (int row_ix = row_start; row_ix < row_end; row_ix+=row_step) { size_t store_offset = row_ix * num_cols + col_start; char *filt_start = filters + store_offset; char *filt_end = filt_start + loc_num_cols; int16_t *trace_start = data + (flow_frame_stride * frame_ix) + (flow_ix * frame_stride) + store_offset; float *ysub_start = Ysub.data() + sample_wells * frame_ix + sample_offset; while (filt_start < filt_end) { if (*filt_start == 0) { *ysub_start = *trace_start; ysub_start++; sample_offset++; } trace_start += col_step; filt_start += col_step; } } } // Copy in all the data into working matrix Y.resize(loc_num_wells, (int)num_frames); for (int frame_ix = 0; frame_ix < (int)num_frames; frame_ix++) { for (int row_ix = row_start; row_ix < row_end; row_ix++) { size_t store_offset = row_ix * num_cols + col_start; int16_t *trace_start = data + (flow_frame_stride * frame_ix) + (flow_ix * frame_stride) + store_offset; int16_t *trace_end = trace_start + loc_num_cols; float * y_start = Y.data() + loc_num_wells * frame_ix + (row_ix - row_start) * loc_num_cols; while( trace_start != trace_end ) { *y_start++ = *trace_start++; } } } Eigen::VectorXf col_mean = Y.colwise().sum(); col_mean /= Y.rows(); for (int i = 0; i < Y.cols(); i++) { Y.col(i).array() -= col_mean.coeff(i); } // Create scatter matrix S = Ysub.transpose() * Ysub; // Compute the eigenvectors Eigen::SelfAdjointEigenSolver<Eigen::MatrixXf> es; es.compute(S); Eigen::MatrixXf Pca_Basis = es.eigenvectors(); Eigen::VectorXf Pca_Values = es.eigenvalues(); // Copy top eigen vectors into basis for projection Basis.resize(num_frames, num_pca); for (int i = 0; i < Basis.cols(); i++) { // Basis.col(i) = es.eigenvectors().col(es.eigenvectors().cols() - i -1); Basis.col(i) = Pca_Basis.col(Pca_Basis.cols() - i - 1); } // Create solver matrix, often not a good way of solving things but eigen vectors should be stable and fast Eigen::MatrixXf SX = (Basis.transpose() * Basis).inverse() * Basis.transpose(); // Get coefficients to solve Eigen::MatrixXf B = Y * SX.transpose(); // Uncompress data into yhat matrix Eigen::MatrixXf Yhat = B * Basis.transpose(); for (int i = 0; i < Yhat.cols(); i++) { Yhat.col(i).array() += col_mean.coeff(i); Y.col(i).array() += col_mean.coeff(i); } // H5File h5("pca_lossy.h5"); // h5.Open(); // char buff[256]; // snprintf(buff, sizeof(buff), "/Y_%d_%d_%d", flow_ix, row_start, col_start); // H5Eigen::WriteMatrix(h5, buff, Y); // snprintf(buff, sizeof(buff), "/Yhat_%d_%d_%d", flow_ix, row_start, col_start); // H5Eigen::WriteMatrix(h5, buff, Yhat); // snprintf(buff, sizeof(buff), "/Basis_%d_%d_%d", flow_ix, row_start, col_start); // H5Eigen::WriteMatrix(h5, buff, Basis); // h5.Close(); // Copy data out of yhat matrix into original data structure, keeping track of residuals for (int frame_ix = 0; frame_ix < (int)num_frames; frame_ix++) { for (int row_ix = row_start; row_ix < row_end; row_ix++) { size_t store_offset = row_ix * num_cols + col_start; int16_t *trace_start = data + flow_frame_stride * frame_ix + flow_ix * frame_stride + store_offset; int16_t *trace_end = trace_start + loc_num_cols; float * ssq_start = ssq + store_offset; size_t loc_offset = (row_ix - row_start) * loc_num_cols; float * y_start = Y.data() + loc_num_wells * frame_ix + loc_offset; float * yhat_start = Yhat.data() + loc_num_wells * frame_ix + loc_offset; while( trace_start != trace_end ) { if (replace) { *trace_start = (int16_t)(*yhat_start + .5); } float val = *y_start - *yhat_start; *ssq_start += val * val; y_start++; yhat_start++; trace_start++; ssq_start++; } } } // divide ssq data out for per frame avg for (int row_ix = row_start; row_ix < row_end; row_ix++) { size_t store_offset = row_ix * num_cols + col_start; float * ssq_start = ssq + store_offset; float * ssq_end = ssq_start + loc_num_cols; while (ssq_start != ssq_end) { *ssq_start /= num_frames; ssq_start++; } } return true; }
void TraceStoreCol::SplineLossyCompress(const std::string &strategy, int order, int flow_ix, char *bad_wells, float *mad, size_t num_rows, size_t num_cols, size_t num_frames, size_t num_flows, int use_mesh_neighbors, size_t frame_stride, size_t flow_frame_stride, int16_t *data) { Eigen::MatrixXf Basis; vector<float> knots; FillInKnots(strategy, num_frames, knots); if (!knots.empty()) { int boundaries[2]; boundaries[0] = 0; boundaries[1] = num_frames; basis_splines_endreps_local_v2(&knots[0], knots.size(), order, boundaries, sizeof(boundaries)/sizeof(boundaries[0]), Basis); } Eigen::MatrixXf SX = (Basis.transpose() * Basis).inverse() * Basis.transpose(); Eigen::MatrixXf Y(frame_stride, num_frames); // Eigen::MatrixXf FlowMeans(num_flows, num_frames); // FlowMeans.setZero(); int good_wells = 0; char *bad_start = bad_wells; char *bad_end = bad_start + frame_stride; while(bad_start != bad_end) { if (*bad_start++ == 0) { good_wells++; } } // if nothing good then skip it if (good_wells < MIN_SAMPLE_WELL) { return; } ChipReduction smoothed_avg; int x_clip = num_cols; int y_clip = num_rows; if (use_mesh_neighbors == 0) { x_clip = THUMBNAIL_SIZE; y_clip = THUMBNAIL_SIZE; } smoothed_avg.Init(num_rows, num_cols, num_frames, SMOOTH_REDUCE_STEP, SMOOTH_REDUCE_STEP, y_clip, x_clip, SMOOTH_REDUCE_STEP * SMOOTH_REDUCE_STEP * .4); for (size_t frame_ix = 0; frame_ix < num_frames; frame_ix++) { smoothed_avg.ReduceFrame(data + flow_ix * frame_stride + frame_ix * flow_frame_stride, bad_wells, frame_ix); } smoothed_avg.SmoothBlocks(SMOOTH_REDUCE_REGION, SMOOTH_REDUCE_REGION); for (size_t frame_ix = 0; frame_ix < num_frames; frame_ix++) { float *y_start = Y.data() + frame_ix * frame_stride; float *y_end = y_start + frame_stride; int16_t *trace_start = data + flow_ix * frame_stride + frame_ix * flow_frame_stride; while(y_start != y_end) { *y_start++ = *trace_start++; } } // subtract off flow,frame avg for (size_t frame_ix = 0; frame_ix < num_frames; frame_ix++) { float *start = Y.data() + frame_stride * frame_ix; float *end = start + frame_stride; for (size_t row = 0; row < num_rows; row++) { for (size_t col = 0; col < num_cols; col++) { float avg = smoothed_avg.GetSmoothEst(row, col, frame_ix); *start++ -= avg; } } } // Get coefficients to solve Eigen::MatrixXf B = Y * SX.transpose(); // Uncompress data into yhat matrix Eigen::MatrixXf Yhat = B * Basis.transpose(); // add the flow/frame averages back for (size_t frame_ix = 0; frame_ix < num_frames; frame_ix++) { float *start = Y.data() + frame_stride * frame_ix; float *end = start + frame_stride; float *hstart = Yhat.data() + frame_stride * frame_ix; for (size_t row = 0; row < num_rows; row++) { for (size_t col = 0; col < num_cols; col++) { float avg = smoothed_avg.GetSmoothEst(row, col, frame_ix); *start++ += avg; *hstart++ += avg; } } } for (size_t frame_ix = 0; frame_ix < num_frames; frame_ix++) { float *yhat_start = Yhat.data() + frame_ix * frame_stride; float *yhat_end = yhat_start + frame_stride; int16_t *trace_start = data + flow_ix * frame_stride + frame_ix * flow_frame_stride; while(yhat_start != yhat_end) { *trace_start++ = (int)(*yhat_start + .5f); yhat_start++; } } Y = Y - Yhat; Eigen::VectorXf M = Y.rowwise().squaredNorm(); float *mad_start = mad; float *mad_end = mad_start + frame_stride; float *m_start = M.data(); while (mad_start != mad_end) { *mad_start += *m_start; mad_start++; m_start++; } mad_start = mad; mad_end = mad + frame_stride; int norm_factor = num_frames;// num_flows * num_frames; while (mad_start != mad_end) { *mad_start /= norm_factor; mad_start++; } }