Tuesday, May 17, 2022

Engineers of #bharat - wake up - know #whoweare - part I

The following text has been taken from Wiki:


The Karatsuba algorithm is a fast multiplication algorithm. It was discovered by Anatoly Karatsuba in 1960 and published in 1962.[1][2][3] It reduces the multiplication of two n-digit numbers to at most 

{\displaystyle n^{\log _{2}3}\approx n^{1.58}}

single-digit multiplications in general (and exactly 

{\displaystyle n^{\log _{2}3}}

when n is a power of 2). It is therefore asymptotically faster than the traditional algorithm, which requires 

{\displaystyle n^{2}}

single-digit products. For example, the Karatsuba algorithm requires 310 = 59,049 single-digit multiplications to multiply two 1024-digit numbers (n = 1024 = 210), whereas the traditional algorithm requires (210)2 = 1,048,576 (~17.758 times faster).

The Karatsuba algorithm was the first multiplication algorithm asymptotically faster than the quadratic "grade school" algorithm. The Toom–Cook algorithm (1963) is a faster generalization of Karatsuba's method, and the Schönhage–Strassen algorithm (1971) is even faster, for sufficiently large n.


Here is an implementation of this algorithm in Java.


 

/*

* The Karatsuba algorithm is a multiplication algorithm developed by Anatolii Alexeevitch Karatsuba in 1960.

* It operates in O(n^log2(3)) time (~ O(n^1.585)), with n being the number of digits of the numbers we are multiplying together.

* Standard grade-school multiplication operates in O(n^2) time. Karatsuba's method is asymptotically much faster.

* Normally, you can choose any base you want, but we will be using base 10 in this algorithm with m varying depending on the length of the inputs.

* Specific details are included with an example in the comments before the actual method.

*

* @author Ayamin

*

*/

 

public class Karatsuba {

        

        // Takes two integers and returns the maximum of them

        public static int max(int x, int y) {

                return (x>y)? x:y;

        }

        

        // Takes a string and an index.

        // The index in this case is the "m". It will count backwards from the last (least significant) digit and split the string there.

        // It will return a 2-element array of the split string.

        // For example: Given 12345 as the string and 2 as the index, it will split the string into the string array ["123", "45"].

        // This is so the 123 can be written as 123 * 10^m, with m = 2 the index.

        public static String[] strCopy(long index, String string) {

                String        first = "",

                                last = "";

                long actualIndex = string.length() - index;

                for (int i = 0; i<actualIndex; i++) {

                        first+=string.charAt(i);

                }

                for (int i = (int)actualIndex; i<string.length(); i++) {

                        last+=string.charAt(i);

                }

                return new String[] {first, last};

        }

        

        // An exponent function. Works the same way as Math.pow, but with 64bit integers instead of double precision floats.

        public static long power(long x, long y) {

                if (y == 0)

                        return 1;

                else {

                        long answer = 1;

                        for (int i = 1; i<=y; i++) {

                                answer *= x;

                        }

                        return answer;

                }

        }

        

        /*

         * Take two numbers, x and y.

         * Example: 12345 and 6789.

         * Find a base b and power m to separate it into.

         * We'll pick base = 10, and m to be half the length of the digits of the numbers in this implementation of the algorithm.

         *         In this case, m will be 2, so 10^2 = 100. We will split the 2 numbers using this multiplier.

         * The form we want is:

         * x = x1*b^m + x0

         * y = y1*b^m + y0

         * ----------

         * Using the above example,

         * x1 = 123

         * x0 = 45

         * ----------

         * y1 = 67

         * y2 = 89

         * ----------

         * b = 10 and m = 2

         * ----------

         * Thus:

         * 12345 = 123 * 10^2  +  45

         * 6789 =   67 * 10^2  +  89

         *

         *

         * The recursive algorithm is as follows:

         *

         * If x<10 or y<10, return x*y. Single digit multiplication is the base case.

         * Otherwise:

         * Let z2 = karatsuba(x1, y1). x1 and y1 are the most significant digits, and are the local variables "high".

         * Let z0 = karatsuba(x0, y0). x0 and y0 are the least significant digits, and are the local variables "low".

         * Let z1 = karatsuba(x1+y0, x0+y1) - z0 - z2.

         * And the result is the following sum:

         * z2 * b^2m        +        z1 * b^m        +        z0

         *

         * @param x The multiplicand.

         * @param y The multiplier.

         * @return The product.

         */

        

        public static long karatsuba(long x, long y) {

                // Base case: single digit multiplication

                if (x<10 || y<10) {

                        return x * y;

                }

                // Recursive case: Decompose the problem by splitting the integers and applying the algorithm on the parts.

                else {

                        // Convert the numbers to strings so we can compute the # of digits of each number.

                        // Note: We could also use floor(log10(n) + 1) to compute the #digits, but remember that we need to split the numbers too.

                        String xString = Integer.toString((int)x);

                        String yString = Integer.toString((int)y);

                        // Local variables

                        long         m = max(xString.length(), yString.length()), // the maximum # of digits

                                        m2 = m/2, // the middle; if the number is odd, it will floor the fraction

                                        high1 = Integer.parseInt(strCopy(m2, xString)[0]), // the most significant digits. this is the scalar multiplier for b^m2

                                        low1 = Integer.parseInt(strCopy(m2, xString)[1]), // the least significant digits. this is what is added on to high1*b^m2

                                        high2 = Integer.parseInt(strCopy(m2, yString)[0]), // same for y

                                        low2 = Integer.parseInt(strCopy(m2, yString)[1]), // same for y

                                        // Three recursive calls

                                        z0 = karatsuba(low1, low2), // z0 = x0y0

                                        z2 = karatsuba(high1, high2), // z2 = x1y1

                                        z1 = karatsuba((low1 + high1), (low2 + high2)) - z2 - z0; // z1 = (x0 + y1)*(x1 + y0) - z2 - z0, courtesy of Karatsuba

 

                        return (z2 * power(10, 2*m2) + (z1 * power(10, m2)) + z0);

                }

        }

 

}

 

 

 

public class Main {

 

        public static void main(String[] args) {

                // TODO Auto-generated method stub

                System.out.println(Karatsuba.karatsuba(200, 200));

                System.out.println(Karatsuba.karatsuba(12345, 6789));

                System.out.println(Karatsuba.karatsuba(2358925, 1259174));

 

        }

 

}



Result:

The Comparision:


Please see the comparison done by some of the college professors of #Bharat


And look at the algorithm that our forefathers had developed thousands of years back, which was actually unbeatable for so many years afterward.


So, my earnest request to the engineers of #Bharat


Know your real worth.


Go back to the roots.


Embrace #Sanskrit


And now you will realize why my wife is learning Sanskrit to teach my currently 11-years-old son so that he can learn Vedic algorithms from the original Sanskrit script


And now the surprises for the people of #universe.


Please have a look at the document that follows to get an idea.



I am happy to see that the teaching community of Bharat are coming forward to reclaim who we are

Enjoy




Friday, May 6, 2022

The tribute from a #guru to his own gurus...

 



here is the #guru inside me is paying his tributes to his #guru from the #techworld and other walks of his life

they are Linus Torvalds, the authors of the #gangoffour #designpatern book, the creator of #android, and many more people who contributed to this enormous effort while still keeping it open source, the authors of the #effectivecpp and #moreeffectivecpp and the similar category of books, professor Doug of the USA for his insights about android internals in the lectures, I think at #coursera, my family/wife for providing me a caring #home and taking care of all the external noises and giving me enough room for in-depth study and research, and last but not the least, my currently 11-years-old son #ridit - my best student so far - for still keeping the fire in the belly alive.

the term Techworld is significant.

they showed me the way to move forward in the maze of the software world.

at last, I am able to claim to be a true engineer

it takes time to gain real expertise.

I look up to other gurus for another purpose - like morality, character, philosophy, or mindset

today is the right time to mention them as well

the #guru that I adore a lot is the avatar of #lordkrishna uttering #gita in the deadly battlefield of #mahabharata and I have learned a lot from this #guru about how to motivate myself in difficult times

the other character that attracts me is #shabari feeding the tired #lordrama - which shows that many times just a bit of kindness is enough to make a dead person alive

the other character I am attracted to is #daupradi who showed what exactly is meant by #agnikanya - a really powerful image of the ancient #bharat - always took the center stage of #mahabharata by her sheer intelligence and beauty - energizing all of her lions in the right direction. there is a lot for the modern-day feminists to learn from her

the other character that has attracted me is #karna - the real fighter - being struck by #destiny - yet never became a coward soul for any selfish reason

the other #guru to mention here is #dronacharya - the man behind creating skills

the other #guru is #vivekananda - who showed that by sheer determination and good intention, we can really move a mountain - a real #guru for the youth of the nation - a #karmyogi

the other few gurus I must mention is my #grandfather who enlightened me with the real history of #bharat - without any manipulation from the people like Romila Thaper and all such leftist propaganda machine

my parents showed me that hard work pays off

and then all of my childhood teachers who taught me - most of the time without even taking a penny must be mentioned here

the childhood friends of #purulia created a really jealousy free environment where collaboration was the real fun way

the raw environment of #purulia where actually there was no restriction as such helped me live the life on my own terms - which was of course a boon in the disguise

and last but not the least all the negative people who actually created hurdles in the journey helped me to become more resilient instead of becoming a weak-hearted guy

The State Design pattern in C++ using timer and notification






As a #guru, let me pay my respects today to my #guru in the tech world, who has influenced my technical skills and mindset.

Although I have never seen them, nor do they know I exist.

But I am grateful to them - and because of them, I have at last become an engineer in the true sense.

First guru: The authors of The Gang of Four Design Pattern Book

Second Guru: Linus Torvalds for offering Linux and rather helping me come out of the vicious cycle of windows

Third Guru: The Android creator and Google for showing me the different nitty-gritty of a complicated framework that i learnt through delving into the Android framework code

Fourth Guru: A professor of a USA University by the name Doug, from whom I got insights of how to study the Android OS difficult parts of the code like the AsyncTask Framework, and he showed  me the right approach of taking the OS study from an engineer’s perspective - delving into the difficult concurrent framework of the Android OS

And my all-time Guru: My family for giving me a sweet, caring, loving #home and my only son, #ridit, for becoming my best student from his early childhood. He is still driving me to burn the midnight oil in front of the laptop to explore the deep ocean of Computer science.

And I am sure, the way the whole professional world of technology is moving, very soon somebody will have to dismiss the book called

#theworldisflat  - The World Is Flat

and write a new one 

#theflatistheworld - The Flat Is The World


Now let's come back to the subject. Let's discuss the technical side of the State Design Pattern.

The state design pattern is a powerful tool in software design, allowing you to encapsulate an object's behavior based on its internal state.

The main participants in this design pattern are:

Context: This object represents the entire entity experiencing state changes. It holds a reference to the current state object and exposes an interface for external interaction.

State: These are concrete classes representing each possible state the object can be in. Each state class defines its own behavior for responding to events and transitions.

Transitions: These define how the object can move from one state to another. They can be triggered by events, user actions, or internal conditions.

In my example, I have cited the process of cooking chicken - how the chicken states alter from an uncleaned state to a cleaned state to a marinated state to a cooked state and finally served to the guests.

Here is the class diagram of the design pattern...


Runtime Behaviour

The runtime interaction follows these steps:

  1. The application creates the Context.
  2. The Context delegates execution to the current State.
  3. The State starts a Timer.
  4. The Timer expires.
  5. The Timer invokes the notification callback.
  6. The callback requests the Context to change its current State.
  7. The Context delegates subsequent operations to the new State.

The source code...

Callback.h

#ifndef CALLBACK_H_

#define CALLBACK_H_


class Callback {

public:

virtual void goToNextStateFromCallback() = 0;

virtual ~Callback() = default;

};


#endif



ChickenState.h

#ifndef CHICKENSTATE_H_

#define CHICKENSTATE_H_


#include <string>


class ChickenState {

public:

virtual ~ChickenState() = default;

virtual void wash(int period, int totalTime) {}

virtual void marinate(int period, int totalTime) {}

virtual void cook(int period, int totalTime) {}

virtual void serve(int period, int totalTime) {}

virtual void goToNextState() = 0;

virtual std::string getTag() const = 0;

};


#endif



UncleanedState.h

#ifndef UNCLEANEDSTATE_H_

#define UNCLEANEDSTATE_H_


#include "ChickenState.h"

#include "Mamma.h"

#include "CleanedState.h"

#include <iostream>


class UncleanedState : public ChickenState {

private:

Mamma* mamma;

std::string tag = "Uncleaned";


public:

UncleanedState(Mamma* ctx) : mamma(ctx) {}


void wash(int period, int totalTime) override {

std::cout << "[Uncleaned] Chicken is getting washed... please wait...\n";

mamma->t.setTimeout([this]() {

mamma->goToNextStateFromCallback();

}, totalTime);

}


void goToNextState() override {

mamma->isUncleanedStateDone = true;

mamma->changeChickenState(std::make_unique<CleanedState>(mamma));

}


std::string getTag() const override { return tag; }

};


#endif


CleanedState.h

#ifndef CLEANEDSTATE_H_

#define CLEANEDSTATE_H_


#include "ChickenState.h"

#include "Mamma.h"

#include "MarinatedState.h"

#include <iostream>


class CleanedState : public ChickenState {

private:

Mamma* mamma;

std::string tag = "Cleaned";


public:

CleanedState(Mamma* ctx) : mamma(ctx) {}


void marinate(int period, int totalTime) override {

std::cout << "[Cleaned] Chicken is getting marinated... please wait...\n";

mamma->t.setTimeout([this]() {

mamma->goToNextStateFromCallback();

}, totalTime);

}


void goToNextState() override {

mamma->isCleanedStateDone = true;

mamma->changeChickenState(std::make_unique<MarinatedState>(mamma));

}


std::string getTag() const override { return tag; }

};


#endif


MarinatedState.h

#ifndef MARINATEDSTATE_H_

#define MARINATEDSTATE_H_


#include "ChickenState.h"

#include "Mamma.h"

#include "CookedState.h"

#include <iostream>


class MarinatedState : public ChickenState {

private:

Mamma* mamma;

std::string tag = "Marinated";


public:

MarinatedState(Mamma* ctx) : mamma(ctx) {}


void cook(int period, int totalTime) override {

std::cout << "[Marinated] Chicken is getting cooked... please wait...\n";

mamma->t.setTimeout([this]() {

mamma->goToNextStateFromCallback();

}, totalTime);

}


void goToNextState() override {

mamma->isMarinatedStateDone = true;

mamma->changeChickenState(std::make_unique<CookedState>(mamma));

}


std::string getTag() const override { return tag; }

};


#endif


CookedState.h

#ifndef COOKEDSTATE_H_

#define COOKEDSTATE_H_


#include "ChickenState.h"

#include "Mamma.h"

#include <iostream>


class CookedState : public ChickenState {

private:

Mamma* mamma;

std::string tag = "Cooked";


public:

CookedState(Mamma* ctx) : mamma(ctx) {}


void serve(int period, int totalTime) override {

std::cout << "[Cooked] Chicken is ready! Enjoy the delicious Ajwaini Chicken!\n";

mamma->isCookedStateDone = true;

mamma->timerRunning = false; // Break the execution loop

}


void goToNextState() override {}

std::string getTag() const override { return tag; }

};


#endif





Mamma.h

#ifndef MAMMA_H_

#define MAMMA_H_


#include <memory>

#include <atomic>

#include "Callback.h"

#include "ChickenState.h"

#include "timer.h"


class Mamma : public Callback {

private:

std::unique_ptr<ChickenState> currentState;


public:

Timer t;

std::atomic<bool> timerRunning{true};


// Flags tracking state milestones safely

std::atomic<bool> isUncleanedStateDone{false};

std::atomic<bool> isCleanedStateDone{false};

std::atomic<bool> isMarinatedStateDone{false};

std::atomic<bool> isCookedStateDone{false};


Mamma();

~Mamma() override = default;


void changeChickenState(std::unique_ptr<ChickenState> nextState);

void startPreparation();

void goToNextStateFromCallback() override;


ChickenState* getCurrentState() { return currentState.get(); }

};


#endif


Mamma.cpp

#include "Mamma.h"

#include "UncleanedState.h"

#include "CleanedState.h"

#include "MarinatedState.h"

#include "CookedState.h"

#include <iostream>


Mamma::Mamma() {

t.setCallback(this);

// Initialize with the starting state

currentState = std::make_unique<UncleanedState>(this);

}


void Mamma::changeChickenState(std::unique_ptr<ChickenState> nextState) {

currentState = std::move(nextState);

}


void Mamma::startPreparation() {

while (timerRunning) {

if (!isUncleanedStateDone) {

currentState->wash(1000, 1500);

} else if (!isCleanedStateDone) {

currentState->marinate(1000, 1500);

} else if (!isMarinatedStateDone) {

currentState->cook(200, 2000);

} else if (!isCookedStateDone) {

currentState->serve(200, 1000);

}

}

std::cout << "Mamma - the cook is leaving the kitchen.\n";

}


void Mamma::goToNextStateFromCallback() {

t.justStop();

currentState->goToNextState();

}





Timer.h

#ifndef TIMER_H_

#define TIMER_H_


#include <thread>

#include <chrono>

#include <atomic>

#include "Callback.h"


class Timer {

private:

Callback* cb = nullptr;

std::atomic<bool> active{true};


public:

Timer() = default;


void setCallback(Callback* callback) {

cb = callback;

}


void setTimeout(auto function, int delay) {

active = true;

std::thread t([this, function, delay]() {

if (!active.load()) return;

std::this_thread::sleep_for(std::chrono::milliseconds(delay));

if (!active.load()) return;

function();

});

t.join(); // Blocks parent execution sequentially per step

}


void stop() {

if (cb) cb->goToNextStateFromCallback();

}


void justStop() {

active = false;

}

};


#endif


Main.cpp


//============================================================================

// Name : Main.cpp

// Author : Som

// Version :

// Copyright : som-itsolutions

// Description : Hello World in C++, Ansi-style

//============================================================================


#include "Mamma.h"


int main() {

auto mamma = std::make_unique<Mamma>();

mamma->startPreparation();

return 0;

}


To compile the above code, we need to activate the -pthread option for the compiler and linker.


Enjoy...