20091231

Order Matters With XCode's Build Phrases

I use a custom script to insert the current git commit into GeoNote, so when I get bug reports I have a better idea of which version the user is running. The script is as below:

import os
from Foundation import NSMutableDictionary

version = os.popen4("/sw/bin/git rev-parse --short HEAD")[1].read()
info = os.environ['INFOPLIST_FILE']
print info
plist = NSMutableDictionary.dictionaryWithContentsOfFile_(info)
print plist
plist['revision'] = version[:-1]
plist.writeToFile_atomically_(info, 1)

This was added as a Run Script Build Phrase. The problem I noticed was that the commit short hash inserted into Info.plist was always one commit behind. After some head scratching, I realised this was because by default the new build phrase is inserted last, and the order matters! It isn't actually possible to reorder build phrases by drag and dropping the children nodes around. You have to do a head-insert by dragging a child to the parent, which inserts it at the top.


Voila, problem solved.

Cheers,
Steve

Labels: , ,


20091216

Yet Another Arduino Float Print Function

void floatPrint(float f, int places=6)
{
        int _d;
        if (f < 0)
        {
                Serial.print("-");
                f*=-1;
        }

        _d = (int)f;
        
        if (!places)
        {
                return;
        }

        Serial.print(_d, DEC);
        Serial.print('.');

        while(places--)
        {
                f-=_d;
                f*=10;
                _d = (int)f;
                Serial.print(_d, DEC);
        }
}

void floatPrintln(double f, int places=6)
{
        floatPrint(f, places);
        Serial.println();
}

Why another float print function? The ones I found wasn't too nice, one of which required long integers. Yuck. It was also fun, and now I know where to look for one in the future :P

Cheers,
Steve

Labels: ,


20091207

A subtle source of linker errors under XCode

If one source file is sourcecode.c.objc and another is sourcecode.cpp.objcpp, you will have problems if you try to call function defined in one file from the other. The resolve this either make them the same source type, or follow this guide.

This drove me nutty because the template I was working off has code set to sourcecode.cpp.objcpp, but XCode adds new classes as sourcecode.c.objc! To check the file type, use "Get Info" in the source file's context menu.

Cheers,
Steve

Labels: ,


20091011

qrbackup

I generated a gpg keypair for myself today, and I was looking for a fairly safe way to back it up. I don't particularly trust DVD/CDs, and keeping it on flash is even more worrying. I wanted a means of backup I can see and touch.

Paperbak would be great if it was ported to something not windows. Since it wasn't, I settled on QR Code.

Thus qrbackup was born. It will base32 encode a file, then encode it into QR codes using google chart service.

I have tested it from backup to restoration, and it works. YMMV, more instructions available after the jump.

Cheers,
Steve

P.S. Pardon my python.

Labels: , ,


20090805

git-daemon on debian vserver

Annoyingly git-daemon-run requires runit on debian, but runit will fail to install properly in a debian vserver because it doesn't have init.

One solution is to reconfigure vserver to use plain init style.

However I didn't want to this because I don't want to take down my vserver just yet. So here is the required line for /etc/inetd.conf:

git     stream  tcp     nowait  nobody /usr/bin/git git daemon --inetd /var/git-repos

Cheers,
Steve

Labels: , ,


20090607

Dealing with rkhunter warnings

rkhunter often warns on file property changes after upgrade and such, and sometimes you just aren't sure whether it is due to recent upgrades, or because you really were compromised. The following script was written to compare the checksum of all files rkhunter warns about against the originals in a debian repository.

The latest version of this is available in my script.git respos.

#!/bin/bash
desc="
This script will verify whether files for which rkhunter has logged a 
warning for is still valid. It does this by finding which debian package
it came out of, and downloads them, unpacks them, then checks
the checksums.

Run it by supplying a rkhunter log file as first argument
"

HASHER="sha256sum"

IFS="
"
function find_suspect_files
{
 echo "parsing $1 for suspect files" 1>&2
 grep -1 Warning "$1"| grep File | sed 's|.*File: ||'
}

function find_packages
{
 echo "finding packages" 1>&2
 for suspect_file in $1
 do
  package=$(dpkg -S $suspect_file|awk '{print $1}'|sed 's/.$//')
  echo "suspect file $suspect_file found in $package" 1>&2
  echo $package
 done

}

function make_aptitude_args
{
 echo "generating aptitude arguments" 1>&2
 for package in $1
 do
  version=$(dpkg -p $package | grep Version | awk '{print $2}')
  echo $package=$version
 done
}

function cleanup
{
 echo "cleaning up"
 popd
 rm -rf tmp
 exit $1
}

function setup
{
 echo "setting up"
 rm -rf tmp
 mkdir tmp
 pushd tmp
}

if [ $# -ne 1 ];
then
 echo "$desc"
 exit 1
fi

suspect_files=$(find_suspect_files "$1")

packages=$(find_packages "$suspect_files" | sort | uniq)

if [ -z "$packages" ];
then
 echo "***WARNING****"
 echo "No packages contain any of the suspect files!"
 cleanup 1
fi

aptitude_args=$(make_aptitude_args "$packages")

setup

echo "downloading packages"
aptitude download $aptitude_args 1>/dev/null
if [ $? -ne 0 ];
then
 echo "aptitude download failed!"
 echo "args=$aptitude_args"
 cleanup 1
fi

echo "unpacking"
for deb_file in *.deb
do
 ar -x $deb_file
 tar zxf data.tar.gz 
 rm -rf data.tar.gz control.tar.gz
done

for suspect_file in $suspect_files
do
 if [ ! -f ".$suspect_file" ]
 then
  echo "***WARNING****"
  echo "For some reason .$suspect_file does not exis!"
  continue
 fi
 echo -n "verifying $suspect_file... "
 suspect_sum=$($HASHER $suspect_file | awk '{print $1}')
 clean_sum=$($HASHER ".$suspect_file" | awk '{print $1}')
 if [ $suspect_sum == $clean_sum ];
 then
  echo "OK"
 else
  echo
  echo "***WARNING****"
  echo "Checksum mistmatch for $suspect_file!!!"
  echo "Should be: $clean_sum"
  echo "Is: $suspect_sum"
 fi
done
cleanup

Cheers,
Steve

Labels: , ,


20090518

Sketch to calibrate SEN-08663

Got my hands on a ADJD-S371 on a breakout board from Sparkfun. The code below can be used to calibrate it. The most up-to-date version of the code can be found at my git repository under colour_sensor_calibration.

#include <Wire.h>
/* Calibrates the sensor to get white balance. Pin 2 should be connected
 * to LED on the breakout board's LED pin. Calibration is done by placing the
 * breakout board inside a pin pong ball, and using the built-in LED for
 * illumination.
 *
 * Amount of light is measured by charging N capacitors for time X then
 * reading off the voltage. (Conjecture)
 *
 * N is controlled by CAP_XXX
 * T is controlled by INT_XXX
 *
 * Calibration is done by adjusting the integration time. No real reason.
 */
int _slave_id = 0x74;
int _LED_pin = 2;

uint8_t read_register(uint8_t addr)
{
  i2c_send(_slave_id, &addr, 1);
  return i2c_read(_slave_id);
}

void write_register_int(uint8_t addr, int data)
{
 write_register_multibyte(addr, (uint8_t*)&data, 2);
}

/* write data[i] = register+i */
void write_register_multibyte(uint8_t addr, uint8_t* data, uint8_t bytes)
{
 for (int i = 0; i < bytes; ++i)
 {
  write_register(addr+i, data[i]);
 }
}

void write_register(uint8_t addr, uint8_t data)
{
 uint8_t bytes[] = {addr, data};
 i2c_send(_slave_id, bytes, 2);
}

uint8_t i2c_read(uint8_t id)
{
 Wire.requestFrom(_slave_id, 1);
 for(int i = 0; i<10 && !Wire.available(); ++i, delay(10));
 if (!Wire.available())
 {
  return 11;
 }
 return Wire.receive();
 
}

void i2c_send(uint8_t id, uint8_t * data, uint8_t len)
{
 Wire.beginTransmission(id);
 for(int i = 0; i < len; ++i)
 {
  Wire.send(data[i]);
 }
 Wire.endTransmission();
}

#define CTRL    0x00
#define CONFIG    0x01

#define CAP_RED   0x06
#define CAP_GREEN   0x07
#define CAP_BLUE   0x08

#define INT_RED_LO   0x0A
#define INT_RED_HI   0x0B
#define INT_GREEN_LO  0x0C
#define INT_GREEN_HI  0x0D
#define INT_BLUE_LO  0x0E
#define INT_BLUE_HI  0x0F

#define DATA_RED_LO  0x40
#define DATA_RED_HI  0x41
#define DATA_GREEN_LO  0x42
#define DATA_GREEN_HI  0x43
#define DATA_BLUE_LO  0x44
#define DATA_BLUE_HI  0x45

int read_colour(uint8_t low_addr)
{
 int lo = read_register(low_addr);
 int hi = read_register(low_addr+1);

 return lo|(hi<<8);
}

int red_integration_time = 2048;
int green_integration_time = 2048;
int blue_integration_time = 2048;

void set_integration_times(int red, int green, int blue)
{
 write_register_int(INT_RED_LO, red);
 write_register_int(INT_GREEN_LO, green);
 write_register_int(INT_BLUE_LO, blue);
}

void setup()
{
 pinMode(_LED_pin, OUTPUT);
 digitalWrite(_LED_pin, HIGH);

 Serial.begin(57600); 
 Wire.begin(); // join i2c bus (address optional for master)
 Serial.println("Setting up...");

 // datasheet says, wait 10us for hardware reset, so lets wait 1000
 delay(1);

 // gain setup
 write_register(CAP_RED, 0x08);
 write_register(CAP_GREEN, 0x08);
 write_register(CAP_BLUE, 0x08);

 set_integration_times(
  red_integration_time, 
  green_integration_time, 
  blue_integration_time
 );

 // ask for colour data and offset
 write_register(CTRL, 0x01);
}

void loop()
{
 if (read_register(CTRL))
 {
  return;
 }
 
 int red, green, blue;
 red = read_colour(DATA_RED_LO);
 green = read_colour(DATA_GREEN_LO);
 blue = read_colour(DATA_BLUE_LO);
 
 Serial.println("--------------");
 Serial.print("red: ");Serial.println(red);
 Serial.print("green: ");Serial.println(green);
 Serial.print("blue: ");Serial.println(blue);


 Serial.print("red_int: ");Serial.println(red_integration_time);
 Serial.print("green_int: ");Serial.println(green_integration_time);
 Serial.print("blue_int: ");Serial.println(blue_integration_time);

 // have to calibrate against blue, because LED has a blue bias otherwise
 // it would look like blue has high gain than it does
 float P = 1;
 int reference = blue;
 red_integration_time += (reference - red)*P;
 green_integration_time += (reference - green)*P;
 blue_integration_time += (reference - blue)*P;

 // set the new integration times
 set_integration_times(
  red_integration_time, 
  green_integration_time, 
  blue_integration_time
 );
 
 // ask for colour data again
 write_register(CTRL, 0x01);
}

Cheers,
Steve

Labels: , ,


20090508

Facebook python authentication gateway

Edit: it occurred to me what I have below is the basics of a thin facebook api wrapper. I might make it into one at some point in the future.

If you don't know what this does, you don't need it. Hope this helps some one. Written because pyfacebook is broken, always returns error 100.

FB_API_HOST="api.facebook.com"
FB_API_PATH="/restserver.php"

def get_session(auth_token):
        params={
                "api_key":FB_API_KEY,
                "v":"1.0",
                "auth_token":auth_token,
                "generate_session_secret":1,
                "method":"auth.getSession",
        }

        sorted = params.items()
        sorted.sort(key=lambda x:x[0])

        str_to_hash = ''.join(["%s=%s"%(x[0], x[1]) for x in sorted])
        str_to_hash += FB_API_SECRET

        md5 = hashlib.md5()
        md5.update(str_to_hash)

        sig = md5.hexdigest()

        params["sig"] = sig

        encoded_params = urllib.urlencode(params)
        headers = {
                "Content-type":"application/x-www-form-urlencoded",
        }

        conn = httplib.HTTPConnection(FB_API_HOST)
        conn.request("POST", FB_API_PATH, encoded_params, headers)

        response = conn.getresponse()

        print response.status, response.reason
        return response.read()

This Works For Me when I use it with iphone facebook-connect client:

[FBSession sessionForApplication:myApiKey getSessionProxy:myURL delegate:self];

Cheers,
Steve

Labels: , ,


20090429

Stripping trailing whitespace from XCode

Firstly, my usual approach of s/\s+$//g doesn't work since it eats up the newline too. s/\s+$/\n/g doesn't work either because the Replace: field in the find dialogue doesn't escape the \n.

Final solution is as shown: s/[ \t]+$//g

Cheers,
Steve

Labels: , , , ,


20090216

Arduino ultrasound ranger

Code to drive it is avaliable under GPL.

An updated version of the schematic as a .sch file is available also.

Cheers,
Steve

Labels: , , ,


20090125

Auto leveller

A simple 2 DoF setup with an accelerometer (LIS302DL) attached to the effector. The seeeduino attempts to drive the servos so the Z and Y axis measure zero acceleration. The sketch is available at the usual place.

The algorithm employed is a simple PD controller with pseduo-gradient stepping to determine how to control each servo without any knowledge of how the servos are arranged. To deal with sensor noise from the accelerometer, a schmitt trigger mechanism is employed along with a moving average.

The code also allows the system to be calibrated to deal with accelerometer miscalibration.

It is cute, but that is about it :-) Coupled with a tripod and better construction ut might be useful for some DIY surveying or construction work.

Cheers,
Steve

Labels: , , ,


20081226

DIY digital spirit level



DIY digital spirit level
Originally uploaded by sentientintelligence
A simply digital spirit level using a LIS302DL accelerometer from nkcelectronics coupled with a seeeduino for processing and a 2x16 character LCD display for output.

Sketch is available for your convenience. Note the Sketch includes an extra feature: PWM backlight on pin3.


Cheers,
Steve

Labels: , , ,


20081009

Some people are going to hate me for this

But you can get the current function's name by using:

sys._getframe().f_code.co_name

Seems to work alright for debugging purposes. See the link embedded in the title for the origins and 3 other methods.

Cheers,
Steve

Labels: , ,


20080716

unoffical libfg repository

I have set up an unofficial git respository for libfg patches and new swig generated python interface, as Gavin Baker (the author) appears to be busy with other things. This is a maintance only repository as far as libfg goes - I don't plan on adding any more features (since all the ones I need are there already). I will however work to produce a more pythonic interface to libfg, as the swig generated interface is a straight port of C api into Python.

Currently the repository contains the following fixes and enhancements:

If you have a patch against libfg, please post it at the libfg project's page first, and then to me if Gavin does not respond. I do not intend to take over development of libfg, and it is my hope Gavin will in the future make this obselete/redundant.

Cheers,
Steve

Labels: , , , , , ,


20080705

Another holiday, another webapp

Thats right, another webapp! This time using google's app engine, so feel free to abuse it, somewhat :P

Rank'em is its name, and it basically lets you create a collection of Things then allow other people to rank each Thing against each other, producing an overall ranking of Things.

Have fun and let me know what can be done better.

Cheers,
Steve

Labels: ,


20080618

Personification of Programming languages 2

An follow up on the last round of language personifications, this time contributed by brett.

PHP

The crazy party girl you meet at Uni; she's easy to get along with at the beginning; she reminds you of other girls you've known before and hey, its a bit of fun; you're only young once. But after knowing her a few months the cracks begin to show; she's pretty inconsistent and while she tries to do favours for you and help you out, she ends up making it more complicated than it needed to be. The whole time you're with her, you have this sneaking suspicion that maybe you'd be better off with Perl, even if she's harder to speak to.

Javascript

The late bloomer; in high school she was pretty dorky; she couldn't do very much and while she might have spent time in different social circles, she could never really fit in. But now the puppy fat has dropped away and she's revealed herself to be one hell of a girl. She can do things you never would have expected a few years ago and suddenly she's the life of the party, appearing in places you never would have expected and doing things that make your jaw drop.

bash

The fat chick you picked up at that party, only because you were drunk and horny. You'd never tell your friends about it, but it got the job done, so to speak.

QBasic

Your first girlfriend in highschool. You were so nervous you didn't even end up kissing.

Many thanks again to brett for sharing these with us :-D

Cheers, Steve

Labels: ,


20080428

{} I <3 thee

Firstly, I am the kind of guy who likes tabs over spaces, because I don't like forcing my particular preferences on to other people. To wax poetic, I like to give other people the freedom of choosing how they want their code indented. This of course brings me into the firing line of python programmers, for whom the 4-spaces-per-indentation-level is equivalent to the Ten Commandments handed down from Mount Sinai. Officially, python doesn't care, but thats like saying officially the Church accepts evolution.

I was editing a working python file written by some one else today, and wanted to convert it to tabs (yes yes, I know all about leaving files as I found them etc. Silence). So I ran unexpand -t 4 on the file. This simply replaces 4 spaces with one tab. This should have given me a working and correct python file though now indented with tabs. Naturally (Moore's law and all) this is not happened. The newly tab-indented file was riddled with errors because the original file was not indented properly so the simple conversion did not work. And as I go about fixing the errors python threw at me, I realised to my horror that information about the structure of the code was corrupted. Because python interprets code structure based on indentation, if your indentation is incorrect, your code is incorrect.

In comparison, a brace using language like C would have made the corrections trivial, because the braces explicitly specify the code structure. Python's argument that everyone indents anyway and thus braces are redundant is flawed - braces are not redundant because braces represent the separation of content from presentation, something that has been hammered into developers. In ignoring this, python has allowed a new class of errors - changing the appearance of code will now change the function of the code. I really can't see how this is a good thing.

If nothing else, python's integration of presentation and content, and thus presentation and program correctness makes it a far less robust language than brace using languages. Less robust in that a mangled python file is unrecoverable unless you actually read the code to figure out its structure, and that incorrectly transcribed python will likely run anyway with no syntactic or runtime errors.

Consider for example, the following code:

for n in names:
    foo(n)
    bar(n)

If you were transcribing the code and accidentally did not indent bar(n), the code now does something complete different yet no syntax or runtime error will be thrown. Now if the above code used braces, then it would have no effect. And if you forgot the brace, a syntax error will be thrown.

To be fair, python is a lovely language, and I do love it and use it extensively. Whitespace-as-syntax stance appeared at first to be a great idea, and one which now appears to be short sighted and naive. If nothing else, at least an interpreter which disallows incorrect space-indent files, that way tab->space and space->tab conversions would work correctly all the time.

Let me now put on my flame retardant undies, and you can flame away

Cheers,
Steve

Labels: , , , ,


20071231

html2pml

I was tired of converting all my HTML ebooks to rtf, then to pdb using Palm Doc Converter only to lose all the nice touches like bold, italics and headings. Since there didn't seem to be a HTML to PML converter for OS X, I wrote one to get more practice in python.

html2pml.py will convert basic HTML file to a PML file suitable for use with DropBook to be converted into a proper Palm ebook. I must stress the basic part - it only does stylistic conversions at the moment. I have no need for tables or links, so I didn't write them in. It does however do what I want - preserve bold and italic attributes, headings, and also translates some non-ascii characters into PML Extended Character Set, and to plain ascii where not possible.

This small python script is released under GPLv2, license is attached. If you find it useful, need more features, or have comments/suggestions, let me know!


Cheers,
Steve

Labels: , ,


20071213

Computing Oddities

Two strange and weird things happened to me recently. One is my /dev/null disappearing from leopard!

A large number of programs, both Cocoa and *nix relies on /dev/null being present. As you can see I could not gain root privileges, and thus could not recreate /dev/null (character device, 3,2). I had to in the end reboot and /dev/null was recreated.

Second strange thing is when I created a self-signed certificate for use with apache2 (for anonshare). I created it with openssl specifying 36500 for -days. The result is an certificate with expiration date in the past!

I am not aware of any X.509 specification regarding the number of days a certificate can be valid for, so I wonder - is this a bug in openssl?


Cheers,
Steve

Labels: ,


20071122

Personification of Programming languages

The following personifications of programming languages came about while I was discussing various languages with my friends. Basically we started off with a description or sentence about a language, and I personified. In spirit it is the OS-tans but for programming languages

C

"Very fast, good at a few things, sucks at everything else". An autistic girl who is very good at maths. You will also need to keep sharp objects away from her because she is happy to run with scissors, so to speak. Does exactly as you tell her, even if it means grievous harm to herself or others. Needs to be kept in a padded room to avoid hurting herself and others.

C++

"I don't want code in it, but I can't help but like it". A girl who is so pretty you can't help but like her. Unfortunately she is also bat-shit insane, and will scratch your eyes out.

Python

"Very flexible, does everything easily and without complaint, but slow as hell". A girl who is flexible and easy going. Can do complicated contortions easily, an absolute joy to be with. Only thing is she is a bit thick.

Java

"Overtly verbose, unnecessarily strict, but pretty fast". She is one of those girls who you need to constantly buy gifts for in order to keep her satisfied. She will also continually talk non-stop about a variety of things, most of them inane. However she is of average intelligence and comes with a lot of accessories by default.

ASM

"Its like C, only dumber". Well thats it really. ASM is C-like, but even more autistic and a bit more dangerous.

Perl

"Well, its perl". Ah, perl. Perl is a girl like python, except she doesn't speak your language, and you don't speak her language. Over time the two of you have worked out a pidgin language which is a mismush of sign language, latin, french, foot stomping, hip gyrations, eye rolling, tongue poking, and so forth. No one else knows what you and perl are saying, and sometimes you don't even know what each other is saying and can only make wild guesses.

Thats all I have for now, will update when I have more to write :-)


Cheers,
Steve

Labels: ,


20071104

Now you can all look and see how much I suck

Mactorii is now open sourced! GPLv2 for the curious. I haven't cleaned it up at all, which means be prepared to stab your eyes out with rusty fork after viewing the source. James told me not to bother, "cause then you will never release it". So blame James, its his fault/.


Cheers,
Steve

Labels:


20070809

JAPH

Not my work, I don't have that kind of perl-fu
not exp log srand xor s qq qx xor s x x length uc ord and print chr ord for qw q join use sub tied qx xor eval xor print qq q q xor int eval lc q m cos and print chr ord for qw y abs ne open tied hex exp ref y m xor scalar srand print qq q q xor int eval lc qq y sqrt cos and print chr ord for qw x printf each return local x y or print qq s s and eval q s undef or oct xor time xor ref print chr int ord lc foreach qw y hex alarm chdir kill exec return y s gt sin sort split

Cheers,
Steve

Labels:


20070716

Introducing SETerm

To learn a bit about using XCode, program in Objective-C using Cocoa and play with bluetooth and my phone, I wrote a simple bluetooth serial terminal. It simply connects to my phone (or any bluetooth device), opens a communication channel, and lets you send characters through it as if it is a serial connection. With my phone, this allows me to do pretty much everything that - list, read, send SMSs, contacts, check battery status, signal strength, etc.

Nifty! Here is a picture:

Download it, give it a whirl. I will one day update it to use Core Data so it handles SMSs and contacts in a nicer way then dumping out as text.


Cheers,
Steve

Labels:


20070414

Writing fitting functions for lmfit

lmfit expects fitting functions with prototypes in the form:

double function_name(double, double *);

For example:

double sin_fit(double t, double * p)
{
return p[0] + p[1] * sin ( 2 * M_PI * ( p[2] * t + p[3]));
}


Note that while lm_minimize takes a pointer to an array of parameters, it may not always pass that pointer to the fitting function. Because of this passing fixed parameters to the fitting function using the 3rd argument will yield incorrect results. For example, the following code is wrong:

double wrong_fit(double t, double *p)
{
return p[0]*p[0] + p[1];
}

....

double p[2];

p[0] = 1;
p[1] = magic_number;

...

lm_minimize(..., 1, p, ..., ..., ...., ...);

Here the fitting function wrong_fit relies on a fixed parameter p[1] which it expects to contain the value magic_number. However it will be passed such a p that only p[0] has a valid value and p[1] is undefined. This will lead to incorrect operation.

To work around this, you can use global variables, as follows:

double magic = magic_number;

...

double right_fit(double t, double * p)
{
return p[0]*p[0] + magic;
}

....

double p = 1;

...

lm_minimize(..., 1, &p, ..., ..., ..., ...);


Cheers,
Steve

Labels: ,


20060318

Fourier fitting with gnuplot

gnuplot can be used to fit a fourier series to a series of data points. In my case it was an observation log for the star BE Lyncis from the Bossom Observatory, curtsey of Geir Klingenberg.

Firstly one needs to define a time function t(x) such that as x progresses from its minimum value to its maximum value t(x) ranges from 0 to 2PI. In my case minimum value of x was 2453416.20172 and maximum value was 2453416.42447. So my t(x) was constructed as follows:

t(x)=(x-2453416.20172)/0.22275*2*pi

We now need to define a fourier series, f(x). It takes the generic form of:

f(t)=c+a0*cos(t)+a1*sin(t)+a2*cos(2*t)+a3*sin(2*t)+ ...+{a#*cos((#+1)*t)+a(#+1)*sin((#+1)*t)}

Where #=0,1,2,3... infinity, and is the degree of the fourier series. Now we can use gnuplot's fit function to determine the values of all co-efficients and the constant c:

fit f(t(x)) 'be_lyn-2005.txt' using 1:2 via c,a0,a1,a2,...,a#,a(#+1)

A quick explanation: we are trying to fit f(t) where t=t(x) using data from the file be_lyn-2005.txt with data from the first and second column. The order of 1:2 is significant as it is in the form of x:y. Thus 2:1 means the first column is y value, second column is x value. (This is from experience, if any one knows better, tell me!)

Co-efficient values and the constant will be computed and shown, along with various statistic data. An plot of the fourier series and the observed data is shown below.

The plain text file be_lyn-2005.txt has 3 columns: JD, instrumental magnitude, and error estimate, the later of which was not used.

Cheers,
Steve

Labels: , , , , ,


20040714

Downloads

Here is a summary of some stuff I wrote for one reason or another. Source is provided where I am not overly embrassed by the code :) Please submit bug reports etc by commenting on this entry :)

Labels: , ,


This page is powered by Blogger. Isn't yours?