新闻详情

新闻详情

首页 / 资讯中心 / 详情

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

发布时间:2026/10/1 2:47:05来源:尧图网络
C++代码实现MATLAB中的lqry函数功能
// lqry.cpp// 独立编译命令不依赖任何第三方库// g -stdc17 -O2 lqry.cpp -o lqry// ./lqry#includeiostream#includevector#includecmath#includecomplex#includeiomanip#includestdexcept#includestring#includealgorithm// // 自实现矩阵类替代 Eigen// classMatrix{public:introws,cols;std::vectordoubledata;Matrix():rows(0),cols(0){}Matrix(intr,intc):rows(r),cols(c),data(r*c,0.0){}doubleoperator()(inti,intj){returndata[i*colsj];}doubleoperator()(inti,intj)const{returndata[i*colsj];}staticMatrixidentity(intn){MatrixI(n,n);for(inti0;in;i)I(i,i)1.0;returnI;}Matrixtranspose()const{MatrixT(cols,rows);for(inti0;irows;i)for(intj0;jcols;j)T(j,i)(*this)(i,j);returnT;}Matrixoperator(constMatrixo)const{MatrixR(rows,cols);for(size_t i0;idata.size();i)R.data[i]data[i]o.data[i];returnR;}Matrixoperator-(constMatrixo)const{MatrixR(rows,cols);for(size_t i0;idata.size();i)R.data[i]data[i]-o.data[i];returnR;}Matrixoperator*(constMatrixo)const{MatrixR(rows,o.cols);for(inti0;irows;i)for(intk0;kcols;k){doubleaik(*this)(i,k);if(aik0.0)continue;for(intj0;jo.cols;j)R(i,j)aik*o(k,j);}returnR;}Matrixoperator*(doubles)const{MatrixR(rows,cols);for(size_t i0;idata.size();i)R.data[i]data[i]*s;returnR;}doublemaxAbsDiff(constMatrixo)const{doublem0.0;for(size_t i0;idata.size();i)mstd::max(m,std::fabs(data[i]-o.data[i]));returnm;}// 高斯-约当消元法求逆Matrixinverse()const{intnrows;Matrix A*this;Matrix Iidentity(n);for(intcol0;coln;col){intpivcol;doublemvstd::fabs(A(col,col));for(intrcol1;rn;r)if(std::fabs(A(r,col))mv){mvstd::fabs(A(r,col));pivr;}if(mv1e-15)throwstd::runtime_error(矩阵奇异无法求逆);if(piv!col)for(intj0;jn;j){std::swap(A(col,j),A(piv,j));std::swap(I(col,j),I(piv,j));}doublepA(col,col);for(intj0;jn;j){A(col,j)/p;I(col,j)/p;}for(intr0;rn;r){if(rcol)continue;doublefA(r,col);if(f0.0)continue;for(intj0;jn;j){A(r,j)-f*A(col,j);I(r,j)-f*I(col,j);}}}returnI;}voidprint(conststd::stringname)const{std::coutname [rowsxcols]:\n;std::coutstd::setprecision(6);for(inti0;irows;i){std::cout ;for(intj0;jcols;j)std::coutstd::setw(12)(*this)(i,j) ;std::cout\n;}}};// // 2x2 矩阵的解析特征值求解// std::vectorstd::complexdoubleeigenvalues2x2(doublea,doubleb,doublec,doubled){std::vectorstd::complexdoubleev;doubletrad;doubledeta*d-b*c;doubledisctr*tr-4*det;if(disc0){doublesstd::sqrt(disc);ev.push_back({(trs)/2,0.0});ev.push_back({(tr-s)/2,0.0});}else{doublesstd::sqrt(-disc);ev.push_back({tr/2,s/2});ev.push_back({tr/2,-s/2});}returnev;}// // Riccati 方程迭代求解器// 求解: A^T P P A - (P B N) R^{-1} (B^T P N^T) Q 0// boolsolveRiccatiIterationC(constMatrixA,constMatrixB,constMatrixQ,constMatrixR,constMatrixN,MatrixP,doubledt0.001,doubletolerance1e-9,unsignedintiter_max200000){intnA.rows;PQ;// 初值 P QMatrixP_next(n,n);Matrix ATA.transpose();Matrix RinvR.inverse();for(unsignedinti0;iiter_max;i){Matrix PB_NP*BN;Matrix termAT*PP*A-PB_N*Rinv*PB_N.transpose()Q;P_nextPterm*dt;doublediffP_next.maxAbsDiff(P);PP_next;if(difftolerance){std::coutRiccati 迭代收敛迭代次数: istd::endl;returntrue;}}std::cerrRiccati 迭代未收敛std::endl;returnfalse;}// // lqry输出加权 LQR 设计// 最小化 J ∫ (y^T Q y u^T R u 2 y^T N u) dt, y Cx Du// boollqry(constMatrixA,constMatrixB,constMatrixC,constMatrixD,constMatrixQ,constMatrixR,MatrixK,MatrixS,std::vectorstd::complexdoublee,constMatrix*Nnullptr){intnA.rows,mB.cols,pC.rows;// 维度检查if(A.cols!n||B.rows!n){std::cerr错误: A 或 B 的维度不匹配std::endl;returnfalse;}if(C.cols!n||D.rows!p||D.cols!m){std::cerr错误: C 或 D 的维度不匹配std::endl;returnfalse;}if(Q.rows!p||Q.cols!p){std::cerr错误: Q 必须为 pxp 矩阵std::endl;returnfalse;}if(R.rows!m||R.cols!m){std::cerr错误: R 必须为 mxm 矩阵std::endl;returnfalse;}Matrix Nmat(N!nullptr)?*N:Matrix(p,m);// 输出加权 → 等效状态加权Matrix CtC.transpose();Matrix DtD.transpose();Matrix Q_barCt*Q*C;// C^T Q CMatrix R_barRDt*Q*DDt*NmatNmat.transpose()*D;// R D^T Q D D^T N N^T DMatrix N_barCt*Q*DCt*Nmat;// C^T Q D C^T N// 求解 Riccati 方程if(!solveRiccatiIterationC(A,B,Q_bar,R_bar,N_bar,S))returnfalse;// 最优增益 K R_bar^{-1} (B^T S N_bar^T)KR_bar.inverse()*(B.transpose()*SN_bar.transpose());// 闭环特征值Matrix A_clA-B*K;if(n!2){std::cerr本示例仅支持 n2 的特征值计算std::endl;returnfalse;}eeigenvalues2x2(A_cl(0,0),A_cl(0,1),A_cl(1,0),A_cl(1,1));returntrue;}// // 主函数// intmain(){// ---------- 系统定义 ----------MatrixA(2,2);A(0,0)0.6;A(0,1)0.25;A(1,0)0.0;A(1,1)0.9;MatrixB(2,1);B(0,0)0.0;B(1,0)10.0;MatrixC(1,2);C(0,0)11.0;C(0,1)0.0;MatrixD(1,1);D(0,0)0.0;MatrixQ(1,1);Q(0,0)2.0;MatrixR(1,1);R(0,0)1.0;// ---------- 调用 lqry ----------Matrix K,S;std::vectorstd::complexdoublee;booloklqry(A,B,C,D,Q,R,K,S,e);if(ok){std::cout\n lqry 求解结果 \n\n;K.print(最优增益 K);std::cout\n;S.print(Riccati 解 S);std::cout\n闭环特征值 e:\n;for(autoev:e)std::cout (ev.real(), ev.imag())\n;std::cout\n闭环矩阵 A - B*K 的特征值实部:\n;for(autoev:e)std::cout ev.real()\n;}else{std::cerrlqry 求解失败std::endl;}return0;}
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

微分方程与差分方程:离散化、数值稳定性与仿真建模避坑指南 2026/10/1 6:45:06

微分方程与差分方程:离散化、数值稳定性与仿真建模避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
多智能体协同的AI招聘系统:架构拆解与落地实践 2026/10/1 6:45:06

多智能体协同的AI招聘系统:架构拆解与落地实践

去年我把手头一个中型团队招聘流程拆掉重做,换成了一套多智能体协同的AI招聘工作流。一开始我并不看好,市面上很多"AI招聘"其实就只是给HR配了个关键词筛选器,离真正跑完流程差得远。真正让我改变想法的,是我自己从零搭…

阅读更多 →
TMC2208步进电机驱动深入解析:静音原理与调试实战 2026/10/1 6:44:59

TMC2208步进电机驱动深入解析:静音原理与调试实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Cursor编程的七宗罪:从Base URL改到TaoToken的排查清单 2026/10/1 6:44:52

Cursor编程的七宗罪:从Base URL改到TaoToken的排查清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
办公文档预处理与任务调度:根治智能体长文本超限的实战方案 2026/10/1 6:44:39

办公文档预处理与任务调度:根治智能体长文本超限的实战方案

做本地智能体差不多两年了,踩过最多的坑不是模型跑不起来,而是办公文档一进来就出各种幺蛾子:PDF表格错位、Word里藏了一堆修订痕迹、扫描件转出来的文字乱成一团,更别说一份合同几万字直接塞进上下文窗口就爆掉。今天我把这套“办…

阅读更多 →
JS数组遍历方法怎么选?for、forEach、map、filter、reduce全解析 2026/10/1 6:44:39

JS数组遍历方法怎么选?for、forEach、map、filter、reduce全解析

关于 for 循环、forEach、map、filter、reduce 这些 JS 里的遍历方式,我见过太多人只是会语法、不会选型。之前面试过一位候选人,把 forEach 和 map 区别背得滚瓜烂熟,一问到“数组里有 10 万条数据,你用什么方式遍历不卡”&#…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉