Recently, I encountered a linear algebra problem on Mathematics Stack Exchange.
For any given matrix $A$ in Octave,
A = [1 2 2; 2 3 4; 4 4 2]
A =
1 2 2
2 3 4
4 4 2
how can one generate its $\rm \LaTeX$ code
1
A = \begin{bmatrix} 1&2&2\ 2&3&4\ 4&4&2 \end{bmatrix}
so that one gets
I searched “octave to latex matrices” and I found this answer quite useful. I issued the first command to see the result.
strrep(strrep(mat2str(A),",","&"),";","\\\\\n")(2:end-1)
ans = 1 2 2\\
2 3 4\\
4 4 2
I suspected that it didn’t work. I posted it as a comment and
verified that I was right. To fix this, I extracted the function
mat2str(A)
in the middle of this command to see the results. From
its result (ans = [1 2 2;2 3 4;4 4 2]
), I realised that strrep
standed for “string replace”. Then, I changed the double-quoted comma
in the second argument of function strrep
to a double-quoted
whitespace character, and got the anticipated result.
strcat("\\begin{bmatrix}\n",strrep(strrep(mat2str(A)," ","&"), ...
";","\\\\\n")(2:end-1),"\n\\end{bmatrix}\n")
ans = \begin{bmatrix}
1&2&2\\
2&3&4\\
4&4&2
\end{bmatrix}
I don’t know how to do this for matrices with fractions. I think I can work it out by searching and testing in several hours, but I don’t have the time to do so.
I revised some definitions in linear algebra.
strrep(str,"foo","bar")
replaces all instances of
foo
in str
with bar
. It can be used in a nested manner for
multiple replacements.strcat(str1,str2,...)
concatenates the strings
inside.When I was writing this article, I wanted to search for “octave”
(with the square brackets “[]”) with grep
inside Vim, but I got
over 1270 results. I tried adding single/double quotes and escaping
the square brackets with a backslash, but I faied again. Finally, I
googled “grep escape character” for a solution. Since then, I know
that I should add the -F
flag to grep
to fix the
string.
It’s easy that one makes careless mistakes in a pivot operation. As a result, in test/exams in which calculators are allowed, I used a simple program to save time.
Answering linear programming question on Mathematics Stack Exchange, I used GNU Octave to do the tedious work.
First write the LPP in standard form. I assume that $b$ and $c$ are column vectors.
c
is the objective function.A
is the coefficient matrix of the constraints. (a.k.a technology
matrix)b
is the RHS of the constraints.T0
is the initial tableau.My habit is to
1
2
3
4
5
6
7
format rat;
c = [-1 2 -3 0 0 0]’; b = [11 0 8]’;
A = [
1 -.5 1 1 0 0;
0 2 -1 0 1 0;
0 0 0 2 0 1];
T0 = [A b; -c’ 0]
The command basis = [3 2 6]
is used to choose the decision variables
$x_3,x_2$ and $x_6$ as the
basis. Note that the order of the entries in the array basis
is
very important. By setting this array, I don’t need to repeat
typing the same set of numbers for $B$ and $c_B$.
1
2
basis = [3 2 6]; B = A(:,basis); cB = c(basis);
T = [B\A B\b; cB’<em>(B\A)-c’ cB’</em>(B\b)]
Since I’m no longer in an LP course, I’m too lazy to write the code for finding the suitable elements for a pivot operation. We don’t need to re-develop something that has been well-developed.
]]>Recently, I post math on Mathematics Stack Exchange instead of here.
How can one get a table for the distribution of reputation on that site?
Write a SQL query on Stack Exchange Data Explorer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
select u.range as [prev row <= Reputation <= this row], count(*) as [Users]
from (
select case
when Reputation between 1 and 4 then 4
when Reputation between 5 and 9 then 9
when Reputation between 10 and 14 then 14
when Reputation between 15 and 19 then 19
when Reputation between 20 and 49 then 49
when Reputation between 50 and 74 then 74
when Reputation between 75 and 99 then 99
when Reputation between 100 and 124 then 124
when Reputation between 125 and 249 then 249
when Reputation between 250 and 499 then 499
when Reputation between 500 and 999 then 999
when Reputation between 1000 and 1999 then 1999
when Reputation between 2000 and 2499 then 2499
when Reputation between 2500 and 2999 then 2999
when Reputation between 3000 and 4999 then 4999
when Reputation between 5000 and 9999 then 9999
when Reputation between 10000 and 14999 then 14999
when Reputation between 15000 and 19999 then 19999
when Reputation between 20000 and 24999 then 24999
else 400000 end as range
from Users) u
group by u.range
The indentation is automatically done by Vim. I know that the
syntax is ugly. If I assign text string to the column u.range
,
then the table is sorted in alphabetical order of that column
instead of numerical order. This doesn’t make sense. Therefore, I
use a dirty way to get the statistics, and played with the built-in
graphing function. However, the visual result isn’t so
satisfactory.
Anyone who has completed high school will realise that a log graph is better. Asking for this feature on Meta Stack Exchange takes time. I believe that such feature request will be rejected by the moderator to reduce the workload of Stack Exchange company. Therefore, I plot the log graph using GNU Octave.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
A = [
4,86698;
9,23074;
14,17793;
19,9897;
49,22201;
74,5852;
99,3187;
124,39216;
249,9960;
499,4471;
999,2496;
1999,1416;
2499,319;
2999,223;
4999,482;
9999,356;
14999,155;
19999,81;
24999,45;
400000,152];
loglog(A(:,1), A(:,2), ".-k");
for i = 1:numel(A(:,1))
text(A(i,1), A(i,2), ['(' num2str(A(i,1)) ',' num2str(A(i,2)) ')'], ...
"fontsize", 12);
end
title("User's Total Reputation Distribution on Math Stack Exchange", ...
"fontsize", 14);
I choose loglog
because semilogx
causes the labels on tail to
overlap. Here’s the results.
I can save plots in GNU Octave as a SVG file. I know this after
searching “octave export svg”. From
Printing and Saving Plots, I see print -d[device]
,
in which one can substitute the output format. For example, I used
print -dsvg
to generate the SVG’s shown above.
To verify the inequality
found on Math Stack Exchange, I wrote the following Octave script.
1
2
3
4
5
a = 0.1; b = 0.2; c = 1 - a - b;
A = ((a+b)*(b+c)*(c+a))^(1/3)
B = (a*b*c)^(1/3)
C = (sqrt((a+b)/c) + sqrt((b+c)/a) + sqrt((c+a)/b))^2
16/(3*A^3)
The above script did the calculations, but a warning message appeared.
$ octave -q test.m
warning: function ./test.m shadows a core library function
A = 0.60000
B = 0.24101
C = 31.975
ans = 24.691
How can I run this script without the warning?
Change the file name of the script to an uncommon name.
$ mv test.m test1.m
$ octave -q test1.m
A = 0.60000
B = 0.24101
C = 31.975
ans = 24.691
]]>