Research Ideas for StructInsight – Any Takers?

        About fifty years ago, when I was in middle-school, one of the favorite essay assignments of my language teachers used to be of the type, “If I were the prime minister of India” or “If I had one crore rupees to spend”.  I was slightly amused to note that this article has turned out to be belonging to the same genre and its title could have been “If I were a professor of civil engineering”.

        I published the first version of StructInsight-in-Python in December 2023.  It is an open source and free software. It’s source code is available on Github. The user manual is available at this link. Like it’s predecessor (StructInsight in Java programming language), the main objectives of  the Python version also are as given below.

1. To act as a learning aid, where students can try many examples of structural analysis in a short time (due to ease of input) and get good insight to structural behavior by instantaneously getting feedback in the form of shear force, bending moment, and deflection diagrams.

2. To act as a teaching tool for professors to quickly create examples with nice-looking detailed structural diagrams during in-person lectures, as well as to create lecture notes and other teaching material.

        However, the reasons to switch from Java to Python programming language for building the StructInsight software were as under.

1. Python has emerged as a more popular programming language in the last several years and I feel that structural engineers should get proficient in it.  I know from my three decades’ experience of teaching programming languages that a student understands a programming construct quickly if the examples are from their familiar domain. For a structural engineering student, it would be quite easier to learn Python if the examples are from the structural engineering field. To benefit them, I have open-sourced this software, so that they can freely tinker with it.

2. One of the main reasons for the popularity of the Python language is the availability of many software tools and libraries suitable for handling problems in the Artificial Intelligence (AI) and Machine Learning (ML) domain. Due to these tools, Python has become the standard language for development of AI / ML software. I felt that if a structural engineer wants to bring AI / ML to their field, learning Python would be essential and for that StructInsight in Python would turn out to be a good starting point and pivot.

3. I envisaged that students at various levels of study would take inspiration from this project and fork it either to create totally independent projects of their own or they may contribute to this project by making improvements in its features. As a brain-stormer, I am listing below a few ideas for such projects. 

Final year B.Tech. students should find the following projects challenging and at the same time doable.

  • At present StructInsight can handle a Uniformly Distributed Load (UDL) only over the full length of a beam element. Make modifications to handle the situation where a UDL is spanning over a part of a beam element.
  • Handle triangular and trapezoidal loads.
  • Write pre-processors such as the ability to save the data about the geometry of a beam to a disk file, so that it can be reused without inputting the data manually every time.  Similarly load data can also be saved separately, so that the same beam can be checked for different load cases.
  • Those who are savvy with the human-computer-interface design can modify the present interface and make it more efficient.

For M.Tech. students as well as B.Tech. students with more time and resources, the following projects would be suitable.

  • Write post-processors such as reinforced concrete design of the analyzed beam.
  • Incorporate analysis of other types of structures such as plane trusses and frames, space trusses and frames, etc. The opening menu of the present version of StructInsight as shown in the following figure gives the idea of this plan.

     

  • Create simulation of deformations of a continuous beam subjected to rolling loads.  

PhD students can venture into the following areas.

  • Create synthetic data for machine learning, so that the behavior of a new structure can be predicted without actually analyzing it.
  • Create digital twin for an existing structure and develop an ability to give advance warning of an impending failure.
  • Physics Informed Machine Learning, i.e., how to bake structural engineering into machine learning for discovering new laws, engineering formulae etc.

        I ruefully ponder that had I been a professor of civil engineering, I could have assigned these projects to my students. Of course, even now, I intend myself to pluck some of the so-called ‘low hanging fruits’ from the above ideas. But I admit that the difficult projects would require a lot of hard work and youthful energy. Any takers?


You may also like:

1. Quick Primer For ‘git’.

2. An Erroneous Construction Practice.

3. Self-driving Cars And India.


chatGPT एक उत्क्रांती

डिसेंबर २०२२ च्या पहिल्या आठवड्यात OpenAI या संस्थेने chatGPT हे सॉफ्टवेअर जागतिक पातळीवरील जनतेच्या वापरासाठी खुले केल्याची घोषणा केली आणि केवळ संगणक क्षेत्रातील लोकांमधेच नव्हे तर एकूण सगळ्या बुद्धिजिवी जनतेमधे खळबळ उडाली. या सॉफ्टवेअर विषयी लोकांच्या मनात इतके कुतूहल निर्माण झाले की त्याच्या जन्माच्या पहिल्या ५-६ दिवसातच १० लाख लोकांनी त्याच्या वापरासाठी सभासद नोंदणी केली. हा एक विक्रमच आहे. या पूर्वी दुसऱ्या कोणत्याही सॉफ्टवेअर ने (अगदी Facebook, WhatsApp, किंवा gMail ने सुद्धा) इतक्या जलद गतीने आपले सभासद निर्माण केले नव्हते. 

से काय आहे या सॉफ्टवेअरमधे ? ते समजण्यासाठी आपण सर्वप्रथम त्याच्या नावाची फोड जाणून घेऊया. chatGPT मधील chat म्हणजे ‘संभाषण’ हे आपल्या सर्वांना ठाऊक आहेच; त्याच्या नावाचा दुसरा भाग म्हणजे GPT हे Generative Pre-trained Transformer ह्याचे संक्षिप्त रूप आहे. Transformer म्हणजे बदल किंवा रूपांतर घडवून आणणारे यंत्र. Pre-trained म्हणजे त्याला जे ज्ञान आहे ते त्याच्या मेंदूत अगोदरच भरून ठेवले आहे; आपण प्रश्न विचारल्यावर त्या संबंधी माहिती ते इंटरनेट वर शोधत बसत नाही. आणि Generative म्हणजे एखादा खरा माणूस देईल अश्या शब्दात आपल्या प्रश्नाचे उत्तर तयार करणे. वेगळ्या शब्दात सांगायचे झाले तर chatGPT म्हणजे एखाद्याने मानवी भाषेत विचारलेल्या प्रश्नाचे रूपांतर संगणकाला उमजेल अश्या प्रकारे करून, त्याचे उत्तर संगणकात अगोदरच भरून ठेवलेल्या ज्ञाना मधून गोळा करून, त्याचे शब्दांकन परत मानवी भाषेत करणारे सॉफ्टवेअर. 

गूगल किंवा बिन्ग सारख्या शोधयंत्रांशी तुलना केली की चॅटजीपीटी चे वैशिष्ट्य जास्त चांगले समजते. उदाहरणार्थ, मला भगवान श्रीराम ज्या रघुकुळातले आहेत त्या रघुवंशातील राजांची नांवे पाहिजे होती. या विषयी मी जेव्हा गुगल शोध यंत्राद्वारे चौकशी केली तेव्हा अपेक्षेप्रमाणे गुगलने, जिथे मला या संदर्भात महत्वाची माहिती मिळेल अश्या इंटरनेट वरच्या पानांची (Web Pages) किंवा संकेतस्थळांची यादी दिली. म्हणजे ही माहिती कुठे उपलब्ध आहे त्या कडे बोट दाखवले, पण थेट नेमकी ती माहिती दिली नाही. ती पाने वाचून, त्यातून मला हव्या त्या माहितीचे संकलन करण्याची जबाबदारी माझी! या उलट, हाच प्रश्न जेव्हा मी चॅटजीपीटीला विचारला, तेव्हा तिने (खालील चित्रांत दाखवल्याप्रमाणे) आपल्या ज्ञान भांडारातून शोध घेऊन, सूर्यापासून रामापर्यंत रघुवंशातील अकरा राजांच्या नावांची यादी दिली. इतकेच नव्हे तर त्या राजांची एकएक वाक्यात जुजबी माहिती पण दिली. म्हणजे एखाद्या खऱ्याखुऱ्या माणसाने व्यवस्थित आणि नेमके उत्तर द्यावे त्याप्रमाणे झाले. 

हे चक्रावून टाकणारे आणि आश्चर्यकारक नाही काय? कृत्रिम बुद्धिमत्ता विज्ञानाच्या क्षेत्रातील प्रगतीचा हा फार मोठा टप्पा आहे. त्याला एक उत्क्रांतीच म्हणता येईल.  

चॅटजीपीटीला तुम्ही कोणत्या प्रकारचे प्रश्न विचारू शकता? वानगीदाखल काही नमुने बघा-

  • समजा तुमच्या मुलाचा वाढदिवस येऊ घातलाय. तुम्ही चॅटजीपीटीला विचाराल: माझ्या ५ वर्षाच्या मुलाचा वाढदिवस साजरा करण्यासाठी योग्य ते थिम सुचव; शिवाय या ऋतुला साजेल आणि त्याच्या मित्र-मैत्रिणींना आवडेल असा मेन्यू पण सांग. चॅटजीपीटी त्याचे सुयोग्य उत्तर देईल. ते तुम्हाला नाही पटले तर तुम्ही तिला तसे सांगा, ती तुमच्या सूचनांप्रमाणे नवीन कल्पना सांगेल.
  • तुम्ही १०वी ला आहात आणि तुम्हाला इंग्रजीच्या वर्गात निबंध लिहायला सांगितलाय. तुम्ही म्हणू शकता, “चॅटजीपीटी, मला ‘माझे आदर्श व्यक्तिमत्व’ या विषयावर १०वी च्या विद्यार्थ्याने लिहावा असा हजार शब्दांचा निबंध लिहून दे; त्यात स्वामी विवेकानंद हे माझे आदर्श असतील.” त्यावर चॅटजीपीटी तुम्हाला असा निबंध सुचवेल. तो पाहिल्यावर तुम्हाला त्यात काही फेरबदल हवे असल्यास चॅटजीपीटीला तसे सांगा आणि ती तुमच्या आज्ञेप्रमाणे त्यात सुधारणा करेल.
  • चॅटजीपीटीला सध्या प्रचलित असलेल्या सर्व संगणक भाषांचे (उदा. C++, Java, JavaScript, Python, Golang, वगैरेंचे) सखोल ज्ञान आहे. त्यामुळे तुम्ही संगणक प्रोग्रॅमर असाल तर चॅटजीपीटी तुमच्यासाठी फारच उपयोगी आहे. तुम्ही लिहिलेला एखादा सदोष प्रोग्रॅम चॅटजीपीटीला देऊन तुम्ही त्यातील चूक शोधू  शकता. दुसऱ्याने लिहिलेला समजायला अवघड असा प्रोग्रॅम तुमच्या आज्ञेवर चॅटजीपीटी अगदी छान स्टेप-बाय-स्टेप तुम्हाला समजावून सांगेल. तुमचा एखादा हळू चालणारा प्रोग्रॅम चॅटजीपीटीला दिला, तर त्याला कार्यक्षम करण्यासाठी काय फेरबदल करता येतील हे पण ती छान सुचवू शकते.
  • समजा तुम्ही एक पत्रकार आहात आणि तुमच्या जवळ एखाद्या शास्त्रज्ञाच्या मूळ भाषणाचा पूर्ण मजकूर उपलब्ध आहे. बातमी देण्यासाठी मात्र तुमच्यावर फक्त २०० शब्द वापरायचे बंधन आहे. तर तुम्ही ते भाषण चॅटजीपीटीला द्या आणि त्याचा २०० शब्दात सारांश तयार करून द्यायला सांगा. आणि ताबडतोब ती अतिशय उच्च दर्जाचा सारांश तयार करून देईल. 
  • तुम्हाला एखाद्या ई-मेल ला उत्तर द्यायचे आहे पण नेमके शब्द सुचत नाहीत, तर चॅटजीपीटीला ती ई-मेल द्या आणि उत्तराचे ४-५ नमुने बनवायला सांगा. चॅटजीपीटी लगेच तुमच्या हुकुमाची तामिली  करेल. 

चॅटजीपीटीच्या निर्मात्यांनी तिला फक्त प्रश्नांची उत्तरे द्यायलाच नाही तर काही विशिष्ठ प्रकारच्या प्रश्नांची उत्तरे टाळण्यासही शिकवले आहे. अश्लीलतेकडे झुकणाऱ्या अनुचित प्रश्नांचे उत्तर, समाजात द्वेष किंवा तेढ निर्माण होईल अशा प्रकारची माहिती पुरवण्यास चॅटजीपीटी सरळ नकार देते. एखादा राजकीय किंवा राजकारणात लिडबिडलेला प्रश्न जर तिला विचारला तर सफाईने ज्याला ‘पॉलिटिकली करेक्ट’ म्हणतात असे उत्तर ती देते. तिचा हा मुत्सद्दीपणा तपासायला मी तिला एक खोचक प्रश्न विचारायचे ठरवले. आता मी पडलो महाराष्ट्रीय, ‘टिळक श्रेष्ठ की आगरकर श्रेष्ठ’ या सारखे वाद घालण्यात पटाईत असलेल्या जमातीतला. त्यामुळे माझ्या प्रवृत्तीला अनुसरून मी तिला विचारले, “पंडित जवाहरलाल नेहरू आणि श्री. नरेंद्र मोदीजी ह्यांच्यात भारताचे पंतप्रधान म्हणून चांगले कोण?”. (खालील चित्र पहा.)  

पेक्षेप्रमाणे चॅटजीपीटीने उत्तर देतांना सर्वप्रथम स्वतःची बाजू सुरक्षित केली; तिने म्हंटले “मी पडले मानवी भाषेचे एक संगणकीय प्रारूप. कोण्या व्यक्तीविषयी मला काही खाजगी मत नाही आणि कोणाचे सापेक्ष मूल्यमापन करणे हे माझ्यासाठी उचित नाही. वस्तुनिष्ठ आणि अचूक माहिती देणे हे माझे काम आहे.” त्यानंतर त्या दोघांविषयी जुजबी माहिती देऊन तिने वरून उपदेश केला, “पंतप्रधान म्हणून चांगले कोण अशी दोन व्यक्तींची तुलना करणे हे बरोबर नाही. कारण अशाप्रकारची तुलना ही  व्यक्तिसापेक्ष आहे, आणि या बाबतीत प्रत्येक जण आपल्या दृष्टिकोनानुसार व गरजेप्रमाणे वेगवेगळे मत मांडू शकतो. त्यापेक्षा त्या दोघांनी त्यांच्या त्यांच्या काळात आलेल्या संकटांवर मात करून कशी देशाची प्रगती केली हे समजावून घेणे जास्त सयुक्तिक ठरेल.”

ता हे सगळे वाचल्यावर जर तुम्हाला चॅटजीपीटी वापरून पाहायची इच्छा झाली असेल तर https://chat.openai.com/auth/login या संकेतस्थळाला भेट द्या. त्यामुळे उघडणाऱ्या पानावर ‘Sign up’ चे बटन दाबून व विचारलेल्या संबंधित प्रश्नांची उत्तरे देऊन प्रथम त्या संस्थेचे सभासद व्हा. सध्यातरी चॅटजीपीटी ही सेवा निःशुल्क आहे, त्यामुळे सभासद व्हायला आणि ती सेवा वापरायला काही पैसे पडत नाहीत. सभासद झाल्यानंतर ‘Log in’ चे बटन दाबून, तुमचे युजरनेम व पासवर्ड टाकून तुम्ही या सेवेचा आनंद घेऊ शकता. 

चॅटजीपीटी वापरताना तिच्या मर्यादांचे भान ठेवणे मात्र आवश्यक आहे. तिचे निर्माण करणारी संस्था openAI च्या म्हणण्यानुसार तिला सन २०२१ पर्यंतच्याच जागतिक घडामोडींची माहिती दिलेली आहे. त्यामुळे गंमत अशी झाली की मी जेव्हा तिला विचारले, “चॅटजीपीटीची निर्मिती केव्हा झाली?”, तेव्हा तिने उत्तर दिले, “चॅटजीपीटी काय आहे हे मला माहीत नाही. कदाचित ही २०२१ नंतरची गोष्ट असेल.” म्हणजे बिचारीला स्वतःच्या जन्माचीच माहिती नाही. दुसऱ्या एका गोष्टीबाबत openAI ने सावधगिरी बाळगण्यास सांगितले आहे, ते म्हणजे पक्षपात (Bias). आपण म्हणजे आपला मेंदू अनावधानाने म्हणा किंवा जाणूनबुजून म्हणा, कश्यानकश्याच्या बाबतीत पक्षपाती असतो. उदाहरणार्थ, एखाद्याने आपल्याला दवाखान्यात गेलो असतांना जर म्हंटले, “अरे जरा नर्सला पटकन हाक मार बरं”, तर आपण “अहो सिस्टर लवकर इकडे या” अशीच हाक मारण्याची शक्यता आहे. आपण ज्या समाजात / वातावरणात वाढलो आहोत तिथे नर्स म्हणजे ‘ब्रदर’ ही  असू शकतो ही शिकवण आपल्या मेंदूवर फारशी ठसवून भरली नसते. त्यामुळे नर्स म्हणजे स्त्री हा लैंगिक पक्षपात आपला मेंदू अनावधानाने करतो. अश्याच प्रकारे जातीय, भौगोलिक, वांशिक, राजकीय विचार धारणे प्रमाणे, इत्यादी पक्षपात असू शकतात. जगातील प्रत्येक व्यक्ती अशीच वेगवेगळे पक्षपात आपल्या मेंदूत साठवून जगत असते. आता चॅटजीपीटीमधे जी माहिती भरली आहे तिचा उगम, कुठल्या न  कुठल्या व्यक्तीच्या मेंदूतूनच आहे. त्यामुळे चॅटजीपीटीने दिलेली उत्तरे पक्षपाती असू शकतात ही चेतावणी तुम्ही लॉगीन करताच openAI तुम्हाला देते. इतकेच नव्हे तर ती धादांत चुकीची असू शकतात हे पण सांगितले जाते. 

ह्या मर्यादा लक्षात घेऊनही चॅटजीपीटी अतिशय उपयोगी ठरते आहे आणि लाखो लोकांच्या पसंतीला उतरते आहे. तिची उपयुक्तता आणि लोकप्रियता बघून आपल्या शोधयंत्राच्या जागतिक बाजारपेठेतील स्वामित्वाला जबरदस्त आव्हान निर्माण झाले आहे ह्याची गूगल सारख्या महान संस्थेला सुद्धा धास्ती पडली आहे. पण त्याहीपेक्षा जास्त चिंता होमवर्क आणि ऑनलाईन परीक्षांच्या द्वारे विद्यार्थ्यांचे मूल्यमापन करणाऱ्या शिक्षणक्षेत्राला लागली आहे. इतकी की अमेरिकेतल्या काही विद्यापीठांनी व शाळांनी त्यांच्या परिसरात चॅटजीपीटीचा वापर करण्यास बंदी घातली आहे. कारण चॅटजीपीटीमुळे विद्यार्थ्यांना केवळ वस्तुनिष्ठ प्रश्नांचीच (objective, multiple-choice etc.) उत्तरे नव्हे तर निबंधात्मक प्रश्नांची उत्तरे तयार करणे पण अतिशय सोपे झाले आहे. म्हणजे चॅटजीपीटी आता ‘मुन्नाभाई’ चे काम अतिशय सरसपणे करू शकते. कृत्रिम बुद्धिमत्ता विज्ञानातील प्रगतीची ही झेप पाहता, येणाऱ्या काळात जगातील सर्व शिक्षणसंस्थांना विद्यार्थ्यांचे मूल्यमापन करणाऱ्या परीक्षा पद्धतीत आमूलाग्र बदल करावा लागेल यात काही शंका नाही. चॅटजीपीटीचा अजून एक वादग्रस्त प्रभाव पडलाय तो म्हणजे संशोधन क्षेत्रात. चॅटजीपीटीचा वापर करून शोधनिबंध तयार करण्याच्या घटना घडताहेत. मग प्रश्न असा निर्माण होतो की त्या शोधनिबंधाचे श्रेय कोणाला मिळावे? त्याच्या मानवी लेखकांना की चॅटजीपीटीला, की चॅटजीपीटीने ही कला ज्यांच्या कडून घेतली त्या अनाम व्यक्तींना? 

कूण चॅटजीपीटीमुळे आपल्या आयुष्यात अनेक गोष्टी खूप सुलभ होणार आहेत पण काही नवीन, जटिल प्रश्न निर्माण सुद्धा होणार आहेत. चॅटजीपीटीची सध्याची आवृत्ती ही GPT-3 या प्रारूपावर आधारित आहे. तिच्यात सुधारणा करणारे आणि तिला अधिक शक्तिशाली बनवणारे संशोधन वेगाने सुरु आहे. नवीन येणाऱ्या आवृत्तीचा क्रमांक GPT-4 असणार आहे. या क्षेत्रातील जाणकार लोकांच्या अंदाजानुसार चॅटजीपीटीची ही येणारी नवीन आवृत्ती इतकी बुद्धिमान असेल की अमेरिकेतील कायद्याची पदवी परीक्षा ती खूप चांगले गुण घेऊन उत्तीर्ण होईल. एकंदरीत येणाऱ्या नजीकच्या भविष्यकाळात चॅटजीपीटी मानवी आयुष्यात आणि संस्कृतीत काय क्रांती घडविते हे बघणे विस्मयकारी आणि रंजक ठरणार आहे. 


तुम्हाला आवडेल असे अजून काही:

1. वाट वेगळी क्वांटम कॉम्प्युटिंगची.

2. ईश्वर द्यूत खेळतो का?


The Quantum Way Of Computing

Coin2-20200801

Remember the quick decision-making tactic used by Jay and Veeru in the Hindi movie ‘Sholay‘? Whenever the two fast friends have a disagreement over the action to choose in some tricky situation, they would toss a coin; if the coin fell ‘Heads’ up, they would go Jay’s way. On the other hand, if it showed ‘Tails’, they would follow Veeru’s action. This was their method of shifting the responsibility of whatever good or bad was happening in their life to destiny and keeping their friendship intact. In a funny scene during a song (“Yeh dosti hum nahi chhodenge…”), both of them like a beautiful village girl passing by. To decide who among them is suitable for her, they toss a coin. But considering their deep and life-long friendship, even the destiny gets confused; and as shown in the movie, the coin falls on its edge and stands still in that position. Destiny keeps the issue unresolved!

The trigger for recalling all these things is ‘Quantum Computing‘, a phenomenon which is in the limelight from the last 3-4 years.  It has evolved from the confluence of some of the principles of the two different branches of study, viz., ‘Quantum Mechanics‘ and ‘Computer Science‘. To understand what is peculiar about Quantum Computing and how it differs from the classical computing that we are using from the last 70-80 years, let us brood over a question. We all know that if we toss a coin, it would show either ‘Heads‘ or ‘Tails‘ after it falls on the ground and comes to rest. If the coin is fair as defined by Statistics, then the probability of the Heads showing up is 50% and of the Tails is also 50%. But for sure, we know that it would be in only one of these two states; it is not possible for the coin to be in any third state or even in any mixture of these two states. And the key question here is, “what is the state of the tossed coin while in the air, is it Heads or Tails?”. Now you would say, “how can we answer that? We can not see the state of the coin while it is twirling in the air”. From the practical point of view, your answer is right. When the coin is in the air, ‘we‘ can not see its state. But does it mean that the coin does not have a state? Very confusing question indeed! But if you ask the same question to a scientist from the Quantum Mechanics field, then they would answer, “it is in both states, albeit with some specific probabilities”. Students of quantum mechanics are quite familiar with such a phenomenon; they call it ‘Quantum superposition of states‘.

From the very early days of the development of quantum mechanics, a science that bloomed and matured about a hundred years ago, the scientists observed that the behaviour of the sub-atomic particles such as electrons or photons, etc is somewhat different than that of the solid objects that we encounter in our everyday life and considered in the classical mechanics. The particles in the quantum world, like the hypothetical example of the ‘coin in the air’ described above, can simultaneously be in multiple states. An interesting detour here! While reading the stories from the epic ‘Ramayan’, I could not understand one thing in my childhood. Bhagwan Parashuram is an incarnation of Lord Vishnu. Similarly, Shriram is also an incarnation of Lord Vishnu. So, how is it possible, as in one of the stories, that both the incarnations of the same Lord Vishnu stand face to face? Similar is the case with these quantum particles. For example, an electron can simultaneously be in the state of clockwise as well as an anti-clockwise spin. However, there is one difference between the capabilities of Bhagwan Vishnu and these quantum particles. A quantum particle can be simultaneously in two mutually exclusive (as per our normal experience) states. But as soon as you look at it (or examine it, or measure its state in any way), you would find it in one of the two states.  Having learnt the quantum mechanics only after forming a rigid understanding of the world from the study of  classical physics, this un-classical behaviour of quantum particles baffled scientists. Even for the great scientist like Albert Einstein, it was very hard to accept this phenomenon. As the story goes, once while discussing this subject with one of his friends, he asked, “can you believe, that the moon exists only when I look at it?”.

This ability of these nano, sub-atomic particles to simultaneously exist in multiple states is used in the modern quantum computers. You must be knowing that only two symbols are used as alphabet to store numbers and text in the classical computers familiar to us from the last 70-80 years; those two symbols are 0 and 1. (For more information, you may read: How numbers are stored in computer’s memory?). These symbols are called ‘bits‘. In classical computers, the physical representation of these bits is achieved by the electric charge or current in a wire. The presence of the electric charge in that wire in the circuit is considered as 1, while the absence of charge is considered as 0 (zero) by the computer. One bit (i.e. a wire) can represent only two states, and at any given moment it can be only in one of those two states. Of course, what meaning or names you give to these two states is your choice. You may use them to represent either 0/1, or ON/OFF, or 3000/4500, or Heads/Tails. It should be obvious that if you want to store more data, you would require more bits (i.e., more such wires in the circuit).

In the case of quantum computers, however, a somewhat different system is used for the storage of data. Here, ‘qubits‘ (quantum bits) are used instead of bits. When examined or seen, a qubit can be only in one of the two states (zero or one), just as in the case of a bit. But because in the intermediate stage (i.e., when you are not looking at it), it can exist in multiple (superposed) states, you can use a qubit to represent more than two data elements. Computations are performed on this large amount of data stored on a single qubit, during this intermediate stage; and once the result of the computation is ready, the qubit is examined to obtain the final answer. Because of such an arrangement, the capacity of a quantum computer to store the data and perform the computation on it is millions of times more than that of a classical computer. Just for the sake of  comparison, consider the electronic chip inside your mobile phone. That chip is essentially, a classical computer. Let us say, the RAM (memory) of your cellphone chip is 1 GB (gigabytes). This means that its circuit consists of about 8 billion bits. As against this, let us consider some examples of quantum computer chips which are much more powerful than the existing classical supercomputers. There were only 72 qubits in the Google’s 2018 quantum computer model, while in October 2019, IBM created a quantum computer chip that consisted only of 53 qubits (source: Wikipedia). Some days ago, I read on the Internet that MIT of the USA is planning to make a chip of 124 qubits this year. So, in all the three examples, the number of qubits is in the neighborhood of a hundred. And what about their data storage capacity? The IBM chip referred above can store 72 petabytes of information, that is 72 billion GB !!!

One more property of these nanoparticles comes into play for measuring the state of the qubits and performing the computation thereby. This second property is more unbelievable and mind-boggling than the first property of superposition of states. In technical jargon, this property is known as ‘Entanglement‘. Quantum scientists can entangle two qubits together. Once entangled, the behaviour of the two qubits is identical. If you change the state of one of the qubits, the other one instantaneously changes itself to that state. This happens irrespective of the distance between the two qubits; one may be on the earth and the other may be on the planet Mars! This is somewhat similar to the funny phenomenon recurring in the Hindi comedy movie ‘Judawaa‘. It is a story of two twin brothers separated at their birth. It is shown in the film that the two brothers, though at different places, experience identical sensations and moods. For example, when one of them is slapped, the other one also gets the pain and his cheek also gets swollen. Of course, the movie is built on fiction. But in the case of qubits, the phenomenon does occur. Even today, the quantum physics can not explain how the information of the change of state of one qubit is conveyed instantaneously to the other entangled qubit. Notice that even for the Light (the fastest entity in the universe), it takes approximately 13 minutes to travel from the earth to Mars. But for qubits, the news of the change of state is shared instantaneously and  in the absence of any medium of communication. Although scientists can not reason this ‘spooky actions at a distance’ property, they know very well how to use it to their advantage. They have used it to enable parallel processing and thereby increase the speed of quantum computers. And how much do you think is this increase in the processing speed? Last year (in October 2019), Google tackled a very hard problem of mathematics on their quantum computer. It took just a few minutes to solve it. Google engineers in their research paper claim that the fastest existing supercomputer would have taken about 10000 years to solve the same problem!! The Quantum computer, thus, is one of the greatest inventions of mankind. Its importance can only be compared with the invention of the airplane by the Wright brothers or that of the Soviet Union’s launch of ‘Sputnik 1’, the first artificial satellite.

Having realized the importance and potential power of  quantum computers, most of the developed nations have jumped into the research in this domain. Now, what would be the applications of quantum computers? Upon reading several articles discussing this issue, I gathered that they would have immediate applications in the following areas.

  • The most promising field for quantum computing applications is chemistry and pharmaceutical science combined. The power of classical computers is turning out to be inadequate for mapping of some specific molecules as well as for the new drug discovery. The researchers in this area are eagerly waiting for quantum computers.
  • The second major application area of quantum computing would be cryptography. We know that information of confidential nature such as money transactions, military movements, or details of ‘Aadhaar‘ card or credit card, etc is encrypted before sending it over the Internet so that it is not misused if it is tapped in the middle. However, the science of breaking these encryption codes has also progressed a lot. And we frequently read stories in the newspapers about antisocial elements misusing it for fraudulent activities. Quantum computers are expected to provide unbreakable encryption.
  • Another important application of quantum computing would be ‘teleporting‘. All of us have experienced the irritation due to the slow speed of downloading a large file or a video. Not only the size of the file but even the distance of the server affects the download speed. For example, it normally takes more time to download something from a distant American server than say, a server at New Delhi. Now, using the property of ‘Entanglement’ discussed above, scientists are trying to build quantum networks. It would then be possible to send information from one place to another without actually transmitting it. The idea is simple; keep one of the entangled qubits in, say, New York office and the other one in your local office in India. Now as soon as any information is loaded on the New York qubit, exactly the same would be instantaneously available on your qubit. This is called teleporting. No long transmission wires are needed and no man-in-the-middle attack for stealing the information is possible! 

The scientists and the other people related to quantum computing are actively searching for more applications in diverse areas besides the above three.

After reading all these things, if you are thinking, “Ok! so it is now just a matter of a few months or a couple of years before we possess ultra-powerful quantum laptops and quantum cell phones”, then STOP! Do not go overboard. At present, the process of building these quantum computers is very complicated. With the kind of technology that is used today, the qubits can work at very cold temperatures only. How cold is that ‘very cold’ do you think? And the answer is, about minus 265 degrees Celsius! That is slightly above the absolute zero temperature (zero degrees Kelvins). This makes it impractical to use these computers in our everyday life. Of course, the research on this front is in progress. They are trying to find a technology that would not require such cold temperatures for the working of quantum computers. But nobody can tell the number of years it would take to reach that goal. Another problem is the appropriate software to run these quantum computers. On this front, however, there is quite promising situation. In June 2020, Switzerland’s national institute of technology (ETH Zurich) released the first high-level programming language suitable for quantum computers with the name Silq. Fortunately, they have kept it royalty-free. That means anybody can learn and use it without paying any money. They claim that Silq would have the same important status for quantum computers as the C programming language has for the classical computers. The main advantage of a high-level programming language is that a program written in that language and tested on a model of one company, works without any change on a different model of a different company. Because of the availability of a high-level programming language, it is expected that the process of application software development for the quantum computers would accelerate.

The quantum computing field is in its nascent stage at present. For a country like India, this is the right time to enter this field. It would require a lot of effort and investment towards research by the private, public, and Government institutions to make our country superior in this emerging technology. If we miss the bus now, it would be very costly to purchase the technology from the developed nations in the future. In the past, we did not invest much in the field of computer and mobile hardware; as a result, today we are very much dependent on countries like China, Taiwan, Korea, etc for the import of these items. On the other hand, we invested heavily in the field of space technology from the very beginning and consequently, we are considered as one of the leading nations there. We should have a similar status in the field of quantum computing also. At the individual level, those intending to make a career in this field must keep in mind that they would be required to do research all their life, and having research mentality is an essential prerequisite. As quantum mechanics is a branch of physics, it is obvious that your knowledge of physics must be very strong. For that, physics should be your major or at least the second major subject at the undergraduate level. If you intend to work on the hardware side of quantum computing, then you should be proficient in one or more subjects like electronics, cryogenics, metallurgy, etc. On the other hand, if you wish to join the software department, you should have graduate-level competency in mathematics and statistics, besides the regular computer science subjects. Thus  you will have to adopt a different approach than your normal education pattern, to be successful in this field.


You may also like:

1.The Hitchhiking Cat’s Guide to Getting a Job in Quantum Computing

2. Self-driving Cars And India.


Self-driving Cars And India

About 30 years ago, I had a chance to attend a scintillating talk by the then CMD of Neyveli Lignite Corporation (now NLC India Limited). Among other things, he narrated an incident that occurred during his official visit to a coal mine in Soviet Russia (USSR). The story went something like this:

Quote.

I was very much impressed by the heavy mechanization of the mining work there. I could see that their productivity in terms of coal output was many times more than that of a similar mine  in India. I remarked this to my Russian counterpart who was showing me around. He definitely was flattered and proud. He started recommending the names of Russian companies which could provide such mining machinery. But I was not enthusiastic. I told him, “Sir, this is not possible in India. We have huge unemployed population and it is major responsibility of our government to create jobs. This kind of automation would drastically reduce jobs in the mining sector and the government would never allow it”. For several seconds, he became speechless and looking towards the ceiling, went into deep thought. Then he narrowed his eyes, turned his gaze towards me and asked, “Sir, what tool do they use in your mines at present to take out coal?”. I could not immediately grasp his line of thought, but nevertheless I answered, “Of course, they use spades”. He absorbed my answer and with serious face, said, “Please ask them to use spoons. You would generate huge employment”. !!!

Unquote.

Sarcasm apart, such was the level of frustration among the torch bearers of cutting-edge technology towards the mood and understanding of the Indian society at that time. The delay in modernization of mining technology costed India heavily; obvious casualty was productivity. But there were other side effects too. For example, in case of coal mining, the low quality of coal output affected the thermal power generation down the line. Not only that the electricity was costly, but there was rampant load shedding. Even in my home state of Maharashtra (which is otherwise considered to be one of the developed and progressive states of India), we faced for several years, daily electricity outages of 22 hours in the rural area and 6 to 8 hours in the urban area. This caused heavy damage to bottom lines of most of the businesses and livelihood of farmers. The resultant unemployment must have far exceeded, the gains of not mechanizing the mining industry.

On the other hand, where there was early adoption of the modern technology, rich benefits were reaped. A glaring example is that of computer and information technology. When it started rising on the Indian horizon in the late 1980s, it also met with stiff resistance from various workers’ unions, specially from the banking and insurance sectors. They were afraid of heavy layoffs and job losses due to computerization. However, the policy makers at that time persisted and promoted this technology heavily and the results are for everybody to see; IT sector is generating maximum employment for the last quarter century. Also, can we even imagine life today without core banking, instant money transfers, ATMs, etc.?

Another illustrious example is that of space technology. The usual objections to it went on the following lines. “When there are millions of people who can not afford even one meal a day and clothes to wear, why should India spend huge money on rockets, satellites, and plans to travel to moon?”. In this case also, the policy makers persisted and went ahead with their planned space program. And today, we are enjoying the benefits of that vision. India is one of the super powers in the field of space technology. We have telecommunication satellites, good weather forecasting, disasters (such as hurricanes) warning systems, and so on. We are earning huge money by launching satellites of other countries. And we have reduced brain drain at least in this discipline.

Today, once again, not only India but the whole world is at the crossroads of a similar dilemma; and that is, should we allow self-driving cars technology? There are two challenges here. The first one is technological, “Are these cars at least as safe as human-driven cars?“. And right now, the answer is, “For Indian traffic conditions, definitely NO!“. However, this problem would eventually be solved; the pace at which AI and machine learning technology are progressing, it would be sooner rather than later. But the second and more important challenge is from the society, “What about the huge job losses that this disruptive technology would cause?“. Obviously, adding to the discomfiture of politicians and society, thousands and thousands of taxi drivers, paid car drivers, truck drivers would be losing their livelihood. Who is going to support them and their families?  It is our collective responsibility to devise appropriate mechanism to handle the situation where a large section of the society is getting adversely affected. In this regard, we should consider the following counter arguments:

  • The advent and actual use of self-driven cars would be gradual and slow process, spread over several years. This would drastically reduce the trauma of mass unemployment; affected people would have breathing time to get re-trained in skills for alternative trades and employment therein.
  • Governments can regulate the speed of introduction of this technology. From safety and acceptability point of view, they can apply it initially to rigidly controlled traffic like that of city tram service and local trains (I am given to understand that somewhat crude form of this technology is already in place for metro trains); then gradually, over several years, for long-distance trains. They may also allow this technology for providing shuttle bus service in such large campuses where vehicular traffic is sparse and disciplined.
  • It is well said that necessity is the mother of invention and adversity enhances creativity. The hard-working and industrious drivers’ community  would definitely invent adaptations and applications of their skills to hitherto unchartered areas. As a spoiler, consider one such idea- In India, due to peculiar societal conditions, most of the farmers have small sized lands. Due to their scale of operations, they can not afford tractors for ploughing and other farming activities; also getting farm labor has become extremely difficult these days. In this scenario, a startup offering shared tractor service would be very lucrative; they would get large trained man power in the form of drivers whose truck-driving skills can be easily adapted to tractor operations.
  • Any successful disruptive technology, although makes some job categories irrelevant, but at the same time, along with the allied developments, creates multitude of new job opportunities. And usually these newly created opportunities far outnumber the jobs lost. I feel that same would be the case with self-driving cars and there would be net gain to our society.  Of course, the section of the people who lose their jobs in the process, have to undergo lot of stress and turmoil in their career and family life.

The self-driving car technology is in nascent stage at present. Lot of research and development is necessary for this technology to be viable. The developed countries are actively pursuing it. It is imperative that India should contribute to this R & D. Otherwise, India would be the net importer and consumer of this technology. The phenomenon would be similar to that of cell phones and electronic chip manufacturing. In both the areas, we are heavily dependent on import from foreign countries, with hardly any indigenous manufacturing of vital components. Because of lack of basic research, patents, and experienced manpower, it has become uneconomical now to start manufacturing  in these domains; that would require very heavy and risky investment which nobody dares to undertake at this stage. If India looses initiative in self-driving car technology because of political, social, or other compulsions, it would meet the same fate in this domain also. Ultimately, this technology is bound to come; it has too many advantages. Some of the oft-discussed and well known advantages of autonomous cars are:

  • They would drastically reduce the parking space congestion in urban areas.
  • They would reduce number of vehicles per family. For example, both husband and wife can use  the same car, if their daily work reporting times are different. This would result in efficient utilization, as the idle time of the vehicle gets reduced.
  • They would make travel safe. A software would be acting as driver for these cars and that would be the best driver. So, there would be no traffic violations and the accident rate would be approaching to zero. The best driver would ensure least fuel consumption and least air pollution.

In the conclusion, I strongly feel that India should whole heartedly embrace and adopt the self-driving car technology. Government and other policy makers should encourage it. Research organizations and educational institutions should actively pursue projects for development and advancement  of this technology.

 

Quickly Creating Multi-user Facility For A Docker Microservice

From the last two-three years, the Docker container technology has become quite popular among software people, specially among Devops engineers. Docker maintains a huge repository of images called the Docker Hub, where one can get millions of ready-to-use applications and microservices. For an educational institute like ours (K.I.T.E.), it becomes a great source of cutting-edge technology applications which we can demonstrate to our students and thereby enrich their learning. One lacuna experienced during such demonstrations was that we could not provide simultaneous hands-on use of such an application to multiple students. Due to perennial resource crunch, we have only a couple of servers where we can run Docker engine. The students work on networked hosts which can almost be categorized as thin clients. Our problem would be solved, if the Linux within the container that we are demonstrating, has multiple user accounts. To mitigate this problem, I devised a procedure to quickly add multiple user accounts to a Docker image. The procedure is explained below, with the hope that it would be useful to people under similar situation.

Let us start with an empty folder. So, create a directory and change to it. Then, using your favorite text editor, create a list of users and passwords and store it in a file with name ‘userlist.txt‘ in that folder. An entry for a user in this file should be in the format user_id:password. For example, the contents of my ‘userlist.txt‘ file was:


   adam:icecream
   ashok:jellybean
   akbar:kitkat
   anthony:lollypop
   alisha:marshmellow

Create another text file with name ‘createusers.sh‘ in the same folder. This file, responsible for creating the user accounts, should contain the following shell script:


   #!/bin/sh
   for i in `cut -d ':' -f 1 userlist.txt`
   do
      useradd -m $i
   done
   cat userlist.txt | chpasswd

Next, create the third (and final!) text file with name ‘Dockerfile‘ having contents as follows:


   # multiuser facility
   #
   FROM ubuntu14.04:latest
   MAINTAINER Sanjay Khirwadkar <sanjayk@kitenagpur.com>

   COPY userlist.txt .
   COPY createusers.sh .
   RUN sh createusers.sh
   RUN rm -f userlist.txt createusers.sh

This is the file, using which we will build the Docker image of our application / microservice. Let us understand the purpose of various statements in this file.
The first two statements (beginning with #) are comment statements.
The argument of the FROM command in a Dockerfile, specifies the base image, on the top of which, the new image is going to be built. I have used here ubuntu14.04:latest as the base image. In your case, you would be using the name of your application or microservice image, where you want to create multiple login ids.
The MAINTAINER command specifies the author of the Dockerfile.
The subsequent two COPY statements copy the two files we have created earlier, from the host OS to the ubuntu linux of the container image that we are building.
After bringing in these two files in the container, we execute the shell script in createusers.sh by the RUN command in the subsequent statement. The execution of this statement during the build process would create the user accounts (with corresponding passwords), we have specified in userlist.txt file.
The last RUN command removes these two files (as their job is over) from the container Linux.

Once these three files are ready, build the image by command like this:

sanjay@kitenagpur ~/multiuser $ docker build -t multiuser:aug2016 .

To test the newly created facility, you may create and run a container as follows:

sanjay@kitenagpur ~/multiuser $ docker run -ti --rm --name kite1 multiuser:aug2016 bash
root@9ac5e2016d3e:/# login
9ac5e2807d3e login: ashok
Password:
Welcome to Ubuntu 14.04 LTS (GNU/Linux 3.2.0-61-generic x86_64)
...
ashok@9ac5e2016d3e:~$ ls
ashok@9ac5e2016d3e:~$ logout
root@9ac5e2016d3e:/# exit
exit

sanjay@kitenagpur ~/multiuser $

Alternatively, you may copy-paste the last four lines of the ‘Dockerfile‘ above, at appropriate place in your ‘Dockerfile‘ to achieve the same result.

Bitwise Operators in C

       Byte is the smallest unit of measurement of computer’s memory. A byte consists of smaller units called bits (for binary digits). On most of the computer systems today, a byte is represented by eight bits. A bit can take one of the two values, 1 or 0. The C programming language gives programmers, the power to manipulate individual bits using several operators, categorized as ‘Bitwise’ operators. Many modern programming languages have copied this feature of C and they also provide these operators. We are going to discuss here these operators; but, before that it would be interesting and useful to understand the way integers are stored in computer’s memory.


Quick links


How numbers are stored in computer’s memory?

Let us first understand how non-negative integers are dealt with. When such a number is stored in computer’s internal memory, its binary equivalent is created there in the form of electronic charges or bits. We know that C language has several integral data types such as char, int, short int, long int, etc. And on most of the C compilers today (I use gcc on Linux), a char variable takes 1 byte (8 bits), a short int takes 2 bytes (16 bits), and an int takes 4 bytes (32 bits). Now suppose that a byte stored at some address in computer’s memory, is a string of eight bits as follows-
0   1   1   0   0   0   1   0
7   6   5   4   3   2   1   0

The rightmost bit of a byte (numbered 0), is known as “least significant bit” (LSB) or “low order bit”, while the leftmost bit (numbered 7) is known as the “most significant bit” (MSB) or “high order bit”. If the data (string of bits) stored in the byte mentioned above, is considered as an integer, then its value is 98. To understand clearly, why it is so, let us take analogy from our familiar decimal number system.

The decimal system derives its name from the fact that there are 10 symbols used to represent a number. These 10 symbols are our 10 digits, 0 to 9.  Every digit in a number has a place value; and the value of the number is sum of the place values of its digits. The place value of a digit is equal to the intrinsic value of that digit multiplied by some power of 10. For example, consider the number 3568. It can be represented as-
3568 = 3000 + 500 + 60 + 8 =  3 x 103 + 5 x 102 + 6 x 101 + 8 x 100

The power of 10 is zero for the right-most digit (at the units place) and goes on increasing by 1 leftwards. Because we are using 10 symbols, that is why the multiplier base is 10.

Similarly, in the binary system, there are 2 symbols (0 and 1), and the value of a number is sum of the place values of its digits. Here, the place value of a digit is equal to the intrinsic value of that digit multiplied by some power of 2, instead of 10. So, the above-mentioned byte is storing the number with value-
0 x 27 + 1 x 26 + 1 x 25 + 0 x 24 + 0 x 23 + 0 x 22 + 1 x 21 + 0 x 20
= 64 + 32 + 2 = 98decimal

Another analogy to notice is the range of numbers that can be stored. We easily understand that, in decimal number system, the largest 3-digit positive number is 999; for 4 digits, it is 9999, and for 5 digits, it is 99999. In general, the largest n-digit positive decimal number is 10n -1. Likewise, the largest positive binary number that can be stored in a char type of variable (which occupies 1 byte or 8 bits) is 11111111, whose decimal equivalent is 28 -1  = 255. For short int type of variable (16 bits), it is 216 -1  = 65,535, and for int type of variable (32 bits), it is 232 -1  = 4,294,967,295. But for this to happen, you must declare these variables as unsigned char, unsigned short int, and unsigned int, respectively.

Why? To understand this, we have to know, how negative numbers are stored in computer’s memory. When you create signed variables,  C language treats the data (in the form of bits) stored therein, somewhat differently. One change is, now the MSB (left most bit) of the variable is considered as sign bit; if it is 0 (zero), then the remaining number is considered as positive (non-negative), while if it is 1 (one), then the remaining number is considered as negative. One more change is, the place value of this sign bit is now taken as negative. For example, consider a byte containing the following string of bits-
1   1   1   0   0   0   1   0
7   6   5   4   3   2   1   0
Here, the C language would consider, the value of the number stored in this byte as –
-1 x 27 + 1 x 26 + 1 x 25 + 0 x 24 + 0 x 23 + 0 x 22 + 1 x 21 + 0 x 20
= -128 + 64 + 32 + 2 = -30decimal

One consequence of this, which you would easily guess, is that the value of largest positive number now reduces to half of the corresponding value in unsigned variable. This is because, now one bit (and that too, the most significant) less is contributing to the value of the number. So, the largest positive binary number that can be stored in a char type of variable now, is 01111111, whose decimal equivalent is 27 -1  = 127. For short int type of variable (16 bits), it is 0111111111111111 = 215 -1  = 32,767, and for int type of variable (32 bits), it is 231 -1  = 2,147,483,647.

What is the largest negative number that can be stored in char type of variable? It is 11111111, whose decimal value can be calculated as –
-1 x 27 + 1 x 26 + 1 x 25 + 1 x 24 + 1 x 23 + 1 x 22 + 1 x 21 + 1 x 20
= -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = -1decimal

You can verify that even in case of short int, int and long int, the largest negative number would have  value -1. The smallest negative numbers, however, would be different in these cases. For char type of variable, the smallest negative number is 10000000, whose decimal equivalent is -27  = -128. For short int type of variable (16 bits), it is 1000000000000000 = -215   = -32,768, and for int type of variable (32 bits), it is -231   = -2,147,483,648.

In technical jargon, this method of storage of signed integers is called as “twos complement notation”. Here, negating a number (whether positive or negative) is achieved by inverting all the bits (replace all 1s with 0s and all zeroes with ones) and then adding 1 to the result. So, remember the rule, “INVERT AND ADD 1”.

For example, 5decimal is stored in a char variable as 00000101. If we flip all the bits in it (this can be achieved by ones complement operator, described later in this article), we get 11111010; next, add 1 to it, which gives 11111011. We can easily verify that it value is -128 + 64 + 32 + 16 + 8 + 2 + 1 = -5decimal.

Again, if you want to negate this -5, to get the original +5, adopt the same procedure. Invert all the bits of 11111011 to get 00000100; then add 1 to it, giving 00000101.

Another View

To further consolidate understanding of storage of negative numbers, consider example of a byte with 3 bits only. For such a byte, the possible permutations of bits are-
000  001  010  011  100  101  110  111.
If we consider these as unsigned integers, then these 8 numbers can be used to represent decimal numbers 0 to 7. If we decide that the left most bit (MSB) should act as sign bit, then the first 4 numbers would represent non-negative integers, while the remaining 4 would be negative. In decimal number system, we get the next integer by adding 1 to the current integer and obtain the previous integer by subtracting 1 from the current integer.  Same procedure is there in binary number system also, but now the addition or subtraction is binary. So, starting with zero, represented by 000, we get 1 by (binary) adding 1 to it: 000 + 001 = 001. Then 2 as 001 + 001 = 010 and then 3 as 010 + 001 = 011. We can not go beyond this, because adding 1 once again would give negative number by our agreed notation (011 + 001 = 100). So, 3 is the largest positive integer possible here. Now, to get negative range, we start from zero and go on subtracting 1. The first subtraction is shown below-

                  ( 1 ) 0 0 0   /* (the 1 in parentheses is borrow) */
                      - 0 0 1
                        1 1     /* (carry) */
                  -------------
                        1 1 1   /* (minus one) */

Subtract 1 to get -2 (111 – 001 = 110). Again subtract 1 to get -3 (110 – 001 = 101). And finally subtract 1, once again, to get -4 (101 – 001 = 100). We can not reduce further, because next subtraction would give 011, which is a positive number in our agreed scheme. So, -4 is the smallest negative number here.

Bitwise Operators

Having understood the storage of numbers, we will now discuss the operators in C to manipulate at bit level. There are six bitwise operator in C language.
  • &        bitwise AND
  • |         bitwise inclusive OR
  • ^        bitwise exclusive OR
  • ~        ones complement
  • <<      left shift operator
  • >>      right shift operator

Out of these, the one’s complement operator is unary, while the remaining five are binary. Only integral type operands are allowed for all the 6 operators.

Ones Complement Operator

This is simplest to understand. It flips the bits of its operand. On a single bit, it operates according to the following rule table-

b ~b
1 0
0 1

For example,

              37       00100101
                      ----------
              ~37      11011010

Bitwise Logical Operators

The 3 of the bitwise operators, viz., &, |, ^ are called as bitwise logical operators. These are evaluated according to the rules in the following truth table.

b1 b2 b1 & b2 b1 | b2 b1 ^ b2
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0

In the following examples, notice that an operator works on a pair of corresponding bits. That means, say, bit number 5 of first number and bit number 5 of second number will go as operands to the operator, to produce bit number 5 of the resulting number. Similar thing happens for all other bits of the operands.

                   37       00100101
                   52       00110100
                           ----------
                   37 & 52  00100100


                   37       00100101
                   52       00110100
                           ----------
                   37 | 52  00110101


                   37       00100101
                   52       00110100
                           ----------
                   37 ^ 52  00010001

Bitwise Shift Operators

Two of the bitwise operators, viz., << and >> are called as shift operators. Each of these are binary operators. The left operand must be of integral type and it represents the bit pattern that is to be shifted. The right operand must be a non-negative integer. It represents the displacement of bits to be carried out in the bit string of the left operand. The right operand number can not be greater than the number of bits (i.e. word size) in the left operand.

Left Shift Operator

When a left shift operation is performed on an integer, the bits contained in that number are literally shifted to the left. Bits that are shifted out through the high order bit of the data item are lost, and zeroes are always shifted into the low order bit position of the value. The left shifting is equivalent to multiplying the number by 2.

Examples-

           37       0000000000100101
           37 << 0  0000000000100101     37
           37 << 1  0000000001001010     74
           37 << 2  0000000010010100    148
           37 << 3  0000000100101000    296

 

Right Shift Operator

This operator shifts the bits of its first operand to the right, by the number of positions specified by its second operand. Bits that are shifted out of the low order bit of the data item are lost. Zeroes are shifted in on the left, that is, through the high order bits. The right shifting is equivalent to dividing the number by 2.

Examples-

           37       0000000000100101
           37 >> 0  0000000000100101     37
           37 >> 1  0000000000010010     18
           37 >> 2  0000000000001001      9
           37 >> 3  0000000000000100      4

Printing Bit Pattern (Binary Number)

You may be wondering, how I have displayed the binary numbers in the examples above (shown in green) and your first guess may be that I have calculated those values and manually typed those. But No! They are output from a C program. We know that the standard C library function printf( ) has format specifiers to print an integer in decimal (%d), octal (%o), and hexadecimal (%x) format, but no facility to print it in binary format. However, it is easy now (with the above knowledge) to write a function to display an integral number in binary format.

The following program has two such functions, one to display 8-bits number and another for 16-bits number.

void show_char_bits(char n)
{
  unsigned char i, j;
  for(i=128; i>0; i = i>>1)
  {
    j = n & i;
    if(j)      printf("1");
    else       printf("0");
  }
}
void show_int_bits(short int n)
{
  unsigned short int i, j;
  for(i=32768; i>0; i = i>>1)
  {
    j = n & i;
    if(j)      printf("1");
    else       printf("0");
  }
}
main()
{
  int i, j;
  printf("\n 37       "); show_char_bits(37);
  printf("\n 52       "); show_char_bits(52);
  printf("\n         ----------");
  printf("\n 37 & 52  "); show_char_bits(37 & 52);
  printf("\n\n");

  printf("\n 37       "); show_char_bits(37);
  printf("\n         ----------");
  printf("\n ~37      "); show_char_bits(~37);
  printf("\n\n");

  i = 37;
  printf("\n    37       "); show_int_bits(i);
  j = i << 0;
  printf("\n    37 << 0  "); show_int_bits(j); 
  printf("   %4d", j);
  j = i << 1;
  printf("\n    37 << 1  "); show_int_bits(j); 
  printf("   %4d", j);
  j = i << 2;
  printf("\n    37 << 2  "); show_int_bits(j); 
  printf("   %4d", j);
  j = i << 3;
  printf("\n    37 << 3  "); show_int_bits(j); 
  printf("   %4d", j);
  printf("\n\n");
}

The show_char_bits( ) function prints, at the current cursor position, the 8 bits of its argument ‘n’ which is of  char type, and the show_int_bits( ) function prints the 16 bits of its argument ‘n’ which is of  short int type. The show_char_bits( ) function has a ‘for’ loop that iterates 8 times and  whose loop control variable (LCV) ‘i’ takes values 128, 64, 32, 16, 8, 4, 2, and 1 in the successive iterations respectively. You would notice that the binary representation of 128 has ‘1’ in the MSB (bit 7) and ‘0’ in all other bits. When this number is bitwise ‘anded’ with the argument ‘n’, it would result either in 128 (considered as true in C) or in zero (considered as false), depending upon whether the MSB of ‘n’ is 1 or 0. The result is stored in ‘j’ and the subsequent ‘if’ statement inspects its value; it then decides, depending upon that value whether MSB (bit 7) of ‘n’ is 1 or 0 and prints accordingly. In the second iteration LCV ‘i’ takes the value 64, which has got ‘1’ at bit 6 and ‘0’ in the remaining seven bits. So, it will print bit 6. This will go on till bit 0 (LSB) is printed after which the loop ends and the function returns. The show_int_bits( ) function behaves in similar fashion, but here the loop iterates 16 times.

In the subsequent article of this series, we will see practical uses of these operators in programming practice.

Quick Primer For ‘git’

There are many good tutorials on the internet on ‘git‘, the famous distributed version control system designed and developed by Linus Torvalds using C language. However, I observed that my students, who are not familiar with the concept of version control at all, find these tutorials quite overwhelming. So, I felt like writing a simple tutorial to introduce the concept of  version control and basic git commands to achieve that.

As an example, we will take case of development of a software for solving quadratic equations using C language. For this project, first, we have to create separate folder (directory). In this folder, the software and its (git) repository would be stored. We will name the folder as ‘learning-git’. To create a repository from scratch, we use the ‘init’ command of git. Initializing a repository creates a sub-folder with name ‘.git’. The interaction goes as shown below-

sanjay@kitenagpur ~ $ mkdir learning-git

sanjay@kitenagpur ~ $ cd learning-git

sanjay@kitenagpur ~/learning-git $ git init
Initialized empty Git repository in /home/sanjay/learning-git/.git/

sanjay@kitenagpur ~/learning-git $ ls -a
.  ..  .git

We will now write the program to solve a quadratic equation. I use vim editor to create source files. Using it, I created the first version as follows-


/* quadratic-equation.c */
#include <stdio.h>
#include <math.h>
main()
{
  double a, b, c, d, r1, r2;

  printf("Enter coefficients of your quadratic equation (a, b, c): ");
  scanf("%lf%lf%lf", &a, &b, &c);

  d = b * b - 4 * a * c;
  d = sqrt(d);

  r1 = (-b + d) / 2 / a;
  r2 = (-b - d) / 2 / a;

  printf("Root 1 = %0.3lf\nRoot 2 = %0.3lf\n", r1, r2);
}       

Next, we will  compile this program and check its correctness by running it on the test data. It goes as follows-

sanjay@kitenagpur ~/learning-git $ gcc quadratic-equation.c -lm

sanjay@kitenagpur ~/learning-git $ ./a.out
Enter coefficients of your quadratic equation (a, b, c): 1 -8 15.75
Root 1 = 4.500
Root 2 = 3.500

sanjay@kitenagpur ~/learning-git $ ls
a.out  quadratic-equation.c

To understand where we have reached, let us inspect the state of our repository with ‘status’ command of git:

sanjay@kitenagpur ~/learning-git $ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#	a.out
#	quadratic-equation.c
nothing added to commit but untracked files present (use "git add" to track)

The output of ‘git status’ command shows that git sees two files in our folder and none of them are tracked. The term ‘untracked file’ means that we have not told to git to record the changes in different versions of that file.

We are ready now to store this version of the program in our repository. It is achieved in two steps. First using ‘add’ command of git we ‘stage’ a file, meaning thereby that we ask git to track that file. Out of the two files in our folder, we are going to stage only ‘quadratic-equation.c’. We are not bothered about staging ‘a.out’ file because it can always be re-created using the source file.
In the second step, we issue ‘commit’ command to tell git that the present state of the software is a major milestone to which we may refer to in the future. Also, using ‘-m’ switch, we attach a small description to this commit.
After committing, I issued the ‘status’ command again. To understand what is going on, compare the output of this command with the output of the ‘status’ command given earlier.

sanjay@kitenagpur ~/learning-git $ git add quadratic-equation.c

sanjay@kitenagpur ~/learning-git $ git commit -m "Quadratic equation solver, version 0.1"
[master (root-commit) 5ec6f8c] Quadratic equation solver, version 0.1
 1 file changed, 19 insertions(+)
 create mode 100644 quadratic-equation.c

sanjay@kitenagpur ~/learning-git $ git status
# On branch master
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#	a.out
nothing added to commit but untracked files present (use "git add" to track)

Assume that after this stage, you discussed the program with your colleagues and somebody pointed out that it lacks the capability to deal with equations having imaginary roots. So you modify the program and change it to second version, which is as follows-


/* quadratic-equation.c */
#include <stdio.h>
#include <math.h>
main()
{
  double a, b, c, d, r1, r2;

  printf("Enter coefficients of your quadratic equation (a, b, c): ");
  scanf("%lf%lf%lf", &a, &b, &c);

  d = b * b - 4 * a * c;

  if(d < 0)
  {
    printf("The roots are imaginary.\n");
    return;
  }

  d = sqrt(d);
  r1 = (-b + d) / 2 / a;
  r2 = (-b - d) / 2 / a;

  printf("Root 1 = %0.3lf\nRoot 2 = %0.3lf\n", r1, r2);
}

After the editing, you would compile the program and run it against test data. If you are satisfied that it is working as expected, you would commit this version with appropriate descriptive message.

sanjay@kitenagpur ~/learning-git $ gcc quadratic-equation.c -lm

sanjay@kitenagpur ~/learning-git $ ./a.out 
Enter coefficients of your quadratic equation (a, b, c): 1 2 3
The roots are imaginary.

sanjay@kitenagpur ~/learning-git $ git add quadratic-equation.c

sanjay@kitenagpur ~/learning-git $ git commit -m "Added 'imaginary roots' case handling"
[master 8f3b196] Added 'imaginary roots' case handling
 1 file changed, 7 insertions(+), 1 deletion(-)

After some days of writing this version, it may be possible that a situation arises where you want to input data to your program through command line arguments instead of through ‘scanf’ function. So, once more you modify the program (third version), so that it looks as shown below-


/* quadratic-equation.c */
#include <stdio.h>
#include <math.h>

main(int argc, char *argv[])
{
  double a, b, c, d, r1, r2;

  sscanf(argv[1], "%lf", &a);
  sscanf(argv[2], "%lf", &b);
  sscanf(argv[3], "%lf", &c);

  d = b * b - 4 * a * c;

  if(d < 0)
  {
    printf("The roots are imaginary.\n");
    return;
  }

  d = sqrt(d);
  r1 = (-b + d) / 2 / a;
  r2 = (-b - d) / 2 / a;

  printf("Root 1 = %0.3lf\nRoot 2 = %0.3lf\n", r1, r2);
}

We compile the latest version of the  program, run it for the test data and if the results are as per our expectation, we commit this version. The interaction would go as follows-

sanjay@kitenagpur ~/learning-git $ gcc quadratic-equation.c -lm

sanjay@kitenagpur ~/learning-git $ ./a.out 1 -8 15.75
Root 1 = 4.500
Root 2 = 3.500

sanjay@kitenagpur ~/learning-git $ git add quadratic-equation.c

sanjay@kitenagpur ~/learning-git $ git commit -m "Input through command line arguments"
[master 316b149] Input through command line arguments
 1 file changed, 4 insertions(+), 3 deletions(-)


Now comes the real power of ‘git’. Let us assume that we want to discard the “Input through command line arguments” approach and stick to our previous line of development, i.e., of taking the input through ‘scanf’. For this, we will have to go back to second commit state from this last (third) commit state. The ‘git log’ command gives information about commit IDs; adding ‘–oneline’ switch to it gives the info in summary format.

sanjay@kitenagpur ~/learning-git $ git log --oneline
316b149 Input through command line arguments
8f3b196 Added 'imaginary roots' case handling
5ec6f8c Quadratic equation solver, version 0.1

The commit ID to which we want to return to is ‘8f3b196’. For that, we issue ‘checkout’ command with the commit ID and the file name as arguments.

sanjay@kitenagpur ~/learning-git $ git checkout 8f3b196 quadratic-equation.c

If you open ‘quadratic-equation.c’ in an editor, you would find that it has now the second version of the program. Please note here that commit ‘316b149’ (version 3) is not destroyed; you may verify that by issuing ‘git log’ command.  And in future, if we want to pursue again command line arguments approach, we are free to checkout that commit.

In my opinion, a student can start productively using ‘git’ with this knowledge. After executing several projects like this, the student would get insight to version control as well as more confidence in using ‘git’. Then, one can go deeper and the other ‘git’ related material on the internet would become easy to understand.

Summary of commands used above:
git init – to create blank repository.
git status – to display the current state of ‘staging’.
git log – to display ‘commit’ information.
git add – to add files to ‘staging’.
git commit – to add the staged files to repository.
git checkout – to go to particular commit state.


‘git’ installation
Installing git on Linux is easy.
For Fedora-based systems (I tested it on Fedora 15):

# yum install git

For Debian-based systems (I tested it on Ubuntu 14.04 and Linux Mint Maya & Qiana):

$ sudo apt-get install git

Simulating a puzzle

It was a pleasant Sunday morning. I was lying on my sofa, engrossed in news paper reading. My wife, Shubha, was busy with  ‘Whats app’ with her friends. Suddenly she asked me, “Hey! what’s answer to this?”.

Shubha’s ‘Whats app’ group keeps on playing various kinds of quizzes & competitions. Some times they are related to music & cinema; other times they are on GK. This time her friend had posted a mathematical puzzle. Shubha read it out to me-

Hundred robotic soldiers are standing in a circle. Soldier with serial number 1 carries a sword. These soldiers are programmed rather in a queer way. A soldier with sword is coded to kill the next adjacent soldier and then pass on the sword to the next living one. So, soldier #1 would kill the soldier #2 and give the sword to soldier #3; he, in turn, would kill soldier #4 and pass the sword to soldier #5. When soldier #99 kills soldier #100, the sword comes back  to soldier #1 as he is next to the killed soldier #100. The process continues till there is only one soldier left. The question is, “what is the serial number of the survivor?”.

Now, I don’t like to be disturbed during my Sunday paper reading. But I did not want to antagonize Shubha, as that would have spoiled my breakfast, which she was yet to prepare. So, I lifted my face from the news paper, scratched my head, and started thinking aloud-

“Let us start with smaller version of the problem, just two soldiers. Here, #1 would kill #2 and would become the survivor. Next, consider the problem with three soldiers; #1 kills #2 and gives the sword to #3, who in turn kills the giver #1 and becomes the survivor. Then, consider four soldiers. Here, #1 kills #2 and the sword comes to #3. He, then, kills #4 and gives the sword back to #1. The #1 then mercilessly kills #3 and becomes the survivor. By similar process, you can verify that if we start with five soldiers, the survivor is #3. Let us now jump to (and this turned out to be faux pas) case of eight soldiers. Here, the survivor is #1 like in the cases of two and four soldiers.”

I wanted to quickly return to my news paper reading. I figured out the pattern from only these five cases. I said to Shubha, “Look! Every time we start with even number of soldiers, the survivor is #1. If we begin with odd number of soldiers, then the survivor is somebody other than #1. As the given problem starts with hundred soldiers, an even number, the survivor would be #1”. She could appreciate my logic and punched the answer on her cell keypad. She was the first to answer the question and instinctively knew that in their group consisting mostly of medicos, nobody else would be able to find solution to this problem. The thought of being called ‘genius of the day’ delighted her and she started humming her favorite song. Jini, our pet bitch, gave a curious stare to her and started salivating in anticipation of a sumptuous treat.

Shubha threw the cell on the sofa and started towards kitchen. But the cell rang  ‘Whats app new message’ alarm and she picked it again. She started reading the message and expressions on her face changed.  I realized instantly that my breakfast is ruined. “You idiot! useless even in this work. The answer to the puzzle is not soldier #1, it is #73.”, she yelled in shrill voice. “Oops! Did I make some silly mistake? or your friend is wrong?”, said I. Then I rolled up my eyes, and gazing towards ceiling, again started thinking over the problem. Three four minutes passed in the suspended animation. And then I found the error in my earlier logic. To get soldier #1 as the survivor, it was not sufficient to start with even number of soldiers; for that the number of soldiers in the beginning must be some power of 2, like 2, 4, 8, 16, etc. So, the trick is to know the serial number of the soldier with sword when the number of soldiers remaining is a power of 2.

I started explaining my new logic to Shubha, but she cut me short and said, “show me the solution actually”. The prospect of writing the numbers on paper and then cancelling out alternate numbers etc., would have been demeaning to a computer professional like me. So I booted my laptop, a Linux Mint box, which comes up very fast and my fingers started punching the C++ program to simulate this puzzle. I quickly typed it, compiled it, and ran it for Shubha. The output was as shown below. For the interested readers, I have given the source code at the end of this post.



How many killers? 100
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99

1 5 9 13 17 21 25 29 33 37 41 45 49 53 57 61 65 69 73 77 81 85 89 93 97

1 9 17 25 33 41 49 57 65 73 81 89 97

9 25 41 57 73 89

9 41 73

9 73

Remaining killer: 73


To mentally solve the puzzle, one may proceed like this: The largest power of 2, less than 100 (initial number of soldiers), is 64. When 36 soldiers are killed, 64 soldiers would remain. As every odd-numbered soldier is killing immediately next even-numbered soldier, a total of 36 soldiers would die, when soldier #71 kills soldier #72. At this point of time the sword is with #73 and total remaining soldiers are 64. The methodical killing continues and the survivor would be this #73 soldier.


// Simulating a puzzle
#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;
class MadKiller
{
  private:
    int myNumber;
  public:
    MadKiller(int srNum) { myNumber = srNum; }
    void printKiller() { cout << setw(4) << myNumber; }
};

main()
{
  int i, nInitialKillers;
  vector<MadKiller> a;
  bool killFirst = false;

  cout << "How many killers? ";
  cin >> nInitialKillers;

  for(i=1; i <= nInitialKillers; i++)
    a.push_back(MadKiller(i));
  int n = a.size();
  for(i=0; i < n; i++)
    a[i].printKiller();
  cout << endl <<  endl;

  vector<MadKiller>::iterator curr;
  while(a.size() > 1)
  {
    curr = a.begin();
    n = a.size();
    if(n % 2 == 0)
    {
      while(curr < a.end() - 1)
        curr = a.erase(curr+1);
    }
    else
    {
      while(curr < a.end() - 2)
        curr = a.erase(curr+1);
      killFirst = true;
    }
    n = a.size();
    for(i=0; i < n; i++)
      a[i].printKiller();
    cout << endl < 1)
    {
      curr = a.begin();
      a.erase(curr);
      killFirst = false;
    }
  }
  cout << "Remaining killer: "; a[0].printKiller();
  cout << endl;
}