新闻详情

新闻详情

首页 / 资讯中心 / 详情

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

发布时间:2026/10/1 10:12:15来源:尧图网络
C++代码实现MATLAB中的lqrd函数功能
// // lqrd: 连续系统的离散 LQR 设计MATLAB lqrd 的纯 C 实现// 零第三方依赖可直接编译// g -O2 -stdc11 lqrd.cpp -o lqrd// ./lqrd// #includeiostream#includevector#includecmath#includestdexcept#includeiomanip#includealgorithm// // 极简矩阵类仅实现本算法所需功能// classMatrix{public:introws,cols;std::vectordoubledata;Matrix():rows(0),cols(0){}Matrix(intr,intc):rows(r),cols(c),data(r*c,0.0){}Matrix(intr,intc,doublev):rows(r),cols(c),data(r*c,v){}doubleoperator()(inti,intj){returndata[i*colsj];}constdoubleoperator()(inti,intj)const{returndata[i*colsj];}staticMatrixIdentity(intn){MatrixI(n,n);for(inti0;in;i)I(i,i)1.0;returnI;}staticMatrixZero(intr,intc){returnMatrix(r,c,0.0);}Matrixtranspose()const{MatrixT(cols,rows);for(inti0;irows;i)for(intj0;jcols;j)T(j,i)(*this)(i,j);returnT;}Matrixoperator*(constMatrixB)const{if(cols!B.rows)throwstd::invalid_argument(Matrix mult dimension mismatch);MatrixC(rows,B.cols);for(inti0;irows;i)for(intk0;kcols;k){doublea(*this)(i,k);if(a0.0)continue;for(intj0;jB.cols;j)C(i,j)a*B(k,j);}returnC;}Matrixoperator(constMatrixB)const{MatrixC(rows,cols);for(size_t i0;idata.size();i)C.data[i]data[i]B.data[i];returnC;}Matrixoperator-(constMatrixB)const{MatrixC(rows,cols);for(size_t i0;idata.size();i)C.data[i]data[i]-B.data[i];returnC;}Matrixoperator*(doubles)const{MatrixC(rows,cols);for(size_t i0;idata.size();i)C.data[i]data[i]*s;returnC;}doublenorm()const{doubles0.0;for(doublev:data)sv*v;returnstd::sqrt(s);}// ---- 高斯-约当消元求逆带部分主元----Matrixinverse()const{if(rows!cols)throwstd::invalid_argument(inverse: non-square matrix);constintnrows;Matrix A*this;Matrix IIdentity(n);for(intcol0;coln;col){intpivcol;doublemaxvstd::fabs(A(col,col));for(intrcol1;rn;r){doublevstd::fabs(A(r,col));if(vmaxv){maxvv;pivr;}}if(maxv1e-14)throwstd::runtime_error(inverse: singular matrix);if(piv!col){for(intj0;jn;j){std::swap(A(col,j),A(piv,j));std::swap(I(col,j),I(piv,j));}}doubledA(col,col);for(intj0;jn;j){A(col,j)/d;I(col,j)/d;}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;}// ---- 矩阵指数缩放-平方 泰勒级数 ----// exp(A) ( exp(A/2^s) )^(2^s)使 ‖A/2^s‖ ≤ 0.5Matrixexp()const{if(rows!cols)throwstd::invalid_argument(exp: non-square matrix);constintnrows;doublenrmnorm();ints0;while(nrm0.5){nrm*0.5;s;}constdoublescalestd::pow(2.0,-s);Matrix A(*this)*scale;Matrix resultIdentity(n);Matrix termIdentity(n);for(intk1;k20;k){termterm*A;for(size_t i0;iterm.data.size();i)term.data[i]/k;resultresultterm;if(term.norm()1e-18)break;}for(inti0;is;i)resultresult*result;returnresult;}voidblockSet(intr0,intc0,constMatrixB){for(inti0;iB.rows;i)for(intj0;jB.cols;j)(*this)(r0i,c0j)B(i,j);}MatrixblockGet(intr0,intc0,intr,intc)const{MatrixB(r,c);for(inti0;ir;i)for(intj0;jc;j)B(i,j)(*this)(r0i,c0j);returnB;}};// // 核心算法lqrd含交叉项 N// voidlqrd(constMatrixA,constMatrixB,constMatrixQ,constMatrixR,constMatrixN,doubleTs,MatrixKd,MatrixS){constintnA.rows;constintmB.cols;if(A.cols!n||B.rows!n)throwstd::invalid_argument(A/B 维度不匹配);if(Q.rows!n||Q.cols!n)throwstd::invalid_argument(Q 维度不匹配);if(R.rows!m||R.cols!m)throwstd::invalid_argument(R 维度不匹配);if(N.rows!n||N.cols!m)throwstd::invalid_argument(N 维度不匹配);// 1) Van Loan 扩展矩阵van Loan, IEEE TAC 23(3), 1978// K [A B; 0 0] (nm 维), W [Q N; N R] (nm 维)// H [-K W; 0 K] (2(nm) 维)// exp(H·Ts) [ exp(-K·Ts) X ;// 0 exp(K·Ts) ]// 其中 X exp(-K·Ts) · ∫₀^Ts exp(Kτ) W exp(Kτ) dτ// 故 [Qd Nd; Nd Rd] exp(-K·Ts)^{-1} · X// Ad, Bd 由 exp(K·Ts) [Ad Bd; 0 I] 提取精确 ZOH 离散化constintdnm;Matrix KMatrix::Zero(d,d);K.blockSet(0,0,A);K.blockSet(0,n,B);Matrix WMatrix::Zero(d,d);W.blockSet(0,0,Q);W.blockSet(0,n,N);W.blockSet(n,0,N.transpose());W.blockSet(n,n,R);Matrix HMatrix::Zero(2*d,2*d);Matrix KtK.transpose();for(inti0;id;i)for(intj0;jd;j)H(i,j)-Kt(i,j);H.blockSet(0,d,W);H.blockSet(d,d,K);// 2) 矩阵指数 e^(H·Ts)Matrix E(H*Ts).exp();// 3) 提取离散量Matrix E11E.blockGet(0,0,d,d);Matrix XE.blockGet(0,d,d,d);Matrix E22E.blockGet(d,d,d,d);Matrix AdE22.blockGet(0,0,n,n);Matrix BdE22.blockGet(0,n,n,m);Matrix QdNdRdE11.inverse()*X;Matrix QdQdNdRd.blockGet(0,0,n,n);Matrix NdQdNdRd.blockGet(0,n,n,m);Matrix RdQdNdRd.blockGet(n,n,m,m);// 4) 迭代求解离散 Riccati 方程Matrix Rd_invRd.inverse();Matrix A2Ad-Bd*Rd_inv*Nd.transpose();Matrix Q2Qd-Nd*Rd_inv*Nd.transpose();SQ2;constdoubletol1e-12;constintmax_iter10000;for(intk0;kmax_iter;k){Matrix S_nextA2.transpose()*S*A2-A2.transpose()*S*Bd*(Bd.transpose()*S*BdRd).inverse()*Bd.transpose()*S*A2Q2;doublediff(S_next-S).norm()/(S_next.norm()1e-16);SS_next;if(difftol)break;}// 5) 计算增益 KdKd(Bd.transpose()*S*BdRd).inverse()*(Bd.transpose()*S*AdNd.transpose());}// 便捷重载N 0voidlqrd(constMatrixA,constMatrixB,constMatrixQ,constMatrixR,doubleTs,MatrixKd,MatrixS){Matrix NMatrix::Zero(A.rows,B.cols);lqrd(A,B,Q,R,N,Ts,Kd,S);}// // 示例主程序// intmain(){// 双积分器ẍ uMatrixA(2,2);A(0,0)0;A(0,1)1;A(1,0)0;A(1,1)0;MatrixB(2,1);B(0,0)0;B(1,0)1;Matrix QMatrix::Identity(2);Matrix RMatrix::Identity(1);constdoubleTs0.01;Matrix Kd,S;lqrd(A,B,Q,R,Ts,Kd,S);std::coutstd::fixedstd::setprecision(4);std::cout离散 LQR 增益 Kd \n;for(inti0;iKd.rows;i){for(intj0;jKd.cols;j)std::cout Kd(i,j) ;std::cout\n;}std::cout\nRiccati 解 S \n;for(inti0;iS.rows;i){for(intj0;jS.cols;j)std::cout S(i,j) ;std::cout\n;}return0;}
网站建设高端定制企业官网
RELATED

相关资讯

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

较早相关资讯

最新相关资讯

PLFM_RADAR:大模型推理服务质量监控与异常告警实践 2026/10/1 10:53:18

PLFM_RADAR:大模型推理服务质量监控与异常告警实践

如果你负责的大模型服务出了这么一个问题:GPU利用率、QPS、P95延迟全部正常,但业务方突然反馈“模型最近变蠢了”,你会怎么排查?我遇到过好几回。传统监控只能回答“机器有没有事”,回答不了“模型是不是在好好干活”。…

阅读更多 →
芯参谋(29):UFS UMCP 软件设计规范 2026/10/1 10:53:11

芯参谋(29):UFS UMCP 软件设计规范

面向 UFS 3.1 LPDDR4X 合封(JEDEC uMCP)的固件驱动设计约定 —— 覆盖 双器件独立初始化、LUN 与 Boot LU、UTP 命令队列、WriteBooster 掉电风险、 LPDDR4X 训练与刷新 与 热耦合温控,逐条给出可落地的流程、判据与超时预算。 2套独立总线…

阅读更多 →
运维转网安:老经验如何变成职业增值资本 2026/10/1 10:53:11

运维转网安:老经验如何变成职业增值资本

运维干了快十年,身边经常有人问:这行到底还能干多久?说实话,“越老越吃香”这句话放在传统运维身上,越来越像个安慰奖。服务器越来越多、故障越来越频繁、值班电话永远响个不停,而工资涨幅却总赶不上通宵抢…

阅读更多 →
SpringBoot+Vue办公用品直售推荐系统毕设:从源码跑通到答辩全流程解析 2026/10/1 10:53:11

SpringBoot+Vue办公用品直售推荐系统毕设:从源码跑通到答辩全流程解析

做毕设的同学拿到一套 SpringBootVue 的日常办公用品直售推荐系统源码时,第一反应往往是:项目能跑起来吗?论文怎么凑?答辩问啥?作为带过不少 Java Web 课程设计和毕业设计的开发者,我拆过、改过、也给学生补…

阅读更多 →
Godot Compute Shader工具链:从零搭建GPU粒子系统 2026/10/1 10:53:11

Godot Compute Shader工具链:从零搭建GPU粒子系统

1. 从Unity/Unreal到Godot:为什么要自己造一套Compute Shader工具链1.1 一个被忽视的现实:引擎之间的Shader能力差距做过Unity或Unreal项目的人,一旦转到Godot,最先感受到的落差往往不是编辑器界面,也不是脚本语言&…

阅读更多 →
Go微服务骨架实战:Gin+gRPC+Consul+Nacos从零到联调 2026/10/1 10:53:11

Go微服务骨架实战:Gin+gRPC+Consul+Nacos从零到联调

先交代背景。上个月我们团队把一个单体后台拆成三个微服务,Gateway 用 Gin,内部用户服务和订单服务都用 gRPC 互相调用,注册发现选了 Consul,配置中心从 Spring Cloud Config 换成了 Nacos,ORM 统一用 GORM&#xff0c…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

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

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