A higher quality of work is expected of graduate students by advisors, peers and others. One of the best ways to start producing a higher quality of work is to start using more advanced tools to produce your work. These particular tools will help you produce material that visually impresses and assists you in producing graduate student quality material.
LaTeX
LaTeX is a "document markup language and document preparation system" that makes your work of print quality. Instead of a "what you see is what you get" (WYSIWYG) editing paradigm used in visual programs such as Microsoft Word, LaTeX is designed as "what you see is what you mean".
Instead of managing a document visually, where you are constantly adjusting spacing, styles, positions, etcetera you simply work directly with the content. Then, after you have created your content, you apply a style after the fact. This is true for content which you are publishing, you provide them with the LaTeX document, and then they apply their own styling rules. Most journals, publishers, and thesis submissions accept LaTeX as the document source, so it's a good idea to get familiar with LaTeX early. You don't want to be struggling with LaTeX while trying to get your thesis out the door under a time crunch.
Windows Editor
For working with LaTeX in a Windows environment, I would highly suggest TeXniCenter.
"TeXnicCenter is a feature rich and easy-to-use integrated environment for creating LaTeX documents on the Windows platform. Its powerful editor and its tight integration with the LaTeX environment helps you to concentrate on what matters: The content of your document. TeXnicCenter is Free Open Source Software (GPL)."
TeXnicCenter
Linux Editor
For working with LaTeX in a Linux environment, I would highly suggest Kile.
"Kile is an integrated LATEX environment for the KDE desktop. Kile gives you the ability to use all the functionalities of LATEX in a graphical interface, giving you easy, immediate, and customized access to all programs for LATEX code completion, compiling, postprocessing, debugging, conversion and viewing tools; you also get very handy wizards, a LATEX reference and a powerful project management." Kile
TeXPoint
TexPoint is a very useful tool for including equations and LaTeX content within PowerPoint presentations. The website is not the most impressive, but the add-in for PowerPoint makes including equations in a presentation remarkably simple and beautiful. You can edit the equations in place using LaTeX markup. This is far superior to MathML and other visual equation editors out there. You can copy your equations from your thesis directly into your presentation with high quality images.
Mendely
As a graduate student, you will go through dozens if not hundreds of articles and papers in PDF form. Mendeley, simply put, makes this manageable. It automatically creates the citations for your PDFs and allows you to organize, annotate and highlight your documents. It's also a social service, so you may use it to collaborate with your peers. Further, the citations are given in LaTeX format so that it is highly compatible with the above mentioned tools.
"Mendeley is a free reference manager and academic social network that can help you organize your research, collaborate with others online, and discover the latest research." Mendeley
Grammarly
As an engineering graduate student, my grammar could always use some help. Grammarly is like a very powerful spell-check in Microsoft Word. It is compatible with LaTeX code and is targeted towards Academics. It even detects any accidental plagiarism. It is exceptional at telling you WHY your sentences are broken instead of just auto correcting.
"Grammarly is an automated proofreader and your personal grammar coach. Check your writing for grammar, punctuation, style and much more." Grammarly
Give these tools a try; all but Grammarly and TeXPoint are free.
I have wrapped the interpolation method using the Fenics Project into a template class. The class is template on the interpolation basis function so that the user may choose the order of interpolation. The class also contains an array of y values so that it may serve as a table of values. Part of this is a map to the variable name for convenience when calling for tabled values.
Since all the work goes into extrapolating to a higher basis function when the Constructor is called, lookups are cheap to retrieve. The cost should be about the level of evaluating a polynomial of the order of the interpolation level (since the weights are known).
An example of it being used:
boost::shared_ptr<Vector> xs (new Vector(n));
boost::shared_ptr<Vector> ys1 (new Vector(n));
boost::shared_ptr<Vector> ys2 (new Vector(n));
std::vector<boost::shared_ptr<Vector> > yss;
std::vector<string> names;
// Populate test data
for(int i=0; i<n; i++)
{
xs->setitem(i,i+i*0.1);
ys1->setitem(i,(*xs)[i]*(*xs)[i]);
ys2->setitem(i,(*xs)[i]*(*xs)[i]*(*xs)[i]);
}
yss.push_back(ys1);
names.push_back("squared");
yss.push_back(ys2);
names.push_back("cubed");
InterpolationTable<Interpolate3::FunctionSpace> interpTable (xs, yss, names);
std::cout << interpTable.eval(0,2.12) << "\t" << interpTable.eval("squared",2.12) << "\n";
std::cout << interpTable.eval(1,2.12) << "\t" << interpTable.eval("cubed",2.12) << "\n";
The code listing:
// InterpolationTable.h
// Class for interpolating tabled values using the Fenics Project.
// Charles R. Cook v1.0 29 Nov 2011
// Copyright (c) 2011 Charles R. Cook
// http://www.charlesrcook.com
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
#ifndef _INTERPOLATIONTABLE_H
#define _INTERPOLATIONTABLE_H
#include <dolfin.h>
#include "Interpolate1.h"
#include "Interpolate2.h"
#include "Interpolate3.h"
#include "Interpolate4.h"
using namespace dolfin;
template <class TFunctionSpace>
class InterpolationTable
{
public:
InterpolationTable(boost::shared_ptr<Vector> xs_in,
std::vector<boost::shared_ptr<Vector> > ys_in);
InterpolationTable(boost::shared_ptr<Vector> xs_in,
std::vector<boost::shared_ptr<Vector> > ys_in,
std::vector<std::string> names_in);
double eval(int index, double x);
double eval(std::string name, double x);
// These vectors contain the raw data
boost::shared_ptr<Vector> xs;
boost::shared_ptr<std::vector<boost::shared_ptr<Vector> > > ys;
// The mesh (defined as nodes at x locations)
boost::shared_ptr<Mesh> mesh;
boost::shared_ptr<Interpolate1::FunctionSpace> V1;
boost::shared_ptr<TFunctionSpace> V2;
boost::shared_ptr<std::vector<Function> > fy1;
boost::shared_ptr<std::vector<Function> > fy2;
boost::shared_ptr<std::vector<std::string> > Names;
private:
void Setup(boost::shared_ptr<Vector> xs_in,
std::vector<boost::shared_ptr<Vector> > ys_in);
boost::shared_ptr<std::map<std::string,int> > mapping;
};
template <class TFunctionSpace>
double InterpolationTable<TFunctionSpace>::eval(
std::string name, double x)
{
if((*Names).size()==0)
throw ("names not defined");
// check key exists in map
if ((*mapping).find(name) == (*mapping).end() )
throw ("name was not found");
int index = (*mapping)[name];
return eval(index, x);
}
template <class TFunctionSpace>
double InterpolationTable<TFunctionSpace>::eval(
int index, double x)
{
if(index >= (*ys).size())
throw ("index out of range");
if(x < mesh->coordinates()[0] ||
x > mesh->coordinates()[(*mesh).num_cells()])
throw ("x location out of range");
return (*fy2)[index](x);
}
template <class TFunctionSpace>
void InterpolationTable<TFunctionSpace>::Setup(
boost::shared_ptr<Vector> xs_in,
std::vector<boost::shared_ptr<Vector> > ys_in)
{
// copy the x locations in
xs = xs_in;
// copy the data in
for (uint i=0; i<ys_in.size(); i++)
{
(*ys)[i] = ys_in[i];
}
// Setup the mesh to interpolate on
// Note the count is the number of elements, not nodes
// when the interval is constructed
for(uint i=0; i<xs->size(); i++)
mesh->coordinates()[i] = (*xs)[i];
// Setup the Function space(s)
for (uint i=0; i<ys->size(); i++)
{
Function fv1(V1,(*ys)[i]);
fy1->push_back(fv1);
Function fv2(V2);
fv2.extrapolate(fv1);
fy2->push_back(fv2);
}
}
template <class TFunctionSpace>
InterpolationTable<TFunctionSpace>::InterpolationTable(boost::shared_ptr<Vector> xs_in,
std::vector<boost::shared_ptr<Vector> > ys_in,
std::vector<std::string> names_in) :
xs(new Vector(xs_in->size())),
ys(new std::vector<boost::shared_ptr<Vector> > (ys_in.size())),
mesh(new Interval(xs_in->size()-1,0,1)),
V1(new Interpolate1::FunctionSpace(mesh)),
V2(new TFunctionSpace(mesh)),
fy1(new std::vector<Function>),
fy2(new std::vector<Function>),
Names(new std::vector<std::string>),
mapping(new std::map<std::string, int>)
{
Setup(xs_in, ys_in);
(*Names) = names_in;
for(uint i=0; i < (*Names).size(); i++)
(*mapping)[(*Names)[i]] = i;
}
template <class TFunctionSpace>
InterpolationTable<TFunctionSpace>::InterpolationTable(boost::shared_ptr<Vector> xs_in,
std::vector<boost::shared_ptr<Vector> > ys_in) :
xs(new Vector(xs_in->size())),
ys(new std::vector<boost::shared_ptr<Vector> > (ys_in.size())),
mesh(new Interval(xs_in->size()-1,0,1)),
V1(new Interpolate1::FunctionSpace(mesh)),
V2(new TFunctionSpace(mesh)),
fy1(new std::vector<Function>),
fy2(new std::vector<Function>),
Names(new std::vector<std::string>),
mapping(new std::map<std::string, int>)
{
Setup(xs_in, ys_in);
}
#endif /* _INTERPOLATIONTABLE_H */
My recent research has been with the Fenics Project, which is an amazing finite element project. In general it provides the tools needed to solve differential equations with the finite element method. For some examples check out their website and view the demos and applications (my interest is in CFD).
In my particular code I need to interpolate tabulated properties (steam tables) with some reasonable level of accuracy. The solution in MATLAB is straight forward, call interp1:
y_i = interp1(xs, ys, x_i, 'cubic');
Where xs and ys are vectors of known x and y values and y_i is the interpolated value at x_i.
The code I am working on is already using the Fenics Project to solve a set of PDEs, so I wanted to see if I could use it for the interpolation as well through the finite element's basis functions. As the title of this post indicates, it can be done and here is how through a code snippet.
In C++…
// Setup data vectors
Vector xs(n);
Vector ys(n);
// Populate test data (this would be the tabulated data)
for(int i=0; i<n; i++)
{
xs.setitem(i,i+i*0.1);
ys.setitem(i,xs[i]*xs[i]);
}
// Setup the mesh to interpolate on
// Note the count is the number of elements, not nodes.
// there are general n-1 elements than nodes.
Interval mesh (n-1,0,1);
for(int i=0; i<n; i++)
mesh.coordinates()[i] = xs[i];
// create the function space of order one.
// this is done so that dof maps directly to
// data points. This provides a linear interpolation.
Interpolate1::FunctionSpace V (mesh);
// copy the data into the function space
Function fy (V, ys);
// Create quadratic function space (quadratic interpolation)
Interpolate2::FunctionSpace V2 (mesh);
Function fy2 (V2);
// 'fit' to the quadratic basis functions through least squares
fy2.extrapolate(fy);
// The fitted function is now available in fy2 as a quadratic fit
std::cout << "O(1): " << fy(2)
<< "\tO(2): " << fy2(2)
<< "\n";
Note that two UFL files (form files) are needed for this snippet.
Interpolate1.ufl
# First order (linear) lagrange elements (polynomials)
element = FiniteElement("Lagrange", interval, 1)
Interpolate2.ufl
# Second order lagrange elements (polynomials)
element = FiniteElement("Lagrange", interval, 2)
To create higher order fitting you can change the element to be of the desired order (instead of 2).
The very nice feature of interpolation through this method is that it will work in two dimensions and three dimensions as well. To do so, the elements would be updated to 2-d or 3-d element types instead of 'interval' (say triangle or tetrahedral). Too cool!