文章目录
学习期间主要做的是无线通信领域的资源分配问题,特别针对的是类似香农信道容量的 log 形式的优化问题的仿真,有射频通信的,也有无线光通信的。在使用cvx求解的过程中也有一点儿心得体会,在这里记录下来和大家交流探讨,如有错误还请批评指正,此文的前提是要对cvx语法基本了解;
在仿真期间碰到过各种各样的问题,每个人的问题建模不同,且仿真的具体参数不同,导致问题五花八门,而在中文网站上,很少看到一些解决方法。本次博客针对香农信道容量的优化问题形式,进行记录,因优化问题形式不同,本文仅能写个大概,如果朋友们碰到问题了的话,建议还是优先去cvx官方论坛上查找或提问:cvx_forum,亦或是查看cvx user’s guide 一文(百度可找到);
对通信理论中信道容量的形式,稍微了解的朋友会知道大概是 这种形式

以下目标函数是凸函数:
- maximize 凹函数
- minimize 凸函数
以下约束是凸约束:
- 凹函数 >= 某一常数
- 凸函数 <= 某一常数
以上原理在boyd的凸优化的书里面,上镜图和下镜凸里有解释。
trace() 函数,因为是求迹,相当于是求矩阵的对角线元素,是个仿射函数 (就是线性的)
如果你的函数比较复杂,一眼看不出其凹凸性。有如下两种方法来验证:
- 查阅boyd的凸优化一书,里面给出了几个常见复合函数的凹凸性,也可以观看b站 中科大凌青老师的凸优化课程,讲的非常好!
- 利用函数凹凸性的一阶和二阶必要条件,求导来判断。至于如何求导,后文有给出相关方法。
- cvx对数据的精度是有要求的,例如上面的有用信号的数值,不能低于10^-12次方。 其实,使得仿真程序中某一块数据的计算值保持在不低于 10^-5 次方,cvx的求解才会很大程度上不会failed;
- 有两个方法解决上面的问题。一是归一化,对无线通信而言,噪声都是比信号小至少一个数量级的,我们可以对上面的log函数里面,先通分后,把1去掉,然后分子分母同时除以噪声,相当于把噪声归一化了,这样可以使得函数整体大小不变,同时放大的我们所需要的项。这个方法在无线光通信的理论仿真里面比较常用,因为光通信仿真里面的信道和信号都特别小,差不多是10的负10多次方了。
- 第二个个方法就是放缩,即是对 约束两边同时乘以一个很大的系数,这样也可以使得约束整体不变,但要注意这个缩放系数需要小心设置。我碰到的仿真,不加缩放系数,cvx求解为failed。加了不同的缩放系数,所得的结果也可能会不太相同。
- 另外你还可以通过设置 cvx_precision 这一选项去调整cvx求解器的默认精度,不过这个方法没怎么在我的仿真中见效。
- 有时可能你无论怎么调整,在程序刚开始的迭代过程中,cvx都是可以求解的,后面突然出现failed,或者程序报 Disciplined convex programming error: Cannot perform the operation 的错误 ,我的经验是缩放系数,或者是实验仿真参数还需要细调。(如果你是采用的迭代算法中是用梯度下降的,你也可以尝试动态调整步长的方法),另外还有如下方法:
- 替换常见的的操作符,如:平方的绝对值替换为square_abs()等等,在范数的平方里面多使用abs() ,具体的我记不太清了,具体可查看cvx_guide 一文。
- 另外,细心的朋友也会发现,在cvx求解过程中,会出现 CVX"s Successive Approximation method的方法,有时cvx里面的这种凸逼近的方法也会出现问题,导致最后,即使有结果,但结果仍然不满足部分约束。这时你可以采用cvx_quad 这个函数包,去替代你问题中的相关函数,比较常用的例子如下:
以上三个例子在SCA的方法中,尤其是指数替代中,有大用!
附:
有时我们会碰到原问题太复杂难以直接转化为凸问题,而是采用固定某一变量的方法,用二分查找的方法去不断迭代查找原问题的可行解。
cvx里面求可行解的方法有两种:一是minimize 0,二是find 优化变量
关于更换求解器,我的这篇文章里有详细的方法,有时采用不用的求解器,的确能得到solved的解。
下面针对我碰到过的这几种优化问题的形式,具体来说
此情况下,无论是该和速率是作为目标函数,还是作为约束,都不是凸函数的形式,原因是涉及到 log()+log() 的形式,是非凸的。常见解决方法,是采用迭代的方法,即采用 凸差 / 连续凸近似 / MM算法 (这三种算法的思想都是类似的),在每次迭代的过程中,用目标函数的下界(此时是凸的) 去替换原来的目标函数,那么,对每次迭代时,新的目标函数都是凸的,且每次的解出的结果都是原函数的下界。且迭代过程期间所得到解是递增的,多次迭代之后可得到原问题的一个local solution,(该算法思想可查看我之前的文章,有写过);
- 最大化最小的公平性问题,言外之意就是,我们需要去提升 系统中 表现最差的那一个用户,相当于是不断拔高木桶原理中最短的那根木板,使得系统总的性能更好。这类优化问题相对于和速率的问题而言,好解一些。
- 在cvx里面,可以采用一个辅助变量,如下,相当于我要求的是 所有的R_i的最小值 t,然后使得这个t 最大。

- 这种情况下的优化问题,目标函数是线性函数,是凸的。此时如果约束条件不那么复杂的话,一般可以采用通分,化简消除log函数,可以直接使得问题转换为凸问题来求解;
- 如果约束比较复杂的话,可以考虑对约束采用近似的方法,类似于前面提过的凸差/连续凸近似/MM算法去迭代求解。
- 针对以上三种形式的优化问题,其中可能会涉及到 波束成形向量的内积问题,是一个二次型优化问题。我们可以采用半正定松弛的方法,把其变为一次优化问题, 这个方法特别经典,在无线通信理论研究中常用。具体可参考 Luo zhiquan 老师的半正定松弛 论文(英文版的)。
- 对于多变量的优化问题,目前主流的方法是采用AO交替优化算法,即先固定某一个变量,对另一个变量而言就是凸的了。这样子进行交替求解,最后得到原问题的驻点。思想类似于块坐标下降法。特别地,目前,有些论文采用强化学习的方法,去解这种多变量互相耦合的优化问题或者是场景十分复杂的单变量优化问题,也取得了较好的效果。
- 另外,对于通信理论优化的研究中,常见的方法感觉都是基于梯度的,不要局限于不同的算法名字。对了,常用的方法还有 mmse优化,拉格朗日乘子法等等。这些算法对于函数的一阶导数甚至于二阶导数都需要一定的计算。关于矩阵函数求导的方法,我这里放上两篇文章,加上一个在线计算器,希望能帮到你。
以上资源也可以从我的阿里云盘里免费下载
链接:https://www.aliyundrive.com/s/7PBGKUigheX
调程序是一件无聊且枯燥的事,希望看到这的朋友们多发顶刊,前程似锦!码字不易,觉得有帮助的可以点赞收藏,有问题随时留言我看到了会及时回复,如有错误还请批评指正!
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。