Dear all,
It is an advanced notice. Three weeks from now I'll be no longer with Intimedia. I surrender my position as CTO in Intimedia to take another challange.
I'll be working for this company as a Developer Evangelist. Please note that this is NOT the open position posted by Risman in his blog last week end. That position is still open, and we encourage you to apply. My process of joining Microsoft Indonesia actually has been started months ago. Just for your information, I'll be replacing Risman's position as he's moving to another position very soon (he'll update you on this
).
As what Risman's been doing, I will work with the developers, developers managers and Senior Management of the whole developers ecosystem (Academia-ISV-SI-Enterprise) thru "depth" engagements. For sure I'll be doing "public appearance" on events, but my actual work will be more on "one on one" kind of stuff with the entities in the ecosystem. So, I will work in the background. More like a Ninja.
While on the position posted by Risman in his blog, it is more on executing "broad" programs.
As I'll be working for Microsoft Indonesia, then it would mean I won't be no longer the MSDN Regional Drector in Indonesia as well.
In the time being, during my last days in Intimedia, I will work in internal Intimedia to ensure smooth transition. I am also looking forward to work with you all on my upcoming role in Microsoft Indonesia. I am very excited. You guys are what my upcoming job is all about; The Developers! The geeks. The ones that make all the magic happens. The ones that really matter.
"Behind every great technologies, products, companies, etc... there are always the geeks!"
Let the chant begin... "Developers! Developers! Developers!"
To Engineer, his mathematical model is the correct representation of the real world.
To Physicist, the real world follows his mathematical model.
To Mathematician, he does not care!

What about Computer Scientist? To Computer Scientist, he is interested in these attributes of the model:
So, they all work with the model! 
In previous posts I talked more on theoretical aspects of parallel computing. In this post I'm going to show some code example of a parallel program that I did. The code is in C and uses the MPI (Message Pasing Interface) library that is part of Microsoft Compute Cluster Pack, part of Microsoft High Performance Computing.
MPI is actually a spec. It's been implemented in Fortran and in C. An attempt to implement it in .NET has been made as well. Note that MPI uses Message Passing approach that is different from Shared Memory approach uses in ParallelFX from Microsoft. In other words, there is no production level library for Parallelism that uses Message Passing in managed code. To really understand parallelism, learning ParallelFX alone is not enough.
Back to the code, here it goes:
#include "stdafx.h"
#include <stdio.h>
#include <mpi.h>
double Function(double x)
{
return 4/(1+(x*x));
}
double IntegrateUsingSimpson(int n, double x0, double xn)
{
double h = (1.0-0.0)/n; // Note: in general (xn-x0)/n, this is for Pi only
int i = 0;
double x = x0;
double result = 0.0;
while(x <= xn)
{
if(i != 0 | i != n-1)
{
if(i%2 == 0)
{
result += 2*Function(x);
}
else
{
result += 4*Function(x);
}
}
else
{
result += Function(x);
}
i++;
x += h;
}
result = result / (3*n);
return result;
}
int main(int argc, char** argv)
{
int size, rank, i;
int n = 500000;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if(rank == 0)
{
double GlobalPi = 0.0;
double bufferPi;
for(i = 1; i < size; i++)
{
MPI_Recv(&bufferPi, 1, MPI_DOUBLE, i, 1, MPI_COMM_WORLD, &status);
GlobalPi += bufferPi;
}
printf("Pi = %f\n", GlobalPi);
}
else
{
double localPi;
double x0 = (rank-1)/(size-1);
double xn = (rank)/(size-1);
localPi = IntegrateUsingSimpson(n, x0, xn);
MPI_Send(&localPi, 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}
What this code is all about?
To understand more, please download the paper I wrote on the subject here: http://geeks.netindonesia.net/files/folders/norman/entry52033.aspx
Here's the abstract of the paper:
Parallel implementation of an algorithm is of high interest because it brings speed up to the execution time of that algorithm. Numerical Integration such as Simpson’s Rule is an example of Numerical Method that can be fully implemented in parallel thru data parallelism (domain decomposition). This paper shows the parallel implementation of Simpson’s Rule to approximate the value of Pi by following Foster’s methodology and using the message passing mechanism. This paper also highlights that parallelism in Numerical Methods is not without problem; parallelism may produce less accuracy due to Error Propagation. It is something that needs to be seriously considered in implementing Numerical Methods in parallel.
I summarized the info in the websites of Microsoft new family of Certifications for developers, the certifications for .NET 3.5 (Visual Studio 2008). It can be used as a "map" while you're browsing the certifications web sites.
You can download the PDF file here: http://geeks.netindonesia.net/files/folders/normslides/entry51962.aspx
Fitter, happier more productive
Comfortable, not drinking too much
Regular exercise at the gym 3 days a week
Getting on better with your associate employee contemporaries
At ease, eating well
No more microwave dinners and saturated fats
A patient better driver, a safer car, baby smiling in back seat
Sleeping well, no bad dreams, no paranoia
Careful to all animals, never washing spiders down the plughole
Keep in contact with old friends, enjoy a drink now and then
Will frequently check credit at Moral Bank hole in wall
Favours for favours, fond but not in love
Charity, standing orders, on sundays ring road supermarket
No killing moths or putting boiling water on the ants
Car wash also on sundays
No longer afraid of the dark or midday shadows
Nothing so ridiculously teenage and desperate
Nothing so childish
At a better pace, slower and more calculated
No chance of escape, now self-employed
Concerned but powerless
An empowered and informed member of society
Pragmatism, not idealism
Will not cry in public
Less chance of illness
Tires that grip in the wet
Shot of baby strapped in back seat
A good memory
Still cries at a good film
Still kisses with saliva
No longer empty and frantic
Like a cat tied to a stick
That's driven into frozen winter ***
The ability to laugh at weakness
Calm, fitter, healthier and more productive
A pig in a cage on antibiotics
"Thom Yorke (Radiohead) is a genius"
The basic general strategy is: Replace a difficult problem with an easier one that has the same solution (or closely related solution). In other words, transform the representation of your difficult problem into a different representation that is easier to solve and producing solution that is a solution to your original problem.
As a simple example, how would you compute 2^3? Simple. You only have to do this: 2*2*2 (multiply three 2s). In general, for a^b, you just have to multiply a, b times. Here you just have to compute it straight away as this is a simple problem. No need to change the representation. But now what about 2000^(1/3)? (Remember, don't use library such as System.Math.Pow - the point here is for you to be able to create such library)
The solution to 2000^(1/3) is actually to find x such that x^3 = 2000. So, you got a Polynomial x^3-2000 = 0 (A different representation of the original problem, but the solution is the solution to the original problem). To solve it you just simply write code to implement the Bisection, Newton or Secant Method. Numerical Methods in Rootfinding Problem. You change a Power Problem into Root Finding Problem which is easier to solve. Numerical Methods for this problem has been established. Writing codes of Bisection, Newton or Secant Method is trivial.
Another example, solution to a linear systems Ax = B (here A & B are matrices), where you want to find the vector x. What you need to do is to change the matrix A into triangular form using Gaussian Elimination, then solving a linear system with A that is triangular matrix is simple. You can simply use Backward Substitution. Here you change the matrix A into a triangular matrix.
Here are more Examples (got it from Michael T. Heath):
-
Replacing infinite processes with finite processes, such as replacing integrals or infinite series with finite sums, or derivatives with finitie different quotients
-
Replacing general matrices with matrices having a simpler form (like the example above)
-
Replacing complicated functions with simple functions, such as polynomials
-
Replacing nonlinear problems with linear problems
-
Replacing differential equations with algebraic equations
-
Replacing high-order systems with low-order systems
-
Replacing infinite-dimensional spaces with finite-dimensional spaces
This general strategy is actually an algorithm design technique called Transform and Conquer. Another design techniques thay you may have heard are: Brute Force, Divide and Conquer, Decrease and Conquer, Greedy Technique and Dynamic Programming. Anany Levitin has a good book on this algorithm design techniques. If you want to be a serious software developer, you should live and breath these algorithm design techniques. The using C#, .NET Framework, Visual Studio is the easiest part! You need to master the more important thing: Algorithms.
PS: You cannot see the implementation of Syste.Math.Pow. When you ILDASM or use Reflector you will get that the body of the method is actually a function call to nternal method, that is method that exists within the CLR! Yes, folks, a method in the CLR, not in the Framework Library. So, you cannot see it.
. It also means that this internal method is so important that is has to be in the CLR. It also means it was built using C++.
As promised in my earlier post, here I'd like to talk about Amdahl's Law, thru which you'll get the formal idea that speed up by parallelism only really works for certain kind of problems. Problems which algorithms to solve have small serial fractions. My goal with this post is to give you a fair understanding that you won't subscribe to the overrated view on parallelism, especially from those who sell multicore machines and Parallel APIs.
Another thing is that to make you see that learning and optimizing sequential algorithm is still very important even if we have all multicore machines in the market.
First, let's look at what is defined as Serial Fraction.
In an algorithm to solve a problem, there is always part that has to be done sequentially (serial), and there is part that can be made to run in parallel. So, the time needed to run this algorithm on a single processor can be expressed as follow:
TSeq = S + P
Where,
TSeg = Time spent to run an algorithm on a single processor
S = Time spent on the sequential part of the algorithm on a single processor
P = Time spent on the parallel part of the algorithm on a single processor
Now, if you run the algorithm in N processors you would have:
TPar = S + (P/N)
Note that the number of processors only affect to the parallel part of the algorithm.
Then the Speed Up that you will get is:
SN = TSeq/TPar
= (S+P) / (S+(P/N))
Lets back to TSeq = S + P, we divide both sides by TSeq we will have:
1 = (S/TSeq) + (P/TSeq)
Now we define S/TSeq as Serial Fraction and name it F.
F = S/TSeq
We now have 1 = F + (P/TSeq) or we can put it this way:
P = (1-F)*TSeq
Let's substitute this back to Speed Up, so we have:
SN = (F*TSeq + (1-F)*TSeq) / (F*TSeq + ((1-F)*TSeq)/N)
= (F + (1-F)) / (F + (1-F)/N)
SN = 1 / (F + (1-F)/N)
Here we have Speed Up as a function of Serial Fraction and number of processors.
So,
-
Ideal Speed Up only happens if F = 0 (there's no Serial Fraction in the algorithm) as it will give you N times Speed Up.
-
If F = 1 (the whole part is Serial), then no matter how many processors you use you won't get any Speed Up, as the Speed Up is 1.
As an example, your program is made up of 0.7 Serial Fraction and 0.3 Parallel Fraction. You use 4 processors to run this algorithm (as if your Parallel Fraction is reduced into 1/4th, you get Speed Up by 1/(0.7+(0.3/4)) that is 1.29 times faster compared to if it was run on a single processor. If you can tweak your Serial Fraction by come up with better Sequential Algorithm and let say you only get it twice faster (as if your Serial Fraction is reduced by half), then even if with still just one processor you would have 1/(0.35+0.3) Speed Up that is 1.54. Faster. Better than running it on 4 processors without working on the sequential algorithm.
What does it tell you?
-
Parallelism only provides significant Speed Up if your algorithm has small Serial Fraction. The bigger the Serial Fraction, the more the number of processors become not really matters.
-
Even if in this new era of multicore machines in the market, it is still important to learn and optimize sequential algorithms (as there are many problems that need to be solve in sequential by nature).
In other words, for problems that has bigger Serial Fraction, working on the algorithm introduce more siginificant speed up compared to adding more processors. As I always say, algorithm is always be the corner stone of computing. Not machines, not Products/APIs, not programming languages. It is Algorithm.
Please note as well that we're still not considering load balancing and communication overhead here. If we include them, then we will get lower Speed Up for the Parallel Fraction. The P/N is too ideal.
So, put it all in one sentence: Speed Up of Parallel Algorithm is effectively limited by the number of operations that need to be done sequentially, i.e. its Serial Fraction.
That's Amdahl's Law!
Let say it takes 6 minutes to do a computation on a set of data in a single processor. Then you have 3 processors altogether. Would your task finish in 2 minutes (6 divided by 3)? NO IT WON'T!
Why? Because your algorithm is a sequential algorithm. Even if with 100 processors your computation would still need 6 minutes to complete. To be able to exploit multiprocessors you would also need PARALLEL ALGORITHM. That said algorithm that was designed from the ground up with parallelism in mind.
Now let's see the other way around. Let say it takes 2 minutes to finish a computation using a parallel algorithm on 3 processors. Would it take 6 minutes if you run that algorithm in a single processor? Maybe. If you are lucky. Chances are it would take more than 6 minutes. Parallel algorithm that runs in a single processor may have worst performance compared to a sequential algorithm runs in a single processor (I'll show you the example on future posts). It is because a parallel algorithm was designed to run on multiprocessors, not on single processor. And it maybe the case that your parallel algorithm will choke in a single processor.
Summary of paragraphs above:
-
The number of processors is irelevant if your algorithm is not a parallel algorithm, you would need a parallel algorithm to exploit multiprocessors.
-
Parallel algorithm is superior only on multiprocessors, in single processor it may not run properly, or it will run with worst performance compared to its sequential algorithm counterpart.
So, algorithm is still the most important factor, more important than the number of processors itself.
It is also dangerous to believe that it is a good thing if a language construct/compiler/API can adapt/switch an algorithm to run on multiprocessors or single processor automatically. The optimal sequential and parallel algorithm for the same problem maybe totally different. The parallel algorithm works best on multiprocessors, and the sequential algorithm works best on single processor. If your language construct/API can make your parallel algorithm to run on a single processor, then it may not be better compared to algorithm designed with sequential in mind. Similar with that, if your algorithm was designed with sequential in mind, then using a language construct/API that automatically make it run on multiprocessors may not result program that runs faster than program with algorithm designed with parallelism in mind.
Again, there's no silver bullet. If you will use multiprocessors, design/use a parallel algorithm. If you use only a single processor, use the best sequential algorithm there is. It is the algorithm that matters, language construct/compiler/API is just a helper.
Design your algorithm properly!
Speed Up & Efficiency
Now I'd like to talk about some terms you may need to understand to explore further on parallelism.
Let's start with the definition of Speed Up. Speed Up is defined as:
SN = Ts/Tp
Where,
SN = Speed Up
Ts = Time taken to run the fastest sequential algorithm on a single processor
Tp = Time taken by a parallel algorithm on N processors
As one can see, Speed Up is determined by algorithm used. Not by number of processors. SpeedUp is about comparing a parallel algorithm runs on N processors with the fastest sequential allgorithm runs on a single processor.
Then we define Efficiency as follow:
EN = SN/N
Where,
EN = Efficiency of a parallel algorithm on N processors.
SN = Speed Up (as defined above).
N = number of processors.
As one can see, the efficiency here means the efficiency of the parallel algorithms. For a given number of processors, two different parallel algorithm may have their own Speed Up and Efficiency.
So, these metrics are measuring algorithms!
100% Efficiency is only achieved when Speed Up is equal with the number of processors, or in other words, when Time Taken by a parallel algorithm run on N processors is equal to 1/N time taken by fastest sequential algorithm. Which may never be achieved due to several factors that limit the Speed Up as follow:
-
Software Overhead; there will always be softare overhead, even with a completely equivalent algorithm with sequential algorithm. As an example, there may be additional index calculations needed by the manner in which data are "split up" among process. There is genrally more lines of code to be executed in parallel progam compared to sequential progam.
-
Load Balancing Overhead; Speed Up is generally limited by the slowest node. So, it is an important consideration to balance the load of work thru out all nodes. It also means a load balancing mechanism must be applied, and it means additional work.
-
Communication Overhead; It is clear that communicating data between processors degrades the Speed Up. So, it is important to keep all processors busy but at the same time reduce the amount of communications. Larger grain size of Tasks is generally better. There is a metric related to Communication cost called Machine Dependent Ratio (MDR) defined as:
MDR = Tcomm/calc
Where,
Tcomm = Time to transfer a single word (byte) between nodes
Tcalc = Time to perform some floating point calculation
The lower the MDR, the better it is. We become less dependent to the machine (lower communication cost).
-
Amdahl's Law; I will make a dedicated post on this. For now I can summarize it as follow: not all portion of algorithm can be made parallel. There is still a fraction that needs to stay sequential. So, parallelism is really be of help if the fraction that can be made parallel is bigger. If most portion cannot be made parallel, then parallelism is not so helpful on that kind of problem. In short, again, parallelism is not silver bullet.
As one can see, there are overheads you must pay for parallelism (Software Overhead, Load Balancing Overhead and Communication Overhead). Ensure what you pay is worth it. Parallelism is useful only if the Speed Up produced by a parallel algorithm is far bigger than these overheads you have to pay. In addition to that, Amdahl's Law helps you to stay aware whether the parallel fraction of your problem is significant. Otherwise, you make this parallel portion to run faster (with big efforts) but then you only get insignificant improvement in total (in case the sequential part is a lot bigger).
Then it is clear that n processors won't make your program runs n times faster. It depends on the algorithm you use, whether parallelism cost is cheaper than the Speed Up gain, and it depends to the nature of the problem, whether the parallel fraction is significant.
So, now you can be more critical to those who sells multicore machines or APIs that says parallelism can solve all your problems faster. They are just trying to sell you their machines or API.
Machines & APIs cannot compensate algorithm design ignorance.
Reference:
-
Seminar, Kudang B., "TM5 Speed Up & Efficiency", Lecture Notes, Deparment of Computer Science - Faculty of Mathematics and Natural Sciences, IPB, Bogor.
Last time I talked about the several kinds of parallelism, now I'd like to talk about the methodology we can use in designing a parallel algorithms, The Foster's Methodology.
First, let's define first a Unit of Computation and call it a Task. A Parallel Computation is merely a set of Tasks. A Task can consist of:
-
Program
-
Local Memory
-
Collection of IO Ports
The Tasks in a Parallel Computation interact one another by sending messages thru channel.
Foster's Methodology is basically a sequence of steps to partitioning computation/data into pieces (tasks), determining communication between these pieces (tasks), grouping the pieces (tasks) that have intense communication to one another, then finally mapping these groups into several processors we have. We will look at these steps in more detail one by one.
Foster's Methodology:
-
Partitioning
-
Communication
-
Agglomeration
-
Mapping
1. Partitioning
Here we divide computation and data into pieces. There are two kind of partitioning:
-
Domain Decomposition: Here we divide data into pieces, then determine how to associate computations with the data. In other words, here we break Data Structure into smaller structure that build the original Data Structure. Let say, break a Matrix into smaller Matrices (subsets of the original Matrix), or maybe break a Matrix into its scalar elements if necessary. Then we determine how to do computation to these Matrices (subsets) or scalar elements. From there, we can see whether there are computations to the pieces that can be performed at the same time (read: in parallel).
-
Functional Decomposition: Here we divide computation into pieces, then determine how to associate data with the computations. In other words, we're recognizing the functions needed in a computation and how these functions related one another (the relation structure between these functions, which function has to be computed first, which functions need results from which functions, etc). Then we determine how data (in a particular Data Structure) flows thru these functions. From there, we can see whether there are computations that can be performed at the same time (read: in parallel).
Here's some Partitioning Guidenes:
-
Minimize redundant computations and redundant data storage.
-
Primitive Tasks (Pieces) are roughly the same size.
-
Number of Tasks (Pieces) is an increasing function of problem size.
2. Communication
Here we're looking at the communication structure between Tasks (Pieces) we have. We determine the Data Structure and values passed among tasks. There are two kinds of comunication:
-
Local Communication: Task needs value from a small number of other Tasks. We need to create channels ilustrating data flow.
-
Global Communication: Significant number of Tasks contribute data to perform a communication. It is not recommended to create channels for them early in the design. We will look into this later.
Here's some Communication guidelines:
-
Communication operations are balanced among Tasks.
-
Each Task communicate with only small group of neighbours.
-
Tasks can perform communications concurrently.
-
Tasks can perform computations concurrently.
3. Agglomeration
Here we group several Tasks (Pieces) into larger parts, larger Tasks. You might be wondering; "We've broken the computations into pieces then now we need to group the pieces again, what's the point?" Well, in this step, we're not putting the pieces back into the original size. We're just grouping "close" Tasks so that we can increase performance, maintain sclability of the program and simplify programming. Let say, we group two or more tasks that are intensely communicate one another into a larger group of Tasks. In MPI (Message Passing Interface) Programming, the goal is often to create one agglomerated Tasks per processor.
How Agglomeration can increase performance? As I said before, we increase performance by eliminating communication between primitive Tasks into consolidated Tasks. We can also combine Tasks into groups of "Sending Tasks" and "Receiving Tasks".
Here's some Agglomeration guidelines:
-
Locality of Parallel Algorithm has increased.
-
Replicated computations take less time than communications they replace..
-
Data replications doesn't affect scalability.
-
Agglomerated task has similiar computational (remember the Big-Oh? [:]) and communication costs.
-
Number of Tasks increases with problem size.
-
Number of Tasks suitable for likely target systems.
-
Trade-Off between agglomeration and code modification is reasonable.
4. Mapping
This is the process of assigning Tasks (Agglomerated Tasks) into processors that we have. There are situations where mapping is done by Operating System (centralized multiprocessor), and there are situations where we manually do the mapping (distributed memory system).
There is a conflicting goals in mapping activities:
Finding an optimal mapping of tasks itself is an NP-Hard problem. Like it or not, we need to rely on heuristics here.
Here's Mapping Decision Tree that can be used as a strategy:
Here's some Mapping guidelines:
-
Consider designs based on one task per processor and multiple task per processor
-
Evaluate Static and Dynamic task allocation
-
If Dynamic Allocation is chosen, the task allocator should not be a bottleneck to the system
-
If Static Allocation is chosen, ratio of tasks to processor at least 10:1.
That's about it. I will talk more on this on future posts, along with examples. Again, my message is that using a parallel API (or even just a multithreading API) is "easy". Designing Parallel Algorithms to solve a problem is where the "real challange" is.
Reference:
-
Quinn, Michael J., "Parallel Programming in C with MPI and OpenMP - Chapter 3 Parallel Algorithm Design", McGrawHill
"Age" is actually a real number (represented as "float" in computers). But by convention, human celebrates only the annual incremental, so it becomes an integer.
Today, May 22, I celebrate the day when my property of "age" is increased by one. So, I am officially one year older now.
Please note that this "age" property is the property of my flesh & blood. Cos I believe, as a spirit I am older than that, and the spirit lives longer than this flesh & blood. Anyway, I thank The Lord to give my spirit a chance to actually walk on earth, feel the sun on my face, taste the water and encountered to Mathematics. Thanks to My Parents too as thru them I could come into this three dimensional world.
O, I'd like to thank the first 10 persons that congratulate me on this birthday too 
-
Firsa Hanita
-
Rini Anggraini
-
Sevatrina Devi
-
Estrelita Maya Zefanya
-
Novia Dhyah Kartika Sari
-
Yusnita Fadilah
-
Anastasia Erika Indrawati
-
Sherly Veronica
-
Silvana Hernawati Aguila
-
Veridiana Tricahyanti
For others that are not in the list, come on, it's not such a big deal. I have limited space in this blog anyway. 
Btw, Adrian Godong gave me a You Tube URL as a b'day gift. And it is indeed fantastic, as a die hard fan of U2 I can say that this kid Sungha Jung is awesome: http://www.youtube.com/watch?v=L4CR3GoB3YY
Here's a summary I wrote in a citizen journalism website about Bill Gates' lecture this morning.
This is not my first Bill G meeting experience, met him couple of times in US, but this is my first President SBY meeting experience. 
Baru aja deliver talk di seminar sehari di Universitas Pakuan, Bogor. Memenuhi undangan dari Himpunan Mahasiswa Ilmu Koputer-nya. Sesuai permintaan, saya membawakan topik "From C++ to C#". Intinya adalah belajar C# bagi mereka yang punya C++ background. Jd, learn C# thru C++. By comparing the two, looking at the differences and similarities. Some comparison with Java was also shown.
Saya juga mengajak Basir untuk share tentang BIND-C-nya, community .NET di Bogor.
Pembicara lainnya adalah orang dari LAPAN, yang membawakan materi tentang "Role of Computer Science in Aerospace", interesting talk kayaknya. Tapi saya gak bisa ikutan. Mesti ke kampus. 
If you have checked out my paper about the using of Feed-Forward Backpropagation Neural Networks, here's another approach that I used. It is called the Probabilistic Neural Networks. This approach can forecast the onset of Diabetes Mellitus with 100% accuracy. Compared to the Feed-Forward Backpropagation approach that could give no more than 93%.
Probabilistic Neural Networks was actually designed for such classification problems. No wonder.
I'd like to sparks and encourage scientific culture in our community. So, I created a new folder called "papers" in our geeks site download section. Here, you can upload (and download) papers, writings that have a more academia style (for more relaxed content, you still can find them in geeks blog). So, I welcome you all to upload your academic works to share your knowledge in the "papers" section, also welcome you to download whatever in there.
To begin the initiative, I uploaded the papers I wrote so far. Note that this is not a research/thesis level papers. They are merely my classes assignments from two classes: Algorithm Design & Analysis and Computational Intelligence. So, don't expect (yet) cooler/bigger stuff.
You are welcome to download them (they're in Word 2007), provide comment/feedback, etc. Here they are:
So, what are you waiting for?
. Upload/share your academic work.
Tahun ini, Imagine Cup utk Software Design utk Indonesia kembali dijuarai team dari ITB, dengan solusi-nya Butterfly (someone else will post what this is all about
). So, July yang akan datang mereka akan berangkat ke Paris untuk final tingkat dunia. Good luck! At least 6 besar deh!
Juara 2 di tahun ini dari IT Telkom (was STT Telkom), sedangkan juara 3 dari ITB juga.
Komposisi top 10 adalah 3 team dari ITB, 3 dari IT Telkom, 3 dari UI dan 1 dari ITS. Komposisi yang saya lihat tidak banyak berubah sejak menjadi juri Imagine Cup 5 tahun terakhir ini. Kampus-kampus lain kemana ya? Computer Science IPB juga
.. hello! Where are you guys?!
Anyway, again congrats untuk adik2-nya Ronald!
More Posts
Next page »