在matlab中用符号变量对矩阵进行排序

Sorting a matrix with symbolic variables in matlab

我该如何排序或排列这个矩阵?第 10 行现在出现在最开始,而它应该按照顺序排在第 10 位。很少有其他元素也错位在中间。在这种情况下,所有变量都是符号的。谢谢。

[ P10_1, P10_10, P10_2, P10_3, P10_4, P10_5, P10_6, P10_7, P10_8, P10_9, P1_1, P1_10, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P2_1, P2_10, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P3_1, P3_10, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P4_1, P4_10, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P5_1, P5_10, P5_2, P5_3, P5_4, P5_5, P5_6, P5_7, P5_8, P5_9, P6_1, P6_10, P6_2, P6_3, P6_4, P6_5, P6_6, P6_7, P6_8, P6_9, P7_1, P7_10, P7_2, P7_3, P7_4, P7_5, P7_6, P7_7, P7_8, P7_9, P8_1, P8_10, P8_2, P8_3, P8_4, P8_5, P8_6, P8_7, P8_8, P8_9, P9_1, P9_10, P9_2, P9_3, P9_4, P9_5, P9_6, P9_7, P9_8, P9_9] 

排序函数 return this.The 第 10 行应该排在最后,但它出现在开头。

[ P10_1, P10_2, P10_3, P10_4, P10_5, P10_6, P10_7, P10_8, P10_9, P10_10, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P5_1, P5_2, P5_3, P5_4, P5_5, P5_6, P5_7, P5_8, P5_9, P6_1, P6_2, P6_3, P6_4, P6_5, P6_6, P6_7, P6_8, P6_9, P7_1, P7_2, P7_3, P7_4, P7_5, P7_6, P7_7, P7_8, P7_9, P8_1, P8_2, P8_3, P8_4, P8_5, P8_6, P8_7, P8_8, P8_9, P9_1, P9_2, P9_3, P9_4, P9_5, P9_6, P9_7, P9_8, P9_9, P1_10, P2_10, P3_10, P4_10, P5_10, P6_10, P7_10, P8_10, P9_10] 

我不知道你说的"symbolic"是什么意思?当它是一个字符串时,简单地将它们解析为数字(删除 'P' 并将下划线 '_' 替换为点 '.')。 最后在保存索引的同时进行排序。

this = '[ P10_1, P10_10, P10_2, P10_3, P10_4, P10_5, P10_6, P10_7, P10_8, P10_9, P1_1, P1_10, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P2_1, P2_10, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P3_1, P3_10, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P4_1, P4_10, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P5_1, P5_10, P5_2, P5_3, P5_4, P5_5, P5_6, P5_7, P5_8, P5_9, P6_1, P6_10, P6_2, P6_3, P6_4, P6_5, P6_6, P6_7, P6_8, P6_9, P7_1, P7_10, P7_2, P7_3, P7_4, P7_5, P7_6, P7_7, P7_8, P7_9, P8_1, P8_10, P8_2, P8_3, P8_4, P8_5, P8_6, P8_7, P8_8, P8_9, P9_1, P9_10, P9_2, P9_3, P9_4, P9_5, P9_6, P9_7, P9_8, P9_9]';

% this is the ugly part :)
original = regexp([regexprep(this, {'\[','\]'}, {'',''}) ','], '(.*?),', 'tokens');
m = eval(regexprep(this, {'_', 'P'},{'.',''}));

[s, idx] = sort(m);

original(idx)

如您所见,这只是部分起作用,因为 "symbolic" P10_1 < P10_10,但在数值层面上,它们是相等的。所以你只需要弄清楚如何处理它,例如确保您始终有两位小数,如果没有,请补上前导零。

如果不是字符串,忽略这个:)

horchler 在评论中建议创建适当的变量名,以使使用 sort 的词典排序正常工作。我认为这是一个非常好的主意,但不幸的是他建议的格式字符串不起作用。它总是填充一个零,最后是这样的:

>> P1 = sym('P0%d_0%d',10)

P =

[  P01_01,  P01_02,  P01_03,  P01_04,  P01_05,  P01_06,  P01_07,  P01_08,  P01_09,  P01_010]
[  P02_01,  P02_02,  P02_03,  P02_04,  P02_05,  P02_06,  P02_07,  P02_08,  P02_09,  P02_010]
[  P03_01,  P03_02,  P03_03,  P03_04,  P03_05,  P03_06,  P03_07,  P03_08,  P03_09,  P03_010]
[  P04_01,  P04_02,  P04_03,  P04_04,  P04_05,  P04_06,  P04_07,  P04_08,  P04_09,  P04_010]
[  P05_01,  P05_02,  P05_03,  P05_04,  P05_05,  P05_06,  P05_07,  P05_08,  P05_09,  P05_010]
[  P06_01,  P06_02,  P06_03,  P06_04,  P06_05,  P06_06,  P06_07,  P06_08,  P06_09,  P06_010]
[  P07_01,  P07_02,  P07_03,  P07_04,  P07_05,  P07_06,  P07_07,  P07_08,  P07_09,  P07_010]
[  P08_01,  P08_02,  P08_03,  P08_04,  P08_05,  P08_06,  P08_07,  P08_08,  P08_09,  P08_010]
[  P09_01,  P09_02,  P09_03,  P09_04,  P09_05,  P09_06,  P09_07,  P09_08,  P09_09,  P09_010]
[ P010_01, P010_02, P010_03, P010_04, P010_05, P010_06, P010_07, P010_08, P010_09, P010_010]

我尝试修复格式字符串但失败了。 MATLAB 拒绝接受需要的格式字符串:

>> P1 = sym('P%.2d_%.2d',10)
Error using sym>createCharMatrix (line
2172)
Symbolic matrix base name must be a
simple variable name.

Error in sym>convertCharWithOption
(line 2138)
        s = createCharMatrix(x,a);

Error in sym>tomupad (line 1871)
        S = convertCharWithOption(x,a);

Error in sym (line 109)
            S.s = tomupad(x,a);

所以我写了自己的函数来解决这个问题:

function [ s ] = symMatrix( A,set )
%preallocate an empty matrix to fill it in the loop
s=sym(zeros(set));
%just some math t get the required amount of digits.
digits=ceil(log10(max(set)+1));
%generate format string with required digits. Check documentation of sprintf for details
format=['%s%.',num2str(digits),'d_%.',num2str(digits),'d'];
%finally go through the matrix...
for r=1:set(1)
    for c=1:set(2)
       %...get the right name for each variable ....
       sprintf(format,A,r,c);
       %...and create a variable with that name.
       s(r,c)=sym(n);
    end
end
end

产生这个结果:

>> P2=symMatrix('P',[11,11])

P2 =

[ P01_01, P01_02, P01_03, P01_04, P01_05, P01_06, P01_07, P01_08, P01_09, P01_10, P01_11]
[ P02_01, P02_02, P02_03, P02_04, P02_05, P02_06, P02_07, P02_08, P02_09, P02_10, P02_11]
[ P03_01, P03_02, P03_03, P03_04, P03_05, P03_06, P03_07, P03_08, P03_09, P03_10, P03_11]
[ P04_01, P04_02, P04_03, P04_04, P04_05, P04_06, P04_07, P04_08, P04_09, P04_10, P04_11]
[ P05_01, P05_02, P05_03, P05_04, P05_05, P05_06, P05_07, P05_08, P05_09, P05_10, P05_11]
[ P06_01, P06_02, P06_03, P06_04, P06_05, P06_06, P06_07, P06_08, P06_09, P06_10, P06_11]
[ P07_01, P07_02, P07_03, P07_04, P07_05, P07_06, P07_07, P07_08, P07_09, P07_10, P07_11]
[ P08_01, P08_02, P08_03, P08_04, P08_05, P08_06, P08_07, P08_08, P08_09, P08_10, P08_11]
[ P09_01, P09_02, P09_03, P09_04, P09_05, P09_06, P09_07, P09_08, P09_09, P09_10, P09_11]
[ P10_01, P10_02, P10_03, P10_04, P10_05, P10_06, P10_07, P10_08, P10_09, P10_10, P10_11]
[ P11_01, P11_02, P11_03, P11_04, P11_05, P11_06, P11_07, P11_08, P11_09, P11_10, P11_11]

最后比较三种可能性的排序:

>> P3=sym('P',[11,11])

P3 =

[  P1_1,  P1_2,  P1_3,  P1_4,  P1_5,  P1_6,  P1_7,  P1_8,  P1_9,  P1_10,  P1_11]
[  P2_1,  P2_2,  P2_3,  P2_4,  P2_5,  P2_6,  P2_7,  P2_8,  P2_9,  P2_10,  P2_11]
[  P3_1,  P3_2,  P3_3,  P3_4,  P3_5,  P3_6,  P3_7,  P3_8,  P3_9,  P3_10,  P3_11]
[  P4_1,  P4_2,  P4_3,  P4_4,  P4_5,  P4_6,  P4_7,  P4_8,  P4_9,  P4_10,  P4_11]
[  P5_1,  P5_2,  P5_3,  P5_4,  P5_5,  P5_6,  P5_7,  P5_8,  P5_9,  P5_10,  P5_11]
[  P6_1,  P6_2,  P6_3,  P6_4,  P6_5,  P6_6,  P6_7,  P6_8,  P6_9,  P6_10,  P6_11]
[  P7_1,  P7_2,  P7_3,  P7_4,  P7_5,  P7_6,  P7_7,  P7_8,  P7_9,  P7_10,  P7_11]
[  P8_1,  P8_2,  P8_3,  P8_4,  P8_5,  P8_6,  P8_7,  P8_8,  P8_9,  P8_10,  P8_11]
[  P9_1,  P9_2,  P9_3,  P9_4,  P9_5,  P9_6,  P9_7,  P9_8,  P9_9,  P9_10,  P9_11]
[ P10_1, P10_2, P10_3, P10_4, P10_5, P10_6, P10_7, P10_8, P10_9, P10_10, P10_11]
[ P11_1, P11_2, P11_3, P11_4, P11_5, P11_6, P11_7, P11_8, P11_9, P11_10, P11_11]


>> sort(P1(:)).' %P1 = sym('P0%d_0%d',10)

ans =

[ P01_01, P01_02, P01_03, P01_04, P01_05, P01_06, P01_07, P01_08, P01_09, P02_01, P02_02, P02_03, P02_04, P02_05, P02_06, P02_07, P02_08, P02_09, P03_01, P03_02, P03_03, P03_04, P03_05, P03_06, P03_07, P03_08, P03_09, P04_01, P04_02, P04_03, P04_04, P04_05, P04_06, P04_07, P04_08, P04_09, P05_01, P05_02, P05_03, P05_04, P05_05, P05_06, P05_07, P05_08, P05_09, P06_01, P06_02, P06_03, P06_04, P06_05, P06_06, P06_07, P06_08, P06_09, P07_01, P07_02, P07_03, P07_04, P07_05, P07_06, P07_07, P07_08, P07_09, P08_01, P08_02, P08_03, P08_04, P08_05, P08_06, P08_07, P08_08, P08_09, P09_01, P09_02, P09_03, P09_04, P09_05, P09_06, P09_07, P09_08, P09_09, P010_01, P010_02, P010_03, P010_04, P010_05, P010_06, P010_07, P010_08, P010_09, P01_010, P02_010, P03_010, P04_010, P05_010, P06_010, P07_010, P08_010, P09_010, P010_010]

>> sort(P2(:)).' %P2=symMatrix('P',[11,11])

ans =

[ P01_01, P01_02, P01_03, P01_04, P01_05, P01_06, P01_07, P01_08, P01_09, P01_10, P01_11, P02_01, P02_02, P02_03, P02_04, P02_05, P02_06, P02_07, P02_08, P02_09, P02_10, P02_11, P03_01, P03_02, P03_03, P03_04, P03_05, P03_06, P03_07, P03_08, P03_09, P03_10, P03_11, P04_01, P04_02, P04_03, P04_04, P04_05, P04_06, P04_07, P04_08, P04_09, P04_10, P04_11, P05_01, P05_02, P05_03, P05_04, P05_05, P05_06, P05_07, P05_08, P05_09, P05_10, P05_11, P06_01, P06_02, P06_03, P06_04, P06_05, P06_06, P06_07, P06_08, P06_09, P06_10, P06_11, P07_01, P07_02, P07_03, P07_04, P07_05, P07_06, P07_07, P07_08, P07_09, P07_10, P07_11, P08_01, P08_02, P08_03, P08_04, P08_05, P08_06, P08_07, P08_08, P08_09, P08_10, P08_11, P09_01, P09_02, P09_03, P09_04, P09_05, P09_06, P09_07, P09_08, P09_09, P09_10, P09_11, P10_01, P10_02, P10_03, P10_04, P10_05, P10_06, P10_07, P10_08, P10_09, P10_10, P10_11, P11_01, P11_02, P11_03, P11_04, P11_05, P11_06, P11_07, P11_08, P11_09, P11_10, P11_11]

>> sort(P3(:)).' %P3 = sym('P',10) 

ans =

[ P10_1, P10_2, P10_3, P10_4, P10_5, P10_6, P10_7, P10_8, P10_9, P11_1, P11_2, P11_3, P11_4, P11_5, P11_6, P11_7, P11_8, P11_9, P10_10, P10_11, P11_10, P11_11, P1_1, P1_2, P1_3, P1_4, P1_5, P1_6, P1_7, P1_8, P1_9, P2_1, P2_2, P2_3, P2_4, P2_5, P2_6, P2_7, P2_8, P2_9, P3_1, P3_2, P3_3, P3_4, P3_5, P3_6, P3_7, P3_8, P3_9, P4_1, P4_2, P4_3, P4_4, P4_5, P4_6, P4_7, P4_8, P4_9, P5_1, P5_2, P5_3, P5_4, P5_5, P5_6, P5_7, P5_8, P5_9, P6_1, P6_2, P6_3, P6_4, P6_5, P6_6, P6_7, P6_8, P6_9, P7_1, P7_2, P7_3, P7_4, P7_5, P7_6, P7_7, P7_8, P7_9, P8_1, P8_2, P8_3, P8_4, P8_5, P8_6, P8_7, P8_8, P8_9, P9_1, P9_2, P9_3, P9_4, P9_5, P9_6, P9_7, P9_8, P9_9, P1_10, P1_11, P2_10, P2_11, P3_10, P3_11, P4_10, P4_11, P5_10, P5_11, P6_10, P6_11, P7_10, P7_11, P8_10, P8_11, P9_10, P9_11]