ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

C++代码实现MATLAB中的normalize函数功能

C++代码实现MATLAB中的normalize函数功能 #includeiostream#includevector#includecmath#includenumeric#includealgorithm#includestdexcept#includestring#includecassert// // 辅助函数// // 计算算术平均值doublecomputeMean(conststd::vectordoublev){if(v.empty())return0.0;doublesumstd::accumulate(v.begin(),v.end(),0.0);returnsum/static_castdouble(v.size());}// 计算样本标准差除以 N-1与 MATLAB normalize 默认行为一致doublecomputeStd(conststd::vectordoublev,doublemean){if(v.size()2)return0.0;doublesqSum0.0;for(doublex:v){doublediffx-mean;sqSumdiff*diff;}returnstd::sqrt(sqSum/static_castdouble(v.size()-1));}// 计算中位数doublecomputeMedian(std::vectordoublev){if(v.empty())return0.0;std::sort(v.begin(),v.end());size_t nv.size();if(n%20){return(v[n/2-1]v[n/2])/2.0;}else{returnv[n/2];}}// 计算 MAD中位数绝对偏差doublecomputeMAD(conststd::vectordoublev,doublemedian){if(v.empty())return0.0;std::vectordoubleabsDev;absDev.reserve(v.size());for(doublex:v){absDev.push_back(std::abs(x-median));}returncomputeMedian(absDev);}// 计算 L2 范数欧几里得范数doublecomputeNormL2(conststd::vectordoublev){doublesqSum0.0;for(doublex:v){sqSumx*x;}returnstd::sqrt(sqSum);}// 计算 IQR四分位距doublecomputeIQR(std::vectordoublev){if(v.size()2)return0.0;std::sort(v.begin(),v.end());size_t nv.size();autopercentile[](doublep)-double{doubleidxp*(static_castdouble(n)-1.0);size_t lostatic_castsize_t(std::floor(idx));size_t histatic_castsize_t(std::ceil(idx));if(lohi)returnv[lo];doublefracidx-static_castdouble(lo);returnv[lo]*(1.0-frac)v[hi]*frac;};returnpercentile(0.75)-percentile(0.25);}// // 核心归一化函数对一维向量// // zscore中心化为均值 0缩放为标准差 1std::vectordoublenormalizeZscore(conststd::vectordoublev){doublemeancomputeMean(v);doublesdcomputeStd(v,mean);std::vectordoubleresult(v.size());for(size_t i0;iv.size();i){result[i](sd!0.0)?(v[i]-mean)/sd:0.0;}returnresult;}// norm按 L2 范数归一化std::vectordoublenormalizeNorm(conststd::vectordoublev){doublenormValcomputeNormL2(v);std::vectordoubleresult(v.size());for(size_t i0;iv.size();i){result[i](normVal!0.0)?v[i]/normVal:0.0;}returnresult;}// range重缩放到 [0, 1]std::vectordoublenormalizeRange(conststd::vectordoublev){if(v.empty())return{};auto[minIt,maxIt]std::minmax_element(v.begin(),v.end());doubleminVal*minIt,maxVal*maxIt;doublerangemaxVal-minVal;std::vectordoubleresult(v.size());for(size_t i0;iv.size();i){result[i](range!0.0)?(v[i]-minVal)/range:0.0;}returnresult;}// medianiqr中心化为中位数缩放为 IQRstd::vectordoublenormalizeMedianIQR(conststd::vectordoublev){doublemedcomputeMedian(v);doubleiqrcomputeIQR(v);std::vectordoubleresult(v.size());for(size_t i0;iv.size();i){result[i](iqr!0.0)?(v[i]-med)/iqr:0.0;}returnresult;}// centerscale 通用形式可自定义中心化值和缩放值std::vectordoublenormalizeCenterScale(conststd::vectordoublev,doublecenter,doublescale){std::vectordoubleresult(v.size());for(size_t i0;iv.size();i){result[i](scale!0.0)?(v[i]-center)/scale:0.0;}returnresult;}// // 矩阵归一化按列处理与 MATLAB normalize(A) 默认行为一致// classMatrix{public:size_t rows,cols;std::vectordoubledata;// 列优先存储Matrix(size_t r,size_t c):rows(r),cols(c),data(r*c,0.0){}doubleoperator()(size_t i,size_t j){returndata[ij*rows];}doubleoperator()(size_t i,size_t j)const{returndata[ij*rows];}// 提取第 j 列std::vectordoublegetColumn(size_t j)const{std::vectordoublecol(rows);for(size_t i0;irows;i){col[i](*this)(i,j);}returncol;}// 设置第 j 列voidsetColumn(size_t j,conststd::vectordoublecol){for(size_t i0;irows;i){(*this)(i,j)col[i];}}// 提取第 i 行std::vectordoublegetRow(size_t i)const{std::vectordoublerow(cols);for(size_t j0;jcols;j){row[j](*this)(i,j);}returnrow;}// 设置第 i 行voidsetRow(size_t i,conststd::vectordoublerow){for(size_t j0;jcols;j){(*this)(i,j)row[j];}}};// 按指定维度归一化矩阵// dim1: 按列归一化默认dim2: 按行归一化MatrixnormalizeMatrix(constMatrixA,intdim1,conststd::stringmethodzscore){Matrixresult(A.rows,A.cols);if(dim1){// 按列处理for(size_t j0;jA.cols;j){std::vectordoublecolA.getColumn(j);std::vectordoublenormCol;if(methodzscore){normColnormalizeZscore(col);}elseif(methodnorm){normColnormalizeNorm(col);}elseif(methodrange){normColnormalizeRange(col);}elseif(methodmedianiqr){normColnormalizeMedianIQR(col);}else{throwstd::invalid_argument(Unknown method: method);}result.setColumn(j,normCol);}}elseif(dim2){// 按行处理for(size_t i0;iA.rows;i){std::vectordoublerowA.getRow(i);std::vectordoublenormRow;if(methodzscore){normRownormalizeZscore(row);}elseif(methodnorm){normRownormalizeNorm(row);}elseif(methodrange){normRownormalizeRange(row);}elseif(methodmedianiqr){normRownormalizeMedianIQR(row);}else{throwstd::invalid_argument(Unknown method: method);}result.setRow(i,normRow);}}else{throwstd::invalid_argument(dim must be 1 or 2);}returnresult;}// // 使用示例// intmain(){// 示例 1向量 zscore 归一化对应 MATLAB: normalize(1:5)std::vectordoublev{1,2,3,4,5};auton1normalizeZscore(v);std::coutzscore: ;for(doublex:n1)std::coutx ;std::cout\n;// 示例 2向量 L2 范数归一化auton2normalizeNorm(v);std::coutnorm: ;for(doublex:n2)std::coutx ;std::cout\n;// 示例 3range 归一化到 [0,1]auton3normalizeRange(v);std::coutrange: ;for(doublex:n3)std::coutx ;std::cout\n;// 示例 4矩阵按列 zscore 归一化MatrixA(3,3);// [8 1 6]// [3 5 7]// [4 9 2]A(0,0)8;A(0,1)1;A(0,2)6;A(1,0)3;A(1,1)5;A(1,2)7;A(2,0)4;A(2,1)9;A(2,2)2;Matrix NnormalizeMatrix(A,1,zscore);std::cout\nMatrix zscore (by column):\n;for(size_t i0;iN.rows;i){for(size_t j0;jN.cols;j){std::coutN(i,j)\t;}std::cout\n;}// 示例 5矩阵按行 zscore 归一化Matrix N2normalizeMatrix(A,2,zscore);std::cout\nMatrix zscore (by row):\n;for(size_t i0;iN2.rows;i){for(size_t j0;jN2.cols;j){std::coutN2(i,j)\t;}std::cout\n;}return0;}
返回列表