2012年1月9日星期一

Custom command, counter and ref in Latex

Custom command, counter and ref in Latex


Beginning of the Story


Before a paper is accepted somewhere, usually I will need to revise the paper based on the reviewers' comments. A document namely "replies_to_reviewer_comments.pdf" is necessary to answer the questions raised by the reviewers and state the changes of the revised paper.


One day I got a decision of my previously submitted paper. The result is "revise and resubmit". So sad. The comments are overwhelming. What I can do is to carry out more experiments, ammend the manuscript and write the "replies_to_reviewer_comments" to answer the questions. The structure and layout of the file is supposed to be like follows:


Reviewer #1
Comment #1-1
Blah blah
Reply:
Blah blah
Comment #1-2
Blah blah
Reply:
Blah blah
Reviewer #2
Comment #2-1
Blah blah
Reply:
Blah blah

I want to add a 2.5mm space between Comment and Reply and make the text Reply: in bold font. Moreover, I don't like to repeat all this and manage all the numbers like #1-2 manually. Therefore I Googled a bit and found it was quite easy to do this with LaTeX.


New Command


Let put aside the numbers and just look at the format: adding space and bold font. I implemented these with three new commands: \reviewer, \comment and \reply.


Defining new command in Latex is easy. Just use the \newcomamnd or renewcommand command, as follows:


\newcommand{\reviewer}{%
\section*{Reviewer }}
\newcommand{\comment}{%
\subsection*{Comment }}
\newcommand{\reply}{%
\vspace{5 mm}%
{\bfseries Reply: }}

If you are interested in the details of \newcommand, please refer to the wiki page.


Managing Numbers: Counters


Now I have the three new commands and want to add the reviewer and comment number to them. Managing the numbers manually is a disaster if there are many comments. Fortunately, this can be easily solved by using counters.


First, I define two counters reviewerno and commentno and set them to 0:


\newcounter{reviewerno}
\setcounter{reviewerno}{0}
\newcounter{commentno}[reviewerno]
\setcounter{commentno}{0}

The counter commentno is defined as a sub-counter of reviewerno. This means that when reviewerno is changed, commentno will be reset to 0, which is exactly what I want.


Now I modify the command \reviewer and \comment to add counters to them:


\newcommand{\reviewer}{%
\stepcounter{reviewerno}%
\section*{Reviewer \#\arabic{reviewerno}}}
\newcommand{\comment}{%
\stepcounter{commentno}%
\subsection*{Comment \#\arabic{reviewerno}-\arabic{commentno}}}

The command \stepcounter{counter} increases counter by 1. Command \arabic{counter} outputs the value of counter in arabic numbers. More operations on counter can be found here.


Now I can write my replies like this:


\reviewer
\comment
Blah blah
\reply
Blah blah

The nubmers will be automatically mantained and added by LaTeX.


Label and Ref


The new commands and counters work pretty good, but now I have a new requirement: two comments asked the same question. I want to answer it in the first comment and put a reference to the answer in the other one. Of course I can just hard code the comment number like "please refer to Comment #1-1 for details", but this is not flexible. What if the nubmer of the comment changes? I don't want to update all the references to it.


Now I need a reference to a custom counter. In LaTeX, we usually use the \label{label_name} command to define a label and \ref{label_name} to generate a reference to it. In fact, what \label{label_name} does is assigning the name label_name to the current value of \ref. Correspondingly, \ref{label_name} retrieves the value using label_name.


Here the command needed is \refstepcounter{counter}. It increases counter by 1 and sets the value of \ref to counter. We can simply replace the previous \stepcounter{count} with \refstepcounter{count}. Now we try to make a reference:


\reviewer
\comment
\label{com:novelty}
Blah blah
\reply
Blah blah
\comment
Blah blah
\reply
Please refere to our response to Comment \ref{com:novelty}

The output of the code is like this


Reviewer #1 
Comment #1-1
Blah blah
Reply:
Blah blah
Comment #1-2
Blah blah
Reply:
Please refere to our response to Comment 1

It works, but not perfectly. What we want to see is a reference to Comment #1-1. How can we set the \ref to two counters with formating in #reviewerno-commentno?


The trick is that everytime you define a counter, say counter, LaTeX will define a command \thecounter for it. counter is printed in LaTeX by using \thecounter. Hence we can redefine this command for commentno to let \ref print whatever we want. Now we define it with the following code:


\renewcommand{\thecommentno}{\#\arabic{reviewerno}-\arabic{commentno}}

and it works like a charm.


More details can be found at this link and the discussion here.


The Code and PDF File


The complete LaTeX source file and the generated PDF file can be found at my GitHub https://github.com/beyondwdq/Recipes/tree/master/latex/custom_ref.


The code is also listed as follows:


\documentclass[a4paper]{article}
\newcounter{reviewerno}
\setcounter{reviewerno}{0}
\newcounter{commentno}[reviewerno]
\setcounter{commentno}{0}
\renewcommand{\thereviewerno}{\#\arabic{reviewerno}}
\renewcommand{\thecommentno}{\#\arabic{reviewerno}-\arabic{commentno}}
\newcommand{\reviewer}{%
\refstepcounter{reviewerno}%
\section*{Reviewer \thereviewerno}}
\newcommand{\comment}{%
\refstepcounter{commentno}%
\subsection*{Comment \thecommentno}}
\newcommand{\reply}{%
\vspace{5 mm}%
{\bfseries Reply: }}
\begin{document}
\title{Replies to Review-Comments}
\begin{center}
{\bfseries Summary of Changes}
\end{center}
\reviewer
\comment
\label{com:novelty}
The paper lacks novelty.
\reply
The novelty of the paper is summarized as follows:
\begin{itemize}
\item Novelty A
\item Novelty B
\end{itemize}
\comment
More simulations are need to fully evaluate the proposed method. The
contributions of the paper is not clear.
\reply
We have carried out extensive simulations based on the reviewer's suggestion.
Please refer to Comment \ref{com:novelty} for the details of our contributions.
\reviewer
\comment
The paper is well-written and can be published with minor changes.
\reply
We have revised the manuscript based on the reviewer's suggestion.
\end{document}

2010年3月19日星期五

Eliminate the warning "./common/packet.h warning: deprecated conversion from string constant to ‘char*’"

When compiling NS-2.33, g++ keeps complaining: ./common/packet.h:329: warning: deprecated conversion from string constant to ‘char*’ . There are many places in packet.h cause this warning. The solution to eliminate it is as follows:

packet.h
about line: 401
change the definition of p_info::name_ to static char const** name_;
about line:278
change the allocation of name to const char * *nameNew = new const char*[PT_NTYPE+1];

packet.cc
about line: 44
change the declaration of p_info::name_ to const char** p_info::name_;

ptypes2tcl.cc
line:13
change the declaration of p_info::name_ to const char** p_info::name_;

2009年6月14日星期日

Papers Related to Media Access Patterns

Here is a list of papers on media access pattern statistics and analysis:

On Feasibility of P2P On-Demand Streaming via Empirical VoD User Behavior Analysis, Distributed Computing Systems Workshops, 2008. ICDCS '08. 28th International Conference on
The Stretched Exponential Distribution of Internet Media Access Patterns, PODC'08
Can Internet Video-on-Demand be Profitable, SIGCOMM'07
GISMO:A Generator of Internet Streaming Media Objects and Workloads, SIGMETRICS'01
Challenges, Design and Analysis of a Large-scale P2P-VoD System, SIGCOMM'08

2009年4月28日星期二

Error When Running Simulation with Valgrind

When I ran my NS2 simulation with valgrind, I got the following error report:

==25876== Use of uninitialised value of size 8
==25876== at 0x3834AC85C0: profil_counter (in /lib64/tls/libc-2.3.4.so)
==25876== by 0x3834A2E2AF: (within /lib64/tls/libc-2.3.4.so)
==25876== by 0x3835ADAD2F: (within /usr/lib64/libstdc++.so.6.0.3)

It occurs from time to time. It seems that only happens when running on a 64 bit system.

I think the possible reason is the simulator is compiled with flag -pg because the field "profil_counter" is used by gcc for profiling. Got no solution yet.

2009年2月4日星期三

The Importance of not Using "bind()" in NS2

As described in my last post, I used valgrind to find out the memory usage of my simulator. Finally, I found that a invocation of "bind()" in UdpAgent::UdpAgent()" consumes most memory. That reminds me that the ns2 manual recommends to use dynamic binding instead of "bind" when the object of a class is frequently created. In my case, the P2P application requires two UdpAgents for a connection. Since the connections are created and removed constantly, the memory consumed by bind() keeps increasing. To solve this problem, I modified class UdpAgent as follows:

apps/udp.h
add two declarations:
virtual void delay_bind_init_all();
virtual int delay_bind_dispatch(const char *varName, const char *localName, TclObject *tracer);
apps/udp.cc
delete "bind("packetSize_", &size_);" in UdpAgent::UdpAgent() and UdpAgent::UdpAgent(packet_t type)
add two definition:
void UdpAgent::delay_bind_init_all()
{
delay_bind_init_one("packetSize_");
Agent::delay_bind_init_all();
}

int UdpAgent::delay_bind_dispatch(const char *varName, const char *localName, TclObject *tracer)
{
if (delay_bind(varName, localName, "packetSize_", &size_, tracer))
return TCL_OK;
return Agent::delay_bind_dispatch(varName, localName, tracer);
}

Then type "make clean; make" to rebuild ns2. Now the memory usage and simulation time is reduced significantly.

I'm not very clear about what does it do when "bind()" is invoked and why the memory is not released even when the UdpAgent object is deleted. Anyone who knows the answer please post me a message.

Profiling Memory Usage for NS2 Simulation

I am using ns2 to simulate peer-to-peer networking. However, it turns out that the simulator consumes much more memory than I expected. I am sure that my algorithm could not use so much memory. What's happening during the simulation.

I tried dmalloc, but it seems that the dmalloc supporting in ns2 is out-of-data and causes some error. Finally I gave up dmalloc and turned to valgrind.

I used valgrind to detect memory leaks and errors. Today I learned that it can also do memory usage profiling.

First, you have to pass '-g' option to compiler and re-make ns2. It is recommended to remove any optimization flags when debugging.

Then run your program by typing "valgrind --tool=massif ns test_script.tcl". BTW, I recommend u to specify a threshold for massif by using "valgrind --tool=massif --threshold=0.01 ns test_script.tcl" to get more detailed information.

massif will generate a report in current directory. The default name is massif.out.pid, where pid is the process number.

massif.out is a plain text file. Though u can read it directly, there is another helpful tool, ms_print to gather information in the report and print it more readable. Use ms_print --threshold=0.01 massif.out to format the report.

The output of ms_print is very easy to understand and the online document of valgrind has a detailed description about that. Please refer to http://valgrind.org/docs/manual/ms-manual.html

2009年2月3日星期二

Enable DMalloc support for NS2

Since my NS2 eats too much memory, which makes the simulation not scalable, I was trying to profile the memory usage by enable dmalloc support for NS2.

Originally I download ns-2.33-all-in-one and install it on my Ubuntu 8.04 Linux.

The NS2 manual seems to show that it very easy to enable dmalloc for NS2, but it's kinda out of date.

First, ns2 needs an old version of dmalloc, for example, I use dmalloc-4.8.2. If u use dmalloc-5.5.1, compiler will complain "_malloc_leap was not declared in this scope"

Extract and drop dmalloc-4.8.2 in the parallel directory of ns-2.33, build it using "./configure" and "make". "make install" is unneccessary. If you use "make install" to install dmalloc in your system, the configure script of ns-2.33 will complain "checking for return.h... no".

Change working directory to ns-2.33, type " ./configure --with-otcl=../otcl-1.13 --with-tclcl=../tclcl-1.19 --with-dmalloc=../dmalloc-4.8.2", it will generate Makefile for you.

Try "make" in ns-2.33, a link error occur: multiple definition of TclpAlloc. This is because libtcl8.4.a already defines TclpAlloc and ns-2.33/lib/dmalloc_support.cc tries to redefine it. I actually have no idea of how to solve this problem. A temporary solution is, if u do not care about the memory TclpAlloc and Tcl_Alloc, just comments out the definition of these two funtions in dmalloc_support.cc and then compilation will success.

After building ns2 with dmalloc, then u can follow the steps in ns2 manual except for the one adding alias for bash. It seems to be a typing error in my ns2 manual. The correct alias should be: function dmalloc { eval `command dmalloc -b $*`; }

That's all.