0% found this document useful (0 votes)
12 views429 pages

STEM Problems With Mathcad and Python - Ochkov

The book 'STEM Problems with Mathcad and Python' aims to alleviate the fear associated with scientific and technical calculations for STEM students by demonstrating that these calculations can be enjoyable and beneficial. It serves as a resource for undergraduates and early postgraduates, providing guidance on various interdisciplinary technical problems using Mathcad and Python. The text includes theoretical and practical materials, tasks for students, and emphasizes the importance of modern technology in education and problem-solving.

Uploaded by

aaa3us
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views429 pages

STEM Problems With Mathcad and Python - Ochkov

The book 'STEM Problems with Mathcad and Python' aims to alleviate the fear associated with scientific and technical calculations for STEM students by demonstrating that these calculations can be enjoyable and beneficial. It serves as a resource for undergraduates and early postgraduates, providing guidance on various interdisciplinary technical problems using Mathcad and Python. The text includes theoretical and practical materials, tasks for students, and emphasizes the importance of modern technology in education and problem-solving.

Uploaded by

aaa3us
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

STEM Problems with

Mathcad and Python


STEM Problems with Mathcad and Python seeks to remove the fear of tackling difcult
scientifc and technical calculations for future mathematicians, engineers, scientists, and
other STEM researchers. Te authors hope to show that such calculations can be not only
useful, but that the process of learning how to do them can be enjoyable, especially with
the help of Mathcad and Python programming skills. Te book will also illustrate how the
use of modern computer sofware allows one to signifcantly expand the range of problems
considered beyond those conventionally taught. Tis includes computational experiments,
multivariate calculations, inverse problems and optimization problems, with both static
and animated visual feedback.

Features
• Suitable for undergraduates and early postgraduates who need simple and accessible
guidance for solving practical interdisciplinary technical problems
• Can be used as an additional textbook on a variety of topics, including calculus, linear
algebra, analytical geometry, discrete mathematics, computer science, computational
mathematics, scientifc visualization, computer graphics.
• Gives computer users access to an exciting new hobby—solving complex problems
described in fction.
STEM Problems with
Mathcad and Python

Valery Ochkov
Moscow Power Engineering Institute, Russia
Alan Stevens
Anton Tikhonov
Moscow Power Engineering Institute, Russia
First edition published 2022
by CRC Press
6000 Broken Sound Parkway NW, Suite 300, Boca Raton, FL 33487-2742

and by CRC Press


2 Park Square, Milton Park, Abingdon, Oxon, OX14 4RN

© 2023 Valery Ochkov, Alan Stevens, and Anton Tikhonov

CRC Press is an imprint of Taylor & Francis Group, LLC

Reasonable eforts have been made to publish reliable data and information, but the author and publisher cannot
assume responsibility for the validity of all materials or the consequences of their use. Te authors and publishers
have attempted to trace the copyright holders of all material reproduced in this publication and apologize to copyright
holders if permission to publish in this form has not been obtained. If any copyright material has not been acknowledged
please write and let us know so we may rectify in any future reprint.

Except as permitted under U.S. Copyright Law, no part of this book may be reprinted, reproduced, transmitted, or
utilized in any form by any electronic, mechanical, or other means, now known or hereafter invented, including
photocopying, microflming, and recording, or in any information storage or retrieval system, without written
permission from the publishers.

For permission to photocopy or use material electronically from this work, access [Link] or contact the
Copyright Clearance Center, Inc. (CCC), 222 Rosewood Drive, Danvers, MA 01923, 978-750-8400. For works that are
not available on CCC please contact mpkbookspermissions@[Link]

Trademark notice: Product or corporate names may be trademarks or registered trademarks and are used only for
identifcation and explanation without intent to infringe.

ISBN: 9781032131658 (hbk)


ISBN: 9781032132587 (pbk)
ISBN: 9781003228356 (ebk)

DOI: 10.1201/9781003228356

Typeset in Minion pro


by codeMantra
Contents

Preface, ix
Authors, xi

Introduction 1

CHAPTER 1 ◾ Portrait of the Roots of the System of Equations 27


TASK FOR THE READER 51

CHAPTER 2 ◾ Oval and Ellipse 53


TASKS TO THE READER 66

CHAPTER 3 ◾ Reading Fiction and Solving Linear Equations 67


TASKS FOR THE READER 89

CHAPTER 4 ◾ Trust but Verify 91


TASKS FOR THE READER 116
REFERENCES 116

CHAPTER 5 ◾ Comet of 1811: Check Harmony with Algebra 117


5.1 END OF THE REMARK 131
5.2 A LITTLE MORE ABOUT ELLIPSE, PARABOLA AND HYPERBOLA OR
SECOND-ORDER CONICAL BEETLE 134
TASK FOR THE READER 138
REFERENCE 138

CHAPTER 6 ◾ Running along the Route given by Pierre de Fermat, or


Geometric Optics 139
6.1 THE TALE OF THE CLEVER HARE 141
6.2 MATRIX OPTICS 151

v
vi ◾ Contents

6.3 FREE SPACE 152


6.4 SPHERICAL SURFACE 152
6.5 BICONVEX LENS 153
6.6 GLASS BALL 155
6.7 THICK-WALLED GLASS SPHERE 156
6.8 CONCLUSIONS 157
TASK FOR THE READER 158

CHAPTER 7 ◾ Patterns on a Complex Plane 159


TASKS FOR THE READER 185
REFERENCES 188

CHAPTER 8 ◾ Rectangle Mappings on the Complex Plane 189


TASKS FOR THE READER 203
REFERENCE 205

CHAPTER 9 ◾ Monte-Carlo: Shapes and Ships 207


9.1 CARDIOID 207
9.2 MANDELBROT SET 210
9.3 BATTLESHIPS 212
TASKS FOR THE READER 220

CHAPTER 10 ◾ Pseudo-Parallelism 221


10.1 EXAMPLE 1. SORTING 221
10.2 EXAMPLE 2. THE PURSUIT PROBLEM 228
10.3 EXAMPLE 3. PANDEMIC 234
TASKS FOR READERS 239

CHAPTER 11 ◾ A Catenary: To Step or Ride Over? 241


ASSIGNMENT TO THE READER 252

CHAPTER 12 ◾ Round and Round 253


TASKS FOR THE READER 262
REFERENCES 262

CHAPTER 13 ◾ Iterations and Fractal Sets of Mandelbrot and Julia 263


QUESTIONS AND TASKS 291
REFERENCES 291
Contents ◾ vii

CHAPTER 14 ◾ Water Digital Twin: Cloud Functions, Correct Temperature


Units 293
14.1 AFTERWORD WITH THE TITLE P v = T 304

CHAPTER 15 ◾ Hydropower Thoughts and Calculations when Looking at a


Banknote or Spline Interpolation 311
TASK FOR READERS 330
REFERENCES 330

CHAPTER 16 ◾ Cellular Automatons 333


QUESTIONS AND TASKS 356
REFERENCES 358

CHAPTER 17 ◾ Arrays and Images 359


QUESTIONS AND TASKS FOR THE READER 394
REFERENCES 395

CHAPTER 18 ◾ Three Circles Tied with an Elastic Band or New Pendulum 397
18.1 AFTERWORD ON NONLINEARITY 407
TASKS FOR READERS 411

INDEX, 413
Preface

Te chapters of this book provide theoretical and practical material on innovative educa-
tional STEM technology, for multi-disciplinary classes that use modern information tech-
nologies to study subjects such as higher mathematics (mathematical analysis: the Chapter
18, linear algebra: Chapters 3 and 18, diferential equation solution: Chapter 5), physics
(Chapter 18), theoretical mechanics (Chapter 18), resistance of materials (Chapter 18), ther-
modynamics (Chapter 14), hydro-gas dynamics (the Chapter 15) and so on. Tis is supple-
mented by plans for conducting such classes at technical universities (in the English version
at school and universities), where multiple academic disciplines are involved. Te terms
“interdisciplinary connections” and “cognitive learning” are also relevant here. One more
name for such a training course at a technical University is “Engineering calculations”.
STEM is an acronym for Science, Technology, Engineering, and Mathematics. Sometimes
the letter A is added here – Art: STEAM, not STEM. Te problem of the humanization of
technical education is an important aspect in the work of a University and High Schools,
which is directly touched upon in this book.
At the beginning of the 19th century in the energy industry, steam prompted the world’s
frst industrial (heat engineering) revolution (Industry 1). Tere were steam engines, steam-
boats, steam locomotives etc. Today, STEM/STEAM training technology can contribute to
the development of the fourth (digital) industrial revolution (Industry 4).
In German, another abbreviation is used that more accurately denotes this learning
technology – MINT: M – Mathematik, I – Informatik, N – Naturwissenschaf (Natural sci-
ence) and T – Technik. Here, in frst place, as it should be, is the queen of sciences — math-
ematics, which has received a second wind with the development of computer symbolic,
numerical and hybrid methods for solving problems. Te combination of mathematics and
computer is a powerful base for a new stage in the development of education, science and
technology. Te word “mint”, by the way, in English means a plant that gives freshness. Te
STEM education (MINT education) technology is designed to “refresh” the stale air in the
premises of our educational institutions.
Te word “stem” in English means a part of a plant that is a supporting part. In this con-
text, STEM education technology can be considered a kind of trunk (frame) from which
branches of individual academic disciplines depart—mathematics, information technol-
ogy, physics, theoretical mechanics, material resistance, hydro-gas dynamics, and, of
course, engineering calculations—the academic discipline this textbook was written for.

ix
x ◾ Preface

Te main tool used in this book for scientifc and technical calculations is Mathcad.
With all its merits it is a proprietary product, which imposes restrictions on its use in the
educational process. Using the freeware version of Mathcad is not always possible because
of its signifcant functional limitations. Tis has led to some chapters of the book also mak-
ing use of the free Python ecosystem, which has an extensive set of libraries for solving
scientifc, technical and engineering problems. Python, in the WinPython and Anaconda
distributions, allows one to deploy a working environment, such as the Jupyter Notebook
and JupyterLab, with all the libraries needed.
Many chapters of the book are supplemented with tasks for students. Te frst task is
to reproduce the solutions of the book (bachelor’s level) and then complete the remain-
ing tasks (bachelor’s and master’s level). In this regard, the title of the book could be:
“Engineering, scientifc and technical calculations”. Engineering calculations are made
according to already developed methods, and scientifc and technical calculations require
the development of new methods.
Te authors hope that readers will forgive them for some faw in the formatting of the
text of the book. Te fact is that the work-sheets of the book were created by the authors in
diferent versions of Mathcad. For this reason, the font style of some functions and vari-
ables turned out to be diferent in diferent chapters. Te authors hope that this will not
prevent readers from studying the problems of the book.
Authors

Dr Valery Ochkov is a Professor at Moscow Power Engineering Institute (Technical


University – MPEI – [Link]) in the Department of Teoretical Basics of Heat
Engineering. He earned his PhD in 1979 on “Research of processes and development of
technology for magnetic water treatment in the energy sector.” In 2006 he defended his
doctoral dissertation on the topic “Improving the design and operation of power plant
equipment using modern information technologies.” In 2005, he founded his own private
company, which is engaged in the creation of computer programs and simulators for the
training of personnel in thermal, hydraulic and nuclear power plants.

Dr Alan Stevens received a Bachelor’s degree in Physics from the University of Warwick,
then a PhD for research in Teoretical Physics from the University of Essex. He then spent
most of his working life at Rolls-Royce as a mathematical modeller, dealing mainly with
engineering heat transfer and fuid fow; also spending a certain amount of time teaching
engineering mathematics to engineers at various Rolls-Royce sites. In retirement, he sat on
several committees of the Institute of Mathematics and Its Applications (IMA) in the UK,
including its Executive Board and governing Council.

Dr Anton Tikhonov received his bachelor’s degree in semiconductor physics and his
master’s degree in applied mathematics from the Moscow Power Engineering Institute
(MPEI). He has spent his entire working life at the Moscow Power Engineering Institute,
where he received his PhD for research on semiconductor devices. He is currently a
professor at MPEI. His research interests are information technology in education,
scientifc visualization.

xi
Introduction as Trialog
about Kings and Cabbages,1
Problem Solving, STEM
and STEAM Technologies
in Education

Once upon a time in a kingdom, the thirtieth state, three people gathered to talk about
everything: about kings and cabbages, about modern education, about tasks, and whether
they present problems that need to be solved, and if necessary, how.
These three we will call Mathematician (M)—teaches mathematics in the junior years of
the technical university, Engineer (I)—a teacher of special engineering disciplines in senior
years, at the same time teaching a course on solving scientific, technical and ­engineering
problems, and one for whom all this is being done—the student (S).
They will talk about obvious things—about setting and solving problems. If the reader
has a good idea of how this is done, then he can skip this chapter.
Tea is poured, and we can begin our trialog.

HOW TO TEACH AND STUDY NATURAL SCIENCES?

M: What we’re going to do in this book is solve problems, turn data into understanding
what the data means, how to use it in practice, and enjoy it. Solving beautiful
problems has always been a pleasure, but only to a few people who are considered
strange by the general public, doing incomprehensible things.
I: We will try to show that the use of mathematical systems that save us from long and
tedious calculations allows us to quickly solve beautiful and interesting ­problems,
do it with pleasure, and get a solution in a visual form.
1 The authors refer the reader to O’Henry’s novel “Cabbages and Kings”.

DOI: 10.1201/9781003228356-1 1
2 ◾ STEM Problems with Mathcad and Python

M: When solving problems, we constantly use mathematics, and there is an incomprehen-


sible, almost mystical connection between beauty and mathematics. No matter
how abstract and abstruse a mathematical theory may be, if it is beautiful then
practical application ofen follows. You might ask; what practical application
can the theory of numbers have? But without it, modern cryptography would
be impossible. Group theory is an abstract discipline, but it works very well in
crystallography, in solid-state physics, without which, in turn, there would be no
modern computers. Without beautiful mathematics, there would be no noise-
correcting coding, so you could not talk on a mobile phone... Tere are many
such examples. As F.M. Dostoevsky: “Beauty will save the world.”
I: Listening to something, we perceive and remember, we receive information. By solv-
ing problems, we transform information into knowledge, which, in turn, is
used in making decisions and solving other problems, to understand how this
world works.
M: I don’t want to hide the fact that in recent years it has become more and more difcult
to teach mathematics, the motivation of students is falling, and they spend their
time at lectures buried in their phones.
S: I heard somewhere that every generation complains that the current youth are worse
than the older generation and have done for 6,000 years, even in ancient Sumer!
I: M does not exaggerate, my fnal qualifcation work was carried out by a student who had
to explain a number of basic concepts of higher mathematics, which he should
have known well in the frst year.
M: Back in the 19th century, the concept was formed that the study of natural sciences
should be based on solving a large number of specially selected problems. Tis
was widely used in teaching mathematics, physics, and engineering disciplines.
Te results were not long in coming.
S: At the same time, you have to solve a huge number of tasks at home, it is completely
unclear what and why...
I: A lot has changed since then. If 50 years ago a higher education received at a university
was enough for a specialist for life, it was one of the few social lifs, now every
5 years you have to retrain, and information technology is changing even faster...
M: In connection with the growth of life expectancy, the attitude toward lifelong educa-
tion is changing. When the children have grown up and there is no need to go
to work, free time appears, which is flled, among other things, with education.
People who have been involved in technology all their lives receive a liberal arts
education, in turn, humanitarians begin to engage in information technology
with enthusiasm...
S: My grandmother goes into the browser on her phone and plays Wordle with enthusiasm.
When I wanted to write an app for her that suggested words from a dictionary
with already guessed symbols, she rejected it, considering it a foul game.
I: Among other things, solving problems prolongs and sometimes restores intellectual
health, but at the same time, the problems themselves should be interesting, and
the process of solving them should be enjoyable. A side efect is the acquisition of
Introduction ◾ 3

additional knowledge and skills. Attractive modern sofware tools allow you to
simultaneously master new technologies, work with new devices...
M: Basically, society and people are changing. Some see education as almost a hindrance
to creative thinking...
I: Many developers of new technologies are half-educated students who receive honor-
ary diplomas from universities, which they did not graduate from, let’s say, at a
respectable age.
S: I don’t understand at all how textbooks were written then. Tey are impossible to read. I
can’t handle more than a page and a half at a time.
M: Yes, that’s another problem. Traditional textbooks, by the way excellent textbooks, are
difcult for today’s youth to comprehend.
S: Tis is imposed by the loss of live contact between us and teachers in a pandemic whose
ending is unknown. At best, you see a talking head on the smartphone screen,
which does not always answer the questions asked...
I: We will not discuss the reasons for this here, as we will return to where we started. It is
important to note that without studying the natural sciences, there is no higher
education, especially in engineering. We just need to change our approach: not
students for us, but we for students, and we have to remember that we don’t have
other students...
We need to make sure that the teaching of the natural sciences, which, as M
rightly noted, requires solving a large number of tasks, becomes understandable,
interesting and visual, so that classes can be equally efectively conducted not
only in a specially equipped university auditorium, but also in distance learn-
ing that we are all facing due to the pandemic. In addition, most of our practi-
cal activities are related to problem solving. True, these tasks are diferent from
those that we solve in the classroom...
S: Tat sounds interesting and attractive, but how do you think it should look? Again, a
talking head and overwhelming homework?
M: Or we cancel homework and get a complete lack of learning outcomes...
I: No, everything is simpler. First, we come up with quite interesting tasks, which most
likely belong not to one, but to several disciplines, and second, we solve them
quickly, being sure to bring them to a clear result. Tird, we do it all together,
and not like now, when the teacher writes out the solution on the blackboard,
and the students copy it in their notebooks if they have time, and ofen, espe-
cially in distance learning, do not participate in solving problems at all. Tis
is the main purpose of using STEM and STEAM, which was discussed in the
preface.
S: It all depends on how it will be implemented.
M: Interesting tasks are always difcult tasks. You can’t solve them quickly and even more
clearly.
I: So we have come to a very serious question: is it necessary to solve problems in the class-
room, if necessary, what tasks to bring to the classroom, and how to solve these
problems?
4 ◾ STEM Problems with Mathcad and Python

TASKS AND STEM TECHNOLOGIES

S: Fair question. Do you need to solve problems? I have the impression that all problems are
solved, one has only to look for a solution on the Internet.
M: Let’s argue the contrary. If all tasks are solved, then how is science and technology devel-
oping, what are startups doing, and why is so much money spent on research and
development?
I: I want to relax a bit. You can fnd a lot of things on the Internet. Quite a long time ago, the
issue was seriously discussed that the drilling of an ultra-deep well on the Kola
Peninsula was stopped due to the fact that they got to hell, and on the web page
it was proposed to listen to the gnashing of teeth of sinners in the .wav sound
format. Unfortunately, that resource is currently unavailable!
M: I remember this story. Te most interesting thing is that this fake news got into the
media, where for some time it was seriously discussed.
I: I mention this only to show that not everything that is published can be trusted. Even
in serious scientifc publications, in which articles are carefully reviewed, some-
times results are published that are not entirely correct. During my time in grad-
uate school, I lost 3 months trying to replicate a result that turned out to be, shall
we say, a joke. Everything needs to be checked...
We have digressed, but the whole history of human civilization is connected
with solving problems, mostly computational ones. Astronomy arose as a means
of calculating the time of sowing crops. Without calculations, there would be
no pyramids. Moreover, subconsciously, we constantly make calculations, even
crossing the street at an unregulated intersection. Te task of how to get to the
airport on time is somewhat more difcult. Here, in addition to the time and cost
of the trip, it is necessary to take into account uncertainty factors, in the form of
trafc jams, unwillingness to spend an extra hour at the airport, leaving home
too early...
To say nothing of the fact that, for example, energy saving is based on the solu-
tion of a large number of both technical and economic computational interre-
lated problems, where any mistakes can lead to accidents and economic damage.
M: We have somehow digressed from the tasks to be solved in the classroom and at home
by students. What should they be?
S: First, the tasks should be clear. I have to fnd out what the teacher wants from me, believ-
ing that I should remember everything that was studied a year ago.
Secondly, tasks should not be boring. Ofen, by the middle of a lesson, you lose
the thread of reasoning and just keep writing down what the teacher is doing.
Sometimes your records make sense later, sometimes not.
I: So, I say that the formulation of tasks should be simple and understandable and not cause
doubts among students. It is best if the wording of the tasks is visual, contain-
ing images and animation. If at the same time questions arise, then we need to
answer, since it is useless to solve a problem without understanding its conditions.
Introduction ◾ 5

M: It seems then that, in addition to preparing for classes, I also have to prepare drawings,
create animations and videos?
I: Yes, you can’t get away from this, but I wouldn’t say it’s difcult. Images are easily
found on the web. As a last resort, they will have to be drawn in a graphics edi-
tor of your choice. We produce animations and videos in the process of solv-
ing problems. Tere is nothing complicated about this: times are changing2,
people are changing, we are changing and the requirements for our profession
are changing.
But the fact that we should not lose the attention of the audience while solving
problems is very important. It seems to me that in the classroom it is impossible
to solve problems that are too “long”, the solutions of which are delayed until the
next lesson. In the most extreme case, we must divide a problem into subtasks
and solve a sequence of demonstrably short subtasks, then “glue” the solution of
the problem from the solutions of the subtasks.
M: But this is a method of solving problems that was established in antiquity. Even chil-
dren know about it. Why talk about it?
I: It was not necessary to talk about this 5 years ago, but now we have to say it and say it
repeatedly.
S: Explain to me, how is it possible to reduce the time for solving problems?
I: Very good question! Everything that is said in this book is based on it. We speed up by
quickly solving typical problems, which we will refer to as well-solvable prob-
lems (WSP). For example, we will ofen solve ordinary diferential equations.
Let’s use the tools that allow us to obtain a numerical, and sometimes analytical
solution of the problem and solve it quickly!
M: I do not agree with you, because as a result, we get what we have—people who do not
know how to solve diferential equations, take integrals, and even, as you told
me, who do not understand what a derivative is!
I: Times are changing. It is necessary to tell students about diferential equations, analyti-
cal and numerical methods for solving them. You need to do this in a frst, or,
in extreme cases, a second course, and then just use the tools to tackle this class
of tasks. With the tools, for the solution and even its visualization, you need to
write just a couple of lines.
M: Tus, we tie students to certain sofware systems. What happens if they can’t use them
when they graduate from university?
I: Tey will use other systems, and there are quite a lot of them in our time, for almost all
tastes and wallets. In addition, in this book, we have tried to use various systems
to solve problems. I am quite ofen sarcastically asked what to do if these systems
become inaccessible, and we have lost the skills of mental arithmetic and per-
forming complex calculations manually. Te answer is simple. Times are chang-
ing... We have lost the skill of making fre by friction, but humanity still exists.
Te world is changing, and so are the tools that we use in our practice...

2 Song reference B. Dylan “Te Times Tey Are A-Changin”.


6 ◾ STEM Problems with Mathcad and Python

M, you remember the time when computers were bought “bare” and they had
to be equipped—to write libraries of programs yourself, which were then used to
solve practical problems.
M: Yes, there was a time... Ten I learned a lot of new and interesting things about the cal-
culation of special functions; the reference book3 translated into Russian helped
me a lot and there was no need to go to the library and photocopy the necessary
pages with formulas. Tese programs were then used for more than 10 years...
I: Tat’s what I’m talking about. A tool is developed, and then everyone uses it. Now let’s
move on to the tools used in solving problems.

BLACK BOXES AND REINVENTING THE WHEEL

I: None of us complains when a screwdriver itself tightens a screw, but when we use com-
putational tools to solve problems, it turns out that “screws” must be tightened
by hand.
M: Here you are wrong and, continuing the analogy, the point is that if you do not know
how a screw is twisted with an ordinary screwdriver, then in the end it becomes
incomprehensible what a screw is, why, what and how to tighten the screwdriver...
I: We are faced with the eternal problem of the black box and reinventing the wheel. I
will return to your example. It is not necessary for users of a special function
library to know what methods are used to evaluate a given function for a given
combination of parameter values. Tis is the lot of specialists, and the user
needs the calculation errors to be small so that the calculations themselves do
not require excessive computing power. For the user, the special function cal-
culation program is a black box. He/she is only required to read the documen-
tation and correctly pass the parameters. Te user solves his tasks and is not
very interested in how additional tasks are solved. Te main thing is that they
are solved correctly.
Moreover, the solution of typical problems, including seemingly simple ones
such as solving systems of linear equations, is associated with a large number of
special cases and tricks, libraries for solving these problems have been improved
over the years. In my opinion, the best approach is a good crafsman who selects
a convenient tool for his work and uses it. Sawing rails with a hand saw is not
recommended! Te crafsman does not need to know how this tool works, he
needs knowledge and skills to use it.
M: Perhaps you are right here, but it is imperative to explain how these problems are solved,
otherwise the students get the impression that there is a big magic blue button,
by clicking on which you can get the solution to any problem. I call it the magical
technology efect.

3 Handbook of Mathematical Functions with Formulas, Graphs and Mathematical Tables. Edited by M. Abramowitz and
I.A. Stegun. National Bureau of Standards. Applied Mathematics. Series 55. Issued June 1964, 832 p.
Introduction ◾ 7

In a course on numerical methods, I always demonstrate how to solve alge-


braic equations using the bisection method and Newton’s method, since it takes
only a few minutes to implement them. At the same time, I draw attention to the
fact that there can be several roots, and the result obtained depends on the choice
of the initial approximation.
Let’s talk in more detail later about libraries for solving scientifc and techni-
cal problems and their use for solving practical problems.
Good! You touched on the second part of the problem under discussion—the
reinvention of the wheel. It has psychological origins, I myself am a sinner, I like
to reinvent wheels! Here, by reinventing wheels, I mean writing your own code to
solve problems, proven tools for solving which are already available in libraries.
Yes, to explain and show how the methods work for tasks such as solving
algebraic or diferential equations, it is necessary to apply them to solve specially
selected problems for didactic purposes, but it is hardly possible to use the wheels
we invented for solving practical problems. It is always better to use industrial
tools—specially designed libraries for solving scientifc and technical problems.
Sometimes you think that it’s faster to write code for solving a problem for
your special case than to read and understand the library documentation and,
perhaps, read additional literature. But as Zen of Python4 says: “Special cases
aren’t special enough to break the rules.”

PROBLEMS SIMPLE AND COMPLEX, SOLVABLE AND UNSOLVABLE

S: All this is interesting. You constantly talk about tasks, but it is still not clear what tasks
you are talking about. “HAPPINESS FOR EVERYONE, FREE OF CHARGE,
AND LET NO ONE LEAVE OFFENDED”5—this is also a task, but its solution
is hardly possible.
M: You are right, we need to limit ourselves and formulate what tasks we will talk about
next.
I: First of all, we will talk about computational problems for which there are input param-
eters, output parameters, and there is a procedure that allows obtaining output
parameters from given input parameter values.
M: What you are talking about is called direct problems. Tere are sets of input parameters
P I, output PO parameters, procedure A that converts P I to PO: PO = A( PI ). It is
important for us that procedure exists and can be implemented with the means
available to us. If this is not the case, then the problem has no solution under our
conditions.
I: In addition to direct problems, there are inverse problems, for them the opposite is true.
For the given values of the output parameters, it is required to select the values
of the input parameters with a known procedure for solving the direct problem.

4 PEP 20 – Te Zen of Python. URL: [Link]


5 Quote from the novel by A. Strugatsky, B. Strugatsky “Roadside Picnic”.
8 ◾ STEM Problems with Mathcad and Python

M: A clarifcation is needed here. For inverse problems, constraints rather than exact val-
ues are specifed for the output parameters.
I: Inverse problems include the problems of designing new technology. Indeed, we must
ensure the required values of the output parameters by choosing materials,
design, and process parameters for this. As M rightly notes, for design tasks, it is
more ofen not the values of the parameters that are set, but the constraints on
them, for example, computer performance.
M: Te conditions of the problem must be formulated, i.e. what we have, what we need to
get, in what form, and sometimes in what way. Te conditions of the problem
should be clear to those who will solve this problem.
I: Te educational tasks and tasks that we deal with afer graduating from the university
difer signifcantly. For the frst, the conditions are strict, it is indicated not only
what needs to be done, but also how to solve the problem. In addition, there is
always a solution for educational problems, but if there is no solution, it is not a
good characteristic of the teacher who proposed such a problem. For practical
problems that specialists have to solve, it is typical that the conditions are set in
the form of constraints, for example, the cost of the product should not exceed a
specifed value, the allowable ranges of parameter values are set, and the method
of solving the problem is determined by the available capabilities. Moreover,
sometimes it is possible to reformulate the conditions of the problem, which are
a compromise between the desires of the one who sets the task and the resources
and capabilities of the one who solves the problem. Tis is not the place or time
to discuss how such compromises are made.
M: To start with, the state of the solver of the problem is close to the state of Ivanushka
from the Russian fairy tale; “Go there, I don’t know where, bring that, I don’t
know what.” We need to “Go where you need to and bring what you need.”
Te transition from the start to the target situation is precisely the solution to
the problem. It is not the Gray Wolf and the magic wand that can help us (which,
as the experience of Harry Potter shows, we still need to learn how to handle),
but our knowledge, skills, the ability to read books and fnd information on the
Internet.
I: When we talk about practical, and not educational tasks, it is necessary to mention
data. Any correct solution to the problem will give an incorrect result if incor-
rect input data is used. No matter how much you grind stones, you still can’t
make four!
M: Our world is imperfect. Even when the data for solving the problem is correct, one
must take into account their uncertainty. Recall the example of the problem of
a transfer to the airport, when, on the one hand, you can’t be late, on the other
hand, you don’t want to sit at the airport for hours.
S: Clearly, nothing is clear. I did not understand how to approach the solution of compu-
tational problems.
М: A fair remark, so let’s see and discuss how the tasks are solved.
Introduction ◾ 9

REAL AND IMAGINARY WORLD, CALCULATIONS,


MODELS AND PREDICTIONS

I: It all starts with a challenge. Tere is a good proverb in Russian: “Tunder will not strike,
the peasant will not cross himself.” It follows from it that until there is an urgent
need in the real world, nothing will be done.
M: We have an initial situation in which we cannot remain, a target situation6 into which
we need to move, but the transition from the initial to the target situation is
precisely the solution to the problem. Tus, we need to come up with a target
situation and a way to get to it.
I: Usually, for our educational tasks, the target situation already exists and is formulated in
the conditions of the task, but in real life, no one canceled goal setting. It is also
important for us to think over the path of transition from the source to the target
situation, to provide this transition with resources and tools.
S: All this is good when you cross the street: look to the lef if the trafc is right-handed,
and to the right if it is lef-handed, and then you don’t even need to think, all this
has been done a 1,000 times...
I: We just came to the solution of a well-solved problem. We know how to solve it, we
have the tools to solve it—our own legs and the head that guides them—it
remains to implement the solution to the problem and reach the opposite side
of the street. If we do not know how to solve the problem, then let’s fgure it
out, draw up a plan or several competing plans on how to achieve the target
situation.
M: Such plans are called models. We move from the real world to the world of our imagi-
nation and try to understand the initial situation, the target situation, try to fnd
a way to move from the frst to the second. By the way, people have always done
this. Mythology is an attempt to make the world understandable, to explain it,
to connect the essences of the real world, to fnd your own way...
I: Just as there are many mythologies—attempts to build models of the world, there are
also many models with which we want to describe our tasks, fnd ways to solve
them. Let’s return to the problem of traveling to the airport. Te simplest model
of behavior: we look out the window and if we see that there is a blizzard outside,
then we get to the station by metro no later than 4 hours before departure (we’d
better sit and wait!) and go to the airport by rail. In a more complex model, we
analyze a road map on a smartphone, fnd out the cost of the trip, the schedule
of buses and aeroexpress, afer which we choose the mode of transport, esti-
mate the time of the trip, its cost, and make a decision. Simple models are easier
to work with, complex ones are more difcult, but they allow you to take into
account additional features of the real world.

6 Tere can be several such situations, which leads to the additional task of choosing the target situation.
10 ◾ STEM Problems with Mathcad and Python

М: In any case, afer working with models in the imaginary world, we will have to move to
the real world and make a decision about the type of transport, time to leave the
house, order a taxi, etc.
Te responsibility for the fact that we should arrive on time lies with you and
me, from how much the model we have chosen corresponds to the real situation,
how careful we are in assessing adverse factors.
S: Everything is clear here, the sequence of actions is clear, it depends on our budget,
weather, trafc jams and our caution. Tis does not apply at all to the tasks that
you set as homework.

MAIN STAGES OF PROBLEM SOLVING

М: Not everything is clear yet, therefore we will list the main stages of solving problems
and the pitfalls that await us on this path. Afer that, we will discuss each of the
stages.
It all starts with a careful reading of the conditions of the problem, under-
standing what they require of us. Afer that, we need to move on to fnding ways
to solve the problem.
I: At this moment, we know how to reach the end—to solve the problem. We need to imple-
ment this path—to fnd tools, data and means that will help us do this in a rea-
sonable time, without spending excessive efort and money.
M: We must defnitely check whether we have made mistakes, both when looking for a
solution, and when implementing a solution to a problem. We don’t want tem-
peratures below absolute zero or speeds faster than the speed of light.
I: Tese can be a kind of tests that allow us to check the correctness of the solution to the
problem. Solutions of the problem for special cases that can be obtained analyti-
cally, data from other researchers, and common-sense considerations serve as
such tests.
But then we will have to plan how we will get the result. If the condi-
tions of the problem require a single calculation, then this is not necessary.
If, however, to solve the problem it is necessary to perform massive calcula-
tions, then it is necessary to set up a computational experiment, planning its
implementation.
M: Since we are talking about a computational experiment, then its results, just like
the results of a real experiment, must be processed and presented in an easily
understandable form. It ofen happens that the results of solving a problem are
understandable only to the one who solved this problem since they completely
understood it, but the value of what was done tends to zero if other people cannot
use the results.
I: Presentation of the results and their interpretation is a very important step in solving the
problem. If earlier the only way was to compile a report, speak at a conference,
publish an article, now there are tools that allow you to present a solution to a
Introduction ◾ 11

problem in the form of a video or even an interactive dashboard that you can
“play around” with just launching a browser.
M: Finally, there comes the stage of obtaining black eyes and feathers in his cap.7 Tis means
receiving well-deserved and sometimes undeserved rewards for the successful
solution of problems or punishments for the absence of, or an incorrect solution.

READING THE CONDITIONS OF THE TASK

M: Te main mistake in solving problems is an inattentive reading of its conditions. Tis is


where the misunderstanding comes from. Before solving the problem, you need
to fnd out what is wanted and do not hesitate to ask if something is not clear.
I: Educational problems difer from practical ones, at least in that the former always have
a solution.
М: For educational tasks, it is always known, even if implicitly, what means must be used
for their solution. Moreover, these tools have been studied previously.
I: In any case, they should have been studied. If, however, additional knowledge is required
to solve the problem, then this is mentioned either in the conditions of the prob-
lem or in the explanations to it, but this rarely happens. I use this approach only
in mini-projects, for the solution of which more than 1 hour is allotted. Many
things can be discussed during consultations, if so desired. In addition, educa-
tional tasks are usually typical, and for their solution quite ofen an analogy is
enough—an analysis of solutions to similar tasks.
In practical tasks, everything is diferent. It is not very important how the
solution of the problem is carried out; the result is important.
М: It is typical for practical problems that conditions are not always exactly set, it might
happen that the task manager does not know the exact values for neither the
input nor the output parameters values.
I: Te conditions of a practical task are a compromise between the desired and the possible.
It is not always possible to get what you want, and the possible is not interesting
for the one who sets the task. Tis compromise is reached as a result of bitter
disputes and a sequence of compromises.
M: Many practical tasks are inverse, as mentioned earlier, we know what we want, but we
don’t know what is needed for this and how to do it. Inverse problems are usu-
ally reduced to solving a sequence of direct problems. Te more we know about
the relationships between the parameters of a problem, the easier it is to fnd the
desired result. Otherwise, we need to enumerate all possible values of the input
parameters, and this is not always possible. As Mephistopheles said: “Art is eter-
nal, life is short8).”

7 A reference to the novel by J. Heller “Catch 22”.


8 Quote from “Faust” by I.V. Goethe, in turn, Goethe drew a quote from the work of the Stoic philosopher Lucius Annaeus
Seneca “On the brevity of life”.
12 ◾ STEM Problems with Mathcad and Python

I: Sometimes design problems come down to optimization problems, but this is more an
example of how the tail wags the dog.9 Te task is adjusted to the proven tools—
optimization methods. For design tasks, a diferent delivery is typical: for the
parameters, the ranges of permissible values are specifed, and a successful solu-
tion means that the values of all parameters are in this range. To use optimiza-
tion methods, it is necessary to reformulate the design problems.
M: Well, that’s always a bee in your bonnet! You did not mention that in order to solve the
design problem, it is necessary not only to enter the range of acceptable values,
but to be as far away from its boundaries as possible. Otherwise, random changes
in the parameters values will lead to going beyond the limits of the range of
permissible values and, as a result, will lead to a decrease in the percentage of
yield in the production process. We have repeatedly discussed this with you, but
probably this does not directly relate to the topic of our trialog and is not very
interesting for S.
S: Indeed, let’s move on to the process of solving problems. Even when the conditions of the
problem are clear, you ofen do not know what to do next, how to solve it.
I: Tere is no silver bullet or magic wand for solving problems, but there are tricks, the use
of which leads to success.

ANALOGY, SEARCH, DECOMPOSITION, WELL-KNOWN


PROBLEMS, “GLUEING”, TRUST BUT VERIFY

M: Te frst and most obvious way is to remember if we have solved similar problems
before. As the well-known proverb says, in a critical situation, and this applies
to exams, you will not rise to the level of your expectations, but will sink to the
level of your preparation. Te more problems solved in a semester, the easier it
is in the exam.
S: You have already talked about this, but apart from studies, there is work and personal
life, and you get what you get.
M: In any case, you frst need to analyze solutions to similar problems. It very rarely
happens that you only need to substitute other numerical values of the input
parameters into the solution of a similar problem, although this is exactly what
we would like. In other cases, everything depends on whether there is enough
knowledge and skills to transform the solution of the found problem into the
solution of the original one.
I: Keep in mind that you can’t rely completely on the web—it may contain errors.
M: It might sound dreadful, but reading textbooks, searching and comparing information
found on the Internet, analyzing solutions to similar problems, although it takes
precious time, can help in solving the problem.

9 Wag the Dog is a 1997 American political satire black comedy directed by B. Levinson and starring Dustin Hofman and
Robert De Niro. URL: [Link]
Introduction ◾ 13

I: If a way to solve a problem is known, then you need to fnd an adequate tool for solving
it. It can be notebook and pen, or one or more mathematical programs used in
the educational process. For example, if we need to solve the Cauchy problem for
a system of nonlinear diferential equations, then the choice is clear for us, we
need to use a mathematical program. If it is required to solve a boundary value
problem, then we are looking for ready-made means for this. If there are none,
then we try to implement the solution of the boundary value problem, reducing
it to solving a sequence of problems, for which we have a tool: namely, one for
solving the Cauchy problem—a problem with initial conditions. In this case, we
will have to implement by our own eforts shooting method, for example. In any
case, we have established a connection between the task and the tools available
to solve them.
M: Analogy and search techniques are useful, but they do not always work, even when
solving educational problems. Any interesting and complex task involves the
decomposition of the original task into several subtasks. In this case, we must
present our problem as a set of solvable problems. Te decomposition itself
is highly dependent on the set of tools that we use. As already mentioned,
tools can be a notebook and pen, textbooks and reference books, mathemati-
cal systems, and specialized sofware packages for solving certain classes of
problems.
S: I understand that the original problem needs to be transformed into a sequence of
known solvable problems for which we have tools.
I: For educational tasks, this is almost always the case, for practical tasks, decomposition
resembles a mosaic, you must frst identify the elements of the mosaic. I call
them WSP. It may turn out that we do not have all the elements of the mosaic. In
this case, we will have to make them ourselves, i.e., in our terminology, reinvent
the wheel.
М: Decomposition is not always carried out in one step. It may turn out that the subtask is
so complex that there is no WSP for it and it is necessary to apply the previously
used approach of decomposition.
I like the mosaic metaphor! We sequentially divide the unifed whole of the
original problem into elements so that each element—a subtask—could be solved
separately. In this respect, the decomposition process resembles the dismantling
of a family of Russian matryoshka dolls.
I: I note that it is this step—the decomposition of the problem into subtasks that can be
solved, that determines the success of solving the entire problem. It requires
knowledge, skills and experience, which is acquired in the process of solving
simpler problems.
M: Decomposition allows us, frstly, to focus on solving individual tasks, and, secondly,
to speed up the solution of the original task by distributing subtasks among the
project participants.
S: Did I understand correctly that decomposition transforms the original problem into a
set of WSP?
14 ◾ STEM Problems with Mathcad and Python

M: Not really. Decomposition saves us time. If we do not fnd WSP, then we will have to
implement this subtask ourselves or hire specially trained people for it.
I: Te decomposition of the original task into subtasks is carried out in a non-unique way
and depends on the knowledge and skills of those who solve the problem, the
available resources and tools available. Do not forget that if the problem is practi-
cal, then in the absence of a solution, you can try to reformulate it.
M: Let’s take an example. Let’s say we have an ordinary diferential equation. Its solution
is expressed in terms of the Bessel functions. We have several possibilities: do
all the calculations manually, use the means of symbolic calculations, and when
we do not have a special need for analytical formulas, then perform all the cal-
culations using numerical methods, using one of the procedures available in all
modern mathematical systems.
S: So, it is necessary to use WSP of the highest possible level?
I: In the case when it leads to the solution of the problem. I ofen miss the lack of solver
capabilities in the Python ecosystem library, sympy, for solving nonlinear equa-
tions. Let’s hope that the developers will add new features to this package, per-
haps using artifcial intelligence tools.
Tools are evolving, computing power is growing, scientifc visualization
tools are evolving and simplifying. Along with them, the tasks to be solved also
change. Ten years ago, I could not even think of solving the problems that we
now solve with students in a visual form, and several per lesson.
S: So, everything is fne and the state of the existing set of tools for solving problems com-
pletely suits you?
M. Not always. I miss the integration tools. Te same features in diferent systems are
implemented diferently, some worse, some better. I would like simple tools that
transfer the results of solving a problem from one system to another.
I: I do not have enough tools for solving the equations of mathematical physics, included in
the main functionality of mathematical systems so that they would not need to
be purchased for additional money or refer to specialized systems.
For free systems, I really wanted to improve the quality of documentation.
Tis is especially true for the Python ecosystem. Ofen you have to explain many
things to students yourself. But as the Russian proverb says: “Don’t look a gif
horse in the mouth!” You have to be grateful for what you have.
S: Where and how to look for these WSPs of yours?
M: In textbooks, articles, the Web. Ask questions and talk to knowledgeable people. Now it’s
called “sof skills”. Tat’s what people go to conferences for. Discussions in a cafe
with a knowledgeable person can contribute more to solving a problem than sleep-
less nights. By the way, in this case, you need to be able to correctly set the context.
S: Let’s go back to our mosaic. We have turned the original task into a set of mosaic ele-
ments, we do not have some of the elements. What to do next?
M: Good question! First of all, we implement the missing elements of the mosaic. Afer
that, we will need to solve each subproblem. For us, WSP is a black box, to which
we give input data, and it returns the result to us. It may turn out that the WSP
Introduction ◾ 15

we found will not be able to cope with the available data. Tis brings us back to
fnding a solution to this subproblem.
It is important that the subtasks of our task are interconnected by data. Te
output of one subtask serves as input to one or more other subtasks.
I: So, it seems that data streams are transferred from subtask to subtask. In the simplest
case, there is one stream, sometimes the data river is divided into arms, then
these arms merge...
M: Everything is as usual, data is transferred from one black box—subtasks—to another.
It’s great when this is done without our participation and the subtasks are coor-
dinated with each other, but this rarely happens. Usually, diferent WSPs are
implemented by diferent people, they have diferent ideas about what data and
how should be passed to the input, what and how the WSP should return. Tis is
where the real work begins for us: we must make sure that the data returned by
one subtask becomes usable for another.
I: We must convert the data, guided by the documentation that is available for each WSP.
Tis process is called “glueing”. It is time-consuming, boring, error-prone, but
you can’t get anywhere without it.
M: Let’s hope that in the next versions of mathematical systems this stage of solving prob-
lems will be automated approximately as it is done in Mathematica.
I: Most likely, this will only be available in paid systems; it will probably never be done in
the Python ecosystem which is developed chaotically by a community that is not
controlled by anyone.
S: Hurrah! Finally, we have reached the end, the result!
M: No, no! We forgot about a very signifcant factor—mistakes. Man is weak, he tends to
err. Errors can occur at all stages, from the formulation of the problem to the
interpretation of the results.
Terefore, in the process of solving problems, we must provide procedures
and means for fnding and correcting errors.
I: We might get a result, perhaps even draw it, but it will not be at all that we are looking for.
M: We cannot insure ourselves against all possible errors, our eforts are aimed at reducing
their number, facilitating their localization and elimination.
I: Te main means we will have are attentiveness, perseverance, common sense and all
available information about the task. Tere is no need to save time on reading
and understanding the documentation, when calling a function or procedure
to solve a WSP, you should not be lazy, you need to fnd out and check again
what needs to be passed to it, what it returns, what data types are used, what is
required from this data. In a good way, these checks should be performed in the
WSP itself and provided by the developers. But everything cannot be foreseen,
and the user will always be able to do something that the developer cannot imag-
ine! It would seem that things are obvious, but I have to repeat them many times
with minimal success.
To fnd and fx errors, we need data. It is only possible to check how WSP
works if we know what results should correspond to the test input data sets. It
16 ◾ STEM Problems with Mathcad and Python

may also turn out that WSP refuses to accept our data, issuing either a warning or
an exception. Te frst means that we do not understand something or have gone
beyond the scope of the application of WSP. In the second case, a question for the
developers, which you should not hesitate to ask either directly to the developers
or on forums where users communicate. Ofen it turns out that the answer to the
question is already there, it only needs to be found using a search engine.
S: Where should I look for it?
M: Almost every mathematical system has a community of users. Developers usually sup-
port these communities, so they help maintain the system, fx bugs, and form
directions for its development. Mathcad and Matlab user communities are
active. Te situation with free systems is somewhat worse. Teir developers have
considerably less power and capacity.
I: But they are more active, otherwise they would not survive. I usually start by formulat-
ing a question in [Link] or [Link]. In 90 out of 100 cases, this helps. If
I didn’t learn, I ask a question in [Link]. In Russian, there is a very
useful resource of questions and answers at [Link]. If this does not help,
then I start calling and writing to friends and acquaintances.
M: Forgot to say that the verifcation process is multi-layered. It is necessary to prepare
data and provide for testing for each subtask and for the entire task as a whole.
I: And here M forgot that checks should also be in the process of “glueing”, when subtasks
are combined with each other. I try to “glue” tasks one at a time and test the
result each time.
M: You can act in a diferent way—glue tasks into blocks, test these blocks of subtasks, and
then combine the blocks together.
I: Te tactic of “glueing” depends on the type of task, the data we have and the number of
subtasks.
S: So, the process of solving a problem essentially depends on the tools used in solving it.
How do I choose these tools?
I: Te answer to this question is paradoxical. You S at the university have almost no choice.
Te tools used are determined by the corporate policy of the university. If your
training is paid for by an employer, then they may require the use of certain tools.
М: Apparently, the time has come to talk about what tools and how to use them when solv-
ing problems.

TOOLS. MANY AND DIFFERENT

I: Let’s start with the question, what do we need from mathematical systems with which we
are going to solve problems?
S: Probably, it is necessary that the mathematical system contains a large number of WSP—
tools for solving various problems, so that it would not be necessary to change
the system, moving from problem to problem and inventing wheels. In addition,
Introduction ◾ 17

it is necessary that this system be easy to work with, and the study of the system
itself does not turn into a separate heavy task.
М: We need that the results of solving individual subtasks could be quite simply “glued”
together and not spend extra efort on it.
I: We will not succeed if visualization tools are not built into the system that allow visual-
izing the results of solving the problem, and the use of visualization tools should
be simple and transparent.
S: I would like to be able to implement all the stages of solving the problem in one place,
starting with the description of the conditions of the problem, ending with plots
and a description of the results. It would be great if you didn’t have to do extra
work to transfer all this into a report, but send the teacher immediately what we
got in the mathematical system.
M: It would be desirable to have tools that allow publishing the results of solv-
ing problems not only in the form of static documents but also interactive
applications...
I: For us teachers, it is very important to provide a working environment with which we
and students could work not only in full-time, but also in distance learning,
which we have had to deal with over the past 2 years.
M: Let me try to list the requirements that we place on systems for solving computational
problems. Tey have to:

• Out of the box to support the solution of a large number of WSP.


• Have means of “glueing”—transferring data from one subtask to another. In fact, we
need some built-in programming language.
• We defnitely need advanced built-in visualization tools that are easy to use.
• Support all stages of problem solving from formulation to interpretation of results.
I: I would call the listed requirements mandatory. By the way, the last requirement, supported
in most mathematical systems, is called a computational document and supports
the metaphor of a school notebook, in which you can formulate conditions from
a problem with text, formulas, pictures, and, if desired, with video. In the same
document, you can carry out all the necessary calculations, visualize and discuss
the results.
Here I would like to list additional requirements related to the support of the
educational process:
• Ease of use in the educational process, low entry threshold.
• Te ability to turn a computational document into an interactive web application
with minimal efort and publish it.
• Opportunity to safeguard the work of students and teachers not only in the computer
classes of the university but also at home.
18 ◾ STEM Problems with Mathcad and Python

• It is highly desirable to have easy options for integrating your own WSP into the sys-
tem, again without undue efort. Afer all, we are not professional developers, but users.
• I would like to be able to easily transfer data from one system to another. Tis is more
of a wish than a requirement.
M: Te basic requirements are met by almost all available mathematical systems, both
proprietary and free.
I: But since there are many systems available, this means that they are tailored for diferent
tasks, diferent users and diferent wallets.
M: What is common is that a modern mathematical system necessarily includes an exten-
sive set of WSP libraries for solving typical problems. In some systems, for exam-
ple, Matlab, tools for solving classes of problems are assembled into packages,
which you need to buy separately.
I: Programming languages are built into all mathematical systems. For some, the capabili-
ties of the built-in programming language are limited, for example, for Mathcad.
On the other hand, the Python ecosystem is built around a high-level general-
purpose programming language. Each of these approaches has its pros and cons.
Te simpler the programming language, the less time and efort it takes to learn
it, but the less its capabilities. In Python’s defense, its architecture is orthogo-
nal in the sense that one can work with a small subset of the language, learn-
ing additional features only as needed. But in the Python ecosystem, you can
do everything from computational applications to web applications and system
administration.
S: As I asked previously, how to choose a mathematical system for solving problems, why in
this book you used Mathcad and Python, as well as Maple, Mathematica?
М: Tere are a lot of systems, besides those listed here we could mention the free ones
Octave, Scilab, Smath. Tere are quite a lot of systems that solve specifc prob-
lems, for example, carrying out fnite element calculations, but we do not touch
on such systems here.
It is important for us that the construction of the systems is practically the
same, they difer in the set of available WSPs, the programming languages used,
visualization tools, and the possibilities of using computational documents. In
our daily work, we mainly use Mathcad and Python, but in some cases, we use
Maple and Mathematica. It is ofen easier and faster to switch to another tool for
a specifc task than to spend precious time staying in a single system. It is also
important that we consider it necessary to show students that they may have to
deal with other mathematical systems at work.
I: We will not start a dispute as to which system is better, their coexistence in the market
speaks volumes. Usually, free systems require more efort to master, the visual-
izations obtained with their help are less attractive; nevertheless, they exist and
continue to be developed.
M: As for other types of human activity, one should not forget about fashion. Now it is
fashionable to carry out calculations using the Python ecosystem.
Introduction ◾ 19

I: When a new system appears and I’m asked if it’s time to switch to this system, then I ask
counter questions about the readiness of the university to acquire licenses for it,
the readiness of teachers to study it, and about the transfer of methodological
support of disciplines to this system. Tis is usually where it all ends. Education
is a conservative industry!
S: It’s time to return to our sheep.10 We know how to solve problems, we have tools for this,
we have discussed how to check the correctness of the results, what is lef to do?

COMPUTATIONAL EXPERIMENT

S: If the initial data and what is required from the result are given in the conditions of
the problem, then why conduct a computational experiment? You are compli-
cating things.
M: Indeed, if this is a purely educational task and it is required to obtain one single result
corresponding to the initial data, then this is indeed the case. But when solving
problems using STEM, you usually need to build dependencies of something on
something. If these are sufciently large calculations, then this requires planning
and performing calculations.
I: In the classroom, we simulate an autogenerator, at the same time analyzing the conditions
for switching to the generation mode, and chose a working point. It would be
interesting to model whether generation always takes place, taking into account
random deviations of circuit parameters from nominal values. It is enough to
simply estimate the yield percentage by setting arrays of random values of the
circuit parameters and solving the original problem for each combination of
parameter values. Tis is called statistical modeling. You can make the problem
a little more difcult by optimizing the yield percentage using stochastic optimi-
zation. It certainly cannot be done without a computational experiment. In the
simplest case, at each optimization step, one should choose the average values of
the parameters, which are calculated only for those combinations of parameters
that are included in the allowable area. In our case, these are the circuit param-
eters for which oscillations are generated.
M: Here we greatly idealize the problem. You need to have a lot of data on how the actual
process behaves.
S: Well, here you are behind the times. Computers are built into technological equipment,
everything is recorded, stored and processed. Big Data Everywhere!
I: Te only question is whether the manufacturers will share this data with you if you do
not work for them and have not signed a non-disclosure agreement.
M: We should not forget about the inverse problems that we talked about earlier. Here it is
necessary not only to conduct a computational experiment but also to plan it in
order to solve the problem in an acceptable time.

10 A reference to the French expression, “revenons à nos moutons”, from the farce Pierre Patlin the Lawyer (circa 1470).
20 ◾ STEM Problems with Mathcad and Python

S: I realized that in solving practical problems, you can’t do without a lot of calculations
and a computational experiment.
I: Calculation results should be saved for future use.
M: Tey need to be processed because millions of numbers by themselves do not give us
anything.
I: Tey must be presented in a form convenient for us and interpreted. We will deal with
this in the next part of our trialog. Well, now let’s think about how to conduct a
computational experiment with minimal labor costs.
S: Press the Big Blue Button and go get cofee or beer.
M: Not everything is so rosy. If there is a lot of data, then they need to be stored so that they
can be found when we need them.
I: In the simplest case, in addition to the results themselves, it is necessary to save their
descriptions. I do this either in the fle names when saving to the fle system, or
to the database. I mainly use SQLite, since you can use it anywhere, including
Android. We may have to mechanize our work on conducting a computational
experiment, for example, by writing utilities to run and save the results.
S: Tat’s boring. Again, you have to write programs. Besides, as you said, such programs
cannot be written for all mathematical systems.
I: Tere is another way—to attach a user interface to the implementation of the solution to
our problem.
S: Tat would be cool. But as I was told, the complexity of developing user interfaces is
comparable in complexity to the development of programs for which these inter-
faces are created.
I: Tis is true if you develop user interfaces that will be used by thousands of people. We
need something simple and unpretentious, which will be used by a limited circle
of people. Here, the developers of mathematical systems thought for us, provid-
ing us with simple tools for building user interfaces. Such tools are available in
Mathcad, Matlab, the Python ecosystem, in the system for statistical calcula-
tions, R.
M: Moreover, some of these tools not only allow you to add graphical interfaces, but also
publish solutions to problems as interactive web applications, so you can work
with the application through a regular browser without installing anything on
your computer.
I: In my opinion, such interactive applications should be built into electronic textbooks. In
addition, we need to think about how these technologies can be adapted to create
virtual laboratory workshops.

VISUALIZATION AND INTERPRETATION. BLACK


EYES AND FEATHERS IN HIS CAP

I: Here I will start with the Russian proverb “It is better to see once than to hear a hun-
dred times”. It is precisely the essence of scientifc visualization. If the results can
Introduction ◾ 21

be presented in a clear and visual form, then this allows us to understand the
essence of the problem.
M: Confucius has a similar saying: “I hear and I forget, I see and I remember, I do and I
understand!”
I: As with user interfaces, we need to do this by writing one or two lines. Everything else,
including line thickness, grid, labels on the axes and the legend, can be added
later. Moreover, there are plenty to choose from, for example, in the Python eco-
system, along with the good old matplotlib library, one can use plotly, bokeh,
gnuplot, HoloViews and a dozen other libraries, depending on one’s needs and
habits.
M: I have always had a hard time with drawing, so I am very grateful to the developers of
matplotlib, who inserted into it the ability to create print-quality drawings, ready
for publication in articles and books.
I: At the same time, not everything can be visualized; even when it can be it is not always
possible to make the results of visualization contribute to understanding. Te
fact is that we live in a three-dimensional world and we cannot visualize on a
screen or a piece of paper something more multidimensional than a function of
two variables.
M: Directly yes, but there are many indirect methods. For example, you can use the size
and color of markers as additional dimensions. Finally, we have another dimen-
sion—time. Nothing prevents us from making an animation, and in cases where
the animation cannot be shown in real time due to limitations in computing
power, we can make a video from the animation, which can then be inserted into
a computational document.
S: Well, that’s probably an exaggeration...
M: Not at all. Most math systems make it fairly easy to create animations. In the book, we
will give animation examples.
I: Animations are good, but our story has another side—interpretation.
M: By interpretation, we mean brief and understandable conclusions that can be drawn
from the solution of a problem. Tey should be reasonably concise, understand-
able and debatable.
I: Diferent people have diferent perspectives, so we need to discuss and defend our opin-
ions on the results of solving problems, especially those that need to be trans-
ferred from the imaginary world to the real one and on which the action plan,
technical solution, and sometimes the fate of people depends.
S: You talk about it with feeling.
I: Nevertheless, it is true. Most engineering systems, and sometimes decisions made at
a high level, depend on the results of calculations that are carried out by you
and me.
S: You used to talk about black eyes and feathers in his cap. Tis is most interesting.
M: Everything is simple here. For you, this means passing a test or an exam, publishing
articles if the problem solved is serious enough. Ultimately, where and how you
will work afer graduation depends on the acquired knowledge and skills.
22 ◾ STEM Problems with Mathcad and Python

HARD SKILLS AND SOFT SKILLS

I: In our trial, we mainly talked about hard skills—knowledge and skills related to the
subject area. When a team works on solving a problem, sof skills become impor-
tant—skills aimed at achieving results and ensuring that work gives pleasure,
and does not turn into hard labor.
M: Let me interrupt you. Sometimes this is important in individual work. We did not talk
about the need to document the solution of problems. Quite ofen, and in prac-
tice almost always, one has to return to the solved problems. And if we saved
time on documentation, we will spend it on re-doing what we’ve already done.
Practical tasks are big tasks, people of various specialties, with diferent char-
acters, knowledge and skills work on solving such problems. In this case, docu-
mentation is essential. We must understand each other, and not only understand
but also verify. Mistakes in solving practical problems are too expensive! Te
solution to our problem should be understood and able to be reproduced by
another person, independently of us.
S: Now it’s clear why you make Mathcad and Jupyter Notebook documents describe in
detail the progress of solving problems and the results obtained.
I: Note that the rules and details of documentation depend not only on the subject area,
but also on state, industry and corporate standards, and agreements with those
for whom the tasks are solved. When solving large problems, documentation may
be handled by special people called technical writers, who write in a form that is
understandable and accessible to users about how to work with what has been done.
S: Documentation is one aspect of sof skills. What is included in them?
I: Let me continue. Te sof skills complex usually includes business communication
skills—interaction between team members, as well as with the outside world.
Tis skill is persuasive, but unobtrusive to lead a discussion, to hear and take into
account the opinions of others. At the same time, it must be remembered that
the presentation should be focused on the customer. As one of my acquaintances
said, try to explain to your grandmother, and if it doesn’t work out, then redo
the report.
S: Now it is clear why you force us to prepare reports and presentations on standard calcu-
lations and arrange their discussion at consultations!
M: An important aspect of sof skills is critical thinking—checking the validity of the
information used, including data, algorithms and their implementation. As the
saying goes, trust but verify!
I: Te next aspect is result orientation. You need to fnd pleasure in your work, but without
forgetting that tasks are solved to achieve results.
M: Te process of solving a large task must be managed: interact with the customer
when formulating the task, transferring results, selecting a team, evaluating
the required resources, breaking the task into subtasks, organizing interaction
between team members, controlling deadlines... All this has to be learned.
Introduction ◾ 23

S: Tese days there are many online courses and trainings on sof skills.
M: Tis is true, but we must not forget that the most valuable is your own experience,
which is acquired in solving educational and practical problems, working in a
team, participating in projects. Tis allows you to perceive someone else’s experi-
ence and meet interesting people.
I: When solving problems, as well as in any human activity, we constantly have to make
decisions and take responsibility. Avoiding making a decision is also a decision.
But making the right decisions, especially in the face of incomplete and confict-
ing information, is wisdom!
M: Tere is another aspect—emotional, without which work and communication turns
into a series of conficts. If communication does not take into account the moti-
vation of people and their emotions, then opposition, not cooperation, is ensured.
I: In the process of communication, you need to look at yourself from the outside and think
about how your words and actions are perceived by others...

FINISHING THE DISCUSSION

M: Probably, it is time to fnish the discussion and briefy summarize the results.
I: We found out that practical and educational activities (remember the abbreviation
STEM), at least in the feld of natural sciences and engineering, are closely related
to solving problems, especially problems involving calculations.
M: I would even say that sometimes the calculations are connected with art, adding another
STEAM symbol to STEM. Just like all other problem solving, it is necessary to
learn, and not only teachers but also students should actively participate in this
process.
S: Perhaps you convinced me that you can’t start solving problems only when there is
nowhere to go. Finding correct answers to all questions on the Web is hardly
possible, especially when solving problems. By the way, I recently read a novel on
my smartphone, which said that knowledge is not superfuous, someday it will
come in handy!
I: I would add skills that save a lot of time to this. Knowledge, skills and abilities help to
fnd an interesting job, and as my supervisor said many years ago: “You never
know where you will be in the future and what you will do.” Nowadays, when
everything is changing rapidly, new technologies and activities are emerging,
this old and simple thesis sounds very, very modern.
S: At the same time, watching a talking head on a laptop screen, and even more so a smart-
phone, trying to write something illegible on a blackboard is not very modern
and interesting.
M: Tat’s for sure. For 2 years now, we have faced the challenge of the widespread use
of distance learning. Terefore, let’s briefy formulate once again what require-
ments are imposed on the tasks that we solve in the classroom and at home.
24 ◾ STEM Problems with Mathcad and Python

We agreed that the tasks should be understandable, interesting, their solution


should not take hours, the solutions should be visual.
S: It would be nice if at least some of the tasks had a game component.
I: Defnitely, for this, there are inverse problems and operational tools for creating user
interfaces, which make it possible to “play around” with the model, trying to
achieve a given result. Tis can be done only when you understand what depends
on what.
S: You correctly said that the decision process should not take too much time so that, hav-
ing received a decision, we would not forget what we did and why.
I: And here we cannot do without tools that allow us to quickly solve typical problems (we
previously called them WSP) and visualize the results using scientifc visualiza-
tion and animation.
In my opinion, we should not get hung up on the use of any specifc tools and
use those tools that, frstly, are best suited for solving the problem, and, secondly,
are available. At the same time, we implicitly compare diferent tools, because it
is not known where you will have to work, what tools the employer uses.
M: You correctly emphasized the availability of tools, students in self-isolation should work
with them not only at the university but also at home.
Once again, let’s return to our sheep, listing the main stages of solving prob-
lems: comprehending the conditions of the problem, collecting and preparing
information for solving it. If it is not possible to solve the problem in the form
in which it is posed, then it is necessary to decompose the original problem into
subtasks. Tis process continues until it becomes clear that all, I repeat all, sub-
tasks can be solved, and the tools for their solution are at our disposal. Afer that,
we implement solutions to subtasks and “glue” them together, passing data from
one task to another.
I: At the same time, we should not forget to create control points—data and procedures
that allow us to control the correctness of solving subtasks and the original task.
M: Afer that, we must plan and conduct a computational experiment, without which the
solution of inverse problems will not do.
I: We must process, interpret and present the resulting data for public viewing, as they said
before urbi et orbi (to the city and the world11)
S. Our discussion has dragged on, let’s get down to business and start solving problems!

QUESTIONS AND TASKS


1. Is it necessary to solve problems in the study of natural science and engineering
disciplines? Justify your opinion.
2. In your opinion, how should approaches to teaching science and engineering
disciplines be changed?

11 Tis refers to ancient Rome, which was considered the center of the Universe.
Introduction ◾ 25

3. What requirements, in your opinion, should be presented to the calculation problems


solved in the classroom and at home? Justify your opinion.
4. How do you feel about the mathematical systems used to solve computational prob-
lems? Justify your opinion.
5. How do you use black boxes and invent wheels in your work?
6. What are direct and inverse problems, how do they difer from each other?
7. What is the condition of the task, what should be indicated in them? Give examples.
8. List the diferences between educational tasks and those solved in practice.
9. List the main steps in solving computational problems.
10. Why is it necessary to consider not one, but many models when solving problems?
What is required of these models?
11. How to check the correctness of the solution of the calculation problem?
12. What is decomposition, and why is it needed?
13. What are WSP – well-solved problems?
14. Why “glue” solutions to subtasks? What is required for this?
15. How is it necessary to prepare data for solving subtasks?
16. How to control the correctness of solving subtasks?
17. How is it possible to fnd and correct errors when solving computational problems?
18. What are the requirements for modern mathematical systems for solving computa-
tional problems? Justify your opinion.
19. What is a computational experiment? When and how should it be done?
20. Why is scientifc visualization widely used in solving scientifc and technical prob-
lems? What can’t be done with modern scientifc imaging?
21. What is meant by the interpretation of the solution of the problem. Why is this
needed?
22. What do the authors understand by black eyes and feathers in his cap? How do you
yourself feel about this?
CHAPTER 1

Portrait of the Roots of


the System of Equations

I <…> was solving some long algebraic equation on a black board. In one
hand I held Franker’s tattered sof “Algebra”, in the other—a small piece of chalk,
with which I had already soiled both hands, face and elbows...
Leo Tolstoy “Youth”, chapter 2 “Spring”

At present, schoolchildren, standing in the classroom at the blackboard, might solve equa-
tions using a tablet and an electronic pencil (stylus), rather than with chalk and textbook
(Franker’s Algebra, for example, a mathematics textbook widely known all over the world
in the middle of the 19th century). In general, the board might not be simple, but elec-
tronic with built-in mathematical tools. Te methods for solving problems are likely to be
numerical, making use of computer graphics, rather than just analytical.
On the one hand, a computer might seem to negate all the pedagogical benefts of solv-
ing equations and systems of equations (“gymnastics for the mind”). Te student enters
the equation into the computer, presses the button—and the answer is ready. On the other
hand, the computer allows the student to discover new and interesting features when solv-
ing equations. One of the features is described in this chapter.
Let’s look at a specifc example—we will solve the system of equations shown in Figure 1.1.
Of the three methods for solving equations and systems of equations on a computer
(symbolic, numerical and graphical), the preferred one—the one you need to use frst of

FIGURE 1.1 System of two trigonometric equations.

DOI: 10.1201/9781003228356-2 27
28 ◾ STEM Problems with Mathcad and Python

FIGURE 1.2 Attempt to analytically solve the system of equations.

all—is the symbolic method, which gives accurate answers to all possible roots of an equa-
tion or system of equations. Te roots of an equation or a system of equations are the values
of the unknowns (we have variables x and y in Figure 1.1), which turn the equations into
identities where the right and lef parts of the equations turn out to be equal (or approxi-
mately equal, if we talk about approximate methods of problem solving).
Figure 1.2 shows an attempt to solve our system of equations by calling the solve opera-
tor in the symbolic mathematics part of Mathcad. Te solution was not found because the
periodic trigonometric functions, tangent and cotangent appear in the equations. Tey
allow for an infnite number of roots in the system of equations.
In the Python ecosystem, we use the sympy library for symbolic computation to solve
the equation system:

from sympy import symbols, Eq, solve, init_printing, tan


init_printing()
x, y = symbols('x y')
eq1 = Eq(1/tan(x) + 5*y, x - 10*y)
eq2 = Eq(x - tan(y), 1/y**2)
eq1, eq2

Here we import everything we needed to solve the problem from the sympy library:
symbols—a function for declaring symbolic variables, Eq—a tool for forming equations,
solve—a function for solving algebraic equations, init_printing—a function that allows us
to print nice-looking symbolic formulas in a Jupyter Notebook.
Next, we declare the symbolic variables x, y, construct a system of equations, and
print it out:
ˆ 1 1
˘ˇ 5y + tan( x ) = x −10y, x − tan ( y ) = y 2 

As in Mathcad, an attempt to solve the generated system of equations fails:

solve([eq1, eq2], [x, y])

Te solver’s capabilities are insufcient, resulting in a NotImplementedError exception


and a message:

NotImplementedError: could not solve (15*y - tan(y) -


1/y**2)*tan(tan(y) + y**(-2)) + 1
Portrait of the Roots of the System of Equations ◾ 29

FIGURE 1.3 Two numerical solutions to the system of equations.

FIGURE 1.4 Verifcation of the numerical solution of the system of equations.

If the “lofy” symbolic mathematics fails, then one has to resort to “mundane” numeri-
cal mathematics, which helps to fnd approximate values of a number of individual roots
of the system. Ofen, for engineering calculations, for example, this is quite enough. A
second unofcial name for numerical mathematics (the ofspring of applied, not “pure”
mathematics) is approximate mathematics.
Figure 1.3 shows how the “numerical” Solve block solves our system of equations (two
roots x1 −y1 and x2 − y2) based on two diferent initial guesses for x and y.
We can change the initial assumptions and get other roots of our system of equations
using blind guesswork.
We will not discuss what specifc numerical method for solving equations is imple-
mented in the Find function. We will just check for the correctness of the solution—see
Figure 1.4, from which it can be seen that the right and lef parts of the equations afer the
substitution of the frst root difers from each other by a very small amount. To see very
small residual, the “arrow to the right” operator (symbolic mathematics) was used, since
the “equals” operator (numerical mathematics), displayed a misleading zero due to the lim-
ited number of characters afer the decimal point. Te same picture is also observed afer
the substitution of the second (“right”) root into the equations. Tese deviations (residu-
als) must be modulo less than the value stored in the system variable CTOL (Constraint
TOLerance—the accuracy of constraints: equalities and inequalities). By default, the value
of the CTOL variable is one-thousandth, but it can be increased or decreased by the user,
if necessary.
Sometimes a diferent accuracy of the solution is required for individual equations of
the system. In this case, the so-called scaling (normalizing) factors for equations help.
30 ◾ STEM Problems with Mathcad and Python

Solving systems of equations in the Python ecosystem is a bit more complicated than in
Mathcad. We need to fnd a way to solve systems of nonlinear algebraic equations, so we type
‘how to solve a system of nonlinear algebraic equations in Python’ in the browser address bar,
and in the frst line of the search engine output, we see an example of the solution of the prob-
lem. It turns out that we need the root function from the [Link] library to do this. We
have agreed to use either the Anaconda or WinPython distribution in our work, and scipy is
included in both of these distributions, so we don’t need to install anything.
Afer that, we have to learn how to use this function to solve systems of algebraic equa-
tions. We have two possibilities: the frst way is to do this directly in Jupyter Notebook:

from [Link] import root


print(root.__doc__)

Here we import the root function and then display the documentation for it in the Jupyter
Notebook.
Te second way is to search for a description of the function on the Internet by typing
‘scipy root’ in the browser.
Below we give a brief description of this function. Te function root passed two
positional arguments: f is the function that returns the error of solution of the system.
Additional parameters can be passed to f: f(p, *args); here p is a sequence or array; x0 is
initial approximation to the solution of the system of equations.
In addition, root may be passed optional named arguments: args—the tuple of values of
additional variables; tol—the accuracy of calculating the roots of the system of equations;
method—the method used. Te function returns an object. We are interested in the fol-
lowing attributes: success—has the value True if the search for a solution was successful,
x—the NumPy array with the solution found.
Let’s try to solve the same system of nonlinear equations as in Mathcad. To do this, write
a function that returns the error of the system of equations:

import numpy as np
def f(p):
x, y = p
return (1./[Link](x) + 5*y - x +10*y,
x - [Link](y) -1/y**2)

We need the NumPy import to calculate trigonometric functions. Tere is no cotangent in


NumPy, so replace it with 1/tan(x),
Let’s test the function of the solution obtained in Figure 1.3.
f(−3.081, −1.305)
Note that the function f is passed a tuple of variable values. Tis is required to solve a
system of nonlinear equations with the root function. Te solution in Figure 1.3 is not very
accurate:
(−0.010551, 0.0050)
Portrait of the Roots of the System of Equations ◾ 31

Te maximum error exceeds one hundredth. Let us refne the obtained solution with
root:

r = root(f, (-3.081, -1.305))


[Link], r.x, f((-3.08102055, -1.3046716))

We get the following result:

(True,
array([-3.08102055, -1.3046716 ]),
(1.8562928971732617e-12, 3.2208680167400416e-12))

Notice how the error has changed.


Te system under consideration has a nonunique solution; the convergence to a particu-
lar solution depends on the choice of initial approximation and the method used to solve
the system of equations.
Our system of two equations with two unknowns can be solved graphically by plotting
curves on a Cartesian plot representing the individual equations and seeing where the
curves intersect.
Figure 1.5 shows the creation of two user functions named fy and fx (with arguments x
and y) using the solve statement. All this can be solved by hand. But even if we rearrange
the terms, the presence of periodic trigonometric functions prevents a simple solution
from being obtained. As the reader might guess, we have specially selected rather complex
equations that can be solved graphically, without problems using the “correct” unknowns.
Figure 1.6 plots these functions in a somewhat unusual way. Usually, the argument (x) is
written along the abscissa axis, and the function itself (f(x)) is written along the ordinate axis.
In our chart, this is done in relation to the user-defned function fy(x). Te function fx(y) on
the chart is written diferently—the argument is on the ordinate axis, and the function itself is
on the abscissa axis. Tis “little trick” allows us to build a graph and see on it the roots of the
system of two equations, two of which, found in the solutions in Figure 1.3, are circled.
Note that the built-in Mathcad tools cannot graphically display the so-called closed
functions of the form f(x, y) = 0, but can only work with functions of the form “ f(x) is equal
to some expression with argument x”.
We also note in passing that the popular site, [Link], graphically solved our
system of equations, marking some roots with dots (Figure 1.7).
In Figure 1.6, two arrows, marking the numerical solutions shown in Figure 1.3, were
drawn on the graph manually. Te arrows start at the values of the initial assumptions and

FIGURE 1.5 Analytical solutions for individual equations of the system.


32 ◾ STEM Problems with Mathcad and Python

FIGURE 1.6 Graphical display of the roots of a system of two equations.

FIGURE 1.7 Graphical solution of a system of two equations on the WolframAlpha website.
Portrait of the Roots of the System of Equations ◾ 33

end at the roots that were obtained—at the intersection of the curves representing the two
equations of the system.
Te frst solution in Figure 1.3 (short arrow: x = −3.081, y = −1.305) is quite clear and
logical—the root was found near the point of the initial guess (x = −1.5, y = −2), so we could
refer to the initial assumption as an initial approximation. However, the second solution
(long arrow: x = 3.002, y = 0.674) may seem somewhat strange, since the roots that are closer
to the initial guess (x = −6, y = 3) were ignored. Moreover, if we set initial guesses that are
very close to the desired root (bring the beginning of the long arrow to the root located
under the beginning of the arrow x = −6 and y = 2, for example), then the Find function will
still stubbornly take us to the “far” root. Getting the Find function to work in the right
direction is almost impossible.
Pushkin’s lines come to mind here:

Why from the mountains and past the towers


Eagle fies, heavy and scary
On a stunted stump? ask him.

Why does the Find function from the initial assumption “fy” past the nearest root and
“sit on a stunted stump”—i.e., search out a distant root? How do we fnd the nearest root?
Introducing additional inequality constraints of type 1 < y < 2 into the Solve block with the
Find function results in an error.
One approach is to make a substitution and reduce the two equations to one.
Figure 1.8 creates a function named f with one argument x. Tis is done using another
useful symbolic math operator, the substitute operator. Further, a graph is constructed
using the resulting function near the region of interest to us for the change of the unknown
x. Te zero of the function is clearly visible on the graph (the point of intersection of the
curve with the abscissa axis), the more or less exact value of which is found using the
built-in root function. Tis will be the desired value x3, by which the value y3 was found
through the function f. A subsequent check shows that this is the desired root, which we
could not previously calculate using the Find function.
Te root function with four arguments does not rely on the frst guess, which occurs
when calling it with two arguments, but on the values of the ends of the interval where the
zero of the function is searched (the root of equation f(x) = 0). Te Find function, unfortu-
nately, cannot work with a given interval—it only works based on the initial guess, which
ofen fnds a solution far from the expected one.
We can deal with this state of afairs by understanding the essence of the numerical
method embedded in the Find function. And we can do it in a diferent, somewhat original
way, by constructing a portrait of the roots of the system of equations. To do this, we will
choose another system of equations with four roots, which we might call a heart pierced by
an arrow—see Figure 1.9.
Te lef side of Figure 1.9 shows a graphical representation of a system of two equa-
tions, one of which is the so-called closed heart equation (the formula was found on
the Internet), and the other is a straight-line equation (“an arrow piercing the heart”).
34 ◾ STEM Problems with Mathcad and Python

FIGURE 1.8 Finding the root of a system of two equations by substituting one equation into
another.

FIGURE 1.9 Portrait of the roots of the system of equations “Heart pierced by an arrow”.
(Levenberg–Marquardt method.)
Portrait of the Roots of the System of Equations ◾ 35

Te closed heart curve was plotted using the implicitplot2d function from Viacheslav
Mezentsev, which can be downloaded from [Link]
Portrait-of-roots-of-two-equations/m-p/776602.
Te right side of Figure 1.9 shows an image that can be called a portrait of the roots of a
system of two equations with two unknowns. Te area of the chart with the “pierced heart”
was scanned horizontally and vertically so that the numbers 1, 2, 3 and 4 points (initial
guesses) were marked, from which we use the Find function to get to one of the four roots
of the equations. If in the lef and right parts of this “portrait”, there is some predictability
(the right part, where the inlet is “flled with blood”), relative order (the solution is close
to the frst assumption), then in the middle of the portrait “everything is mixed up in the
Oblonsky house”. You can think about this portrait for a long time, or you can simply put
it in a frame and hang it in your room, intriguing guests with the essence of this “artwork
in an abstract style.” So, they say, I, a mathematician, see the image of a heart pierced by
an arrow! Weird, but beautiful! On the reverse side of this “portrait” (and there really is a
certain head with eyes, a nose, a mustache ...), you can place the heart itself, pierced by an
arrow. Better yet, draw this heart on top of the portrait…
Tere are four colors on our “portrait”. Here there is an association with the mathemati-
cal problem of the minimum number of colors needed to color the political map of the
world (Four-color theorem—Wikipedia ([Link])). But with a more complex system
and with a less sophisticated method of solving it, a ffh color may also appear marking
the points from where the solution was not found, and where the Find function returned
not a pair of numbers (a specifc root of the system of equations), but an error message
with a recommendation change the initial guess and/or calculation accuracy. In this sense,
the portrait of the roots of equations can be used to test the perfection of one or another
method for the numerical solution of systems of equations. Te higher the percentage of
the ffh color, the more it can be concluded that the applied solution method is less perfect.
Figure 1.10 shows a portrait of the roots of our system of equations if we change the
method of fnding it. A ffh color (white) is evident. Figure 1.10 on the right shows a

FIGURE 1.10 Portraits of the roots of the system of equations “Heart pierced by an arrow”. (On the
lef, the Conjugate Gradient method, on the right, Quasi-Newton.)
36 ◾ STEM Problems with Mathcad and Python

portrait of the roots of our system of equations if we change the method of fnding it. In
Figure 1.9, the Levenberg–Marquardt method was displayed, but in Mathcad 15, it can be
changed to the conjugate gradient method or the Newton method. Tere is white paint!
Tis indicates that the Levenberg–Marquardt method is better. It is also much faster. Tis
explains the fact that in the new version of Mathcad—in Mathcad Prime, the developers
lef only the Levenberg–Marquardt method, which is fundamentally diferent from the
rather similar conjugate gradient method and the Newton (pseudo-Newton) method. It
is elegant to draw such a conclusion without delving into the essence of the methods, but
simply by looking at their portraits.
An analysis of Figures 1.9 and 1.10 shows that the Levenberg–Marquardt method is bet-
ter than the conjugate gradient method and the Quasi-Newton method. Tis is one of the
reasons why only the Levenberg–Marquardt method was lef in Mathcad Prime, blocking
the possibility of moving away from it—i.e., switching to the methods of conjugate gradi-
ents or Newton.
Te arrow evokes Pushkin’s poem “Te Prose Writer and the Poet”.

What, prose writer, are you fussing about?


Give me any thought you want.
I will sharpen it from the end,
Flying rhyme opera,
I’ll put it on a tight string,
I will bend an obedient bow into an arc,
And there I will send at random,
And woe to our enemy!

It’s not about the arrow, but what if:


An applied mathematician could rewrite these stocks in this way:

“What are you bothering about, pure mathematician?


Give me the problem you want:
I will create a program for its numerical solution,
and...”

Yes, numerical mathematics and modern computers quickly and beautifully solve many
problems that seemed unsolvable by traditional analytical methods. As an example, we might
mention the fnite element method, without which solutions to the problems of fuid dynam-
ics, heat and mass transfer, resistance of materials, etc. are now inconceivable. Honestly, one
can argue about who is a poet and who is a prose writer—a “pure” mathematician or an
applied mathematician-programmer. Te success of solving a problem ofen lies in the joint
(hybrid) use of analytical and numerical methods. Let’s consider a specifc example.
Figure 1.11 shows a hybrid search for all roots of the “Heart pierced by an arrow” system
of equations. First, the symbolic operator, substitute, substitutes the second linear equation
(arrow) into the nonlinear equation (heart). Ten, the symbolic operator, coefs, extracts
Portrait of the Roots of the System of Equations ◾ 37

FIGURE 1.11 Hybrid solution to the problem “Heart pierced by an arrow”.

seven coefcients from the resulting sixth degree polynomial, with which the “numerical”
function polyroots fnds six zeros, of which four are real and two are complex. Next, the
correctness of the solution is checked, and the values of the ordinates of the original roots
of the equation system are calculated
If we change the position of the arrow, it may turn out that there are two real roots or
there are none at all. Te position of the arrow can be changed smoothly while observing
in the animation how the portrait of this task changes.
Te portrait of the roots of an equation has been discussed on the site [Link]
[Link]/t5/PTC-Mathcad/Portrait-of-roots-of-two-equations/m-p/776602. Tis discussion
ended with ... mysticism—see Figure 1.12. A site visitor, named Werner_E, accidentally dis-
covered this symmetrical case with two roots, generating a mystical scary portrait resem-
bling a Gorgon Medusa ([Link] or some kind of demon.
An animation is placed on the site—an arrow piercing the heart, smoothly rises from top to
bottom along the heart, outlining the woman’s face, which frowns in terrible grimaces (see
[Link]
image-dimensions/610x389?v=v2). Death grimaces caused by an arrow that hit the heart!
Te black color in Figure 1.12 fxes the regions of the initial values of the variables x and y, in
which the Find function cannot fnd the root and generates an error message. Te other two
colors fx the areas from which the lef or right root of the system can be found. When there
are four real roots, two more colors will appear on the portrait. Te portrait in Figure 1.12
was entrusted in Mathcad 15. On the same portrait created in Mathcad Prime, there would
be no black color—the portrait is drawn with only two or four colors. Te new Mathcad dif-
fers from the old one in terms of more advanced numerical mathematics embedded in the
Find function. Figure 1.12 is no longer a portrait in a fgurative sense, but in the truest sense
of the word. Tis portrait has some critical points near the mouth and on the forehead,
played with animation on the above site. Te video is accompanied by Wagner’s music “Ride
of the Valkyries”.
Ofen mathematicians see mystical numbers in their studies (the number of the Beast
666, for example) or mystical fgures (sacred geometry). And here our mathematical
research has generated whole portraits of mystical characters.
38 ◾ STEM Problems with Mathcad and Python

FIGURE 1.12 Mystical portrait of the roots of the system of equations “Heart pierced by an arrow”.
(a) Te portrait. (b) Five frames of the portrait. (Levenberg–Marquardt method, Mathcad 15.)

Note that the Find function also fnds complex roots of an equation very well. To do this,
it is necessary, but not sufcient, to specify complex initial assumptions—see Figure 1.13.
You can come up with a way to display the paths of all the roots of the system of equations,
and not just the real ones. Here you can move away from the plane to the volume—get not
a portrait, but... a sculpture. Get to work, reader!
Let us try to reproduce the situation in Figures 1.9 and 1.12 in Python. To do this, we
will fnd exact solutions to the system of equations using analytical methods. Recall that
we are solving a system of equations:

y = ax + b,

(x )
2 3
+ y 2 − 0.5 = 3x 2 y 3 .
Portrait of the Roots of the System of Equations ◾ 39

FIGURE 1.13 Calculation of complex roots of a system of equations.

We will change the coefcients � and � as we solve the problem. Te frst equation describes
the arrow, and the second the heart. We need to determine the solutions to this system of
equations. Both equations are polynomials: the arrow is a polynomial of the frst degree,
and the heart is a polynomial of the sixth degree.

import numpy as np
from sympy import symbols, expand, roots
def symbolic_heart_arrow(a=0.2, b=0.9):
x, y, z = symbols('x y z')
# symbolic expressions for heart and arrow
arrow = a*x + b
heart = (x**2 + y**2 - 0.5)**3 - 3*x**2*y**3
# substitute arrow to heart
heart = [Link](y, arrow)
# expand the polynomial
heart = expand(heart)
heart_roots_dict = roots(heart, x)
x_roots = []
for r in heart_roots_dict:
c_root = complex([Link]())
miltiplicity = heart_roots_dict[r]
for _ in range(miltiplicity):
x_roots.append(c_root)
x_roots = [Link](x_roots)
y_roots = a*x_roots + b
return [Link]([x_roots, y_roots])

Te coefcients a, b are passed to the function symbolic_heart_arrow. We write in it the


symbolic expressions for the arrow and the heart and, taking advantage of the linearity of
the arrow expression, substitute it in the expression for the heart using the subs method,
then open the parentheses with the expand function.
40 ◾ STEM Problems with Mathcad and Python

As a result, we get a polynomial of one variable x. With the function roots, we can fnd
all its roots, some of which will be complex. Roots returns a dictionary, its keys are the
roots, its values are multiples of the corresponding roots. We are going to use the values
of the roots in numerical procedures, so we further convert them to the NumPy array
x_rooots. Note that we have converted the values of the roots to complex numbers. Tis
is necessary because the roots function returns both real and complex numbers.
Next, we calculate y_roots using the expression for the arrow. Te function returns a
NumPy array with two rows and six columns with complex root values. Te frst row cor-
responds to x_roots and the second to y_roots.
We need this array to solve the system of equations for diferent initial approxima-
tions, exploring their areas of attraction. We will have to compare the solutions calculated
numerically with the roots determined by the symbolic_heart_arrow function.
We will visualize the relationship between the initial approximation—the point ( x 0 , y0 )
and the number of the root. In turn, we will match the root number with the color. In
doing so, we need to keep in mind that there may be a situation when the procedure will
not be able to solve the system of equations. In this situation, we will match the color with
the number zero, the frst root with the frst color, etc.

%matplotlib inline
import [Link] as plt
from [Link] import ListedColormap
colors = ('black', 'lightgray', 'blue', 'red',
'yellow', 'lime','white', 'purple',
'cyan', 'magenta')
root_cmap = ListedColormap(colors)
def visialize_areas_of_attractions(root_numbers, figsize=(6,5),
cmap=root_cmap, figname=None):
fig = [Link](figsize=figsize)
c = [Link](root_numbers[::-1,:], vmin=0,
vmax=len([Link]), cmap=cmap)
cb = [Link](c)
[Link]('off')
if figname:
[Link](f'{figname}.png', dpi=300, facecolor='white')

root_numbers = [Link](0, 15, 16, dtype=np.int16)\


.reshape(4,4)%len(root_cmap.colors)
visialize_areas_of_attractions(root_numbers)

Here we use the matplotlib library to display a picture. Te frst line allows to embed the
output of matplotlib graphics in the Jupyter Notebook even without calling show(). Te
second line imports matplotlib, and the third line provides a tool to create a color map, a
correspondence between colors and root numbers, using ListedColormap. To do this, we
specify a list of colors and create a color map.
Portrait of the Roots of the System of Equations ◾ 41

Te visialize_areas_of_attractions function draws regions of attraction for the solu-


tion of the system. It receives: root_numbers—a two-dimensional array containing num-
bers of roots corresponding to points of initial approximations ( x 0 , y0 ), fgsize—size of
drawing, cmap—matplotlib color map, fgname—fle name for saving drawing.
Te image is displayed with the function imshow, which receives a two-dimensional
array of root numbers, minimum (vmin) and maximum (vmax) root numbers, and a color
map (cmap). In imshow function, the vertical axis is downward, so we change the order
in which the rows of the root_numbers array are displayed. Next, we display a colorbar,
which represents the correspondence between colors and root numbers. Next, we turn of
the output of digitization on the coordinate axes.
If the parameter fgname is set, then we save the resulting fgure in the fle system. Tis
is how Figure 1.14 is constructed.
To test the function, a two-dimensional integer NumPy array of size 4 by 4 was created.
It displays squares of all colors included in the root_cmap color map, which was created
earlier.
Te root function operates with real values, so the conversion of complex values has to
be done manually. Tis is what the function heart_arrow_numerical was written for:

def heart_arrow_numerical(p, a, b):


x_re, x_im, y_re, y_im = p
xc = complex(x_re, x_im)
yc = complex(y_re, y_im)
arrow = yc - a*xc - b
heart = (xc**2 + yc**2 - 0.5)**3 - 3*xc**2*yc**3
return [Link], [Link], [Link], [Link]

FIGURE 1.14 Visialize_areas_of_attractions function test result.


42 ◾ STEM Problems with Mathcad and Python

Te function is passed an array p containing real and imaginary parts of x and y, and a,
b—parameters of the arrow that pierced the heart. Te complex values xc, yc are substi-
tuted into the expressions for the arrow and heart. Te function returns a tuple of real and
imaginary parts of errors for the system of equations for the arrow and heart.
Above we learned how to use symbolic methods to calculate the coordinates of the
points where the arrow pierces the heart for given a, b. Let’s use this data to test the heart_
arrow_numerical function:

# complex root value


xx = -0.46327506+1.25517086j
a, b = 0.2, 0.9
yy = a*xx + b
p = [Link](([Link], [Link], [Link], [Link]))
heart_arrow_numerical(p, a, b)

We got the following tuple of errors:

(0.0, 0.0, -2.72876e-09, 3.52446e-08)

Let’s make a test run of the root function:

r = root(heart_arrow_numerical, p, args=(a,b))
[Link], r.x

Run result:

(True, array([-0.46327506, 1.25517086, 0.80734499,


0.25103417]))

Te function get_heart_arrow_root is designed to calculate the number of the root


to which a given initial approximation (x0, y0) is attracted. It is given an array of roots
croots, a function f that describes the system of equations, an initial approximation (x0,
y0), additional parameters args, and a method for solving the system of equations method.
Te value of eps is used to check the closeness of the solution and the root.

def get_heart_arrow_root(croots, f=heart_arrow_numerical, x0=0.5,


y0=0.5,
args=(0.2, 0.9), method=None, eps=1e-4):
p = (x0, 0, y0, 0)
if method:
r = root(f, p, args=args, method=method)
else:
r = root(f, p, args=args)
# root is not found
if not [Link]:
return 0
Portrait of the Roots of the System of Equations ◾ 43

x_root = complex(r.x[0], r.x[1])


y_root = complex(r.x[2], r.x[3])
croot = [Link]([x_root, y_root], dtype=np.complex128)
# root number
err = [Link]([Link](croot - croots.T), axis=1)
iroot = [Link](err<eps)[0]
iroot = 0 if [Link]==0 else iroot[0] + 1
return iroot

Te execution of the function begins with preparing a tuple of initial approximations for
the function root.
Te system of equations is solved with the function root, optional parameter method
is passed to it. It may turn out that no solution is found, in this case, we assume that the
root number is zero. If the system is solved successfully, we compare the obtained solution
with the analytic solution stored in the croots array. We calculate the distance between the
obtained solution and the elements of the croots array and return the root number. Since 0
is reserved for when no solution, we add 1 to the root number in croots.
Now we need to put everything together in the visualize_roots function.
def visualize_roots(n=10,f=heart_arrow_numerical, a=0.0, b=0.2,
method='hybr', eps=1e-4,
area=(-1.5,-1.5,1.5, 1.5),
figsize=(6,5), figname=None):
xmin, ymin, xmax, ymax = area
xx = [Link](xmin, xmax, n)
yy = [Link](ymin, ymax, n)
field = [Link]((n, n), dtype=np.uint8)
croots = symbolic_heart_arrow(a=a, b=b)
for iy in range(n):
for ix in range(n):
xs, ys = xx[ix], yy[iy]
iroot = get_heart_arrow_root(croots, f=f, x0=xs,
y0=ys,
args=(a, b), method=method, eps=eps)
field[iy, ix] = iroot
# visualization
colors = ('black', 'lightgray', 'red', 'blue',
'yellow', 'lime','white', 'purple',
'cyan', 'magenta')
root_cmap = ListedColormap(colors)
visialize_areas_of_attractions(field, figsize=figsize,
cmap=root_cmap, figname=figname)

Te following parameters are passed to the function: n – number of partitions of the


area, in which the initial approximations are located, along the coordinate axes; f –
function returning the error of solving the system of algebraic equations. By default it is
44 ◾ STEM Problems with Mathcad and Python

heart_arrow_numerical; a – arrow parameters, method – name of method used in root


function when searching for solution of the system of equations (see description of root
function), eps used when determining numbers of roots, area – coordinates of cirner points
of rectangle from which initial approximations are taken to solve the system of equations,
fgsize – fgure size, fgname – fle name to save fgure.
Te sequence of operations performed by the function is simple. First, you unpack the coor-
dinates of the corner points of the rectangle (xmin, ymin, xmax, ymax) that contain the ini-
tial approximations of the solutions of the system of equations. In arrays xx, yy coordinates
of these points along coordinate axes are prepared. Next, we prepare a two-dimensional
array feld in which we write the numbers of the roots. Root numbers are calculated using the
get_heart_arrow_root function and written into the feld array.
Te visualization of the areas of attraction of the solutions of the system of equations
includes the creation of the colors array, the root_cmap color map and the rendering of the
feld array using the previously discussed function visialize_areas_of_attractions.
Te results of the visualization depend signifcantly on the method used. Figure 1.15
shows the visualization results for a heart pierced by a horizontal arrow.
Te reader is invited to experiment with diferent methods for solving systems of equa-
tions admissible with the root function as well as with the set of colors given by the colors
tuple in the visualize_roots function.
But let’s get back from the Python package to the Mathcad package. Graphical analy-
sis of the method for determining the quality of the numerical solution of problems on a
computer can be applied to a wide class of problems that seem diferent to us, but turn out
to be almost the same.
It is possible to build a portrait of a numerical search not only for the roots of the system
of equations but also for the minima of the function—the points where the function takes
the minimum value (locally or globally).
Figures 1.16 and 1.17 show a Mathcad numerical calculation of extreme points for
the Himmelblau function, ([Link]

FIGURE 1.15 Root attraction areas for a = 0 and b = 0.6 (lef fgure) and a = 0, b = −1 (right fgure).
Portrait of the Roots of the System of Equations ◾ 45

FIGURE 1.16 Numerical search for the maximum and four minima of a function of two arguments.

FIGURE 1.17 Portrait of a numerical search for the minima of a function of two arguments.
(Levenberg–Marquardt method.)

which, along with other similar functions (see [Link]


tions_for_optimization) is used to test optimization programs. Using the built-in Maximize
function in Mathcad, one maximum was found and using the antipodal function Minimize,
four minima were found. Tese extreme points are graphically displayed on the lef side of
Figure 1.17 on a contour plot: the highs and lows are surrounded by dotted lines of the
same level.
Te Minimize function also requires an initial guess, just like the Find function
(see above). Such a common feature of these two functions allows us to build also a portrait
of the numerical search for the minima of the function of two arguments—see the right side
of Figure 1.17. Te lines separating the colors on the right side of Figure 1.17 are some kind
46 ◾ STEM Problems with Mathcad and Python

FIGURE 1.18 Portrait of a numerical search for the minima of a function of two arguments.
(Conjugate Gradient method on the lef, Quasi-Newton on the right.)

of watershed lines (a drainage divide) that determine which streams and rivers will fow into
other large rivers, lakes, seas and oceans. Separate islands surrounded by the same color are
some anomalies that mark some tunnels through which water fows in the wrong direction.
Note in passing that the Minimize and Maximize functions difer from the Find func-
tion; in that, the Minimize and Maximize functions can be called without a Solve block.
Tis takes place in cases where there are no restrictions on the numerical search for a mini-
mum or maximum, as is the case here (see Figure 1.16).
Te portraits of numerical methods shown in Figures 1.9 and 1.17 have a common prop-
erty: on them you can see a certain point (let’s call it critical), in which all four colors
converge—from which you can get to the four roots of the system of equations (Figure 1.9)
or to four minima. When solving a system of equations, this point is located at the origin
of coordinates. When searching for minima, this point “climbed to the top of the moun-
tain”—is at the maximum point. When looking for a minimum, we kind of slide down the
mountain into one of the four holes.
In Mathcad 15, the problem of the numerical search for the Himmelblau function min-
ima can only be carried out using the Conjugate Gradient and Quasi-Newton methods.
Te Levenberg–Marquardt method is muted (see bottom of Figure 1.18). At the same time,
two almost identical portraits emerge (see Figure 1.17), which can be called chipped. Tere
are no white spots on them (the minimum is searched for from any point of the frst guess),
but there are “jagged” areas where the colors are mixed. In addition, straight lines are
drawn on the portrait.
Figure 1.19 shows which menu “falls out” in the Mathcad 15 environment when you
right-click on the Find or Minimize functions.
And here (see Figure 1.18) is how the portrait of fnding the minimum of the Himmelblau
function may look like when using a simple program that can be called “Two steps” (see
Figure 1.20).
Portrait of the Roots of the System of Equations ◾ 47

FIGURE 1.19 Menu for selecting and setting up methods for solving systems of equations and
optimization.

FIGURE 1.20 Te program “Two steps” search for a minimum.

Te program in Figure 1.20 has the following algorithm: From the starting point, steps
of length D are taken to the lef and to the right (the analyzed function has one argument),
steps to the lef, right, forward and backward (two arguments to the function), etc. up
to any dimension of the function. Ten a point is determined where the “descent from
the mountain” is the largest. You need to go to this point and repeat everything again.
Tis should be done until the steps from the next point show that we are going up (the
inner while loop). Here we halve the step and repeat everything. Tis is done until (the
outer while loop) the step becomes less than the predetermined value (we have 0.00001 in
Figure 1.20).
48 ◾ STEM Problems with Mathcad and Python

FIGURE 1.21 Portrait of a numerical search for the minima of a function of two arguments.
(TwoStep method for diferent values of the initial step D.)
Pictures in Figure 1.21 can be called—“Colored Square”. Kazimir Malevich painted his
famous “Black Square” in 1915 ([Link]
which became a kind of apotheosis of avant-garde art in fne arts. Our colored squares in
Figure 1.21 is a kind of apotheosis of minimalism when creating a program for fnding the
minimum of a function with a variable number of arguments.
If we have a continuous smooth function without restrictions (as is the case for the
Himmelblau function), then we can fnd its minima by solving a system of two equations
with two unknowns. Te frst equation is the partial derivative of a function of two argu-
ments with respect to the frst argument, and the second equation is the partial derivative
with respect to the second argument.
Figure 1.22 shows two curves plotted using the implicitplot2d function we used earlier.
Te curves intersect at nine points where the partial derivatives of the Himmelblau func-
tion are zero. Tese are the local maximum point (max), four minimum points (min) and
four so-called saddle points (sp). All these points can be seen on the contour plot—see
Figure 1.17.
Figure 1.23 shows the use of the solve symbolic mathematics statement, to fnd the
roots of a system of two partial diferential equations of the Himmelblau function. At frst
glance, the attempt turned out to be unsuccessful, such as is shown in Figure 1.2. But this
is only at frst glance. Te error message in Figure 1.23 does not say that there are no solu-
tions, but that the solution is too cumbersome, and because of this, it cannot be shown. Te
roots are stored in a matrix Ro with two columns (x and y values) and four rows (the roots).
Why four lines and not nine? Why are minimum points found, and not a local maximum
point or saddle points? Tis is some other mysticism of this chapter of the book.
We can end this mysticism in a fgurative and direct sense like this—by putting a deci-
mal point behind one zero of the system of equations—see Figure 1.24. In this case, the
answer is complete and without imaginary components.
Portrait of the Roots of the System of Equations ◾ 49

FIGURE 1.22 Plot of partial derivatives of the Himmelblau function.

FIGURE 1.23 Solving a system of equations composed of partial derivatives of the Himmelblau
function. (Option 1: without a decimal point.)

In Figure 1.25. a “portrait” of the solution of a system of equations composed of par-


tial derivatives of the Himmelblau function is shown, where the colored areas mark the
“spheres of interest” of certain roots.
On the site [Link]
Mathcad-15/m-p/777726, you can see the progress of solving the problem shown in Figures
1.20–1.23.
By the way, the problem we mentioned about four colors on the political map of the
world was solved in a hybrid way. First, it was proved analytically that four colors are
50 ◾ STEM Problems with Mathcad and Python

FIGURE 1.24 Solution of a system of equations composed of partial derivatives of the Himmelblau
function. (Option 2: with a decimal point.)

FIGURE 1.25 Portrait solution of a system of equations composed of partial derivatives of the
Himmelblau function.

sufcient for coloring any map, except for 1936 special maps. Ten the computer went
through these special cases and showed that four colors were enough for them. But even
now, in popular science magazines—in the April Fool’s issues, articles appear with contour
maps and the statement that it cannot be painted with four colors.
Te author’s method of drawing portraits of the roots of systems of equations (http://
[Link]/ochkov/Carpet/carpet_eng.htm) has not only aesthetic but also
practical applications for lens design, for example ([Link]
cfm?uri=oe-17-8-6436&id=178936).
Portrait of the Roots of the System of Equations ◾ 51

TASK FOR THE READER

1. Create functions of two arguments with an interesting portrait of roots.


2. Create your own custom procedure (see Figure 1.20) for fnding the roots of a system
of two equations with two unknowns and drawing its portrait.
3. Select the functions of the three arguments and suggest a way to create not a portrait,
but a sculpture of roots.
Chapter 2

Oval and Ellipse

T here is probably no user of a personal computer who has not at least once drawn
something using the Microsoft Paint graphic editor—a multifunctional, but at the
same time quite easy-to-use raster graphic editor, which is part of all Windows operating
systems from its first versions. The authors of this book finalized almost all the drawings
in the Paint environment—they “captured” the display screens using the PrintScreen key,
transferred the picture to the Paint environment, and edited it there.
In Paint, there is a panel of elementary graphic objects—segments of straight and curved
lines, ovals, rectangles, rectangles with rounded corners, polygons, triangles, etc.—see the
upper left corner in Figure 2.1.
If you click on the button with the image of an oval and with the corresponding drop-
down hint “oval”, then you can draw this same oval—a closed convex egg-shaped curve
(the term “oval” comes from the Latin word ovum—egg). To do this, place the cursor in
the right place in the drawing field, “stretch” the cursor and get an oval. If, while dragging
the cursor, you hold down the Shift button, then a circle will be drawn. Incidentally, the
oval, shown in Figure 2.1, was first created in Paint, and then the drawing itself was edited
in Paint—a point was drawn on the oval in the form of a crosshair and indicating a straight
line from the point to its coordinates in the lower left corner.
The best-known oval is the ellipse, and we have already dealt with it in Chapter 3
“Reading fiction and solving linear equations” (see Figure 3.16) and in Chapter 5 “The
Comet of 1811: Check Algebra for Harmony” (see Figures 5.3 and 5.6). Let’s check if the
oval that Paint draws is an ellipse! This oval is very similar to an ellipse.
If you move the cursor to the oval drawn in Paint, you can find out the coordinates in
pixels of this point of the oval (see Figure 2.1), which are counted from the upper left corner
of the drawing field. You can select several such points by pointing the cursor at different
places on the oval and writing these pairs of numbers in Mathcad in the form of a matrix
with the name M—see Figure 2.2. Such work is best done by two people at the same time
on two computers—one person scans an oval with a cursor and reports pairs of numbers
to another person, who writes them in a matrix in Mathcad. One of the authors of this
book at one time created a small utility that allows you to automate this work—move the

DOI: 10.1201/9781003228356-3 53
54 ◾ STEM Problems with Mathcad and Python

FIGURE 2.1 Oval drawn in paint.

FIGURE 2.2 Te coordinates of eight randomly chosen points of the oval shown in Figure 2.1.

mouse cursor along the curve, press its lef button and form a matrix with two columns
of numbers. So you can, for example, digitize a graph—make it interactive. According to
such a graph, you can set the value of the argument and see the value of the function. In
Mathcad 15, by the way, there is a Trace command that allows you to see the coordinates
of points on the graph.
From the matrix M (Figure 2.2), two vectors X and Y are further extracted, storing the
coordinates of the points on the oval separately horizontally and vertically.
Te canonical equation of an ellipse, the equation of an ellipse whose axes coincide with
the axes of the graph, is well known. Tis is x2/a2 + y2/b2 = 1, where a and b are the lengths of
the semi-axes of the ellipse, the distances from the center of the ellipse to its extreme points
vertically and horizontally. Tese points are called the vertices of the ellipse. If parameter
Oval and Ellipse ◾ 55

FIGURE 2.3 Solving the problem of points on an oval.

a is equal to parameter b, then we will get the equation of the circle—x2 + y2 = R2, where R is
the radius of the circle. Tis equation is essentially a recording of the Pythagorean theorem
with legs x and y and with the hypotenuse R.
Let’s assume that the oval we draw with Paint is an ellipse. Te axes of this ellipse are
parallel to the axes of the Cartesian plot, but its center is ofset horizontally and vertically
from the center of coordinates by distances that we will denote by the variables x0 and y0,
respectively. Such a problem is well known in mathematics and is called the problem of
reducing a second-order curve (an ellipse in our case) to a canonical form. Solving such a
problem in a general form, it is necessary to fnd not only the displacement of the ellipse
(the value of x0 and y0) but also the angle of rotation of the ellipse. But Paint, the oval’s
axes are always parallel to the graph axes. Terefore, the rotation angle does not need to
be found (it is equal to zero)—it is enough just to fnd the values of the variables x0 and
y0, and, at the same time, the values of the semi-axes of the ellipse a, b. We will do that
now—see Figure 2.3.
To solve the problem, it is enough to mark four points on the ellipse and solve four
equations with four unknowns. But for reassurance and to minimize possible inaccura-
cies when placing the mouse cursor on the oval, we will also use eight points. Let’s take
four points frst, and then we will add new points (new rows in the matrix M shown in
Figure 2.2) and see what happens.
So, with four points, the Find function (see Figure 2.3) produces a clear solution—a
vector with four elements. But afer adding additional points (ffh, sixth, etc.), the problem
becomes overdetermined—fve or more equations with four unknowns. Te Find func-
tion will not return a solution in the form of a vector of numerical values, but an error
message asking you to change either the guess values or the calculation accuracy value,
which is stored in the CTOL (Constraint TOLerance) system variable. Afer we change
the value of the CTOL variable from 0.001 (default) to 0.01 (see the top of Figure 2.3), the
Find function returns a vector solution, and not an error message. Te default precision of
one-thousandth of a pixel turned out to be excessive. One hundredth is enough here. Tis
feature of the numerical solution of problems should always be remembered.
56 ◾ STEM Problems with Mathcad and Python

An alternative approach is to replace the Find function with the MinErr function,
which, with the built-in value CTOL = 0.001, does not produce an error message, but the
value of its arguments minimizing (Min) the error (Error)—the discrepancy of the system
of equations, which in Figure 2.3 is shown by one equation, but in which the variables,
or rather, the coefcients X and Y, are not scalars, but vectors (see Figure 2.2): one vector
stores eight scalars. Tis is very convenient since when adding a new point on an ellipse,
nothing needs to be changed in the Mathcad sheet.
Note. Together with the CTOL system variable, the TOL system variable works; this
is responsible for the optimization accuracy—for the result produced by the Minimize
and Maximize functions. In earlier versions of Mathcad, where there were no Minimize
and Maximize functions, there was only one TOL variable. Optimization in these ver-
sions of Mathcad was carried out through the MinErr function. Ten the Minimize and
Maximize functions appeared, and the TOL variable was renamed CTOL, assigning a
diferent role to the TOL variable—storing the accuracy of the Minimize and Maximize
functions. When optimizing with constraints, the CTOL variable is responsible for the
accuracy of fulflling these same constraints.
In Figure 2.4, the graph shows the selected eight points and the ellipse itself. It turns
out quite clearly that the ellipse passes exactly through the points. But under the graph, for
clarifcation (not qualitatively, but quantitatively), the values of the residuals of the system
of equations are shown, from which it can be seen that only one point deviated from the
ellipse by an amount less than 0.001 pixel. So our decision to change the value of the CTOL
system variable from 0.001 to 0.01 was correct. But when the problem was solved for four
selected points, the residual of the system was much less than 0.001. However, this does not
mean that the problem was solved more accurately.
Te solution to the problem shown in Figures 2.2–2.4 in Python is as follows.
First of all, we import the libraries we need:

import numpy as np
import [Link] as plt
from [Link] import minimize

Here NumPy is used to work with arrays, and the minimize function from the [Link]-
mize library is used to determine the parameters of the ellipse by minimizing the error in
the solution of the equation in Figure 2.3. Te arrays of points of the ellipse X, Y are defned
as follows:

X = [Link]([276, 884, 1041, 200, 67, 679, 64, 1005], dtype=np.


float64)
Y = [Link]([ 78, 80, 503, 560, 207, 636, 458, 139], dtype=np.
float64)

Te minimize function must be passed a tuple of ellipse parameters and additional param-
eters X, Y, this function must return a single number—the error. In addition, the minimize
function must be passed an initial approximation array for the ellipse parameters and X,
Oval and Ellipse ◾ 57

FIGURE 2.4 Solving the problem of points on an oval.

Y arrays in the named argument args. We implement a function to calculate the error in
two steps: the frst function returns an array of errors, the second—a single number that
characterizes this error. Tis is exactly what the minimize function requires. We use the
standard deviation of the error for this.

def oval_func_err(p, X, Y):


a, b, x0, y0 = p
return (X—x0)**2/a**2 + (Y—y0)**2/b**2 - 1

def oval_func(p, X, Y):


return [Link](oval_func_err(p, X, Y))

Tis allows us to calculate the array of errors and the standard deviation for the calculated
in Mathcad in Figure 2.3.

p = (558.674, 305.514, 575.548, 334.951)


err = oval_func_err(p, X, Y)
err_std = oval_func(p, X, Y)
err, err_std
58 ◾ STEM Problems with Mathcad and Python

in Jupyter Notebook the result looks like this:

(array([-0.00515794, 0.00121827, -0.00332399, -0.00551432,


0.00400212,
0.00527364, 0.00062496, 0.00226787]),
0.003854554620327379)

Now let’s run the minimize function, using the data from Mathcad as the initial
approximation:

sol = minimize(oval_func, x0=p, args=(X, Y))

Te minimize function returns a complex data structure, we are only interested in


two attributes: success, which takes the value True if the minimization was successful,
and x is the result array. In Jupyter Notebook we display the results – values (a, b, x0,
y0):

[Link], sol.x

We have managed to reduce the error only slightly:

(True, array([558.69511481, 305.52872263, 575.74720167,


334.95073271]))

At the same time, we calculate the array of errors and the standard deviation:

oval_func_err(sol.x, X, Y), oval_func(sol.x, X, Y)

As a result, we get:

(array([-0.00486685, 0.00073309, -0.00399861, -0.00512002,


0.00457107,
0.00504728, 0.00119971, 0.00163443]),
0.003821444002863897)

In technical drawing before the era of computers and CAD, ovals were ofen built using a
compass and straightedge in the form of a fat closed curve made up of two pairs of arcs of
circles—see Figure 2.5. Tis drawing method was discussed at [Link]
t5/PTC-Mathcad/Oval-or-Ellipse-It-is-a-question/m-p/769030.
An oval constructed using arcs of two pairs of circles is a smooth closed surface, the cur-
vature of which has two values in four sections—the arcs of a circle. Te curvature of such
oval changes abruptly at the junction points of the large and small circles. In an ellipse,
the curvature of a closed line does not have jumps and changes smoothly. Terefore, in
the computer era, the oval, made up of four circles, was abandoned, and we began to build
ovals in the form of ellipses.
Oval and Ellipse ◾ 59

FIGURE 2.5 Drawing an oval using arcs of two pairs of circles.

But the opposite case is the case when an oval is called an ellipse rather than an ellipse
being called an oval.
One of the key episodes of Leo Tolstoy’s novel “Anna Karenina” is horse racing at the
hippodrome. Tolstoy describes the track of this hippodrome as follows: “Te race course
was a large three-mile ring of the form of an ellipse... ” (Anna Karenina, by Leo Tolstoy.
Translated by Constance Garnett).
Let us assume that the race track of the Krasnoe Selo (Red, Nice village) hippodrome
really had the shape of an ellipse (Figure 2.6). And it turned out to be so because it was
marked out on a huge meadow in the following way: two pegs F1 and F2 were driven into
the ground at a distance of 1 mile from each other (interfocal distance—value S); a rope of
length l was tied to them and pulled to point X. Te ellipse was then drawn with a perim-
eter L (3 miles) with this rope. Remember that an ellipse is not just a closed oval curve, but
a locus of points on a plane for which the sum of the distances to two foci is equal to a given
value. We have this amount—the desired value l, the length of the rope used for marking.
So, what should be the length of the rope l, tied with its ends to 2 pegs 1 mile apart, so
that the length of the ellipse drawn by such a rope is equal to 3 miles?
In Figure 2.6, in the right corner, the canonical equation of an ellipse is written—a
closed plane curve of the second order. Tese curves also include hyperbola and parab-
ola. A circle is a special case of an ellipse when its two foci are in the same place. It is
easy to prove that the length of the semi-major axis of our ellipse, a, is equal to half the
desired length of the rope. To do this, it is enough to pull the rope to the right or lef top
of the ellipse. Te length of the minor semiaxis, b, is also easy to determine by pulling
the rope to the upper or lower vertex of the ellipse, thereby creating two right-angled
60 ◾ STEM Problems with Mathcad and Python

FIGURE 2.6 Scheme of the problem about the Krasnoe Selo hippodrome.

triangles, in which the length of the hypotenuse is equal to half the length of the rope,
and the length of one of the legs is half the interfocal distance S. Tese will be the two
equations forming the system with three unknowns (a, b and l), the solution of which
will give the answer (see these equations under the canonical equation of the ellipse on
the right in Figure 2.6).
Figure 2.7 shows the solution to the problem. On the frst line, the function y(x, a, b) is
formed by solving the canonical equation of the ellipse, and the values of the variables L
and S are entered. Next, the Solve block solves three equations with three unknowns, the
last of which includes a defnite integral that returns the length of the half of the ellipse.
Te shape and dimensions of the racetrack are shown below the Solve block.
But the elliptical hippodrome is inconvenient because it does not have a straight section
where the stands for spectators are located. Let’s look for another form of hippodrome.
If, in the mathematical defnition of an ellipse, the sum is replaced by a product, then we
get the so-called Cassini oval. Tis oval can be called a multiplying ellipse by analogy with
an ordinary oval—a summing ellipse. Cassini ovals are the locus of points in a plane whose
distances to two foci are a constant, usually labeled a2.
Te site [Link]
discusses methods for constructing Cassini ovals in Mathcad. Two of them are shown in
Figures 2.8 and 2.9.
Te Cassini oval (a closed curve no longer of the second (ellipse), but of the fourth order)
is probably the most suitable curve for the hippodrome described in Leo Tolstoy’s novel
Anna Karenina, and here’s why.
If you increase the parameter a of the Cassini oval, then the frst two pear-shaped ovals
grow from two focal points, which, at a = c, (c is half the interfocal distance) will touch each
other, forming the so-called Bernoulli lemniscate. Tis infnity-shaped curve is beauti-
ful in itself, and its name is even more beautiful (lemniscate – “entwined with ribbons”).
Further, a single oval is formed with a “waist”, which will thicken and disappear at a cer-
tain point (see below).
Giovanni Cassini (1625–1712) believed that its oval better described the motion of two
celestial bodies than an ellipse (see Chapter 5). But he turned out to be wrong.
Oval and Ellipse ◾ 61

FIGURE 2.7 Solving the problem of the Krasnoe Selo Hippodrome.

Among the Cassini ovals, there is one in which, at two opposite vertices, not only the
frst, but also the second derivative is equal to zero (the “waist” disappears), and the sections
of the oval near these points are almost rectilinear. It is at these sections of the Cassini oval
that it is necessary to arrange stands for spectators, gazebos, and a tote. If necessary, this
oval can be cut in half, and the resulting semi-ovals can be moved apart, connecting their
ends with straight line segments. Te curvature of such a closed line will not undergo a step
change. Similar curves, in which the curvature smoothly changes from zero (straight sec-
tion) to a given curvature (circular arc), are used in the design of railway and tram tracks.
Among Cassini’s ovals, there is one nominal one—this is the previously mentioned
Bernoulli’s lemniscate, which by no means looks like an oval. For such an “oval”, we repeat,
62 ◾ STEM Problems with Mathcad and Python

FIGURE 2.8 Construction of the upper halves of the Cassini ovals (working with the formula).

a = c. But a real oval with two zero derivatives of the frst and second orders, very suitable
in shape for a hippodrome, can be given the name of Tolstoy’s oval. At the Tolstoy oval, the
parameter a is equal to half the focal length c, multiplied by the root of two. Te name of
this closed curve (Tolstoy oval) is recorded in the Encyclopedia of Mathematical Curves
([Link] [Link]
If the perimeter of the Tolstoy oval is equal to 3 miles (the hippodrome on the Krasnoe
Selo meadow), then it will have the dimensions shown in Figure 2.10.
Let’s try to draw a Cassini oval in Python.

%matplotlib inline
import numpy as np
import [Link] as plt
def cassini_oval_y(x, a, c):
x = [Link](x, dtype=np.complex128)
y = [Link]([Link](a**4 + 4*c**2*x**2) * x**2 - c**2)
return [Link]
n = 1000
Oval and Ellipse ◾ 63

FIGURE 2.9 Building a family of Cassini ovals (scanning).

x = [Link](-2,2,n)
c = 1
aa = (0.6, 0.95, 1, 1.2, [Link](2), 1.6, 1.7)
styles = 'k-', 'k--', 'k-.', 'k:'
[Link](figsize=(8,4))
for i, a in enumerate(aa):
[Link](x, cassini_oval_y(x, a, c), styles[i%len(styles)],
label=f'a={a:6.4f}', lw=3)
[Link](loc='best', fontsize=14)
[Link](0, 1.5);

Te cassini_oval_y(x, a, c) function calculates the vertical coordinate of the Cassini oval


for the given horizontal coordinates x and the values of the parameters, a, c. We wrote a
64 ◾ STEM Problems with Mathcad and Python

FIGURE 2.10 Oval of Tolstoy (the size of the Krasnoe Selo hippodrome, with a track length of 3
miles).

universal NumPy function that accepts both scalar x values and arrays to it. Tis is why we
force the x value passed to the function into a complex array. As in Mathcad, the function
returns only the real part of y, because the imaginary part has no physical meaning.
Next, the preparation of drawing a family of ovals is carried out, for which the mat-
plotlib library is imported, where the “magic” command, % matplotlib inline, allows us to
embed images in Jupyter Notebook. In addition, an array of x values on the segment [−2,
2] containing 1,000 elements is created, as well as an array, aa, with a values. In the styled
array, we store the line styles that will be used to draw ovals for various values of a.
Drawing is done in a loop. Te results are shown in Figure 2.11.
Notice how the labels in the legend are formatted and how the line styles are interleaved
when drawing the ovals.
Now, using NumPy, we cut the oval in half, and move the resulting semi-ovals apart,
so that the distance between them is l, and connect their ends with straight line segments.
We do this using the cassini_oval_with_line function:

def cassini_oval_with_line(n=1000, l=None):


a = [Link](2)
c = 1
x = [Link](-2, 2, n)
y = cassini_oval_y(x, a, c)
if l:
xl = [Link](-l/2, l/2, n)
yl = [Link](n)*cassini_oval_y(0, a, c)
Oval and Ellipse ◾ 65

FIGURE 2.11 A family of Cassini ovals drawn with matplotlib.

FIGURE 2.12 Family of curves composed of halves of the Cassini oval.

x = [Link]([x[:n//2]-l/2, xl, x[n//2:]+l/2])


y = [Link]([y[:n//2], yl, y[n//2:]])
ind = [Link](y>0)
return x[ind], y[ind]

Te number of partitions of the oval segments and the length of the straight line are passed
to the function. By default, a Cassini oval is drawn for a = √2 and l = 0. First, we calculate
the arrays of coordinates for the Cassini oval and only then form the arrays of coordinates,
xl, yl, for the horizontal line. Next, we combine the lef half of the oval, the horizontal
part, and the right half into x, y arrays. Tis is done using the NumPy hstack function.
Figure 2.11 shows that horizontal “tails” are formed on the lef and right of the oval, for
which y == 0. We cut them of with NumPy fansy indexing, excluding from consideration
the x, y elements for which y == 0.
66 ◾ STEM Problems with Mathcad and Python

As a result, we obtain a family of curves for various straight section lengths l, as shown
in Figure 2.12. But when the value of l is greater than zero, the curve is no longer an oval.
An oval, as fxed in geometric optics, is a closed plane curve that a straight line can cross
no more than two times, which can have no more than two common points with a straight
line. We have in Figure 2.12 a horizontal line for y = −1 or 1 and for l > 0 which has an inf-
nite number of points in common with a closed curve. Te curves in Figure. 2.12 for l > 0
are no longer ovals, but each is a closed curve called a stadium—see [Link]
org/wiki/Stadium_(geometry). Only the classic stadium has half circles at the ends. Our
stadium has at the ends halves of Tolstoy’s oval. Te curvature of such a closed planar curve
will not change abruptly at the four points where the straight line segments end.

TASKS TO THE READER

1. Construct and explore Cassini’s three-focal oval.


2. Find and solve other mathematical problems encrypted in literary works (see for
example [Link]
Chapter 3

Reading Fiction and


Solving Linear Equations

I n the story, “Tutor”, the great Russian writer Anton Chekhov, describes how a tutor—
a seventh-grade student of the gymnasium, prepares a boy to enter the second grade of
the gymnasium. Together they are trying to solve the following math problem:
“The merchant bought 138 arshins1 of black and blue cloth for 540 roubles. How many
arshins did he buy of each, if the blue cost 5 roubles per arshin, and the black 3 roubles?”
Then:
“This problem is, strictly speaking, algebraic,” he (the tutor) says.—It is possible to solve
it with X and Y. However, you can do it this way: I, here, divided... you understand? Now,
now, you have to subtract... do you understand? Or, here’s what... Solve this problem for me
by tomorrow... Think...”
Petya (he is preparing for the second grade of the gymnasium) smiles balefully. Udodov
(Petya’s father) also smiles. They both understand the teacher’s confusion. The 7th grade stu-
dent is even more embarrassed, gets up and starts walking from corner to corner.
“You can solve it without algebra,” Udodov says, reaching out to the abacus and sighing.—
Here, if you please see...
He clicks on the abacus,2 and he gets 75 and 63, which is what was needed.
Nowadays, Udodov would not click on an abacus, but on the keys of a computer key-
board. Figure 3.1 shows the procedure for solving the problem of the merchant and the
cloth in the mathematical program Mathcad.
There are three areas in the Solve block: the area of initial guess values for the solu-
tion, the area of constraints, where not only equalities (equations, as in Figure 3.1),
but also inequalities can be written, and the area where the Find function is placed.
According to a special numerical algorithm, the Find function changes the values of
its arguments, starting from the initial guesses, until the equations turn into identities.

1 Arshin: an obsolete Russian measure of length, equal to 71.12 cm.


2 [Link]

DOI: 10.1201/9781003228356-4 67
68 ◾ STEM Problems with Mathcad and Python

FIGURE 3.1 Solving the problem of the merchant and the cloth on the computer (option 1).

FIGURE 3.2 Solving the problem of the merchant and the cloth on the computer (option 2).

Tey are only approximately identities: the right and lef sides of the equations should
not difer in absolute value from each other by more than one-thousandth (a default
that can be changed).
Initial guesses for the solution are indicated if there are two or more solutions. Tis is
ofen the case when the equations of the system are nonlinear. But the system of the two
merchant and cloth equations is linear. Terefore, to solve it, it is better to use not the
Find function, but special computer tools for solving systems of linear algebraic equations
(SLAE), as shown in Figure 3.2.
In Figure 3.2, a square matrix M of the coefcients that multiply the unknowns, and a
vector, v, of the constants on the right-hand side of the equations, form the matrix equa-
tion, M x = v, where x is a vector of unknowns to be found. Te determinant of the matrix
M is not equal to zero (it equals minus two). Tis means that the SLAE has one solution,
which is found by vector multiplication of the inverse matrix of coefcients, IM, by the vec-
tor of constants, v. Everything is simple and clear!
Reading Fiction and Solving Linear Equations ◾ 69

In the Python ecosystem, the task is just as easy, but you need to import libraries for solv-
ing linear algebra problems. Tese libraries are found in the NumPy and SciPy packages:

import numpy as np
import [Link] as la
import [Link] as lanp

Currently, NumPy works best with arrays, and everything related to linear algebra is best
taken from SciPy, since it updates procedures more frequently, maintaining NumPy rou-
tines for compatibility with previously written code. Here we have imported both libraries.
In terms of composition, both libraries are almost the same, but there are diferences that
need to be consulted in the documentation. Te solution to the problem repeats what has
been done in Mathcad, the only diferences are in the way of forming the arrays.

A = [Link]([[1,1],[5,3]])
b = [Link]([138, 540])
x = [Link](A, b)
print(f'A=\n{A} \nb={b}')
print(f'det(A)={[Link](A)}')
print(f'rank(A)={lanp.matrix_rank(A)}')
Ainv = [Link](A)
x = Ainv @ b
print(f'Ainv=\n{Ainv}\nx={x}')

Please note that we mainly use SciPy tools, but some convenient functions remain in
NumPy, we had to calculate the matrix rank using this package. Te result of executing the
code snippet looks like this:

A=
[[1 1]
[5 3]]
b=[138 540]
det(A)=-2.0
rank(A)=2
Ainv=
[[-1.5 0.5]
[ 2.5 -0.5]]
x=[63. 75.]

Let’s change Chekhov a little and solve the following problem:


“Two merchants each bought 138 arshins of black and blue cloth, the frst paying 540
roubles, the second 1620 oroubles. Te question is, how many arshins of each cloth
did they buy, if the frst merchant bought cloth at a price of 5 roubles per arshin for
blue and 3 roubles per arshin for black, while the second paid the exorbitant price of
15 roubles per arshin for blue and 9 roubles per arshin for black.”
70 ◾ STEM Problems with Mathcad and Python

FIGURE 3.3 Computer solution of the problem of two merchants and cloth.

For the new problem, the matrix of coefcients for unknowns is not square, since the
new SLAE has three equations for two unknowns. Te system, as mathematicians say, is
underdetermined. Te determinant of a rectangular matrix cannot be calculated to make
sure that it is non-degenerate and that there is a solution. Here we are helped by an impor-
tant theorem of linear algebra (the Kronecker – Capelli theorem, Rouché – Capelli theo-
rem), which states that a SLAE is consistent (has at least one solution) if and only if the rank
of its main matrix M is equal to the rank of its augmented matrix AM. If the number of
unknowns is equal to the rank of the main matrix, then the solution is unique. We will not
explain what the rank of a matrix is (all of this can be viewed on the Internet), but simply
show how the rank is calculated in Mathcad—Figure 3.3.
Figure 3.3 shows that the ranks of the main and augmented matrices are two, and the
number of unknowns (the number of columns of the matrix M) is also two. Hence, the
conclusion—the SLAE has one unique solution, which is found using the lsolve function
and, by the way, we have already described (Figure 3.2) the vector multiplication of the
inverse matrix of coefcients by the vector of constants. Note that even many experienced
mathematicians believe that an inverse matrix can only be obtained from a square one.
But here’s what you can read on the Internet: “A square matrix is invertible if and only
if it is non-degenerate, that is, its determinant is not zero. For non-square matrices and
degenerate matrices, inverse matrices do not exist. However, it is possible to generalize this
concept and introduce pseudoinverse matrices similar to inverse ones in many ways.” Yes,
a non-square matrix cannot be raised to the power −1, and thus be inverted in the same
way we did with a square matrix—see Figure 3.2. But Mathcad’s built-in function, geninv
(gen – general, generalized; inv – invert: see Figure 3.3) allows us to fnd the inverse of
Reading Fiction and Solving Linear Equations ◾ 71

a rectangular matrix. Te test showed that the multiplication of the original non-square
matrix M by the non-square inverted matrix IM gave the answer as the identity matrix—a
square matrix, the main diagonal of which consists of ones. Te solution in Figure 3.3 also
uses the built-in Mathcad lsolve function, which is also designed to solve systems of linear
(l) algebraic equations. But we also worked with the geninv function here’s why.
Te fact is that the lsolve function is deleted in the free version of Mathcad Prime—in
Mathcad Express. Te developers forgot to delete the geninv function.
Let’s solve the above problem using Python. Te sequence of actions is the same, only
the names of the functions are changed.

M = [Link]([[1,1], [5,3],[15, 9]])


v = [Link]([[138], [540], [1620]])
AM = [Link]([M, v])
print(f'M=\n{M}\nv=\n{v}')
print(f'AM=\n{AM}')
print(f'det(AM)={[Link](AM)}, rank(AM)={lanp.matrix_rank(AM)}')
Mpinv = [Link](M)
x = Mpinv@v
print(f'x=\n{x}\nMpinv@M=\n{Mpinv@M}')

Te result of executing the code snippet looks like this:

M=
[[ 1 1]
[ 5 3]
[15 9]]
v=
[[ 138]
[ 540]
[1620]]
AM=
[[ 1 1 138]
[ 5 3 540]
[ 15 9 1620]]
det(AM)=-8.862475970486035e-15, rank(AM)=2
x=
[[63.]
[75.]]
Mpinv@M=
[[ 1.00000000e+00 -1.33226763e-15]
[ 3.55271368e-15 1.00000000e+00]]

Here, perhaps, it is necessary to make a remark about the pseudoinverse matrix. Te prod-
uct of the pseudoinverse matrix by the original matrix is not always equal to the identity
matrix. Let’s give an example:
72 ◾ STEM Problems with Mathcad and Python

M = [Link]([[1,2,3], [4,5,6]])
Mp = [Link](M)
print(f'Mp@M\n{Mp@M} \nM@Mp\n{M@Mp}')

Te result of the multiplications is shown below:

Mp@M
[[ 0.83333333 0.33333333 -0.16666667]
[ 0.33333333 0.33333333 0.33333333]
[-0.16666667 0.33333333 0.83333333]]
M@Mp
[[1.00000000e+00 2.22044605e-16]
[0.00000000e+00 1.00000000e+00]]

In fact, you need to check the identities M @ Mp @ M and Mp @ M @ Mp:

print(f'M\n{M}\nMp\n{Mp}')
print(f'M@Mp@M\n{M@Mp@M}')
print(f'Mp@M@Mp\n{Mp@M@Mp}')
M
[[1 2 3]
[4 5 6]]
Mp
[[-0.94444444 0.44444444]
[-0.11111111 0.11111111]
[ 0.72222222 -0.22222222]]
M@Mp@M
[[1. 2. 3.]
[4. 5. 6.]]
Mp@M@Mp
[[-0.94444444 0.44444444]
[-0.11111111 0.11111111]
[ 0.72222222 -0.22222222]]

Let’s slightly change our redefned system shown in Figure 3.3.


Suppose the second merchant paid not 1,620, but 1,600 roubles for the cloth. At frst,
he was deceived (if you can’t be fooled—you won’t buy!) by the infated prices, but then
they made a small comforting discount. Tis is a common practice of trade; prices frst go
up and then are discounted. In Turgenev’s “Spring Waters” you can read about Gemma’s
failed fancé, Mr. Kluber, a clerk in a fashionable store in the German city of Frankfurt:
“Selling cloth and velvet and swindling the public, stealing from it “Narrep-, oder Russen-
Preise”(stupid, or Russian prices) – that’s his ideal!”.
Figure 3.4 shows the solution to this slightly modifed problem of two merchants and cloth.
Te rank of the main matrix remains equal to two, and the rank of the augmented
matrix becomes equal to three. According to the Rouché–Capelli theorem, the system
is no longer consistent—it has no solutions. However, the built-in functions lsolve and
Reading Fiction and Solving Linear Equations ◾ 73

FIGURE 3.4 Computer solution of the problem of two merchants, cloth and a trade discount
(option 1).

FIGURE 3.5 Computer solution of the problem of two merchants, cloth and trade discount (option 2).

geninv produce an answer that must be checked. It turns out to be incorrect—the clos-
est to the correct one: for such values of the unknowns, the residual of the system will
be minimal.
Figure 3.5 shows the operation of the Find and MinErr functions when solving the
problem of two merchants, one of whom was frst deceived and then ofered a 20-rouble
discount.
Te Find function refused to solve the problem, giving an error message, and the
MinErr function returned the same incorrect answer that is shown in Figure 3.4.
74 ◾ STEM Problems with Mathcad and Python

FIGURE 3.6 A graphic illustration of a computer solution to the problem of two merchants, cloth
and a trade discount.

In Figure 3.6, you can see that the three lines (these are our three equations shown in
the Constraints areas in Figure 3.5) do not intersect at the same point. Terefore, the Find
function (Figure 3.5) did not return an answer. Te MinErr function gave the answer
shown as a dot in Figure 3.6.
Ditto in Python:

M = [Link]([[1,1], [5,3],[15, 9]])


v = [Link]([[138], [540], [1600]])
AM = [Link]([M, v])
print(f'M=\n{M}\nv=\n{v}')
print(f'AM=\n{AM}')
print(f'det(AM)={[Link](AM):3.0f}, ' +\
f'rank(AM)={lanp.matrix_rank(AM):3.0f}')
Mpinv = [Link](M)
x = Mpinv@v
print(f'x=\n{x}\nMpinv@M=\n{Mpinv@M}')

Te result of executing the code snippet:

M=
[[ 1 1]
Reading Fiction and Solving Linear Equations ◾ 75

[ 5 3]
[15 9]]
v=
[[ 138]
[ 540]
[1600]]
AM=
[[ 1 1 138]
[ 5 3 540]
[ 15 9 1600]]
det(AM)= 40, rank(AM)= 3
x=
[[60.]
[78.]]
Mpinv@M=
[[ 1.00000000e+00 -1.33226763e-15]
[ 3.55271368e-15 1.00000000e+00]]

Let’s change the conditions of the problem even more radically.


“Te merchant bought 300 arshins of black and blue cloth, as well as cloth the color
of “Navarino smoke with fame3” for 1,500 roubles. Te question is, how many
arshins of each did he buy if the blue one cost 5 roubles per arshin, the black one was
3 roubles per arshin, and the “Navarino” cloth was 10 roubles per arshin?”
You can read about a cloth with the exotic “Navarino” color (which is why it is the most
expensive) in Gogol’s “Dead Souls”. A clerk in a shop sold Chichikov such cloth, which had
been previously used for advertising. “I brought it to the light, even when I came out of the
shop and viewed it there, squinting in the light, I said:” Excellent color. Cloth of Navarino
smoke with fame.”
Tis new task is underdetermined—see Figure 3.7.
Te rank of the main matrix is two. Te rank of the augmented matrix is also two. But
now there are three unknowns (matrix columns). According to the Rouché–Capelli theo-
rem, such a SLAE has an infnite number of solutions, one of which (fractional) is shown
in Figure 3.7. Tis result checks out.
Te underdetermined problem of a merchant and three kinds of cloth can be solved
using the geninv function, which, unlike the lsolve function, also works in the free (freely
distributed) program Mathcad Express. But this function will need to be improved, as it
fails with an argument matrix with fewer rows than columns. Tis refnement is shown in
Figure 3.8: Te original matrix is transposed, and then the matrix returned by the geninv
function is also transposed. ([Link]

3 A dark shade of gray, a fashionable color of cloth, which appeared afer the victory of the Anglo-Russian-French squad-
ron over the Turkish feet in Navarino Bay in 1827 during the liberation of Greece from the Ottoman yoke (https://
[Link]/wiki/Battle_of_Navarino).
76 ◾ STEM Problems with Mathcad and Python

FIGURE 3.7 Computer solution of the problem of a merchant and cloth of three colors (option 1).

FIGURE 3.8 Working with the “free” geninv feature when solving an underdefned SLAE.

Te answer obtained with the geninv function (Figure 3.8) turned out to be more com-
plete than the answer obtained with the lsolve function (Figure 3.7): there is no need to
additionally calculate the amount of cloth at the price of 10 roubles per arshin.
Te solutions in Figures 3.7 and 3.8 show that:

1. Free is not always worse than paid.


2. “You never know what you can do until you try.” And in the fnished programs, there
may be faws that need to be corrected.
Reading Fiction and Solving Linear Equations ◾ 77

FIGURE 3.9 Te problem of the cloth and the deceived merchant.

By the way, the non-integer solution will be obtained if, in the problem of three merchants
and cloth of two colors (Figure 3.4), we leave only the deceived merchant who paid 1,600
rubles for the cloth – Figures 3.4–3.9.
It is not difcult to reproduce the solution to the above problem in Python:

M = [Link]([[1,1,1], [5,3, 10]])


v = [Link]([[300], [1500]])
AM = [Link]([M, v])
print(f'M=\n{M}\nv=\n{v}')
print(f'AM=\n{AM}')
print(f'rank(AM)={lanp.matrix_rank(AM)}')
Mpinv = [Link](M)
x = Mpinv@v
print(f'x=\n{x}\nM@Mpinv@M=\n{M@Mpinv@M}')

Te result is:

M=
[[ 1 1 1]
[ 5 3 10]]
v=
[[ 300]
[1500]]
AM=
[[ 1 1 1 300]
[ 5 3 10 1500]]
rank(AM)=2
x=
[[111.53846154]
[134.61538462]
[ 53.84615385]]
M@Mpinv@M=
[[ 1. 1. 1.]
[ 5. 3. 10.]]

We can see in Figure 3.10 the solution to this underdetermined problem using the Find func-
tion with two diferent guess values giving diferent answers, both of which are correct. Te
second answer (300, 0, 0) is correct from the standpoint of mathematics, but incorrect in the
78 ◾ STEM Problems with Mathcad and Python

FIGURE 3.10 Solving the problem of a merchant and cloth of three colors using the Mathcad
function Find.

essence of the problem, which implies that the lengths of each of the clothes must be positive.
If you supply fractional numbers for the initial guesses, then fractional answers can result.
However, the question implies the lengths must be integers, and the conditions of the prob-
lem are specially selected. Cloth was usually measured in shops in yardsticks without frac-
tional parts, which makes it easier to solve such problems when doing so without a computer.
Figure 3.11 shows how the [Link] site, which is in great demand by school-
children and students around the world, solved the problem of cloth of three colors, giving
not one solution out of many depending on the frst approximation (Figure 3.10), but the
formulas, by which, by setting the value of the number n, one can fnd the values of the
unknowns x (blue cloth), y (black cloth) and z (cloth of the color of Navarino smoke with
fame). Here, a caveat is also added to the system of equations, namely, that the answers
must be integer. Tere is no such tool in the Mathcad environment, which is why we
switched to [Link] (the cloud version of the Mathematica package).
Yes, there are no integer solution tools for equations and systems in Mathcad. But in
Mathcad, you can write a small program (Figure 3.12) with two for loops and with an if
construct, which will go through all the options for buying 300 yards of cloth in three col-
ors for the cost of 1,500 roubles in total and will print all 42 options, and not just the four
shown in Figure 3.10. In the program in Figure 3.10, the augment function already known
to us is used, expanding the matrix M, attaching to it another column with a solution when
the purchase price is equal to 1,500 rubles. Te fact that exactly 300 yards of cloth of difer-
ent colors were bought is recorded in the expression z ← 300—x—y.
In Python, it is easy to reproduce the search for integer solutions, and at the same time
calculate their number and maximum error:

eps = 1e-3
x = [Link](1, 300, 300, dtype= np.int32)
y = [Link](1, 300, 300, dtype= np.int32)
X, Y = [Link](x, y)
Z = 300—X—Y
Reading Fiction and Solving Linear Equations ◾ 79

FIGURE 3.11 Solving the problem of a merchant and cloth of three colors using the WolframAlpha.
com website.

Err = [Link](5*X + 3*Y + 10*Z—1500)


inds = [Link](Err<=eps)
xs = x[inds[1]]
ys = y[inds[0]]
zs = 300—xs—ys
err = 5*xs + 3*ys + 10*zs—1500
sol = [Link]([xs, ys, zs])
print(f'solution: x, y, z =\n{sol}')
print(f'solutions= {len(xs)} \nmax error= {[Link](err)}')

Here we have used NumPy’s array capabilities. In order to iterate over all possible values
of x and y, two-dimensional arrays X and Y were created, and the error values err were
calculated on them. Only those values x, y for which the error is close to zero correspond
to the solution of the problem. Te indices in the x, y arrays corresponding to the solu-
tion to the problem are calculated using the NumPy where () function, which returns a
80 ◾ STEM Problems with Mathcad and Python

FIGURE 3.12 Solving the problem of a merchant and cloth of three colors using the Mathcad
program.

two-dimensional array of indices. To obtain solutions xs, ys, zs, it turned out to be enough
for us to index the original arrays x, y with integer arrays obtained using where (). Here,
working with arrays, we have never used Python loops, which are slow. For verifcation, we
computed an array of errors err. Te calculation result is shown below:

solution: x, y, z =
[[293 286 279 272 265 258 251 244 237 230 223 216 209 202 195 188
181 174 167 160 153 146 139 132 125 118 111 104 97 90 83 76
69 62 55 48 41 34 27 20 13 6]
[ 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80
85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165
170 175 180 185 190 195 200 205 210]
[ 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32
34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66
68 70 72 74 76 78 80 82 84]]
solutions= 42
max error= 0

Tere were 242 solutions in total, and the error is exactly 0.


Commentary on cloth and literature.
Te theme of cloth is ofen seen in Russian and world literature. Take Gogol with his
“Marriage”, for example.
Reading Fiction and Solving Linear Equations ◾ 81

Podkolesin. Have you seen, however, that he has other tailcoats? Afer all, he sews
for others too?
Stepan. Yes, he has a lot of tailcoats.
Podkolesin. However, afer all, the cloth will be on them, tea, worse than on mine?
Stepan. Yes, it’ll be clearer than yours.:
Arina Panteleimonovna. And the merchant, if he wants, will not give a cloth; but
a nobleman is naked, and a nobleman has nothing to wear.

Further still:
Cloth, afer all, is English! Afer all, what is it worn! In 1795, when our squad-
ron was in Sicily, I bought it as a midshipman and sewed a uniform from it; in
1801, under Pavel Petrovich, I was made a lieutenant—the cloth was completely
new; in 1814 made an expedition around the world, and that’s just a little worn at
the seams; in 1815 I retired, only redesigned it: I have been wearing it for 10 years,
it is still almost new.
All!
Here is another interesting literary and mathematical problem, which can be
called “Te Dostoevsky Matrix”.
In the story, “Te Gambler”, by this great Russian writer, who is well known in
the West, you can fnd seven quotes in which the rates of European currencies in
the second half of the 19th century are converted. Behind the quotation number
in brackets is the equation to which the quotation is reduced.

Quote 1 (120 rubles = 100 thalers + 4 Friedrichsdoor + 3 forins)


“You will get them immediately,” the general replied, blushing a little, rummaged in his
bureau, consulted a book, and it turned out that he had my money for about one hundred
and twenty roubles.
- How can we count,—he began,—we must translate into thalers. But take 100 thalers, in
round numbers—the rest, of course, will not be lost.
and further
You should get these four Friedrichsdoors and three forins from me for the settlement here.
Quote 2 (700 guilders = 700 forins)
Pauline just got angry when I gave her only 700 guilders.
and further
Listen and remember: take these 700 forins and go to play, win me as much as you can on
roulette; I need money by any means now.
Quote 3 (5 friedrichsdoor = 50 guilders)
I began by taking out 5 friedrichsdorfs, that is, 50 guilders, and put them on a rosary.
Quote 4 (13,000 forins = 8,000 rubles)
- Yes, sir, here she took and won 12,000 forins! What is 12, but gold? With gold, almost 13
will come out. How much is coming our way? Six thousand, or what?
I replied that it was over seven, and at the current rate, perhaps, it will reach eight.
Quote 5 (4,000 forins = 4,000 guilders)
82 ◾ STEM Problems with Mathcad and Python

FIGURE 3.13 Solving the problem of exchange rates (Dostoevsky’s matrix).

“Oui, madame,” the croupier confrmed politely, “ just as any bet must not exceed 4,000 fo-
rins at once, according to the rules,” he added to the explanation.
I placed the highest bet allowed, 4,000 guilders, and lost.
Quote 6 (420 Friedrichsdors = 4,000 Florins + 20 Friedrichsdors)
She went to collect exactly 420 Friedrichs dors, that is, 4,000 forins and 20 Friedrichsdors.
Quote 7 (25,000 forins = 50,000 francs)
- Pauline, here’s 25,000 forins—that’s at least 50,000 francs.
You can, of course, solve this system of equations in your head, gradually reducing it
to one equation. You can also “clamp” these seven equations in the Given-Find “vice” (see
Figures 3.1, 3.5 and 3.10), and solve the problem. But it is possible to create Dostoevsky’s
“matrix and vector”, which will convert the currencies quoted in Te Gambler, describing
the complex and intricate fnancial relations of the characters in this story. Tus, we will
reduce the problem to solving the SLAE—see Figure 3.13.
Te lsolve function, as shown earlier, can produce a rather imprecise solution (see
Figures 3.4 and 3.6). Te ranks of the main and extended Dostoevsky matrices suggest that
there is only one solution.
When implemented in Python, we can use the least-squares method to solve systems of
linear equations with rectangular matrices.

M = [Link]([
[100, 4, 3, 0, 0],
[0, 0, -700, 700, 0],
[0, 5, 0, -50, 0],
Reading Fiction and Solving Linear Equations ◾ 83

[0, 0, 13000, 0, 0],


[0, 0, 4000, -4000, 0],
[0, 420-20, -4000, 0, 0],
[0, 0, 25000, 0, -5000] ])
v = [Link]([120, 0, 0, 8000, 0, 0, 0])
exc, res,rank, sv = [Link](M, v)
print(f'rank = {rank}')
print(f'condition number of the matrix = {sv[0]/sv[-1]:6.3e}')
print(f'thaler = {exc[0]:6.2f} roubles')
print(f'friedrichsdor = {exc[1]:6.2f} roubles')
print(f'florin = {exc[2]:6.2f} roubles')
print(f'gulder = {exc[3]:6.2f} roubles')
print(f'franc = {exc[4]:6.2f} roubles')

Te lstsq() function, which implements the least-squares method, returns interesting addi-
tional information: exc is the solution to the system of equations, res are residues, rank is
the rank of the matrix, sv are the singular values of the matrix. Te latter can be used to
determine the condition number of the matrix (the ratio of the maximum to the minimum
singular number).
Te result, of course, turns out to be the same:

rank = 5
condition number of the matrix = 2.909e+02
thaler = 0.94 roubles
friedrichsdor = 6.15 roubles
florin = 0.62 roubles
gulder = 0.62 roubles
franc = 3.08 roubles

Te above examples of solving systems of equations are simple. Tey can all be solved men-
tally, without a computer and even without a calculator.
A quote from the novel of the great Russian writer Leo Tolstoy about the comet of 1811
will help us to form a more complex SLAE, which can no longer be handled without a
computer. At the end of the second volume it is said that Pierre Bezukhov: “Joyfully, eyes
wet with tears, I looked at this bright star, which, with inexpressible speed as if fying an
immeasurable expanse along a parabolic line, suddenly, like an arrow piercing the ground,
slammed into one place it had chosen, in the black sky.”
Was this line parabolic!?
Figure 3.14 shows two vectors with the coordinates of the comet in 1811 at diferent
times. How these numbers were obtained will be discussed in a separate chapter of the
book. Tese values are marked with dots on the graph (see also Chapter 5).
Did people understand that the comet of the 12th-year fies not along a parabolic, but
along a closed elliptical trajectory? Here it is very appropriate to recall Alexander Pushkin
and his poem “Te Stone Guest”:
84 ◾ STEM Problems with Mathcad and Python

FIGURE 3.14 Five points of the position of the comet of 1811.

Don Juan
You can’t see her at all
Under this widow’s black veil
I noticed a slightly narrow heel.
Leporello
Enough with you. You have imagination
He will fnish the rest in a minute;
We have it more nimble than a painter,
You don’t care where you start
Whether from the eyebrows or from the legs.

Astronomers in those days could “notice only a narrow heel” of the comet—the trajec-
tory of its motion near the Earth. Imagination, or rather cold mathematical calculation,
helped to draw the rest. We will do it now, but not by hand as was done at the time of the
formation of astronomy as a science, but on a computer!
It is known that to draw a straight line on a plane (a curve of the frst order), at least two
points are required. Te ellipse and the hyperbola (curves of the second order along which
celestial bodies fy) should have fve such reference points. Tree points are enough for a
parabola.
In Figure 3.15, the frst line contains the general equation of a second-order plane curve.
If you fnd the values of the six coefcients of the equation, then it is easy to plot the curve
itself. Tis problem is reduced to solving a system of fve SLAEs with fve unknowns. Why
Reading Fiction and Solving Linear Equations ◾ 85

FIGURE 3.15 Formation and solution of a SLAE describing the fight of a comet in 1811.

are there six unknown coefcients and fve equations? Te point is that the equation of a
plane curve of the second order with six unknown coefcients has an infnite number of
solutions, including the trivial solution when all the coefcients are equal to zero. One
of the “non-zero” solutions can be found like this: set the value of one of the coefcients,
and then calculate the values of the other fve. In the second line of the calculation in
Figure 3.13, a square matrix M of coefcients with unknown SLAEs and a vector of con-
stants, v, is formed, which stores the specifed value of the sixth coefcient a0 of the equation
of the second-order curve (let it be minus one). Te lsolve function returned the solution to
the SLAE—the fve desired coefcients, which can be used to construct the trajectory of the
86 ◾ STEM Problems with Mathcad and Python

comet from two halves of the ellipse—the upper y1(x) and the lower y2(x). Tese two func-
tions are obtained as a result of the analytical solution of the equation of the second-order
curve with respect to the variable y (the last two lines in Figure 3.15).
Additionally, in the solution shown in Figure 3.15, the ranks of the main and augmented
matrices of the SLAE are calculated. Teir values (fve plus fve and fve equations—a single
solution) are obtained with two nuances. First, we had to remove the dimensions from the
terms in the matrix M and the vector v, using the built-in Mathcad function SiUnitsOf
and vectorization (arrow above the fraction), and second, we had to use symbolic (→) rather
than numerical (=) mathematics. Numerical mathematics, due to limited accuracy, pro-
duced two triples, not two fves.
Figure 3.15 also shows the numerical values of the resulting coefcients of the second-order
plane curve. We can assume that the three coefcients ax2, ay2 and a0 are nonzero, and the other
three (axy, ax and ay) are equal to zero within the limits of the calculation accuracy. Analysis
of these values shows that this is an ellipse with a semi-major axis equal to 212.225 AU and a
semi-minor axis equal to 20.715. Approximations of these values can be seen in Figure 3.16.
Figure 3.16 plots the complete elliptical trajectory of the comet based on fve points,
which are shown at the rightmost edge of the elliptical orbit. Figure 3.17 zooms in on the
right edge of the fve-point ellipse.

FIGURE 3.16 Ellipse of motion of a comet in 1811, constructed from fve points.

FIGURE 3.17 Right edge of the ellipse of motion of the comet in 1811 with the Sun at the focus.
Reading Fiction and Solving Linear Equations ◾ 87

FIGURE 3.18 Solution of a system of two canonical ellipse equations.

Yes, analysis of the values of the coefcients ax2, axy, ay2, ax and ay, as well as the form
of the ellipse in Figure 3.16 shows that the axes of the ellipse coincide with the coordinate
axes, and the equation itself with the canonical equation of the ellipse: x2 / a2 + y2 / b2 = 1.
Small deviations are associated with the calculation error. In Figure 3.18, the coefcients
a and b are found by solving a system of two equations based on two points of the comet’s
trajectory—the zeroth and fourth.
On the website [Link]
ODEs-solution/td-p/736652 you can see the analytical solution to the problem of the comet
in 1811, as well as an animation of its motion.
We will reproduce the calculation of the orbit of comet 1811 in Python using the
lstsq() function:

# data from Mathcad


X = [Link]([202.662572911686, 208.952538616392,
211.966669674178,
208.751324696265, 200.49273138321])
Y = [Link]([6.07060831977258, 3.48650425174498,
—0.232488037752813, -3.59964263161568,
-6.72285224432161])
a0 = 1
# Matrix M and vector v
M = [Link]([X**2, 2*X*Y, Y**2, 2*X, 2*Y]).T
v = [Link](5)*a0
# Solve the system of linear equations
a, residues,rank, sv = [Link](M, v)
print(f'rank = {rank}, condition number = {sv[0]/sv[-1]:6.3e}')
print(f'a_x2 = {a[0]:6.3e}, a_xy = {a[1]:6.3e}')
print(f'a_y2 = {a[2]:6.3e}, a_x = {a[3]:6.3e}')
print(f'a_y = {a[4]:6.3e}, a_0 = {a0:6.3e}')

Notice how the matrix M is formed: frst, element-by-element operations are performed
with the vectors X, Y according to the formulas in Figure 3.15, one-dimensional arrays
are combined vertically into two-dimensional, afer which the resulting two-dimensional
array is transposed.
88 ◾ STEM Problems with Mathcad and Python

Te results are as follows:

rank = 5, condition number = 9.924e+05


a_x2 = 2.220e-05, a_xy = 2.370e-09
a_y2 = 2.330e-03, a_x = 5.453e-06
a_y = -4.933e-07, a_0 = 1.000e+00

It is important to notice that the condition number of the matrix is almost equal to a mil-
lion here, and the question arises of how the errors in measuring the comet coordinates
will afect the array of coefcients, a. Te second question that Python will help us to
answer is that it is possible to determine the trajectory of a comet’s orbit (coefcients a)
from more than fve points, and this is done in practice. In this case, we will have to solve
a system of linear equations with a rectangular overdetermined matrix, which we will do
using the least-squares method.
We carried out a statistical simulation of calculating the coefcients a, adding random
normally distributed numbers to the initial data X, Y and calculating the maximum rela-
tive deviation of the array elements a for fve and twenty points (we denoted the number of
points by q), by which the comet’s orbit was calculated. In the second case, the set of initial
points X, Y was supplemented by a random selection of 15 more points in the comet’s orbit.
To compile statistics, the calculations were repeated 50,000 times, and the results are pre-
sented as histograms in Figure 3.19.

FIGURE 3.19 Distributions of the relative errors of the coefcients a when calculating them from
q = 5 and q = 20 points of the comet’s orbital elements, r is the relative error, p is the frequency.
Reading Fiction and Solving Linear Equations ◾ 89

From Figure 3.19 it can be seen that with an increase in the number of points q, by
which the comet’s orbit is determined, the error in determining the coefcients dramati-
cally decreases. Te source code for statistical modeling of relative errors is provided in the
Jupyter notebook chapter.
Te plot of the Hollywood movie “Armageddon” is as follows. An asteroid “the size of
Texas” is approaching the Earth. Scientists calculated its trajectory and realized that a col-
lision with the Earth is inevitable. An expedition is sent to the asteroid, which drills a well
on it and puts a nuclear charge there. Te asteroid explodes into small fragments that did
not cause catastrophic damage to the Earth. So knowledge of mathematics, coupled with
the heroism of people, saved the Earth!

TASKS FOR THE READER

1. Reproduce the calculations done in this chapter in (a) Mathcad, (b) Python.
2. What is the rank of a matrix, why is it calculated.
3. What conditions must a system of linear algebraic equations satisfy in order to have
a unique solution.
4. Is it possible to solve systems of linear equations with a rectangular matrix? How to
do it?
5. What is an underdetermined system of linear equations, how many solutions does it
have, how to determine them?
6. Try to calculate the dependence of the average relative error in determining the
array of coefcients a (see Figure 3.13) on the number of randomly selected points
of the orbit, which are used to calculate these coefcients (a problem of increased
complexity).
7. Draw fve points randomly on the plane and draw an ellipse or one of the branches
of the hyperbola through them. Do it in two ways—by calculating the values of the
coefcients of the equation of the second-order curve (see Figure 3.13) and by cal-
culating the parameters of the canonical equation of an ellipse or hyperbola. Plot
these second-order curves through fve points. If you get a hyperbola, then draw both
of its branches. For a hint for this task, see the article: Valery Ochkov. New Year
Mathematical Card or V Points Mathematical Constant // Recreational Mathematics
Magazine, Number 11, 2019, 27–33 pp (DOI: [Link]
Chapter 4

Trust but Verify

W hen solving equations, it is quite often necessary to make equivalent transfor-


mations, for example, adding or multiplying the left and right sides of the equation
by the same numbers or expressions. But equivalent transformations are not limited to
addition and multiplication. Sometimes, it is required to square the right and left sides of
the equation. Here’s a concrete example.
Equation (4.1) is to be solved:

5x − 9 = 3 − x . (4.1)

Let us square the left and right sides of the equation (4.2):

5x − 9 = (3 − x ) .
2
(4.2)

Then, using simple transformations (4.3), the original equation is reduced to a quadratic,
(equation 4.4):

5 x − 9 = −6 x + x 2 , (4.3)
x 2 − 11x + 18 = 0. (4.4)

Two roots of equation (4.4) are found by the well-known “school” formula (equation 4.5):

x1 = 2, x 2 = 9. (4.5)

In this case, one of the roots turns out to be false (or extraneous, as mathematicians say),
which is easy to show during the check—substitution of the roots into the original equa-
tions (4.6 and 4.7):

5 x1 − 9 = 1, 3 − x1 = 1, (4.6)
5 x 2 − 9 = 6, 3 − x 2 = −6. (4.7)
DOI: 10.1201/9781003228356-5 91
92 ◾ STEM Problems with Mathcad and Python

FIGURE 4.1 Schematic representation of the Nautilus submarine (source unknown).

Te original equation turns into identity only when the value of the unknown is equal to 9
(equation 4.7). Tis is the only root of the original equation (4.1).
Now let’s consider a more interesting and more complex problem, the solution of which
also leads to the appearance of an extraneous root (not just one, but several). Tis is more
difcult to identify, but, if not identifed correctly, will lead to an incorrect result.
Let’s explore such a root by solving analytically (symbolically), numerically and graphi-
cally one interesting problem from the science fction literature.
In Jules Verne’s famous novel 20,000 Leagues Under the Sea, you can read the following:
“Voici, monsieur Aronnax, les diverses dimensions du bateau qui vous porte. C’est
un cylindre très allongé, à bouts coniques. <…>. Ces deux dimensions vous per-
mettent d’obtenir par un simple calcul la surface et le volume du Nautilus. Sa sur-
face comprend mille onze mètres carrés et quarante-cinq centièmes; son volume,
quinze cents mètres cubes et deux dixièmes—ce qui revient à dire qu’entièrement
immergé il déplace ou pèse quinze cents mètres cubes ou tonneaux.”
With this phrase, Captain Nemo answers the question of his captive, Professor Aronax,
about the size of the Nautilus submarine. Translated into English and into the language of
mathematics: the submarine has the shape of a geometric body made up of two identical
straight circular cones (bow and stern of the boat) and a straight circular cylinder (boat
hull—see Figure 4.1). Te radii of the bases of the two cones and the cylinder are equal.
Te volume of the boat (displacement) V in cubic meters and the area of its outer surface S
in square meters are known. It is necessary to determine its geometrical dimensions—the
radius of the bases of two cones and one cylinder r, the heights of the two cones (the length
of the bow and stern) h and the height of the cylinder (the length of the hull) l.
Note on Figure 4.1. On the Internet, using the keywords “Image of the Nautilus sub-
marine”, you can fnd many diferent drawings of the boat itself (exterior) and its interior
(interior). Tese are illustrations from a huge number of books published in diferent coun-
tries in diferent languages. But only the drawing with the profle of a man on the deck
of a boat with a height of about 2 m, shown in Figure 4.1, corresponds more or less to the
dimensions of the boat indicated by the phrase of Captain Nemo above, and the calcula-
tions that will be made below. Te author of this drawing remained unknown despite a
careful search.
Te problem of the dimensions of the Nautilus submarine is reduced to solving a system
of two equations (the equation for the volume of the boat V =… and the equation for the
surface of the boat S =…) with three unknowns r, h and l. Te system is underdetermined
since the number of equations is less than the number of unknowns.
Trust but Verify ◾ 93

FIGURE 4.2 Formation and analytical solution in Mathcad of two auxiliary (solve, l) and one
main (solve, h) equations for the submarine Nautilus.

In Figure 4.2 (Mathcad), the symbolic mathematics tool (solve operator) generates two
functions—one named lV and three arguments V, r and h, and one named lS and also three
arguments S, r and h. Te frst function is obtained as a result of the analytical (symbolic)
solution1 of the equation for the volume of the boat in the variable l, and the second—the
equations of the boat’s surface in the same variable. But the length of the cylindrical part
(boat hull) does not depend on how it was defned—through the volume or through the
outer surface. Terefore, these two functions are equivalent, which allows us to form a
new equation lV (V, r, h) = lS (S, r, h), which is solved again analytically2 but with respect
to another variable—the variable h. An attempt to analytically solve this equation with
respect to the variable r was unsuccessful—a complex answer was returned containing the
Root function (root of a polynomial of a high degree). In this sense, the Mathcad package
is somewhat similar to Captain Nemo: the question is not given a specifc and clear answer,
but a new question is issued, a new riddle is asked that needs to be solved.
As a result of solving the equation lV (V, r, h) = lS (S, r, h) with respect to the variable h,
two expressions were obtained containing the variables V, S and r, which form a vector
function with the name H and with three arguments V, S and r (Figure 4.2). For this func-
tion (for its two expression elements), a graph is built (Figure 4.3) for fxed values of the
arguments (parameters) V = 1,500 m3 and S = 1,010 m2 (see the problem statement above)

1 Tis equation is easy to solve mentally, without a computer, by transferring individual terms from the right side to the
lef as well as using other transformations. To avoid mistakes and typos, it is better to do this on a computer. On the
other hand, it is always useful for training to do such analytical calculations frst by hand and then check the answer on
a computer. An example from everyday life. A modern phone (smartphone) stores numbers in its memory. Nevertheless,
doctors recommend that the elderly and not only the elderly keep these numbers in their heads, dialing them manually
if necessary. Tis will train memory and delay dementia.
2 Tis equation is not so easy to solve mentally. One of the authors asked an experienced mathematics teacher to do this.
Tey flled three sheets of paper, did not complete the task, but made a well-founded assumption about the root causes
of the error in symbolic mathematics, which we will consider below.
94 ◾ STEM Problems with Mathcad and Python

FIGURE 4.3 Te graph of the solution to the equation for the submarine Nautilus, obtained in
Mathcad.

and for the argument r varying from 1 to 14 m.3 One meter is the minimum reasonable size
of a boat in which a person can walk without bending. Fourteen meters were obtained by
selection: this value was changed manually so that Figure 4.3 is a closed curve.
Note that Jules Verne was a lawyer by training, not an engineer. Tis might explain
the excessive accuracy used when specifying the volume and area of the submarine,
V = 1,500.2 m3 and S = 1,011.45 m2. One could easily set V = 1,500 m3 and S = 1,010 m2
(which, by the way, we did) or even S = 1,000 m2. In science fction novels, authors ofen try
to operate with ostentatiously high precision, so that it appears to be more scientifc and
less fantastic.
Our system of equations is underdetermined. Terefore, the roots of the equation are not
scalar quantities (points), but sets of points (curves) described by some algebraic expres-
sions. We have shown this above analytically (Figure 4.2) and graphically (Figure 4.3).
In Python, for the analytical solution of the problem, we will use the SymPy library, and,
for drawing curves, the matplotlib library:

from sympy import pi, symbols, Eq, solve, init_printing


from sympy import sqrt, Rational, lambdify
V, S, r, l, h = symbols('V S r l h')
init_printing()

3 Mathematical packages build graphs of the “explicit” function y(x), tabulating the values of the argument and the func-
tion and connecting the resulting points with straight line segments or approximating it with some function, for exam-
ple, a polynomial. If a student in a mathematical analysis class begins to build a graph in this way, then a demanding
teacher will kick such a student out of class, stamping his feet and hooting afer the student. We usually build such
graphs in a more intelligent way – qualitatively, and not quantitatively: we analyze the function, look for its singular
points – zeros, extrema, infection points, asymptotes, break points, etc. Tat is why many teachers of mathematics in
schools and universities quite reasonably believe that machine analytics and graphics (computer mathematical pro-
grams) dull students, wean them of working with their heads ... Or rather, it dulls the bulk of students, but enriches the
rest – smart and conscientious.
Trust but Verify ◾ 95

We import everything we need from SymPy, then create symbolic variables and initialize
formulas ready for pretty printing.

lV = Eq(2*Rational(1,3)*pi*r**2*h + pi*r**2*l, V)
lS = Eq(2*pi*r*sqrt(r**2+h**2) + 2*pi*r*l, S)
lV_Vrh = solve(lV, l)
lS_Srh = solve(lS, l)
lV_Vrh, lS_Srh

Equations in SymPy are created as an instance of the Eq class, and to solve nonlinear
equations, we call the solve function twice, which is passed the equation to be solved
and the symbolic variable relative to which the solution is carried out. As a result, we
get:

 ° V 2h ˙ ° S 2 2 ˙
 ˝ πr 2 − 3 ˇ , ˝ 2πr − h + r ˇ .
˛ ˆ ˛ ˆ (4.8)

Expression (4.8) is obtained from the Jupyter Notebook. Actually, for this, you need a call
to the init_printing () function. In addition, we draw attention to the fact that solve func-
tion issues a tuple consisting of two lists; therefore, to obtain a solution for h, we have to
extract the zeroth element from each list:

H_VSr0, H_VSr1 = solve(Eq(lV_Vrh[0], lS_Srh[0]), h)

Here we equated the expressions lV_Vrh [0] = lS_Srh [0] and solved the resulting equa-
tion for h, (see Figure 4.2). As a result, we got two expressions depending on S, V, r:

˙ ˘
ˇ
ˇ
(
3 2Sr − 4V − 9S 2r 2 − 36SVr + 36V 2 − 20π 2r 6 ), 

2
ˇ 10πr 
ˇ . (4.9)
ˇ 
ˇ
ˇ (
3 2Sr − 4V + 9S 2r 2 − 36SVr + 36V 2 − 20π 2r 6 ) 

ˇˆ 10πr 2 

We need to substitute the values of S and V into (4.9), which is easily done using the subs
method, and also plot the dependences on r. Te latter can be done using the plot function
in the SymPy package, but we convert the expressions (4.9) to universal NumPy functions
in order to use the familiar matplotlib renderers.

hr0 = lambdify(r, H_VSr0.subs(V, 1500).subs(S, 1010), 'numpy')


hr1 = lambdify(r, H_VSr1.subs(V, 1500).subs(S, 1010), 'numpy')
96 ◾ STEM Problems with Mathcad and Python

It remains for us to build graphs. As in Mathcad, we will plot the graphs for htr0 and hr1
with lines with diferent styles:

%matplotlib inline
import numpy as np
import [Link] as plt
n = 10000
r = [Link](1,14, n)
[Link](r, hr0(r),'k:', lw=3, label='hr0')
[Link](r, hr1(r),'k-', lw=3, label='hr1')
[Link](-20, 50)
[Link](loc='best')
[Link]('r', fontsize=14)
[Link]('hr0(r), hr1(r)', fontsize=14)
[Link]()
[Link]()

In this snippet, we entered the magic command to embed drawings into Jupyter Notebook
cells and imported NumPy and matplotlib. Ten the array of r values was calculated and
two graphs were plotted (Figure 4.4). Everything else in this fragment is needed to label the
picture. Tis is how we set the boundary values along the ordinate axis, brought out the
legend, labels on the coordinate axes and a grid.
Te Python solution turned out to be somewhat longer than with Mathcad.
Now let’s use numerical methods for completeness. Earlier we worked with analytics
and graphics. But graphics, curves and surfaces are based on numerical mathematics.
Figure 4.5 shows Mathcad’s numerical procedure for one of the points of the graph in
Figures 4.3 and 4.4. Te system of two equations defning the geometry of the Nautilus
submarine is solved here numerically. To do this, I am guided by Figure 4.1, so the value
of the boat radius r (3.4 m) is fxed, and in the Solve block initial approximations to the
solution of the system of two equations with two unknowns are set—the values of the
unknowns h and l (5 and 100 m) and the Mathcad built-in Find function is called. Using a

FIGURE 4.4 Plot of the solution to the equation for the submarine Nautilus, obtained in Python.
Trust but Verify ◾ 97

FIGURE 4.5 Numerical solution of the Nautilus submarine equation in Mathcad.

numerical algorithm (in Mathcad 15, you can choose from several algorithms), this func-
tion will “intelligently” change the values of the variables h and l until the lef and right
sides of the equations written in the Constraints area become almost equal (this “almost” is
determined by the built-in Mathcad variable CTOL—Constraints TOLerance; by default,
it is equal to 0.001 m3 for the frst equation and square meters for the second). Numerical
methods for solving problems may also be called approximate. Lower, beneath the Solve
block in Figure 4.5 is a check of the solution to the problem—the calculation of the values
of the right-hand sides of the equations for a given value of r (3.4 m) and the resulting val-
ues of h and l (29.988 and 21.311 m; the answer is given with three digits afer the decimal
point). Tese numerical values roughly correspond to the dimensions of the submarine
shown in Figure 4.1. Tis is one of the points of the upper half of the closed curve shown
in Figures 4.3 and 4.4.
If in the calculation in Figure 4.5 a negative value for the variable h is specifed as an ini-
tial approximation, then the Find function will return the second solution—a point located
on the lower half of the closed curve shown in Figures 4.3 and 4.4 as a dashed curve. Tis
can be achieved in another way—by inserting the operator h < 0 into the Constraints area.
Tus, changing the values of the variable r and calculating the values of the variable h, one
can determine the coordinates of all points forming a closed curve. Negative values of the
h variable mean that the bow and stern do not protrude from the boat’s hull, but intrude
inside it. Tis is unrealistic in relation to the shape of the boat, but it is quite acceptable
from the point of view of the geometry of three bodies—a cylinder and two cones.
Now we will try to numerically calculate one of the points on the open curve shown in
Figures 4.3 and 4.4.
If the value of the radius r is set to 2 m, then the Find function will return unexpected
numerical values for the roots of the system of equations (Figure 4.5), and a message stat-
ing that the answer was not found—see Figure 4.6. Tis may be a consequence of incorrect
98 ◾ STEM Problems with Mathcad and Python

FIGURE 4.6 Failed numerical solution of the Nautilus submarine equation.

FIGURE 4.7 Numerical and graphical solution of the Nautilus submarine equation through the
formation of a user function (Mathcad).

initial approximations, too high specifed accuracy of the numerical solution of the prob-
lem, or the fact that the solution in the region of the open curve does not exist at all, and
the open curve itself, shown in Figures 4.3 and 4.4, is false.
Te Find function built into Mathcad not only gives an answer in the form of numbers,
but can also generate user functions that can be used to build graphs. Figure 4.7 shows
this: the value of the variable r is not specifed (3.4 m – Figure 4.5, or 2 m – Figure 4.6); it
becomes the argument of a user-defned function called HL. Tis function is a vector with
the zeroth and frst elements split into scalar functions H (r) and L (r), where their sub-
scripts,1 and 2, mark the “upper” and “lower” segments of them. Based on these functions,
two closed curves were constructed that connected the boat’s radius r with the bow and
stern length h, as well as with the hull length l. Tese closed curves can also be seen on the
axial surfaces in Figure 4.12.
Trust but Verify ◾ 99

FIGURE 4.8 Checking the analytical solution of the equations for the submarine Nautilus.

Two diferent pairs of open curves that make up a pair of closed curves are obtained due
to diferent initial assumptions for h and l when solving the problem numerically.
Te open curve representing the extraneous root of the equation is again not seen in
Figure 4.7!
We checked the numerical solution of the problem of one possible size of the Nautilus
submarine—see Figure 4.5, but not the analytical one. Let’s do it!
Figure 4.8 shows what lV (V, r, h) and lS (S, r, h) return when you substitute the numeric
values of V, S, r, and h in their arguments. For r = 3.4 m (see Figure 4.5 and the top of
Figure 4.8), the functions lV (V, r, h) and lS (S, r, h) return the same result, but for r equal to
2 m (see Figure 4.6 and the lower part of Figure 4.8), they are diferent.
Hence the fnal conclusion: the open curve in Figure 4.3 is a false, extraneous solution
to the Nautilus size problem.
Te symbolic (analytical) mathematics of Mathcad (Figures 4.2 and 4.3) gives the wrong
solution. Rather, it gives a partially correct solution. Tis answer is given not only by Mathcad
but also by Python Sympy, as well as by the “whales” of symbolic mathematics—the Maple
and Mathematica packages (see Figures 4.15, 4.16 and 4.19 at the end of the chapter). Tis
can be explained by the fact that when the problem (see the beginning of the chapter) is
reduced to solving a quadratic equation, there are two roots, one of which is extraneous [1].
Figure 4.9 shows the construction of a 3D curve for solving the Nautilus submarine siz-
ing problem. To do this, the values of the variables r and h are changed (scanned) in nested
“for” loops, over the intervals from 1 to 14 m, for r, and from −10 to 50 m, for h. Te current
values of the variables r and h are used to calculate the value of the variable l according
to the equation for the boat surface. If the volume of the submarine calculated from the
values of the variables r, h and l turns out to be approximately equal to the specifed value
of 1,500 m3, then their values are stored in the vectors R, H and L, which are then displayed
as a three-dimensional closed curve without any additional false (extraneous) open curves.
It is also not difcult to reproduce a scan of a rectangular area in Python. We will do this
using the NumPy library, which signifcantly increases the speed of program execution
compared to pure Python. To do this, we write two functions, the frst of which is auxiliary
and is used to calculate the length of the submarine’s hull:

def L(S, r, h):


return (S - 2 * [Link] * r * [Link](r ** 2 + h ** 2)) /\
(2 * [Link] * r)
100 ◾ STEM Problems with Mathcad and Python

FIGURE 4.9 Solution equation for submarine Nautilus by scanning method.

Te second function is used to scan a rectangular area on the r, h plane:

def scanroots(S=1010, V=1500, hmin=-10, hmax=50, hs =.01,


rmin=1, rmax=14, rs = .01, ϵ=.1):
r = [Link](rmin, rmax+rs/2, rs)
h = [Link](hmin, hmax+hs/2, hs)
rm, hm = [Link](r, h)
l = L(S, rm, hm)
error = [Link](2 / 3 * [Link] * rm ** 2 * hm + [Link] * rm ** 2
* l - V)
ih, ir = [Link](error<=ϵ)
return r[ir], h[ih], L(S, r[ir], h[ih])

r, h, l = scanroots()

Te functions are transferred to the area and volume of the submarine (S, V), the mini-
mum and maximum values of h and the scanning step (hmin, hmax, hs), the same values
for the radius of the submarine hull (rmin, rmax, rs), as well as the admissible error of the
solution equations ϵ. Default values are specifed for all function arguments. Te function
returns the arrays r, h, l, which are the solution to the problem.
When scanning, we frst of all create one-dimensional arrays of r, h values with rs,
hs steps, on the basis of which we form two-dimensional arrays rm, hm. Tis allows a
universal function (a function that takes both scalar arguments and arrays) L to be used to
compute the error in solving the error equation on the grid. Here we have used the expres-
sions obtained in Mathcad in Figure 4.8.
Trust but Verify ◾ 101

FIGURE 4.10 Te set of grid nodes in the plane (r, h) satisfying the condition ϵ ≤ 0.1

Unlike Mathcad, where scanning is carried out sequentially node by node of the grid,
NumPy allows you to get in one line all grid nodes for which the error is less than or
equal to ϵ. Te universal where function is used for this. A logical expression on a two-
dimensional array is passed to this function, it returns one-dimensional arrays of indices.
In turn, arrays of indices can be used to calculate r, h, l, for which this condition is satisfed.
We can visualize r, h for which ϵ ≤ .1 will be executed (Figure 4.10):

[Link](figsize=(5,5))
[Link](r, h, 'ko', ms=2)
[Link]('r', fontsize=14)
[Link]('h', fontsize=14)
[Link]();

Here we create a 5-by-5-inch drawing and use the plot function to plot all nodes on the
grid that meet the condition ϵ ≤ .1 with 2-pixel black round markers, in addition, we display
labels on the coordinate axes.
What is shown in Figures 4.9 and 4.10, is an approximate solution to the problem. To get
a solid line in Figure 4.10 it is necessary either to decrease the grid step in h, r, or to increase
the admissible value of the error in calculating the root ϵ, or to increase the marker size,
which was done in Figure 4.9. As an exercise, experiment with all three ways to get a solid
curve. In any case, now we know how the set of solutions works and we can fnd exact solu-
tions by fxing one of the variables and calculating the exact value of the other variable,
using the values obtained in Figure 4.10.
Te [Link] or [Link] function is commonly used to solve non-
linear algebraic equations in the Python ecosystem. In both cases, we will have to read the doc-
umentation on using these functions [2,3]. Te fsolve function needs to be passed a function
equal to zero for the root of the equation, an initial guess, and a tuple of additional parameters.
102 ◾ STEM Problems with Mathcad and Python

For almost all r (see Figure 4.10) there are two values of h, which are the roots of the
equations, therefore, in order not to create additional difculties for oneself, it is neces-
sary to make sure that there are no unexpected “jumps” from one value of the root to
another. Te set of solutions on the plane (r, h) is a convex curve. Let’s select any point
inside the curve, for example, (8, 20) and we will build exact solutions depending on the
angle between the r-axis and the root. Divide the curve into four parts to provide a con-
tinuous dependence of the solution on the angle. To do this, we write two functions that we
pass to the fsolve function to calculate the exact value of the root:

def err(r, S, V, h):


l = L(S, r, h)
return [Link](2 / 3 * [Link] * r ** 2 * h + [Link] * r ** 2 * l - V)
def erh(h, S, V, r):
l = L(S, r, h)
return [Link](2 / 3 * [Link] * r ** 2 * h + [Link] * r ** 2 * l - V)

Te frst function, “err”, is used to determine r for given values of S, V, h; we apply it for the
lef and right parts of the curve in Figure 4.10. Te erh function is needed to calculate the
exact value of h for given values of S, V, r and is used for the top and bottom of the curve.
Tese functions completely satisfy the requirements that are necessary for fsolve to
work: they are passed one required argument (in the frst case r, and in the second h), the
remaining arguments are optional and are passed as a tuple either by the third positional
argument (the second is the initial approximation) or in the named argument, args.
Now we switch to the function that calculates the exact solutions.
from [Link] import fsolve
def exact_solution(m=500, r=r, h=h, r0=8, h0=20, S=1010, V=1500):
angles = [Link](0, 2*[Link], m)
angles0 = np.arctan2(h-h0, r-r0) + [Link]
r_exact, h_exact, errs = [Link](m), [Link](m), [Link](m)

for i in range(m):
i0 = [Link]([Link](angles0 - angles[i]))
r0, h0 = r[i0], h[i0]

if ([Link]/4 <= angles[i]<= 3*[Link]/4) or \


(5*[Link]/4 <= angles[i]<= 7*[Link]/4):
r_exact[i] = r0
h_exact[i] = fsolve(erh, h0, args=(S, V, r0))[0]
else:
h_exact[i] = h0
r_exact[i] = fsolve(err, r0, args=(S, V, h0))[0]

errs = err(r_exact, S, V, h_exact)


max_err = [Link](errs)

return r_exact, h_exact, max_err


Trust but Verify ◾ 103

Te function is passed m—the number of points at which we want to get the exact solu-
tion; r, h—arrays of approximate solutions, which we will use as initial approximations
to calculate the exact solution; r0, h0 is a point inside the curve in Figure 4.10; S, V—area
and volume of Nautilus. Our function returns an array of exact values of the roots r_exact,
h_exact and the maximum error in determining the roots.
Since we decided to parameterize the exact solution using the angles angle, we create
an array of these angles, and at the same time defne angles0 angles for the elements of
the array of initial approximations, which can be easily calculated based on the r, h arrays
using the built-in NumPy function, arctan2.
In the loop through the angles in the angle array, we determine the initial approxima-
tion, and then, depending on the value of the current angle, we solve the equation either
with respect to h or r, as noted earlier.
To calculate the maximum error, we calculate the array of errors on the exact solutions
and select the maximum value of this array.
We just have to call our function with default parameter values.

r_exact, h_exact, max_err = exact_solution(m=1000)

As it turns out, the maximum error does not exceed 4.0e-10. We can easily visualize
the constructed exact solution on the r, h plane (Figure 4.11), for which we simply call the
matplotlib plot function:

[Link](r_exact, h_exact,'k-', lw=3)

Everything is ready to go into the third dimension, drawing the dependencies among r,
h, l. But unlike Mathcad, in addition to the spatial curve, we will draw its projections onto
the coordinate planes and will also use the opportunity to rotate the curve about the verti-
cal axis. To do this, we write the vizualize3d function, which allows us to display spatial
curves by rotating them relative to the vertical axis at diferent angles.

FIGURE 4.11 Exact solution in the plane (r, h).


104 ◾ STEM Problems with Mathcad and Python

def visualize3d(r, h, l, plot=111,


style='k--', stylep='k:',ms=1,msp=1,
lw=1, lwp=1, azim=60, fsize=14, proj=True,
xlim=(1,14), ylim=(-10, 60), zlim=(-20,60),
ixlim = 0, iylim=0, izlim=0):
ax = [Link](plot, projection='3d')
[Link](r, h, l, style, lw=lw, ms=ms)

ax.view_init(azim=azim)

ax.set_xlabel('r', fontsize=fsize)
ax.set_ylabel('h', fontsize=fsize)
ax.set_zlabel('L', fontsize=fsize)

ax.set_xlim(*xlim)
ax.set_ylim(*ylim)
ax.set_zlim(*zlim)

if proj:
rd = [Link]([Link][0])*xlim[ixlim]
[Link](rd, h, l, stylep, lw=lwp, ms=msp)
hd = [Link]([Link][0])*ylim[iylim]
[Link](r, hd, l, stylep, lw=lwp, ms=msp)

ld = [Link]([Link][0])*zlim[izlim]
[Link](r, h, ld, stylep, lw=lwp, ms=msp)

Te functions are passed r, h, l—arrays with the coordinates of the curve along the coordi-
nate axes, plot—the location of the subplot in the fgure: the frst two digits are the number of
rows and columns into which the fgure is divided into subplot, the third digit is the number
of the subplot, starting from 1. Since 122 means that the two fgures will be placed next to
each other, we plot the curve in the right subplot. style and stylep—codes of colors and styles
of lines, which will be used to display a spatial curve and its projections on coordinate planes;
we assume that curves can be drawn both as lines and markers, so we pass ms, msp—the sizes
of the spatial curve markers and projections; lw and lwp—line thickness of the spatial curve
and its projections; azim—angle of rotation about the vertical axis in degrees; fsize—font
size for displaying labels on the coordinate axes; proj = True means that the projections of
the spatial curve to the coordinate planes will be displayed. xlim, ylim, zlim—minimum and
maximum values along the coordinate axes; ixlim, iylim, izlim—integers that can take values
0 or 1 and determine where the projection of the spatial curve will be displayed.
In the function itself, we frst of all create an object to display the three-dimensional
drawing ax. Please note that you need to set the number of the plot, indicate that the draw-
ing is 3D and pass the Figure object created outside the function. Next, we draw the spatial
curve and use the view_init method to rotate the subplot around the vertical axis. Here we
could stop, but we need, frstly, to apply labels on the axes, secondly, to set the boundary
Trust but Verify ◾ 105

values along the coordinate axes, and thirdly, to display the projections of the spatial curve
on the coordinate planes.
Projections are displayed only if proj = True. To display projections, it is enough to fx
the values of the curve along one of the coordinates. Tis is why we created the rd, hd and
ld arrays, for example, to display a projection on the r, h plane, we need to set the elements
of the ld array equal to either zlim [0] or zlim [1]. Tis is why we introduced the ixlim, iylim,
izlim arguments.
To call the visualize3d function, we need to calculate the l_exact array corresponding
to the previously obtained exact solution r_exact, h_exact, create a drawing object and
visualize our spatial curve and its projections onto coordinate planes with diferent angles
of rotation around the vertical axis (Figure 4.11):

S = 1010
l_exact = L(S, r_exact, h_exact)
fig = [Link](figsize=(14,6))
visualize3d(r_exact, h_exact, l_exact, lw=3, plot=121,
azim=30, lwp=3, izlim=0)
visualize3d(r_exact, h_exact, l_exact, lw=3, plot=122,
azim=150, lwp=3, ixlim=1)
plt.tight_layout()
[Link]()

Te tight_layout function call must be done whenever several subplots are displayed so
that the subplots do not overlap.
Looking at Figure 4.12, you can see that there are some odd values in it, such as what
l < 0 or h < 0 means. In any case, going back to Figure 4.1, we see that for l < 0 there will be
no room for the crew of the submarine, for h < 0 there will be nowhere to place the rudders
and screws. Tus, some of the resulting solutions violate common sense. Let us introduce
additional restrictions on r, h and l; fortunately, it is very easy to do this using NumPy’s

FIGURE 4.12 Spatial curve of the exact solution of the problem and its projection onto the coordi-
nate planes at angles of rotation of 30° (lef fgure) and 150° (right fgure) around the vertical axis.
106 ◾ STEM Problems with Mathcad and Python

indexing capabilities. Indeed, the diameter of the submarine’s hull must be more than 2 m,
otherwise it will be impossible to stay in it for a long time, just as we impose restrictions
from below on h and l. All imposed restrictions must act in concert:

restr = (h_exact>=2*r_exact) & (l_exact>2*r_exact) & (r_exact>=1)

Te restr array contains boolean values, the value True corresponds to elements that satisfy
all the restrictions; the value False corresponds to elements for which at least one of the
restrictions is not met. You can get the arrays of values for which the constraints are satis-
fed by simply using the restr boolean array for indexing:

r_restr, h_restr, l_restr = (r_exact[restr], h_exact[restr],


l_exact[restr])

Note that if the length of the arrays r_exact, h_exact, l_exact and restr is 1,000 in our case,
then the arrays r_restr, h_restr, l_restr each contain 409 elements that satisfy the specifed
restrictions. We just have to visualize the result by calling the visualiaze3d function twice:

fig = [Link](figsize=(14,6))
visualize3d(r_restr, h_restr, l_restr, style='ko', stylep='ks', ms=5,
msp=3, plot=121, azim=30, lwp=3, izlim=0,
xlim=(1,5), ylim=(0, 40), zlim=(0, 60))
visualize3d(r_restr, h_restr, l_restr, style='ko', stylep='ks',
ms=3,
msp=3, plot=122, azim=150, lwp=3, ixlim=1,
xlim=(1,5), ylim=(0, 40), zlim=(0, 60))
plt.tight_layout()
[Link]()

Te result is shown in Figure 4.13. Here we draw the spatial curve and its projections with
markers to avoid artifacts in the form of connecting lines.
In Figures 4.14–4.16, you can see attempts to analytically and graphically solve the
problem of the dimensions of the Nautilus submarine using the internet version of the
Mathematica package—the [Link] site.
Figure 4.14 solves the submarine equation with two roots in terms of the variable h. Te
expressions look diferent from those shown in Figures 4.2 (Mathcad) and 4.10 (Python).
In the equation being solved in Figure 4.14, the variables V and S are replaced by their
numerical values 1,500 and 1,010, respectively.
Te answers for the variable h shown in Figure 4.14 are copied to the address bar of the
[Link] website for graphing—see Figures 4.15 and 4.16. Te only thing lef
to do to the copied expressions for the variable h is to assign the plot keyword and specify
the range of values for the r argument (from 1 to 15—units of measurement are not used).
Figures 4.14 and 4.16 also show the lef, open, false curve, which indicates a limitation
in symbolic mathematics.
Trust but Verify ◾ 107

FIGURE 4.13 Spatial curve of the exact solution of the problem, taking into account additional
restrictions at angles of rotation of 30° (lef fgure) and 150° (right fgure) around the vertical axis.

FIGURE 4.14 Solving the Nautilus submarine equation at [Link].

Figures 4.14, 4.15, and 4.16 are shown here not only to show that the symbolic math-
ematics of [Link] (Mathematica) also gives the extraneous answer in the
Nautilus hull problem, but for the following reason.
Te symbolic mathematics package Mathcad is a commercial sofware product for
which one must pay. A shortened version of the Mathcad package—Mathcad Express, with
disabled symbolic mathematics—is distributed free of charge—like Python. Te Nautilus
108 ◾ STEM Problems with Mathcad and Python

FIGURE 4.15 Plotting the frst result shown in Figure 4.14.

FIGURE 4.16 Plotting the second result shown in Figure 4.14.


Trust but Verify ◾ 109

FIGURE 4.17 Solving the problem of the size of the Nautilus using the root function.

submarine problem can be solved numerically in Mathcad Express, and the necessary
symbolic transformations can be carried out on the [Link] website or on
other similar ones.
Also, the Find function does not work in Mathcad Express. Terefore, the calculations
shown in Figures 4.5–4.7, cannot be done in that environment. A way out of the situation
is as follows. Te system of two equations—the equations of the volume of the submarine
V = ... and the equation of its surface S = ... need to be reduced to one equation by substi-
tuting the expression for l obtained from the frst equation into the second equation. Tis
single equation must be further transformed into a function for which zero is sought—the
value of the argument at which the function is equal to zero. Both Mathcad Prime and
Mathcad Express have a built-in root function for this task. Te numerical solution of the
problem of the dimensions of the Nautilus submarine using this approach is shown in
Figure 4.17.
On the frst line of the calculation shown in Figure 4.17, the volume equation is written
and solved with respect to the variable l. Next, the values of the volume and surface of the
boat are entered and a user-defned function is formed with the name H and with two argu-
ments r and h, using the built-in “numerical” function root. We have already shown such a
technique in Figure 4.7. Next, the function H(r, h) is called to construct the already familiar
closed curve, where r is an area variable in the range from 2 to 13 m in 1 cm increments, and
the variable h is the frst guess for the root function. For diferent values of the argument h
(20 and −20 m), two halves of a closed curve are constructed—the upper and the lower.
To complete the picture, we will show how the problem of the dimensions of the
Nautilus submarine is solved in the mathematical program Maple—a direct competitor of
Mathematica.
110 ◾ STEM Problems with Mathcad and Python

FIGURE 4.18 Plotting a curve solving the Nautilus submarine equation on Maple.

In Figure 4.18, the boat volume and surface equations are solved analytically with
respect to the variable l. Next, the values of the variables V and S are set and the graph of
the closed function lV = lS is plotted with respect to the variables r and h. Tis is done by the
implicitplot command obtained using with(plots).
We don’t see any open curve in Figure 4.18!
But if we do not construct a closed curve, but try to solve the equation lV = lS in the vari-
able h, then we will again get a false open curve (Figure 4.19). We also get another open,
false curve if we capture negative values of the variable h.
Let’s complicate the task!
Te original description of the size of the Nautilus submarine does not specify that the
lengths of the stern and bow are the same. Tis is what we assumed. But if we assume that
the cones forming our composite geometric body can have diferent heights h1 and h2,
then the problem will be even more underdetermined: two equations V =… and S =… with
four unknowns r, l, h1 and h2.
Figure 4.20 shows the solution to this new complicated problem in Maple. We aban-
doned the solution of the “general” equation lV = lS, and proceeded directly to plotting a
three-dimensional graph. Te result is not a closed curve, but a closed surface, the points of
which fx the values of the variables r, h1 and h2, which are the solutions to the problem of
the dimensions of an “asymmetric” boat. Te fourth unknown variable l (the length
of the boat’s hull) is calculated using the formulas for lV or lS (second and third lines in
Figure 4.20).
Trust but Verify ◾ 111

FIGURE 4.19 Analytical and graphical partially correct solution of the Nautilus submarine equa-
tion in Maple.

In Figure 4.20 on the lef, a complete solution surface is plotted. On the right is the same sur-
face with the negative values of the variables h1 and h2 cut of. Tis was done in order to show
with such sections that this is not a geometric body, but a surface similar to the red mouth of the
green monster that Captain Nemo met under water. But the main thing is that the grid is clearly
visible, along which the surface is built according to the 30,000 points used here.
Mathematicians all over the world argue which package, Maple or Mathematica, has the
most powerful and correct symbolic mathematics. But we have shown that both of these
packages have limitations on a fairly simple task. So trust, but verify!
In an attempt to reproduce the results obtained in Figure 4.20 in Python, we will use
numerical methods and focus on satisfying the physical constraints on the values of r, l,
h_1, h_2 using the [Link] function. Tis function allows one to solve systems
of nonlinear equations and specify the solution method to be used. It returns a data struc-
ture with detailed information about the solution, and in case of a failure—no solution,
reports this. We will set h_1, h_2, and the values r, l will be determined by solving a system
of two equations for the volume and surface area of the submarine.

from [Link] import root


def v(r, l, h1, h2):
112 ◾ STEM Problems with Mathcad and Python

FIGURE 4.20 Analytical and graphical solution of the Nautilus submarine equation with diferent
bow and stern lengths (Maple).

return 1/3*[Link]*r**2*h1 + 1/3*[Link]*r**2*h2 + [Link]*r**2*l


def s(r, l, h1, h2):
return [Link]*r*[Link](r**2 + h1**2) + [Link]*r*[Link](r**2 +
h2**2) + \
2*[Link]*r*l
def err_rl(rl, h1, h2, S, V):
r, l = rl[0], rl[1]
return v(r, l, h1, h2) - V, s(r, l, h1, h2) - S

Te v, s functions are designed to calculate the volume and surface of the submarine,
with function err_rl being passed to the root function imported at the beginning of the
Trust but Verify ◾ 113

fragment. Note that the r, l values are passed as a tuple, as required by the root documenta-
tion. Te function returns a tuple of errors in solving a system of equations.
Te constr function returns True if the physical constraints on the size of the submarine
are satisfed and False otherwise:

def constr(r, l, h1, h2, S, V):


return (r>=1) & (l>=2*r) & (h1>=2*r) & (h2>=2*r)&(l>=h1)&(l>=h2)

In order to allow the restrictions on the size of the submarine to be varied, we pass the
function that implements the restrictions to the solver as an argument:

def solver_rl(r0, l0, h1, h2, S, V, constr):


result = root(err_rl, (r0, l0), args=(h1, h2, S, V))
if [Link]:
r, l = result.x
if constr(r,l, h1, h2, S, V):
return r, l
else:
return [Link]
else:
return [Link]

Te solver_rl function is designed to solve a system of equations to determine r, l. It receives


the initial approximations for r0, l0, the given values h_1, h_2, S, V, as well as the constr
function, which determines the admissibility of the calculated dimensions of the subma-
rine. We need to calculate and then visualize the valid and invalid values of r, l. For invalid
values, we use the special NumPy constant [Link]—not a number. Tere are several pos-
sible sources for the occurrence of invalid values of r, l: the absence of a solution for a given
combination of arguments, an unsuccessful choice of the initial approximation, and, fnally,
the inadmissibility of a combination of arguments, which is calculated using the constr
function. Tus, the function returns either a tuple r, l, if the solution is valid, or [Link].
Te rlh1h2 function calculates two-dimensional arrays r, l on the h_1, h_2 grid

def rlh1h2(n =100, rminmax=(1.,5.), lminmax=(1., 100.),


hminmax=(1., 50),
constr=constr, S=1010, V=1500, r0=3, l0=5):
h1h2r = [Link]((n,n)) * [Link]
h1h2l = [Link]((n,n)) * [Link]
for ih1 in range(n):
h1 = hminmax[0] + (hminmax[1] - hminmax[0])/n*ih1
for ih2 in range(n):
h2 = hminmax[0] + (hminmax[1] - hminmax[0])/n*ih2
result = solver_rl(r0, l0, h1, h2, S, V, constr)
if not result is [Link]:
r, l = result
114 ◾ STEM Problems with Mathcad and Python

r0, l0 = r, l
h1h2r[ih1, ih2] = r
h1h2l[ih1, ih2] = l
return h1h2r, h1h2l, [Link](hminmax[0], hminmax[1], n)

Te parameters transferred are: n—the number of mesh divisions on the h_1, h_2 planes;
rminmax, lminmax, hminmax tuples of minimum and maximum values of r, l, h_1, h_2; in
addition, the function that calculates the admissibility of the solution constr is passed: S, V—
surface area and volume of the submarine, r0, l0—initial approximations for r, l. Te function
returns two-dimensional arrays h1h2r, h1h2l of the radius and length of the submarine for the
given values h_1, h_2 and a one-dimensional array of h values, which we need for rendering.
Please note that some of the returned items will be equal to [Link]. Tey must be
excluded when rendering. Note also that the plot_surface function we used earlier work
exclusively with rectangular grids on which all values are defned.
We can solve this problem by excluding from the rectangular mesh the nodes in
which the values are [Link], and at the remaining nodes set the triangular mesh. Tis
operation is called triangulation; matplotlib allows you to do this and displays surfaces
in 3D space defned on an arbitrary triangular grid. We will solve the set task using the
visualize_h1h2rl function.
We additionally have to import the [Link] triangulation library. Te visualize_
h1h2rl functions, in addition to the results of solving the system of equations, are passed
to a colormap that connects the r, l values with the color and font size for displaying labels
on the coordinate axes.

import [Link] as mtri


def visualize_h1h2rl(h, h1h2r, h1h2l, cmap='jet', fontsize=14):
H1, H2 = [Link](h, h)
h1, h2 = [Link](), [Link]()
r, l = [Link](), [Link]()
ir = ~[Link](r)
h1, h2, r, l = h1[ir], h2[ir], r[ir], l[ir]
tri = [Link](h1, h2)
triangles = [Link]
fig = [Link](figsize=(14,6))
ax = [Link](121, projection='3d')
ax.plot_trisurf(h1, h2, [Link]([Link][0]),
triangles=triangles,
cmap='binary_r', alpha=0.3)
c = ax.plot_trisurf(h1, h2, r, triangles=triangles, cmap=cmap)
ax.set_xlabel('$h_1$', fontsize=fontsize)
ax.set_ylabel('$h_2$', fontsize=fontsize)
ax.set_zlabel('$r$', fontsize=fontsize)

[Link](c, fraction=0.038, pad=0.06)


Trust but Verify ◾ 115

ax = [Link](122, projection='3d')
ax.plot_trisurf(h1, h2, [Link]([Link][0]),
triangles=triangles,
cmap='binary_r', alpha=0.3)
c = ax.plot_trisurf(h1,h2, l, triangles=triangles, cmap=cmap)
ax.set_xlabel('$h_1$', fontsize=fontsize)
ax.set_ylabel('$h_2$', fontsize=fontsize)
ax.set_zlabel('$r$', fontsize=fontsize)
[Link](c,fraction=0.038, pad=0.06)
plt.tight_layout()

First of all, we create two-dimensional grids H1, H2, afer which, to perform triangulation,
we turn all two-dimensional arrays into one-dimensional ones and exclude invalid grid
nodes with [Link] values, this is done using the isnan function. Note that applying isnan
to an array returns an array of True and False values, which can be used to index other
arrays to isolate a subset of valid values.
We cover the resulting area defned by the nodes h1, h2 with triangles and, using trisurf,
display the dependences of r, l on h1, h2. To do this, a Figure object is created with two
subplots.
To see what the admissible area looks like on the h1, h2 plane we draw it in gray with a
transparency of 0.3. Te result is shown in Figure 4.21.
In this chapter, we have solved a simple engineering problem involving a system of
algebraic equations that has no unique solution. We have used symbolic, graphical and
numerical methods. Te absence of a unique solution forced us to analyze how many solu-
tions work, using an approximate solution. We, in turn, used the approximate solution as
an initial approximation for the exact solution.
At all stages, we had to check whether the results obtained made sense. Tis is connected
both with the mathematical methods we use, in this case with equivalent transformations,
and with the physical feasibility of the results obtained, which allowed us to go through all
the main stages of solving engineering computational problems.

FIGURE 4.21 Dependences of permissible values of r, l on h1, h2.


116 ◾ STEM Problems with Mathcad and Python

TASKS FOR THE READER

1. Try to solve the problem posed in the chapter, using hemispheres as the bow and
stern part of the Nautilus. How will the structure of the solution change?
2. Try to solve the problem posed in the chapter, using semi-ellipsoids of rotation as the
bow and stern part of the Nautilus.
3. Tink about what other restrictions can be imposed on the solution, for example, in
order to make a long stay on the submarine comfortable, while controlling the pres-
ence of at least one solution to the problem.
4. Try to impose constraints on the values h, r, l, as we did in Python at the end of the
chapter, in Mathcad.
5. Change the S and V values. How will this afect the solution to the problem? Draw
spatial curves for them in one drawing.
6. Tink about whether it is possible to take into account the constraints in the process
of solving the problem? What do I need to do?
7. When analyzing the infuence of h_1, h_2 on the size of the submarine, investigate
the infuence of the constraints given by the constr function.
8. Explore how the volume and surface area of a submarine afects the allowable values
of its diameter, hull length, new and stern lengths.

REFERENCES
1. Ochkov, V., Vasileva, I., Nori, M., Orlov, K., Nikulchev, E. Symbolic computation to solving
an irrational equation on based symmetric polynomials method // Computation. Volume 8,
Issue 2, 1 June 2020, Article number 40 ([Link]
2. [Link], url: [Link]
[Link].
3. [Link], url: [Link]
[Link].
Chapter 5

Comet of 1811: Check


Harmony with Algebra

I n Chapter 3, “Reading Russian fiction and solving linear equations”, in Figure 3.14,
the values of two vectors were entered into the calculation, along which the trajectory of
the celestial body, the comet of 1811, was determined. Where did these figures come from?
In Leo Nikolaevich Tolstoy’s novel War and Peace, you can read (and we already wrote
about this in Chapter 3) that Pierre Bezukhov said:
“Joyfully, eyes wet with tears, I looked at this bright star, which, with inexpressible
speed as if flying an immeasurable expanse along a parabolic line, suddenly, like
an arrow piercing the ground, slammed into one place it had chosen, in the black
sky.”
Let’s show in another way—through physical laws, rather than formally through two
ready-made vectors, that this comet flew along an ellipse not a parabola. We will do this by
solving a system of differential, rather than linear algebraic, equations.
In December 1811, people, including Pierre Bezukhov, did not yet know that comet
C/1811 F1 (this is its official astronomical designation) does not fly in a parabola, as Tolstoy
believed, or hyperbola, but in a closed elliptical trajectory with a period of about 3,096 years.
Figure 5.1 summarizes the 1811 comet data from Wikipedia ([Link]
wiki/Great_Comet_of_1811). These numbers will serve as the initial data in our calculation.
Figure 5.2 shows a diagram of the comet flight problem—the parameters of an ellipse,
where the Sun is at one focus (F2). The coordinate origin is located in the center of the
ellipse, and from its left edge, near the focus F1, the comet starts vertically upward with
a velocity v. In space, of course, there is no top, bottom, left or right sides, but we will
adopt the convention that the Cartesian coordinate system has top, bottom, right and left
sides, on which positive and negative numbers are marked on the coordinate axes—on
the abscissa and ordinate. In space, there is also a third dimension, but for a start, we will
consider only a 2-D problem.

DOI: 10.1201/9781003228356-6 117


118 ◾ STEM Problems with Mathcad and Python

FIGURE 5.1 Information from Wikipedia about the comet of 1811.

Te frst line of the Mathcad calculation in Figure 5.3 introduces the values of the gravi-
tational constant G, the astronomical unit of length AU (it is approximately equal to the
distance from the Earth to the Sun—150 million km) and the mass of the Sun (ms). Te
numbers are taken from Wikipedia.
On the second line, the mass of the comet’s nucleus (m) is estimated. We assumed that
the comet’s nucleus is a sphere with a diameter of 30 km (d) with a density of 500 kg/m3.
Te mass of the comet’s nucleus in our calculation will not afect the shape of its orbit, since
this mass is negligible compared to the mass of the Sun around which the comet revolves.
But some value for this mass must be taken so that there is no error in the calculation,
which will be discussed below.
Te third line contains the parameters of the comet’s orbit, taken from Wikipedia—
the length of the semi-major axis of the ellipse a and its eccentricity e—the degree of its
Comet of 1811: Check Harmony with Algebra ◾ 119

FIGURE 5.2 Diagram of the comet fight problem. (See also Figure 2.6 in the Chapter 2.)

FIGURE 5.3 Start of the calculation of the comet fight.

oblateness (see Figure 5.1). A circle (a special case of an ellipse, when a = b) has zero eccen-
tricity. As the eccentricity approaches one, the circle fattens and gradually turn into an
ellipse, then into a straight-line segment, and then generally “smears” in the form of a
degenerate parabola (the eccentricity of a parabola is less than one, and a hyperbola is
greater than one). On the third line, the value of the comet’s orbital period is also entered,
which is assigned to the variable tend—we will numerically determine the parameters of the
comet’s orbit, starting from time zero to tend (one comet’s revolution around the Sun—one
comet’s encounter with the Earth—see Figure 5.1).
On the fourth line, using well-known geometric formulas, the length of the semi-minor
axis of the ellipse, b, the focal distance, c, and aphelion distance, Q (the maximum distance
to which our comet will move away from the Sun, which is at the right side focus), are cal-
culated. Te second such characteristic point is the perihelion with a minimum distance
from the Sun.
On the ffh line of the calculation, the comet’s velocity is set at the starting point we’ve
adopted, namely, at aphelion. Tis speed must be manually selected so that the length of
the semi-minor axis of the comet’s elliptical orbit becomes equal to the given value b. We
will return to this issue at the end of the chapter (Figures 5.9 and 5.10). Te variable N is
120 ◾ STEM Problems with Mathcad and Python

FIGURE 5.4 Numerical solution of a system of algebraic-diferential equations of comet fight.

the number of partitions into separate points of the time interval from zero (the start of
calculating the motion of the comet) to the value tend. Te coordinates of the comet will
be calculated at these points. Tis period of time is divided into months, of which twelve
a year.
Te Solve block (Figure 5.4) contains, frst, the function r(t), which sets the distance
from the comet to the Sun, indicating that this distance is equal to Q at the initial moment
r(0 s) = Q, and second, two well-known physical laws: Newton’s second law and the law of
universal gravitation. Newton’s second law says that the force acting on a material point is
balanced by the product of the point’s mass by its acceleration—by the value of the second
derivative of distance with respect to time (see the double-prime notation for the functions
x(t) and y(t)). Te force acting on the comet is the gravitational force, which is directly pro-
portional to the product of the mass of the two celestial bodies (i.e. the Sun and the comet)
and inversely proportional to the square of the distance between them. At the right edge
of the ellipse in Figure 5.2, however, there are other celestial bodies—the Earth, the Moon
and other planets of the solar system. But their efect is very small in comparison with the
efect of the Sun. In these two equations, it is possible, of course, to remove the comet’s
mass m, but this should not be done, since in this case the physical meaning of what has
been written will be lost. Te variable m here acts as a kind of comment. Te Mathcad
Prime package will not confuse this variable with the unit of length meter, since they have
a diferent type, which is externally marked with color—black and blue. Tere are two
balance of forces equations—in the X direction and in the Y direction (the principle of
superposition—the projection of vectors onto the coordinate axes). I would like to say—in
the horizontal (X-axis) and vertical (Y-axis) directions, but in space, as already mentioned,
there is no top and bottom! Te second fraction on the right-hand side of the force balance
equations is used to calculate the values of the projections of the gravitational force in these
same directions X and Y.
Te problem is solved numerically. Tis means that the Odesolve function built into
Mathcad generates discrete values of three required functions named r, x and y at given N
points of the orbit, from which the functions r(t), x(t) and y(t) themselves are created by
interpolation. If N is not specifed, then it will be equal to 1,000 by default. However, this is
too small for our calculation, especially in the area near the Sun.
Comet of 1811: Check Harmony with Algebra ◾ 121

FIGURE 5.5 Orbit of 1811 comet (axes have diferent scales).

Te frst function, called r, returns the distance from the Sun to the comet as a function
of time t. Te other two, named x and y, are the coordinates of the comet. Teir values and
the values of their frst derivatives (values of two projections of velocities) at the initial
moment of time are also set by the user.
Figures 5.5 and 5.6 show the calculated trajectory of the comet as a whole (Figure 5.5)
and near the Sun (Figure 5.6).
In Figure 5.5, the ellipse is drawn with two lines — a thick pale line (yellow in the color
version of the picture) and a thin black line running inside a thick pale line. Te thick pale
line is the comet’s trajectory obtained by numerically solving the system of diferential
equations (Figure 5.4), and the thin black line is an ellipse with semi-axes a and b, con-
structed parametrically with parameter α ranging from 0° to 360° (2π) in increments of
one angular degree (π/180). Tese two curves practically coincide, which testifes to the
high accuracy of the numerical implementation of our mathematical model of the motion
of a comet, implemented on a digital computer—a digital twin of a comet, as they say
now. Tis mathematical model allows you to calculate the speed of a comet at diferent
points in its orbit. In aphelion (the lefmost point in Figure 5.2), it is equal to the value we
set at 100 m/s (360 km/h is the speed of a racing car). At perihelion (the rightmost point
near the Sun), the comet accelerates to about 41 km/s. At the point where the comet is
approximately located at the present time (see the lower part of the ellipse to the right of
the Y-axis), its speed is approximately 16 km/s.
It is interesting to look at the trajectory of the comet near the Sun and the Earth
(Figure 5.6)—where Pierre Bezukhov saw it in December 1811.
Te dots in Figure 5.6 are the monthly cometary positions calculated from the diferen-
tial equations in Figure 5.4, and the dotted line passing through the points (almost through
the points!) is the arc of an ellipse with semi-axes a and b. It is the arc of an ellipse, not a
parabola, as Tolstoy wrote! Te points are very close to the dotted line, which once again
confrms the high accuracy of the numerical solution of the system of diferential equa-
tions of motion for the comet in 1811. If we connect the points with straight-line segments,
122 ◾ STEM Problems with Mathcad and Python

FIGURE 5.6 Te orbit of the comet in 1811 near the Sun (the axes have the same scales).

then we get a broken thick pale (yellow) line, which can be seen if we greatly increase the
right edge of the ellipse shown in Figure 5.5. Te coordinates of these points were found by
the Odesolve function, which performed piecewise linear interpolation in order to draw
curves using the user functions x(t) and y(t).
Tis comet was frst noticed in the sky by the French astronomer Honore Flaugerg on
March 25, 1811, which is marked at the top of Figure 5.6 (the comet moves clockwise). It
was at that time at a distance of 2.7 astronomical units from the Sun—see the arc of a circle
with the corresponding radius in Figure 5.6. And on September 12 of the same year, the
comet was at the minimum distance from the Sun (perihelion, 1.04 astronomical units).
Te dotted circle in Figure 5.6 with a radius of one astronomical unit is not the Earth’s
orbit, as one might think. Te fact is that the planes of rotation of the comet in 1811 and
the Earth around the Sun are tilted relative to each other by almost 107° (see Figure 5.1).
Terefore, the orbit of the Earth, if you draw it in Figure 5.6, will not represent a circle, but
again a strongly oblate ellipse, touching with its vertices a circle with a radius of one astro-
nomical unit. Te earth will rotate counterclockwise along this ellipse. Tis is indicated
by the fact that the angle of inclination of the orbits of the Earth and the comet is greater
than 90°.
Figure 5.6 graphically displays Kepler’s second law—a celestial body moving in an ellip-
tical orbit draws (sweeps out) sectors with the same area for the same time intervals, which
is a consequence of the fact that the celestial body’s velocities are diferent at diferent
Comet of 1811: Check Harmony with Algebra ◾ 123

FIGURE 5.7 Analytical equations describing orbital motion of the 1811 comet (Mathcad 15).

points of the elliptical orbit. Figure 5.6 identifes three such adjacent sectors with equal
areas s1, s2 and s3.
An analytical solution to the problem (ellipse equation) is also easy to obtain—see
Figures 5.7 and 5.8. Te equations used are derived in reference [1] (note: time zero is taken
to be at perihelion for this analytical solution).
Te important equation is the connection between the mean anomaly, M, and the eccen-
tric anomaly, E, given by: M = E − sin(E) (for historical reasons the word “anomaly” here just
124 ◾ STEM Problems with Mathcad and Python

FIGURE 5.8 Orbital trajectory and velocity of 1811 comet (Mathcad 15).
Comet of 1811: Check Harmony with Algebra ◾ 125

FIGURE 5.9 Finding v value in manual mode.

means “angle”)—see the diagram in Figure 5.7. M and E are functions of time. M is simply
calculated as the product of frequency and time, but E must be determined from the previ-
ously noted equation by an iterative process.
We assumed in Figure 5.3 that the starting speed of the comet at the initial, zero moment
of time (at aphelion) is equal to 100 m/s. But this speed can be determined more accurately.
Whether this is necessary for our rather simple mathematical model is a separate question.
Now we will just show you how you can refne this speed.
Figure 5.9 shows the fnal calculation of this quantity. Te frst approximation of the
starting speed is set at 100 m/s, and then the function y(t) is generated through the Solve
block with the Odesolve function. We have already described this earlier. Tis function
looks for the numerical values of the argument and the function at the maximum point—
at the top vertex of the ellipse. Te Maximize function works, based on the frst approxi-
mation t = 1,000 years. Te value of the function y at this point will be less than the value of
the semi-minor axis of the ellipse b. Ten it will be necessary to increase the value of v to
101 m/s. Te value of the function y at this point will be greater than the value of the semi-
minor axis of the ellipse b. Ten it will be necessary to reduce the value of v to 100.5 m/s.
Te value of the function y at this point will be less than the value of the semi-minor axis
of the ellipse b. Tese actions (successive approximations by the method of half division)
will need to be continued until—see Figure 5.9.
Te authors tried to automate this process by creating functions x and y with not one,
but two arguments: the frst argument is the comet’s fight time t, and the second is the
comet’s initial velocity v. Here’s what happened—Figure 5.10.
First, the function y was plotted for a fxed time taken from Figure 5.11 (1,269.292 years)
and at diferent values of v. Te graph clearly shows zero (the root is the point of intersec-
tion of the graph with the X-axis), marked with a vertical line. Eleven points of the graph
(v = 100, 100.1, 100.2, 100.3, 100.4, 100.5, 100.6, 100.7, 100.8, 100.9 and 101 m/s) were calcu-
lated for a rather long time, more than 23 seconds. Tis calculation was carried out using
the built-in function time (it has a formal argument—written down to zero), which returns
the machine time in seconds. Tis function is ofen used to optimize calculations—reduce
their execution time.
Ten an attempt was made to fnd the zero of the function using the built-in
Mathcad function root with a frst approximation. But the attempt was unsuccessful.
126 ◾ STEM Problems with Mathcad and Python

FIGURE 5.10 Finding the value of v using a graph.

FIGURE 5.11 Calculation of the frst and second cosmic velocities of the comet in 1811.

Tis failure could not even be explained by visitors to the forum [Link]
com/t5/PTC-Mathcad/Boundary-problem-with-f-x-Odesolve/m-p/756893#M198095.
Te failure to work with the root function, apparently, is due to the fact that when it is
called too many times, the user-defned function y(t, v).
Comet of 1811: Check Harmony with Algebra ◾ 127

If the initial velocity of the comet is increased, then its orbit will become circular (the frst
cosmic velocity v1). A further increase in speed will lead to the fact that the orbit will again
assume an elliptical shape, but the ellipse will not be fattened horizontally (see Figures 5.2,
5.5 and 5.8), but vertically: the semi-minor axis of such an ellipse will be located along the
X-axis, and the big one—along the Y-axis. When the second cosmic velocity v2 is reached,
the comet will fy along the parabola that Pierre Bezukhov had imagined. But Pierre would
not have seen this parabola, how far it would be from the Earth. A further increase in the
initial velocity v would lead to the fact that the comet’s orbit would transform into one of
the branches of the hyperbola.
Figure 5.11 shows the calculation of the frst and second cosmic velocities of the comet
in 1811.
Let’s go down to earth and solve the problem of the rotation of an artifcial satellite
around the Earth while explaining what the frst and second cosmic velocities are.
Te task. A launch vehicle at a height h from the Earth’s surface accelerates a satellite
parallel to the Earth’s surface. What is the satellite’s fight path?
Figure 5.12 shows the beginning of the calculation (in Mathcad Prime) of the satellite
fight around the Earth. Using the table (this is a new feature of Mathcad Prime), the fol-
lowing initial values are entered:

• Gravitational constant G;
• Earth mass m1;
• Radius of the Earth r1;
• Earth satellite mass m2;
• Starting altitude of the satellite above the Earth’s surface h;
• Estimated fight time of the satellite tend.

FIGURE 5.12 Initial data for calculating the fight of the Earth satellite.
128 ◾ STEM Problems with Mathcad and Python

Ten, using two well-known square root formulas (Figure 5.11) we calculate:

• Te frst space speed v1—the speed at which a satellite will fy around the earth in a
circular orbit with a radius equal to that of the earth;
• Te second space speed v2—the speed at which the satellite will move away from the
Earth in a parabolic orbit.

Ten, through two matrices (a matrix with physical quantities and formulas is assigned
to a matrix with variable names), the following quantities are entered into the calculation:

• Starting Cartesian coordinates of the center of the Earth x10 and y10;
• Starting Cartesian coordinates of the Earth satellite x20 and y20;
• Projections of the starting speed of the Earth vx10 and vу10;
• Projections of the starting speed of the Earth satellite vx20 and vу20.

From the numbers in the matrix in Figure 5.12 it follows that the satellite starts horizon-
tally from the Earth’s surface (h = 0) at a speed exceeding the frst space speed by 1 km/s.
Te earth is stationary, and its center is at the origin of the Cartesian coordinates.
Figure 5.13 shows the Mathcad operators for the numerical solution of a system of one
algebraic and four diferential equations describing the motion of a satellite around the
Earth. Tese equations are collected in the Constraints area of the Solution block (see the
lower right corner in Figure 5.13). Te equations describe three fundamental physical laws:

FIGURE 5.13 Calculation of the Earth satellite fight.


Comet of 1811: Check Harmony with Algebra ◾ 129

• Te law (principle) of superposition, which states that any complex movement can
be divided into two or more simple ones—into “horizontal” (along the abscissa) and
“vertical” (along the ordinate) as in our problem;
• Newton’s second law, which states that the forces acting on a material point are bal-
anced by the product of the point’s mass by its acceleration (by the second time deriv-
ative of the path);
• Te law of universal gravitation, which says that two celestial bodies are attracted to
each other in proportion to the product of the masses of the two bodies, is divided by
the square of the distance between the bodies (between material points); the aspect
ratio is the gravitational constant G.

In the Constraints area to the right of the main equations, the initial conditions are also
written in the form of equations—the numerical values of the desired function r(t), x1(t),
y1(t), x2(t), and y2(t) at the initial time moment t = 0 s.
Since we have second-order diferential equations, the numerical values of the frst
derivatives are also set—the values of the projections of the velocities at the initial moment
of time x1ʹ(t), y1ʹ(t), x2ʹ(t) and y2ʹ(t). Te numerical solution of our problem will consist in
tabulating the desired functions—in fnding their numerical values at individual points in
the interval from 0 (these values are given) to tend, followed by interpolation of tabular data
and the generation of fully-fedged smooth continuous functions that can be displayed
graphically and have other computational procedures performed on them. By default,
1,000 points are tabulated, but this option can be changed through the third additional
argument to the Odesolve function.
Figure 5.14 shows a graphical representation of the solution to the system of equations
shown in Figure 5.13. If the satellite is launched “horizontally” from the Earth’s surface

FIGURE 5.14 Satellite in orbit around the earth.


130 ◾ STEM Problems with Mathcad and Python

FIGURE 5.15 Trajectories of the satellite (probe) around (from) the center of the Earth.

(h = 0) at a speed greater than the frst space velocity (v1—see Figure 5.12) and less than the
second space velocity (v2), it will enter an elliptical orbit.
Figure 5.15 shows the orbits of a satellite launched from the Earth’s surface in the hori-
zontal direction with diferent initial velocities v:
v = 0: the satellite fies (falls) in a straight line toward the center of the Earth, if we assume
in our mathematical model that the Earth is not a sphere with a radius r1, but a material
point with a circle outlined around it; the segment of the straight line along which the sat-
ellite fies is a degenerate ellipse; note: if the variable vx20 is set to zero, then the numerical
solution of the problem (see Figure 5.13) will be interrupted by an error message; therefore,
you need to set the value of the variable vx20 to slightly more than zero;

• 0 < v < v1: the satellite “fies” in an elliptical orbit inside the Earth, if, again, the Earth
is considered not as a ball with radius r1, but as a material point with a circle outlined
around it with radius r1;
• v = v1: the frst space velocity is also called the circular velocity; our satellite will fy in
a circular orbit with a radius of r1 (on the surface of the Earth);
• v1 < v < v2: the satellite fies around the Earth in an elliptical orbit (see also Figure 5.14);
• v = v2: the second space velocity is also called parabolic velocity; our satellite will
move away from the Earth along a parabolic trajectory (this is no longer a satellite,
but a kind of space probe);
• v > v2: the space probe will move away from the Earth along a hyperbolic trajectory.

Te orbit of comet 1811 (Figure 5.5) is somewhere in between the two orbits shown at the
lef edge of Figure 5.15: vx20 is almost zero (comet has 0.1 km/s and vx20 is 3 km/s). Note also
that our 1811 comet started from the extreme lef top of the future ellipse, and the Earth’s
satellite started from the top top of the future ellipse.
Te center of the Earth in Figure 5.14 is marked as a fxed point. But this is certainly not
the case, to be very precise! Tis center is also moving, but very slightly.
Figure 5.16 shows the migration of the center of the Earth around which the satellite is
launched. It can only be called migration (movement) with a big stretch of the imagina-
tion: on the axes of the graph in Figure 5.16, the length is given in units of am (attom-
eter)—10−18 m (see the input of this unit of length in Figure 5.16); in Figure 5.14 another
Comet of 1811: Check Harmony with Algebra ◾ 131

FIGURE 5.16 Moving the Earth with a satellite.

slightly unusual unit of length Mm (megameter—thousand kilometers, million meters)


is introduced into the calculation, with which we measure the coordinates of the satellite.
Hence the conclusion: if the mass of the satellite is much less than the mass of the planet
(the case shown in Figures 5.12–5.16), then the functions x1 and y1 can be removed from
the calculation and a system of one algebraic and two diferential equations can be solved,
assuming that x1(t) = 0 and y1(t) = 0.
Remark. In Figure 5.14, a circle representing the Earth’s surface was drawn using the para-
metric form of writing a circle: the parameter α (alpha) was introduced, along which a circle
was drawn using the sine and cosine. But this could be done in the way shown in Figure 5.17—
by solving the canonical equation of the circle and drawing two semicircles on the graph.
Te canonical equation of the circle (Figure 5.17) is obtained if the following coefcients
are set in the equation of the second-order curve (Figure 5.17): a11 = 1, a12 = 0, a22 = 1, a1 = 0,
a2 = 0 and a0 = −r12.

5.1 END OF THE REMARK


Te problem of the motion of two celestial bodies is solved not only numerically, which
we showed above, but symbolically (analytically) with the generation of curves (orbits and
trajectories) of the second order. Tis can`t be said about the problem of three or more
celestial bodies (material points) which can only be solved numerically in general.
Figure 5.18 shows a system of three algebraic and six diferential equations, prepared in
the Mathcad Prime package for solving the problem of the motion of three celestial bodies.
132 ◾ STEM Problems with Mathcad and Python

FIGURE 5.17 Creating a graph of a circle by drawing two semicircles.

FIGURE 5.18 Te problem of three celestial bodies—numerical solution.


Comet of 1811: Check Harmony with Algebra ◾ 133

FIGURE 5.19 A special case of solving the problem of three celestial bodies.

FIGURE 5.20 A special case of solving the problem of three celestial bodies.

If you set the required initial data, you can get quite interesting trajectories of three bod-
ies—see Figures 5.19 and 5.20.
Figure 5.19 shows the fight of three celestial bodies along the infnity sign afer they
have been given certain initial positions and speeds. Te black (frst) body will fy from the
center of coordinates to the right and up, and the blue (second) and red (third) from the
134 ◾ STEM Problems with Mathcad and Python

FIGURE 5.21 Initial conditions of the satellite interception problem.

other two points to the lef and down. Tese three bodies will rotate endlessly both in the
sense of time and in the sense of the trajectory—writing out the symbol of infnity. Tis
is one of those cases where the three-body problem has an analytical solution that can be
used to verify the numerical one.
Figure 5.20 shows the interception of a satellite of one planet by another planet. Tis
case is notable for the fact that a change in the method for solving the problem (and this
is possible in the Mathcad 15 environment) leads to a qualitative change in the three-body
fight pattern—the process of intercepting a satellite changes to the process of knocking it
out of orbit. Te initial conditions for this problem are shown in Figure 5.21.
On the website [Link]
ODEs-solution/td-p/736652 you can see the animation of the 1811 comet moving around
the Sun, and on the website [Link]
Mechanics/mp/562213 animations of other interesting cases of the movement of celestial
bodies.

5.2 A LITTLE MORE ABOUT ELLIPSE, PARABOLA AND


HYPERBOLA OR SECOND-ORDER CONICAL BEETLE
If you ask schoolchildren or students what a circle is, then almost all of them will answer in
unison that this is the geometrical locus of points on a plane, equidistant from the center of
the circle. By no means all, but many schoolchildren or students will also without hesita-
tion answer a similar question about an ellipse—about a “fattened” circle, noting that the
ellipse has not one, but two “centers” called foci. An ellipse is a locus of points on a plane,
the sum of the distances from which two foci is constant. By the way, an ellipse can have
more than two foci. Te three-focus ellipse is named afer Count Tschirnhaus, who frst
explored such ovals. You can calculate the percentage of schoolchildren and students who
will say what curves we get if, in the defnition of an ellipse, the addition is replaced by
other three elementary arithmetic operations—subtraction, multiplication and division.
Reader, do you know these curves? Check yourself, and then read the book further!
So, if addition is replaced by subtraction, multiplication or division, then we will get,
respectively, a hyperbola, Cassini’s oval and... (the circle is closed) again an ellipse, more
precisely, its special case is a circle—the circle of Apollonius. If in the arithmetic operator
the subtraction of the operands is reversed, then the second branch of the hyperbola will
be obtained. You need not do this, but simply take the absolute value from the diference
between the two distances to the foci and immediately get two branches of the hyperbola.
When dividing, you can also swap the numerator and denominator and get two circles—
the circle of Apollonius.
Comet of 1811: Check Harmony with Algebra ◾ 135

In the case when the product of distances from points to two foci is large enough, the
Cassini oval becomes like an ellipse. Tis is one of the reasons why, at the time of the birth
of celestial mechanics, scientists argued about in which orbits the planets and their satel-
lites fy—along the ellipse or along the Cassini oval. But it was proved that these orbits have
the shape of an ellipse or a circle (a special case of an ellipse). Tis is one of the greatest
scientifc discoveries of mankind, and we used it in this and the previous chapters of the
book. Note also that when the product of the distances from the points to the two foci is
small enough, the Cassini oval splits into two pear-shaped ovals. At the moment of divid-
ing the Cassini oval into two separate ones, it forms a beautiful well-known curve in the
form of an infnity sign—the Bernoulli lemniscate.
A circle, an ellipse, and a hyperbola are obtained when a circular cone is cut by a plane.
Terefore, the ellipse and hyperbola are called conical curves. But here we missed the
parabola—a transitional link from monkey to man, sorry, from ellipse to hyperbola. We’ll
fx it!
Here is another question that perplexes not only schoolchildren and students, but even
many professors: what is a parabola? Here, when answering, many begin to remember the
quadratic equation, the graphical display of which gives a parabola. But here you have to
interrupt the respondents and ask them to start the answer traditionally: “A parabola is a
geometric locus of points on a plane that...”. Te continuation of the correct answer will
no longer rely on two points (foci), but on one focal point and on a straight line called the
directrix. In addition, the translation from the ancient Greek word ellipse: “defcient, lack”
will suggest the correct answer. Lack of what? Te lack of eccentricity—a parameter that,
along with the length of the semi-major axis, fxes the dimensions of the elliptical trajec-
tory of a celestial body—see Figure 5.1.
In one Russian novel, a lady is described who, in communication with others, managed
only 30 words. But she had a friend who was reputed to be a cultured girl—there were
about 180 words in her vocabulary. And she knew one word, which the frst lady could not
even dream of: it was a rich word—eccentricity. Shakespeare’s vocabulary is known to have
approximately 12,000 words, but not the word eccentricity. To be fair, let’s say that in the
dictionary of our friend’s lady there was not the word eccentricity, but another word that
we will not voice here.
Since we have touched on the literature, we will say that the term ellipsis means a def-
ciency, a gap in the text or speech of an element of a sentence, which is restored by means
of context.
Let’s go back to the parabola!
So, a parabola is a locus of points on a plane, equidistant from a point (called a focus)
and a straight line (called a directrix). In another way, we can say that at the points of a
parabola, the ratio of the distance to the focus to the distance to the directrix is equal to
one. Tis attitude is called the tricky and difcult to pronounce word eccentricity.
If this distance ratio is less than one, then we get an ellipse (see Figure 5.1) with its lack
of eccentricity. If this ratio of distances is greater than one, then we get a hyperbola with
its excess of eccentricity. In such a description of an ellipse and a hyperbola, one of the
two foci (see above) is replaced by a straight line (directrix). If the eccentricity tends to
136 ◾ STEM Problems with Mathcad and Python

infnity, then the two branches of the parabola will merge into one straight line. A priori, it
is assumed that the eccentricity of a circle is zero.
Tree remarks.

1. If historically it had happened that the reciprocal was considered—not the ratio of
the distance to the focus to the distance to the directrix, but the ratio of the distance
to the directrix to the distance to the focus, the ellipse would be called a hyperbola,
and the hyperbola would be an ellipse. A circle would have an eccentricity equal to
infnity, and a straight line would have zero. Te parabola would remain a parabola
with its unit eccentricity.
2. If a beam of parallel rays is sent to the parabola, they, refected from the parabola,
converge in focus. Tis physical and mathematical “hocus pocus” is used in parabolic
antennas.
3. If a lens has one side fat, and the other is made in the form of a paraboloid, then a
beam of parallel counting rays, passing through the lens and the directrix plane, con-
verges at the focus of the hyperbola.

Optical instruments—telescopes-refractors and telescopes-refectors have been widely


used in astronomy since ancient times. Hence, so have parabola and hyperbola.
Figure 5.22 shows a Mathcad program that draws a “conical” beetle: two hyperbola
branches (eccentricity 1.7), a parabola (1), an ellipse (0.7), and a focus (almost zero—see
Figure 5.23). Te headmistress is the vertical axis of the chart.

FIGURE 5.22 Te conical beetle drawing program.


Comet of 1811: Check Harmony with Algebra ◾ 137

FIGURE 5.23 One-eyed “conical beetle” of the second order.

How the program works in Figure 5.22.


Figure 5.22 shows a universal method for constructing almost any lines on a plane—
straight lines and curves, closed and open, unambiguous and ambiguous, single and in a
family... Te following mechanical analogy is suitable for describing this method. In times
past, in order to make any part, it was frst necessary to cast a workpiece, and then process
it on machines—turning, drilling, milling, planing, etc. Now, many such parts are made
on 3D printers that “stupidly” scan the volume of the future parts and drip the material
(plastic, molten metal, etc.) at the “right moment at the right point”. So, in the past, in order
to construct a curve by its description, and not by a formula, one had to look for its analyti-
cal expression and work with it, which in itself was a difcult, and in some cases, insolu-
ble problem. Now, in the era of high-speed computers, with displays and high-resolution
printers, it is also possible to “stupidly” scan an area of the graph and “drip” paint on the
display screen or on the printer paper where the point should be on the graph. Figure 5.22
shows how a parabola, a hyperbola, an ellipse, a circle and its focus are constructed by 2D
printing in a rectangular area bounded by the given values x1, x2 y1 and y2. To do this, an
auxiliary function “approximately equal” is introduced into the calculation (the opera-
tor “exactly equal” is not suitable here for obvious reasons), and in a double for loop with
parameters x and y, two vectors X and Y are created, storing the coordinates of the points
of the forming a parabola, a hyperbola, an ellipse, a circle and its focus. Tis construction
of curves, we emphasize once again, is not based on its quadratic analytical formula, but
on the basic defnition of those curves as a locus of points equidistant from the focus of
a parabola, etc and its directrix—a given straight line. For the parabola, for example, the
138 ◾ STEM Problems with Mathcad and Python

FIGURE 5.24 Calculation of the eccentricity of the comet of 1811.

distances from the current point of the parabola with coordinates x and y to its focus with
coordinates xf and yf and to the directrix are entered into the variables Lf and Ld, if (opera-
tor), of course, these distances are equal—approximately equal...
On the Internet, for example, [Link]
ics), you can fnd formulas (Figure 5.24), which can be used to calculate the eccentricity of
a second-order curve, if the numerical values of its coefcients are known—see Figure 3.15
in Chapter 3.
Figure 5.1 shows that the eccentricity of comet 1811 is 0.995125. We have in Figure 5.24
obtained almost the same value. Te circle of narration, in this chapter, has closed like
an ellipse—returned from Figure 5.24 up in Figure 5.1. It only remains to add that Pierre
Bezukhov (Figure 5.1) was not so wrong when he thought that this comet was fying in a
parabolic orbit. He was not one hundred percent right, but 99.99 percent right! Te eccen-
tricity of the comet in 1811 is almost equal to one, slightly less than one. If the eccentricity
were more than one, then the comet would fy not in an elliptical, but in a hyperbolic orbit,
and we would no longer see it.

TASK FOR THE READER


Create a program that simulates the solar system—the rotation of the planets around the
Sun.

REFERENCE
1. A.E. Roy, Orbital Motion. Published by Adam Hilger, 2008 DOI [Link]
BF01230230.
Chapter 6

Running along the Route


given by Pierre de Fermat,
or Geometric Optics

T he hare needs to hide in the forest from the wolf as soon as possible. It runs with
speed v, from point 0 to the forest at point 3 (see Figure 6.3). The perpendicular dis-
tance to the forest is Δ. The hare takes the shortest path to the forest and runs in a straight
line perpendicular to the starting edge of the field. It stumbles upon a circular area (point
1). This might be an agricultural helicopter pad with a smooth concrete surface, for exam-
ple, where it can run twice as fast at a speed of vr. This circular section of radius r is in the
middle of the field. At point 1, the hare changes direction, crossing the circular section
along a chord, leaving it with another change of direction (point 2) and finishing in the
forest along the shortest path (point 3). Determine the trajectory of the hare (more specifi-
cally, the coordinates of point 2), for which the total running time is minimal. The point of
intersection of coordinates is in the center of the circle.
Figure 6.1 shows the solution to this problem in Mathcad—the first line gives the input
data including the abscissa of the zero point x0. If this value is greater in absolute value than
the radius of the circle, then the hare can run in a straight line into the forest in 4 seconds,
without running into the circular area. But now we will consider the case when |x0| < r.
On the second line, the coordinates of the first point are set, followed on the third line by
the objective function with the name, Time, which has one argument—the abscissa of the
second point. This function is called the objective function because the object of our calcu-
lation is to minimize it. In other tasks, the goal may be to maximize the objective function
or equate it to a certain value.
The Minimize function, based on the initial guess of −0.5 m for x2, returns the value of
x2 for which the running time from the first to the third point (the beginning of the forest)
is minimal. Then the ordinate of the second point y2 is calculated.

DOI: 10.1201/9781003228356-7 139


140 ◾ STEM Problems with Mathcad and Python

FIGURE 6.1 Start calculating the run of the stupid hare.

FIGURE 6.2 Graphically checking the minimize function.

Figure 6.2 shows a graphical test of the Minimize function. Tis function is usually
placed in a restricted Solve area—see Chapter 11, for example, and this chapter below.
But in our problem about the hare (Figure 6.1), we placed the constraint (the value of y2)
directly in the objective function, Time, itself. Tis allowed us to leave only one argument,
x2, in it, and not two—x2 and y2. Tis made it possible to visually verify that the minimum
was found—see Figure 6.2.
In Figure 6.3, the dashed line shows the hare’s running route, and the rays emanating
from the center of the circle help to indicate the angles of incidence and refraction of the
hare, or perhaps, light. Afer all, it’s not only hares that run along the shortest route but
also photons of light.
Running along the Route given by Pierre de Fermat ◾ 141

FIGURE 6.3 Graphical display of the stupid hare problem solution.

Fermat’s principle ([Link] states that


“the path taken by a ray between two given points is the path that can be traveled in the
least time”.
Te second important principle of geometric optics is Snell’s law—a formula used to
describe the relationship between the angles of incidence and refraction, when referring to
light or other waves passing through a boundary between two diferent isotropic media,
such as water, glass, or air ([Link]
Te calculation of the values of the angles on the path of the hare running to the forest
(angles of incidence and refraction) shows that at point 2 Snell’s law is fulflled, but at point
1 it is not!
Tis confused the author, and he posted the problem to the Mathcad users site https://
[Link]/t5/PTC-Mathcad/Hare-and-Snell-s-law/m-p/760586. Collective intel-
ligence and the boxed formula in Figure 6.3, demonstrated that our hare is not running
along the optimal route. Tat’s why it is a stupid hare.

6.1 THE TALE OF THE CLEVER HARE


Te clever hare has run across this feld many times and knows in advance that there is
an area in the center where you can run much faster. Terefore, it runs from point 0 to
the round section to point 1 not along the shortest path (greedy running algorithm), but
obliquely. It does, however, run along the shortest, vertical, path from point 2 to point 3.
142 ◾ STEM Problems with Mathcad and Python

FIGURE 6.4 New target function for the smart hare.

FIGURE 6.5 Graphical check the solution to the problem of running a clever hare (a contour plot).

Figure 6.4 shows how the objective function Time needs to be changed to solve the new
problem.
Te Time function in the smart task has two arguments. Te constraints (points 1 and 2
are on a circle with radius r) are both included in the Time function itself. Tis allows us to
have just two arguments and to be able to check the solution graphically, not on a separate
curve as in Figure 6.2, but on a contour plot—see Figure 6.5. (To do this we make the Time
function dimensionless, otherwise Mathcad Prime won’t construct the contour plot).
Running along the Route given by Pierre de Fermat ◾ 143

FIGURE 6.6 Graphical check the solution to the problem of running a clever hare (a surface plot).

Te graph in Figure 6.5 can be interpreted this way—this is a feld along which our hare
runs at diferent speeds, the value of which is marked with a contour graph. You can, if
you wish, calculate the trajectory of the hare running along such a feld, but for now, we
will restrict ourselves to one circular contour line (Figure 6.3), on which the hare’s speed
changes abruptly from 1 to 2 m/s.
Te graph of a function of two variables can also be illustrated on a surface plot—see
Figure 6.6. Tis “drooping” surface will help us clarify the essence of some numerical
methods for fnding the minimum of functions (see Figure 6.4). We place a steel ball (our
curled up hare) at the initial approximation point and release it. Te ball, sorry, the hare,
under the infuence of gravity, begins to roll along an intricate trajectory downward until
it stops at the minimum point. Here a new interesting problem arises—what trajectory
should the hare roll in order to reach the minimum point in the shortest time? Te calculus
of variations shows that such a trajectory should have the shape of a cycloid arc—a curve
resulting from the rolling of a round wheel on a plane.
In Figure 6.2, the low point is clearly visible and marked with a marker. In Figure 6.5,
this point is not so clearly visible—it is simply outlined by closed curves enclosing the min-
imum (the color indicates where the minimum is). A colored bar under the contour graph
marks the running time of the hare in seconds. Recall that a hare’s time running in directly
from edge to edge of the feld without running onto the circular area is 4 seconds. Te axes
of a contour plot are the abscissas of the frst (horizontal) and second (vertical) points.
Figure 6.7 illustrates the solution to the smart hare running across the feld, where
Snell’s law holds at both point 2 and point 1.
Te ovals in Figure 6.5 suggest a more difcult problem than that of a running hare,
namely, that for a ray of light. Oval stripes in Figure 6.5 can be considered not as the
range of values of the objective function Time for diferent values of the two arguments,
144 ◾ STEM Problems with Mathcad and Python

FIGURE 6.7 Graphical display of the smart hare problem solution.

but as sections of the feld requiring diferent running speeds. In the case of light, note
that its speed in the air depends on the air temperature, which may depend on the height
above sea level or the ground. As a result, a ray of light can “run like a hare” not in a
straight line, but along a curved line. Tis explains, in particular, the phenomenon of a
mirage, where we see on the sea or in the desert what we would otherwise not see along
a straight line.
What if the speed of the hare on the circular platform is signifcantly less than that
outside? For example, we might have a pond where the hare will need to swim. Te hare,
of course, swims reluctantly (the situation is, perhaps, reminiscent of the triathlon, where
athletes alternately run, swim and ride a bike). Te hare can move in diferent ways—run-
ning around it in an arc of a circle (recall the phenomenon of a mirage), swimming in the
water along a chord of a circle, or a combination of these two methods.
We tackle this by comparing the time for the hare to run around the pond in an arc with
the time to swim across a chord. We assume the scenario is as illustrated in Figure 6.8, so
only the times from point 0 to point 2 need to be compared (a priori, we don’t know that
point 1 will be the same for both situations; though it turns out they are, as we will see
later). Te values of the straight-line distance between start and safety, and the radius of the
circular region remain as for the previous cases. Te angle, ˜ , in Figure 6.8, is constrained
to lie between the angle, ˜ , made by a line from the origin to the start point, 0, and the
angle, ˜ , made by a line from the origin to a tangent line of the circular region that extends
to the start point (all angles measured relative to the positive x-axis).
Running along the Route given by Pierre de Fermat ◾ 145

FIGURE 6.8 Two possible paths.

FIGURE 6.9 (a) Two path data and functions (Mathcad 15). (b) Two path minimization compari-
son (Mathcad 15).

We see from Figure 6.9a and b that for the chosen start position and velocities the hare
takes less time along the arc path. Te minimum time in both cases occurs when the path
from the start position, 0, to position, 1, meets the circle at a tangent. If we increase the
velocity, vr, we will eventually fnd that the time to travel the straight-line from 1 to 2 is less
than that to travel the arc path (when straight/vr is less than arc/v).
146 ◾ STEM Problems with Mathcad and Python

Te problem is also modeled very simply using Python. Here is a Python program that
does the same task:

import numpy as np
from [Link] import minimize_scalar
from math import degrees as deg

# Distance, radius, velocity, in-circle velocity


D, r, v, vr = 4, 1, 1, 0.5

# Functions
def alpha(x): # Upper bound angle for point 1
return [Link](D/(2*x))
def gamma(x): # alpha - beta
return [Link](r/[Link](x**2 + (D/2)**2))
def beta(x): # Lower bound angle for point 1
return alpha(x) - gamma(x)
def x1(theta): # x-coordinate of point 1
return r*[Link](theta)
def y1(theta): # y-coordinate of point 1
return r*[Link](theta)
def t01(theta): # time to go from 0 to 1
return [Link]((x1(theta)-x0)**2 + (y1(theta)-D/2)**2)/v
def t02(theta): # time to go from 0 to 2 in straight line
return [Link]((x1(theta)-r)**2 + y1(theta)**2)/vr + t01(theta)
def t02arc(theta): # time to go from 0 to 2 along arc path
return r*theta/v + t01(theta)
x0 = 0.25 # x-coordinate of point 0
lo, hi = beta(x0), alpha(x0) # lower and upper bounds for theta

theta0 = (lo + hi)/2 # initial guess for theta


# Find angle at 1 and time from pt 0 to pt 2 along chord
res = minimize_scalar(t02, bounds = (lo,hi), method='Bounded')
theta12 = res.x
time12 = [Link]

# Find angle at 1, and time from pt 0 to pt 2 along arc


resarc = minimize_scalar(t02arc, bounds = (lo,hi),
method='Bounded')
theta12arc = resarc.x
time12arc = [Link]

print('\nStraight line')
print('Angle of pt 1 = ', round(deg(theta12),4), 'deg, Time = ',
[Link](time12,4), 's\n')
print('Arc path')
print('Angle of pt 1 = ', round(deg(theta12arc),4), 'deg,
Time = ', [Link](time12arc,4), 's\n')
Running along the Route given by Pierre de Fermat ◾ 147

Tis produces the following results, which agree with those of Mathcad:

Straight line
Angle of pt 1 = 22.6202 deg, Time = 2.5345 s

Arc path
Angle of pt 1 = 22.6201 deg, Time = 2.1448 s

Note that Python’s minimize_scalar function returns more than just the value of the min-
imization parameter; it also returns the value of the minimized objective function. Both
of these can be extracted by using post-fx notation: .x (for the value of the minimization
parameter) and .fun (for the value of the minimized function).
Both variants of the problem are also interesting because they are close to reality. Raindrops
hang in the air and refract white light, the components of which are refracted at diferent
angles. So much for a rainbow in the sky! You have a glass lens for a telescope (see below),
and it turns out to have a defect—a round air bubble. Te speed of light in glass is lower than
the speed of light in air—how will a ray of light will behave when it hits an air bubble in glass.
Te problems described above have real physical analogs.
We cast a glass plate for a future lens, inside which a defect has formed—an air bubble.
How will it refract light passing through the glass? Te speed of light in glass is known to
be lower than the speed of light in air—see Figures 6.3 and 6.7.
Te case when the speed of a hare running outside the circle is higher than in the circle
reminds us of... a rainbow. Tere are raindrops in the air, through which white light is
refracted—a mixture of colored rays of light. Te speed of light in water is known to be
lower than the speed of light in air. In addition, multi-colored rays of light have diferent
speeds in air, water and glass (diferent refractive index).
You can also consider the problem not with a circular section in the middle of the feld,
but with a section of a diferent shape—in the form of a square or a rhombus, for example.
Tere are some eccentric amateurs who mow intricate areas in a feld with wheat so that
those fying by plane can admire the picture. And how would hares and rabbits run away
from a wolf or fox run across such a feld?
We fnish the problem of two hares with an old Jewish joke and move on to more com-
plex and more real problems: Two students come to the professor and ask him to solve their
dispute about how a hare runs along a feld with a circular platform inside. Te frst student
says that as shown in Figure 6.3, and the second is as shown in Figure 6.7. Te professor
says they are both right. But here the professor’s wife shouts from the kitchen that the stu-
dents cannot both be right. Te professor sighs and says that his wife is also right!
Let’s model an optical device based on one more important principle of geometrical
optics, directly following from the Fermat principle, the principle of tautochronism: the
optical paths of light rays from a point source to its image are the same and the light spends
the same time on the passage of these optical paths.1
1 Te principle of tautochronism in general form is formulated as follows: the optical length of any beam between two
wave fronts is the same. We have clarifed this principle for the calculation in Figure 6.8, where one wave front is a point-
focus, and the second is a fat (upper) surface of the lens.
148 ◾ STEM Problems with Mathcad and Python

FIGURE 6.10 Solving the diferential equation of the lens.

At the end of Chapter 4, “Reading fction and solving linear equations,” we showed you
how you can calculate the orbit of a comet from the points in the sky. How were the coor-
dinates of these points determined? Trough telescopes with their lenses and mirrors. Let’s
take a look at how these optical instruments are designed.
Let’s simulate the efect of an optical lens on light (Figure 6.10). Mathcad can elegantly
and simply solve this more complex problem—see its diagram in Figure 6.10.
Figure 6.10 shows a diagram of the problem of a plano-convex lens made of a transpar-
ent material with a refractive index n. Te question is: what shape should the lower surface
of the lens have in order for a parallel light beam to converge at a focus spaced from the
origin (from the lower edge of the lens) at a focal length F? We intentionally turned the fat
side of the lens upwards to simplify the task. On the site of the book, the reader will fnd a
solution for the lens turned with the convex side up—to the light source. Tis is usually the
orientation when burning a mark on a tree on a sunny day with a plano-convex lens [5].
With the lens in this position, it is necessary to consider the refraction of the light beam not
once, but twice—at the boundaries “air-glass” and “glass-air”.2 Te solution to this prob-
lem can be found on the book website. In the case shown in Figure 6.10, light refraction
occurs only on the lower surface, and there is no refraction on the upper surface.

2 In the last century, many families had lenses with four interfaces between the “air-glass (or rather, plexiglass)”, “air-
liquid”, “liquid-glass” and “glass-air” media. Tey were placed in front of televisions, the screens of which in those days
were slightly larger than a postcard (see [Link] Tese lenses were flled
with water or glycerin, which has a higher refractive index.
Running along the Route given by Pierre de Fermat ◾ 149

Note that we are considering not a 3-d, but a 2-d problem. Te shape of the lens is the
surface obtained by rotating the 2-d curve around the ordinate, which is ofen overlooked.
Te numerical solution of the lens problem is shown in Figure 6.10. It is reduced to
solving a system comprising one diferential equation (the derivative of the function y(x)
is equal to the tangent of the slope of the tangent) and two algebraic equations. Te frst of
them is Snell’s law with a refractive index n, and the second expresses the tangent of the
“lower” angle β-α in terms of the ratio of the length of the opposite leg, x, to the length of
the adjacent leg, F + y (x).
Te lens, which should focus a parallel beam of light, does not have a spherical shape;
it is, as opticians say, aspherical (an asphere is a non-sphere): see the graph in Figure 6.10,
where a circular arc is drawn (dotted line) under the true curve y(x), passing through the
lower point of the lens and its edges. Aspherical lenses are typically made by grinding a
rotating spherical blank (see the dotted line in Figure 6.10) to the desired aspherical shape
(see the solid line in Figure 6.10).
School physics just assumes a lens surface that ensures the convergence of the par-
axial beam at a point called the focus. Te problem of fnding the shape of this surface
for a wide beam is not considered. Tis is understandable as, when the science of geo-
metrical optics was developing, there were no convenient, simple and accessible means
for solving equations—algebraic and diferential. Now they exist, and this enables us to
change the methods of solving problems and the very content of the academic discipline
of optics.
Te solid curve in the graph in Figure 6.10 is not one curve, but two that have merged
into one. Te frst curve, y(x), displays the numerical solution of the problem using the
built-in Mathcad function Odesolve, and the second ysym(x) is the analytical (symbolic)
solution. Tis “terrible” formula was derived by a Mathcad user called Luc Meekes from
Holland—the birthplace of the great Christian Huygens, who made a great contribution
to the development of optics. Luc had the good old 11th version of Mathcad with a sym-
bolic engine from Maple, not from MuPAD, which allowed him to solve the problem. And,
of course, his intelligence and skill helped. For the solution it was necessary to fnd the
asymptotes of the solid curve in Figure 6.8, i.e. fnd a cone into which the lens would ft
with an infnite increase in its diameter at a fxed focus. Finding the limit of the expres-
sion, y(x)/x, turned out to be impossible since the function y(x) is defned only in the speci-
fed range from the center of the lens to its edge. Anyway, the function y(x) is not a “real”
function, but a kind of pseudo-function created by interpolating table values generated by
a numerical method for solving an ordinary diferential equation. Te lens cone problem
was posted on the Mathcad user forum. Luc responded to the request and solved the prob-
lem analytically, fnding the required asymptotes for the resulting expression—see: https://
[Link]/thread/130129.
A literature and Internet search for the analytical equation of the lens (an aberration
curve) shown in Figure 6.10, found, in [4], the equation of the surface, for a lens with a
refractive index n relative to air and a focal length F, has the form:

(n 2 −1) y 2 + n 2 x 2 − 2n (n −1) Fy = 0
150 ◾ STEM Problems with Mathcad and Python

Tis equation allows one to express the dependence y = y(x) in an explicit form, without
going beyond the scope of school algebra. Indeed, it is only a quadratic equation

ay 2 + by + c = 0, in which c = n 2 x 2 ; a = n 2 −1;a = n 2 −1;b = −2n(n −1) F

If, when solving optical problems with lenses, we assume that the sine and tangent of an
angle are equal to the angle itself (and this, as is known, can be done at small angles3), then
the solution is greatly simplifed4 and, most importantly, many analytical and matrix solu-
tions become available, on which most of the optical formulas are based that “torture poor
schoolchildren and students.” Replacing the sines of the angles in Snell’s equation by the
angles themselves reduce the three equations from Figure 6.10 to one diferential equation
y′(x) (n−1) = x/(F + y(x)) with the initial condition y(0) = 0, which is easy to solve analytically
(for example, through separation of variables or directly through the Internet site), as well
as, of course, numerically (in Mathcad). Tese solutions are posted on the book site.
In our calculations, there were important assumptions: we considered the refractive
index of light n as a constant that does not depend on the wavelength of the light beam
(the phenomenon of chromatic aberration), or on the intensity of the light fux, or on the
position of the beam in the refractive material. But we should recall a glass prism, which
decomposes white light into color components and helps, for example, determine the com-
position of a substance by spectroscopic methods. Tis made it possible, for example, to
fnd helium frst on the Sun, and only then in the Earth’s atmosphere. Always remember
that real lenses reduce a beam of light, not to a point, but to a kind of rainbow bunch of
light energy, with which boys play on sunny days, burning all kinds of fgures on a tree.
Te heroes of Jules Verne’s novel “Te Mysterious Island”, for example, made fre with the
help of two glasses removed from a clock. Tey flled this makeshif lens with water (see
footnote 1) and sealed the edges with clay. Tis is how a real incendiary glass was made,
which focused the sun’s rays on an armful of dry moss and ignited it.
Fermat’s optical principle can be applied to another important law—the law of light
refection. Figure 6.11 shows an analytical solution to the problem of the minimum travel
time of a ray of light from point 1 to a refecting surface (point 2) and to point 3. An objec-
tive function t is created with an argument l1 (horizontal ofset of point 2 from point one),
which is searched for the value of the argument at which the derivative is zero. Indeed, if
the function is smooth and continuous, then at the point of its minimum the derivative
is equal to zero. Figure 6.11 shows that the minimum of the function t (l1) occurs when
the tangent of the angle of incidence α is equal to the tangent of the angle of refection β.
Terefore, α = β. By the way, refection and refraction “go hand in hand”: light falling on a
glass surface, for example, is partially refected, and partially refracted deep into the glass,
and the ratio of these parts depends on the angle of incidence.

3 Tis assumption, by the way, is also made when considering a mathematical pendulum, the thread of which deviates
from the horizontal by an angle whose value does not exceed 5°–7°. Many people remember the formula for the oscilla-
tion period of a pendulum, but few people know that it refers to a mathematical, not a physical pendulum.
4 In the problem in Figure 6.2, by the way, such a simplifcation would complicate the task—it would be necessary to intro-
duce the arcsine into the calculation.
Running along the Route given by Pierre de Fermat ◾ 151

FIGURE 6.11 Proof of the law of light refection.

Te book site contains a calculation of the shape of a mirror that focuses on a parallel
beam of light at a point. It is shown once again that this is a parabola or rather a paraboloid.

6.2 MATRIX OPTICS


Geometric optics is the frst approximation in the description of light processes. In geo-
metric optics, the propagation of a light wave is modeled using rays—lines along which
light waves move. Tis does not take into account the wave phenomena of light (difrac-
tion and interference). Further, when describing the passage of rays through an optical
system, only meridian rays are taken into account, as a rule, i.e. rays that we depict in the
plane of the drawing of the optical system. Also, nonlinear efects associated, for example,
with the dependence of the refractive index of a substance on the radiation intensity, are
ignored.
Even when these complexities are ignored, calculations can remain difcult because of the
n!
nonlinear nature of refraction, as described by Snell’s law: n1 ˝sin ( ˜1 ) = n2 ˝sin ( ˜ 2 ) ,
r !(n − r )!
(where ni is the refractive index of medium i, and ˜i is the angle of incidence/refraction).
However, the calculations may be greatly simplifed when the angles become very small,
such that sin ˜ ° ˜ . Tis is known as the paraxial optics approximation, or, simply, the
paraxial approximation.
For optical system calculations using the paraxial approximation, it is convenient to use
matrix methods, especially when computer programs that handle matrices are available.
A detailed description of the methods of matrix optics can be found in the book by A.
Gerrard, D. M. Birch “Introduction to matrix optics”.
Te essence of the matrix optics method is to describe a light beam by specifying two
of its parameters: the height, y, above the optical axis, and the reduced angle, v, equal to
the product of the refractive index of the medium and the angle between the beam and the
optical axis, i.e., v = n · α. Te reduced angle introduced in this way has an interesting and
important feature—it does not change when light is refracted on a fat surface perpendicu-
lar to the optical axis, because of the linearization of Snell’s law: n1 ° ˜1 = n2 ° ˜ 2, so v1 = v2.
152 ◾ STEM Problems with Mathcad and Python

FIGURE 6.12 Ray propagation in free space.

6.3 FREE SPACE


First, let’s derive the matrix for ray propagation through free space (refer to Figure 6.12).
Using trigonometry and the small angle (paraxial) approximation, we have:
x ˝ n ˝˜ x
y 2 = y1 + x ˝ tan˜ ˙ y1 + x ˝˜ = y1 + = y1 + ˝v1
n n

and, since there is no refraction, v1 = v 2, so we have the following simple system of equations:

x
y 2 = y1 + ˛v1
n
v 2 = v1

˜ y2 ˝ ˜ y1 ˝
Which we can write in matrix form as: ˛ ˆ = R ˘˛ ˆ , where the propagation
° v2 ˙ ° v1 ˙
matrix, R, is:

° x ˙
1
R=˝ n ˇ (6.1)
˝ ˇ
˛ 0 1 ˆ

6.4 SPHERICAL SURFACE


Next, we’ll derive the matrix for ray propagation through a spherical refracting surface,
where the surface has radius, r, and the refractive indices are n1 and n2 to the lef and right
of the surface, respectively (refer to Figure 6.13).
Te refraction point of the ray does not change its coordinates, therefore y 2 = y1.
Refraction satisfes Snell’s law in the paraxial approximation, so n1 ° ˜1 ˛ n2 ° ˜ 2.
By the triangle outer angle theorem:

y1
˜1 = ° 1 + ° = ° 1 +
r
y1
˜2 = ° 2 + ° = ° 2 +
r
Running along the Route given by Pierre de Fermat ◾ 153

FIGURE 6.13 Ray propagation through a spherical surface.

˝ y ˇ ˝ y ˇ
so: n1 ° ˆ ˜ 1 + 1  = n2 ° ˆ ˜ 2 + 1 
˙ r ˘ ˙ r ˘

y1 y
or: v1 + n1 ° = v 2 + n2 ° 1
r r

y1 y y
v 2 = v1 + n1 ˙ − n2 ˙ 1 = v1 − (n2 − n1 ) ˙ 1
r r r

˜ y2 ˝ ˜ y1 ˝
Tus, in matrix form: ˛ ˆ = R ˘˛ ˆ
° v2 ˙ ° v1 ˙
where the propagation matrix, R, is:

˙ 1 0 ˘
R=ˇ 
ˇ − ( 2 − n1 )
n (6.2)
ˇˆ 1 
r 

(Note that (equation 6.2) is only valid if r > 0)

6.5 BICONVEX LENS


Now, consider the passage of a ray through a thin biconvex lens with surface radii r1 and
r2, with n as the refractive index of the lens material. In this case, the transformation of the
beam by the lens is described by the product of two matrices: R = R2 R1, where, making use
of (equation 6.2) above, we have:

˛ 1 0 ˆ
R1 = ˙ n −1 ˘
˙ − 1 ˘
˙˝ r1 ˘ˇ

˛ 1 0 ˆ
R2 = ˙ 1− n ˘
˙ − 1 ˘
˙˝ r2 ˘ˇ
154 ◾ STEM Problems with Mathcad and Python

so that:

˙ 1 0 ˘
ˇ 
R=ˇ ˙1 1˘ (6.3)
− (n − 1)ˇ −  1 
ˇˆ ˆ r1 r2  

(Again, note that (equation 6.3) is only valid if r1 , r2 > 0).


When a beam passes sequentially through several optical elements, the resulting propa-
gation matrix R, is equal to the product of the corresponding matrices of each optical
element.

˛ A B ˆ
R = Rn Rn−1 …R2 R1 = ˙
˝ C D ˘ˇ

If we set each of A, B, C , D separately to zero, we get the following confgurations (see


Figure 6.14).

1. A = 0. A parallel beam of rays entering, exit to a point focus. (Figure 6.14a)


2. B = 0. A beam of rays entering from a point, exit to a point focus. (Figure 6.14b)
3. C = 0. A parallel beam of rays entering, exit as a parallel beam. (Figure 6.14c)
4. D = 0. A beam of rays entering from a point, exit as a parallel beam. (Figure 6.14d)

FIGURE 6.14 Paraxial ray confgurations.


Running along the Route given by Pierre de Fermat ◾ 155

FIGURE 6.15 Paraxial rays through glass ball.

6.6 GLASS BALL


Let’s fnd the focal position, x, of a glass ball of radius, r, and refractive index, n (Figure 6.15),
making use of equations (6.1–6.3).
Te propagation matrix, R, is R = R4 R3 R2 R1, where:

˙ 1 0 ˘
ˇ 
ˇ − (n −1)
R1 = 1st spherical surface
ˇˆ 1 
r 

° 2r ˙
1
R2 = ˝ n ˇ beam inside ball
˝ ˇ
˛ 0 1 ˆ

˙ 1 0 ˘
ˇ 
ˇ − (1− n )
R3 = 2nd spherical surface
ˇˆ 1 
−r 
° 1 x ˙
R4 = ˝ emergent beam
˛ 0 1 ˇˆ

Using Mathcad to multiply the matrices together we obtain:

ˇ 2˝ r + 2 ˝ x r + 2 ˝x 2˝ r + 2 ˝x 
 − −x 
 n ˝r r n 
R simplify ˛
 2˝(n − 1) 2 
 −1 
˘ n ˝r n 
2˝ r − n ˝ r
Case A = 0 R0,0 = 0 solve , x ˛
2˝ n − 2

2r − nr
Te focus is located a distance x = from the surface of the ball. Interestingly, for a
2n − 2
refractive index of n = 2, focusing occurs on the inner surface of the ball. Te action of a
spherical refector is based on this.
156 ◾ STEM Problems with Mathcad and Python

FIGURE 6.16 Paraxial rays through thick-walled glass sphere.

6.7 THICK-WALLED GLASS SPHERE


Now we’ll fnd the focal position of a thick-walled glass sphere of inner radius, r1 = 3 cm,
outer radius, r2 = 6 cm and refractive index, n = 1.5 (Figure 6.16).
Here, we have the overall propagation matrix, R, given by R = R8 R7 R6 R5 R4 R3 R2 R1, where
(refer to Figure 6.16):

˙ 1 0 ˘
ˇ 
ˇ − (n −1)
R1 = 1st spherical surface (i)
1 
ˇˆ r2 

˛ r2 − r1 ˆ
1
R2 = ˙ n ˘ beam from (i) to (ii)
˙ ˘
˝ 0 1 ˇ

˙ 1 0 ˘
ˇ 
ˇ − (1 − n )
R3 = 2nd spherical surface (ii)
1 
ˇˆ r1 

° 2r1 ˙
˝ 1 ˇ
R4 = 1 beam from (ii) to (iii)
˝ ˇ
˛ 0 1 ˆ

˙ 1 0 ˘
R5 = ˇ 
ˇ − (n − 1) 3rd spherical surface (iii)
1 
ˇˆ −r1 

˛ r2 − r1 ˆ
1
R6 = ˙ n ˘ beam from (iii) to (iv)
˙ ˘
˝ 0 1 ˇ
Running along the Route given by Pierre de Fermat ◾ 157

˙ 1 0 ˘
ˇ 
ˇ − (1 − n )
R7 = 4th spherical surface (iv)
1 
ˇˆ −r2 

° 1 x ˙
R8 = ˝ emergent beam path
˛ 0 1 ˇˆ

Again, using Mathcad to do the matrix multiplications we obtain:

solve , x 2 ˙ r 2 − 2 ˙ n ˙ r22 − 2 ˙ r1 ˙ r2 + n ˙ r1 ˙ r2
x ( r1 , r2 , n ) = R0,0 = 0 ˝ 2
simplify 2.( r1 − r2 − n ˙ r1 + n ˙ r2 )

r1 = 3 cm r2 = 6 cm n = 1.5

x ( r1 , r2 , n ) = 15 cm

Te thick-layer spherical shell acts as a difusing lens, the focus of which is 15 cm from the
last spherical boundary (or 3 cm to the lef of the sphere).
Note that individual propagation matrices, R3 and R5 , are not defned if r1 = 0, so these
matrices must be set to 1 in the limit as r1 ˜ 0. With this taken into account, the thick-
walled glass sphere reduces to that of the glass ball in this limit, as we would expect.
(Te author is grateful to the teacher of physics of the MPEI Sergey Fedorovich and the
teacher of physics of the lyceum № 1502 at MEI Aleksey Sokolov for help in writing this
chapter.)

6.8 CONCLUSIONS
Optics is present not only in textbooks and problem books on physics but also in fc-
tion. Let us recall not only Jules Verne (see above), but Pushkin’s “Everything is clapping.
Onegin enters,/Walks between the chairs on his legs,/Double lorgnette is leaning towards
him/On the boxes of unfamiliar ladies.” Or Vasily Shukshin’s story “Microscope”, as well
as Krylov’s fable “Te Monkey and Glasses”. Te eyes through which a person receives
the bulk of information about the world around him (reading, for example, this book) is
nothing more than the most perfect of optical instruments, which we ofen correct and
enhance with man-made optical devices: a monocle, lorgnette, pince-nez, glasses, a tele-
scope, binoculars, periscope, microscope, telescope, etc. Combining mathematics, physics
and literature (basic school subjects) with modern information technology, you can suc-
cessfully and, most importantly, enjoyably, solve rather complex optical problems, while
studying the laws of physics.
Modern computer tools make it possible to abandon many assumptions and simplifca-
tions and more accurately calculate optical devices. Tis can be done not only with the
help of specialized programs for calculating optical systems (TracePro, OPTIS, LightTools,
etc.), but also in the environment of the universal mathematical program Mathcad, as well
158 ◾ STEM Problems with Mathcad and Python

as with the help of Internet sites and specialists working in professional forums. And it is
possible and necessary to start studying optics not by memorizing ready-made formulas,
ofen incomprehensible due to the assumptions and simplifcations made in them, but by
constructing the basic equations of optics on a computer, then moving on to simplifed
formulas, which is what we have tried to do in this chapter.

TASK FOR THE READER


Calculate the trajectory of the passage of a beam of light in a telescope, microscope, or
binoculars.
Chapter 7

Patterns on a Complex Plane

T he geometric image of a complex number z = x + jy is a point on the complex plane


(Figure 7.1), when the real part, x, is displayed along the horizontal axis, and the imag-
inary part, y, along the vertical axis. Here, j denotes the imaginary part, as is customary
in Python.
A complex number can be represented by Euler’s formula (Figure 7.1):

 y
z = x + jy = re jϕ = r ( cosϕ + j sinϕ ) , ϕ = arctan   (7.1)
 x
If you specify a sequence of x , y or r , ϕ values, you can draw a curve. Below we draw an
Archimedean spiral using the formula z = ϕ e jϕ .

%matplotlib inline
import [Link] as plt
import numpy as np

n, φmax = 1000, 30

FIGURE 7.1 Representation of a complex number on a plane.

DOI: 10.1201/9781003228356-8 159


160 ◾ STEM Problems with Mathcad and Python

FIGURE 7.2 Archimedes’ spiral.

φ = [Link](0, φmax, n)
z = φ*[Link](1j*φ)

[Link](figsize=(6,6))
[Link]([Link], [Link], 'k-', lw=3)
plt. axis('off');

To draw a spiral (Figure 7.2), we used the plot function from the matplotlib library, which
can only work with real numbers, so we had to separate the real and imaginary parts of
the arrays.
Tus, to draw curves, it is enough to specify a sequence of values z. In this chapter, we
will consider the curves described by the formula (equation 7.2):

w (t ) = ˜a e
k=0
k
1 jbkt
(7.2)

where ak , are generally complex numbers, bk are real numbers, a0 = b0 = 1, 0 ˜ t ˜ 2π is a


sequence of real numbers used in drawing curves, and 1j is the imaginary unit. Using
Euler’s formula, equation (7.2) can be rewritten as:
n
ˆ n

w(z ) = ˜
k=0
bk
ak z = z ˘ 1+
ˇ
˜ k=1
ak z bk −1  , z (t ) = e jt

(7.3)

It is easy to see that for n = 0 the geometrical image of the formula (equation 7.2) is a circle
of unit radius.
To see the curves of formula (equation 7.2), we implement it as a function:

def curve(a=(1,0.5,0.3j), b=(1, 3, -7), n=5000, T=[Link]*2,


lw=3, color ='k', figsize=(4, 4)): Œ
Patterns on a Complex Plane ◾ 161

if len(a) != len(b): 
raise ValueError('The lengths a and b must be equal')

# array initialization
t = [Link](0, T, n) Ž
z = a[0]*[Link](1j*T*b[0])

l = len(a)
# curve points coordinates
for i in range(l): 
z += a[i]*[Link](1j*b[i]*t)

# draw curve
fig = [Link](figsize=figsize) 
ax=[Link](aspect='equal')

[Link]([Link], [Link], color+'-', lw=lw) ‘


[Link]('off')

return z

1. Te following arguments are passed to functions:


a, b – coefcient tuples;
n – the number of points on the curve;
T – the maximum value of the parameter t
lw – the thickness of the line for drawing a curve;
color – line color;
fgsize – the size of the picture.
2. Checking the same number of items in tuples a, b.
3. Initialization of arrays t, z.
4. Calculation of coordinates of curve points (array elements). z
5. Create a picture object using matplotlib and ensure equal axes scales.
6. Draw a curve and turn of the coordinate axes.
7. Te function returns an array of coordinates of the points of the curve.

Now you can analyze how the tuples a, b affect the curve. Figure 7.3 shows an ellipse corre-
sponding to the tuples a = (1, 2 ) , b = (1, −1). Multiplying the coefficients of the tuple a by a real
number leads to a change in scale along the axes of the coordinates, and by a complex num-
ber to a rotation of the ellipse. Figure 7.4 displays the curve for a = (1 + 1j , 2 + 2 j ) , b = (1, −1).
Changing the coefficients b allows you to get curves with self-intersections (Figures 7.5
and 7.6).
162 ◾ STEM Problems with Mathcad and Python

FIGURE 7.3 Curve for a = (1, 2 ) , b = (1, −1).

( )
FIGURE 7.4 Curve for a = 1 + 1 j , 2 + 2 j , b = (1, −1).

FIGURE 7.5 Curve for a = (1, 2 ) , b = (1, 2 ).


Patterns on a Complex Plane ◾ 163

FIGURE 7.6 Curve for a = (1, 2 ) , b = (1, −2 ).

FIGURE 7.7 Curve for a = (1, 0.1) , b = (1, 50 ).

Increasing the value b1 allows you to draw symmetrical patterns, as shown in Figures 7.7
and 7.8.
As mentioned above, the geometric image of each term of the formula (equation 7.2) is
the arc of a circle with radius ak e1 j˜bk ˜t , the center of this circle is on ak, the center of circle
a0e jb0t is at z = 0 + 0 j. Tis allows you to develop an interactive application with an anima-
tion of the curve drawing process (Figure 7.9).
Te curve_animation.ipynb application runs in a Jupyter Notebook and animates
drawing curves on a complex plane. Before you start drawing, you specify tuples a, b that
determine the shape of the curve, the number of frames of the animation, n, the size of
the picture, size, the thickness of the curve, lw. Separately note the parameter, step, that
164 ◾ STEM Problems with Mathcad and Python

FIGURE 7.8 Curve for a = (1, 0.7 ) , b = (1, 50 ).

FIGURE 7.9 Interactive application for animation of curve construction on a complex plane.

specifes the speed of display of the animation – the step with which the animation frames
are displayed. Te current position of the end of the curve is displayed with a red round
marker. In addition, circles, ak e1 j˜bk ˜t , and lines are displayed that mark the current value of
each member of the formula (equation 7.2) that describes the curve. Te title of the picture
is the current frame number. To start the animation, just set the curve parameters and
click the Run button.
Until now, we have assumed that all values bk are real numbers. If you specify complex
values bk .real + jbk .imag , then the geometric position of points for each term of the formula
(equation 7.2) will not make a circle, but a spiral that winds if bk .imag > 0 and unwinds if
bk .imag < 0. It should be remembered that, in this case, the radius of the circle will change
according to the formula, ak e − bk .imag °t , so you need to limit yourself to the values, bk .imag << 1
Patterns on a Complex Plane ◾ 165

( )
FIGURE 7.10 Draw a spiral for a = (1, ) , b = 1 − 0.02 j , , T = 50.

FIGURE 7.11 Open curve a = (1,2 ) , b = ( −1,1.1) , T = np. pi * 2.

as shown in Figure 7.10, where another spiral is drawn, which is not an Archimedean spi-
ral, because the radius of the spiral does not change linearly, but exponentially.
A sufcient condition for the periodicity of the curves described by equation 7.2 is
the condition that all the bk are integers. As soon as this condition is violated, the curves
become open (Figure 7.11).
However, as the parameter value T increases, patterns can form, as shown in Figure 7.12.
Consider curves that are regular concave polygons. For them, a = (1, m , ) b = (1, −m ).
Here is m +1 is the number of vertices of the polygon. For our implementation of the curve
function, it is necessary to increase the default T = 2 *np. pi * m so that the entire polygon is
drawn. In Figures 7.13 and 7.14, two such polygons are drawn.
Formula (equation 7.2) describes, as a special case, patterns that can be drawn with a
device called a spirograph [1]. In this device, the inner surface of the circle of radius R
moves along a circle of radius r , R > r (Figure 7.15).
At every moment of time, the circles touch and do not slip relative to each other. In a
real device, this is done with gearing. In the inner circle, at a distance ˜q ° r , q = 0, 1, …
from its center, one or more pens are embedded, moving with it. Tese pens draw curves
on the sheet of paper on which the spirograph is placed. Te curves are usually drawn in
diferent colors.
166 ◾ STEM Problems with Mathcad and Python

FIGURE 7.12 Te pattern obtained a = (1,2 ) , b = ( −1,1.1) , T = 100.

( )
FIGURE 7.13 Concave triangle, m = 2, a = (1,m ) , b = −1,1 m , T = 2 * np. pi .

When you move the inner circle clockwise, its center moves along a circle of radius R − r
(dotted line in Figure 7.15). If you move the center of the inner circle by angle ˜ clockwise,
the path traveled along the outer circle will be ˜ R. At the same time, the inner circle will
rotate at a counterclockwise angle ˜ , and its center will move to a clockwise angle ˜ . Since
there is no slippage, the movements along the outer and inner circles are equal:

˜ R = (˜ − ° ) r (7.4)
Patterns on a Complex Plane   ◾    167

( )
FIGURE 7.14 Concave pentagon, m = 4, a = (1, m ) , b = −1,1 m , T = 2 * np. pi.

FIGURE 7.15 Scheme of functioning of the spirograph.

Using equation (7.4), it is possible to express the angle of rotation of the inner circle relative
to the center:

β =−
(R − r )α (7.5)
r
168 ◾ STEM Problems with Mathcad and Python

Tis allows us to describe the functioning of the spirograph in terms of the formula
(equation 7.2):

˙
a = ( R − r , r ), b = ˇ 1,−
(R − r )˘
ˆ  (7.6)
r 

Formula (equation 7.6) describes the movement of a point on the surface of the inner circle.
For pens located at a distance ˜q from the center of the inner circle, 0 < ˜q < 1 (7.6) can be
rewritten as follows:

ˆ
a = ( R − r , ˜q r ), b = ˘ 1,−
( R − r )  , q = 0,1,.... (7.7)
ˇ r 

Drawing with a spirograph is implemented using the function:

def spirograph(R=1., r=0.75, ρs=(1., .75, .25),


T=10, n = 1000, figsize=(6,6), lw=3,
styles=('k-', 'k--', 'k:','k-.')): Œ
a = (R-r, r/R) 
b = (1, -(R-r)/r)
t = [Link](0, 2*[Link]*T, n) Ž
m = len(ρs)
z = [Link]((n, m), dtype=np.complex128)

for i in range(m): 
z[:, i] = a[0]*[Link](1j*b[0]*t) +\
a[1]*ρs[i]*[Link](1j*b[1]*t)

fig = [Link](figsize=figsize) 
ax=[Link](aspect='equal')
for i in range(m): ‘
st = styles[i%len(styles)] if styles else ''
[Link](z[:, i].real, z[:,i].imag, st, lw=lw,
label=f'ρ={ρs[i]:5.3f}')

[Link](loc='best') ’
[Link]('off')

1. Te following arguments are passed to the function: R– radius of the outer circle,
r – radius of the inner circle, ρs – tuple of positions of pens of the spirograph,
T – maximum value of t, n–number of points on curves, fgsize – size of the picture,
lw– thickness of the line for drawing curves, styles – styles with which lines are drawn.
If you set styles = 0, the curves will be drawn in color. All arguments passed to the
function have default values.
Patterns on a Complex Plane ◾ 169

FIGURE 7.16 Curves drawn by a spirograph for R = 1., r = 0.75 .

2. Form tuples a, b describing the shape of curves.


3. Initialize arrays to calculate the coordinates of the curves t, z. Note that the z array
will contain the curve coordinates for the writing tools given by the ρs array.
4. Calculate the coordinates of the curves.
5. Create a fgure object and make the scales along the coordinate axes the same.
6. In the loop, draw curves for all writing tools.
7. In the picture, display the legend and disable the display of coordinate axes and
digitization.

Figure 7.16 shows the curves for the default argument values.
In Figures 7.17–7.19, here are a few more families of curves drawn by the spirograph.
Our implementation allows us to do more than a real spirograph, we can set r > R
(Figure 7.20) and even negative r values (Figure 7.21).
Te formula (equation 7.2) allows you to draw an infnite number of curves, including
those presented in Figures 7.22–7.24 [2]. Some of them seem attractive, others don’t. In
our opinion, attractive curves should have symmetry, i.e., overlap with themselves when
turned through a certain angle.
Te rotation of the curve relative to its center is carried out by multiplying the complex
array z by e1 j˜ , where ˜ is the angle of rotation in radians. Figure 7.25 shows the original
curve of Figure 7.22, together with a version of itself rotated by 180°.
170 ◾ STEM Problems with Mathcad and Python

FIGURE 7.17 Curves drawn by a spirograph for R = 1., r = 0.7.

FIGURE 7.18 Curves drawn by a spirograph for R = 1, r = 1/ 3.


Patterns on a Complex Plane ◾ 171

FIGURE 7.19 Curves drawn by a spirograph for R = 1, r = .6.

FIGURE 7.20 Curves for R = 1, r = 1.25.


172 ◾ STEM Problems with Mathcad and Python

FIGURE 7.21 Curves for R = 1, r = −.8 .

FIGURE 7.22 Curve at a = (1, .2, .1) , b = (1, 7, −14 ).


Patterns on a Complex Plane ◾ 173

FIGURE 7.23 Curve at a = (1, .5, .3) , b = (1, 6, −14 ) .

( )
FIGURE 7.24 Curve at a = 1.,0.5,0.3 j , b − (1,6, −14 ) .

It is easy to check that when rotating by 120o, 240o the curves will be aligned. For the
curves shown in Figures 7.23 and 7.24, the rotation angle for combining the curves is 72°.
When you rotate the curve relative to its center by an angle, ˜ , the starting point cor-
responding to s = t0 , where t0 is fxed, will move to the curve. Select so that this point s,
remains in the same place. Tis means that for any 0 ˜ t ˜ 2° there is:

n n

˜a e
k=0
k
1 jbkt
− ˜a e
k=0
k
1 jbkt −1 jbk s +1 j˝
=0 (7.8)
174 ◾ STEM Problems with Mathcad and Python

FIGURE 7.25 Rotation of the curve at a = (1, .2, .1) , b = (1, 7, −14 ) by 180o.

You can show that if all the elements of the tuple b are calculated by the formula:

bk s − ˜ = 2˝rk (7.9)

where bk , rk are integers, and we need to set s,˜ . Let’s imagine bk in the form:

bk = mqk + h (7.10)

where m > 0, qk , h are integers. Substituting equation (7.10) in equation (7.9), we get:

mqk s + hs − ˜ = 2˙rk . (7.11)

Selection s = ˜ /h simplifes the expression (equation 7.11):

mqk˜ = 2˛rk (7.12)

Now, by fxing m, you can get a formula for generating curves that combine with them-
selves when turning by an angle: ˜

2˛rk
˜= . (7.13)
mqk
Patterns on a Complex Plane ◾ 175

So far, we haven’t chosen rk, so, set rk = qk, which simplifes (equation 7.13):


˜= (7.14)
m

We are also not limited in the choice of integer h in the formula (equation 7.10), so let’s set
h = 1. Tis allows us to formulate a simple algorithm for generating a family of curves that
reproduce themselves when rotating by an angle ˜ .

1. Set m ˜1, qmax defnes the maximum value of bk , as well as the tuple of the coef-
cients ak. Te length of this tuple is stored in the variable l.
2. Form a sequence −qmax, −qmax +1, …− 1, 1, 2,… qmax of valid values Qk .
3. Form a sequence of valid value bk according to the formula bk = mqk +1.
4. Generate tuples bk to draw curves and remove identical tuples.
5. Draw curves that have a given symmetry.

It should be noted that the generated curves can have additional symmetry elements when
rotating by angles, ˜ ° p, p = 2,3, ... as well as when mirroring from the horizontal and ver-
tical axes of coordinates. Below is the curve function, which is used not only to calculate
curves with given a, b.

def curve(a=(1,1,1), b=(1,1,-3), γ=0, s=0, n=5000):


t = [Link](0,1, n)
z = [Link](n, dtype=np.complex128)
for i in range(len(a)):
z += a[i]*[Link](2j*[Link]*(b[i]*(t-s)))
z *= [Link](2j*[Link]*γ)
return z

Te following arguments are passed to the function: tuples a, b that determine the shape
of the curve, the number of points n on the curve, also the values s – shif on the curve and
γ– the angle of rotation of the curve relative to the origin.
To check for the presence of an element of symmetry when rotating by an angle of
˜ = 2˛ i , i = 2,3, …, it is enough to shif by s = ˜ , rotate the curve by an angle −˜ and check
whether the original and transformed curves coincide. Te match is checked by the for-
mula (equation 7.8). If the match occurs for the given i, then it is said that the curve pro-
duces an axis of symmetry of the i-th order.
Mirror symmetry is somewhat more difcult to verify. To check the symmetry with
respect to the horizontal axis, it is necessary to shif by ˜ for the transformed curve, w,
calculate −w .conj(), change the direction of the transformed curve, and, fnally, compare
with the original curve. Here conj() means calculating the complex conjugate.
176 ◾ STEM Problems with Mathcad and Python

Similarly, checking the symmetry of the vertical axis passing through the origin of the
coordinates is done by shifing by ˜ = ˛ 2 and calculating −w .conj(). Changing the direc-
tion of the curve traverse is necessary, which is why mirror refections cannot be reduced
to curve rotations.
Symmetry checks for mirror refections are designed as functions h_refection() –
refection relative to horizontal, v_refection–vertical axes:

def h_reflection(a, b, n, eps=1e-5):


z_u = curve(a=a, b=b, s=0, n=n)
z_d = -[Link](curve(a=a, b=b, s=0.5, n=n))[::-1]
err = [Link]([Link](z_u - z_d))
return err<=eps

def v_reflection(a, b, n, eps=1e-5):


z_r = curve(a=a, b=b, s=.25, n=n)
z_l = [Link](curve(a=a, b=b, s=-0.25, n=n)[::-1])
err = [Link]([Link](z_r - z_l))
return err<=eps

Checking the presence of symmetry elements is carried out by the function:

def check_symmetry(a=(1,1,1), b=(1,1,-3), n=5000, eps=1e-5,


els=(2,3,4,5,6,7,8,9,10,12)):
z = curve(a, b, n=n, γ=0, s=0)
sym = []
if h_reflection(a, b, n, eps):
[Link]('h')
if v_reflection(a, b, n, eps):
[Link]('v')

for i in els:
γ = 1/i
u = curve(a=a, b=b, n=n,s=γ, γ=γ)
err = [Link]([Link](z-u))
if err<=eps and i>1:
[Link](str(i))
sym =f"[{','.join(sym)}]"
return z, sym

In addition to the arguments listed above, eps– the permissible error when checking the
symmetry elements and els – the tuple of the symmetry axes to be checked are passed. Te
function returns an array with the coordinates of the curve and a string with symmetry
elements.
Te auxiliary functions discussed above make it possible to generate galleries of curves
that have at least an axis of symmetry of order m.
Patterns on a Complex Plane ◾ 177

from itertools import permutations


def symmetric_curves(m=3, qmax=5, a=(1, .5, .3j), n = 5000,

eps=1e-4,
els=(2,3,4,5,6,7, 8, 9, 10, 12), rows=5,
cols=4, w=3, save=False):
qvals = [i for i in range(-qmax, qmax+1) if i!=1] Œ
bvals = [m*q+1 if q>=0 else m*(q-1)+1 for q in qvals]
p = tuple(permutations(bvals, len(a)-1)) 
bs = [] Ž
for b in p:
[Link](tuple([1] +list(b)))
bs = list(set(bs)) 
[Link]()

nb = len(bs) 
pics = rows*cols
pages = int([Link](nb/pics))
ipic = 0
for ipage in range(pages): ‘
fig = [Link](ipage+1,
figsize=(cols*w+1, rows*w+1))
pics_on_page = nb%pics if ipage==(pages-1) else pics
for i in range(pics_on_page):
[Link](rows, cols, ipic%pics+1,
aspect='equal') ’
b = bs[ipic]
ipic += 1
# calculate and draw curve
z, sym = check_symmetry(a=a, b=b, n=n,
eps=eps, els=els) “
[Link]([Link], [Link], 'k-', lw=3) ”
title = f'p={ipic}, b={b}'
# symmetry elements
if sym:
title += f', s={sym}'
[Link](title)
[Link]('off')
plt.tight_layout()
if save: •
fn = f'sym_curve a={a} m={m} qmax={qmax} ' +\
f'page={ipage}.png'
[Link](fn, dpi=300)
return nb

Following arguments are passed to function: m – the order of the axis of rotation, which
will have all the generated curves, qmax – the maximum value of the parameter used in
the formula (equation 7.10) to generate curves, n – the number of elements in the array of
178 ◾ STEM Problems with Mathcad and Python

coordinates of the curve, eps – the permissible error when checking the symmetry ele-
ments, els – the tuple of the symmetry elements to be checked. Te gallery of curves is
saved in the form of a sequence of drawings. Te layout is organized as a table with rows
rows and cols columns; w – width and height of the curve. Te argument save determines
whether to save the gallery to the fle system.

1. First, we prepare sequences of possible values qk bk for curves having an axis of sym-
metry of order m, according to the formula (equation 7.10).
2. Permutations of b form curves using the standard Python library function, which
returns all combinations of elements of a sequence of a given length. For example, a
call to list(permutations ([2,3,4],2)) returns [(2, 3), (2, 4), (3, 2), (3, 4), (4, 2), (4, 3)]. If l
is the length of the tuple a, then when generating combinations, we use l −1 because
for all curves b0 = 1.
3. Form a list of b tuples for drawing curves, adding 1 to the beginning of the tuple.
4. Remove possible repetitions and sort the list of tuples bs.
5. Now everything is ready to draw curves, calculate the total number of curves nb, the
number of curves pics on the page, initialize the curve number ipic.
6. Loop through a number of drawings, create a picture object and determine the num-
ber of curves pics _ on _ page on this page, because in the last picture there may be
fewer fgures than pics.
7. Looping through the number of curves on the page that we create for each subplot,
we ensure the placement of curves by row and columns. Note that we forcibly set the
same scales along the coordinate axes using aspect=‘equal’.
8. Create a curve and check the existing symmetry elements.
9. Display the next curve, and in the header display the tuple b and symmetry elements,
also disable the display of coordinate axes and digitization.
10. If save=True is set, then save the created pictures in the fle system.

Jupyter Notebook symmetric_curves. ipynb provides galleries of curves generated for dif-
ferent m. So, Figure 7.26 shows one of the gallery pages for m = 1 i.e. the minimum sym-
metry. In the gallery, there are fve curves, numbered 11–13, 16, 17, which do not have the
symmetry elements we have considered. Rotation by 360o, which corresponds to m =1, we
do not consider for an element of symmetry.
As you increase m, the number of symmetry elements increases, and the complexity of
the curves increases. Figure 7.27 shows one of the pages of the curve gallery for m = 3. Some
of the curves have a very whimsical shape, for example, 43–45, 55–58. As a rule, this is due
to the fact that one of the elements of the tuple bk is negative.
Figure 7.28 shows curves for m = 8. On it, the curves, although they have a large number
of symmetry elements, are overloaded with details, which interferes with their perception.
Patterns on a Complex Plane ◾ 179

( )
FIGURE 7.26 Page for curve gallery for m = 1, a = 1, .5, .3 j .
180 ◾ STEM Problems with Mathcad and Python

( )
FIGURE 7.27 Page for curve gallery for m = 3, a = 1, .5, .3 j .
Patterns on a Complex Plane ◾ 181

( )
FIGURE 7.28 Page for curve gallery for m = 8, a = 1, .5, .3 j .
182 ◾ STEM Problems with Mathcad and Python

FIGURE 7.29 «Gears».

Most of the generated curves can be broken down into classes, for example, Figure 7.29
shows curves belonging to the “gears” class.
Another class is “sockets” (Figure 7.30).
In the following Figure 7.31, you can observe the evolution of “rosettes”. “Stars” are simi-
lar to “rosettes”, moreover, “rosettes” can turn into “stars”.
Next, we embark on a rather slippery slope, attributing to “magic” a few curves that are
distinguished by their unusual behavior. In Figure 7.32 there are four such curves cor-
responding to m = 3–6. Te most attractive are the curves obtained for m = 4,5. When m
enlarged, the magic curves turn into hybrids of “stars” and “gears”.
Patterns on a Complex Plane ◾ 183

FIGURE 7.30 «Rosettes».

Te lef curve in Figure 7.33 corresponds to m = 7, and the right curve corresponds to
m = 9.
We have to see what happens to the curves when the tuple a changes and the b tuple is
fxed, for example: b = (1, 5, −11). Figure 7.34 shows how the “magic” curves change when
the elements of the tuple a change.
It would seem that increasing the lengths of the tuple coefcients a,b should gener-
ate more attractive curves, but this is not the case. Figure 7.35 shows the frst page for
a = (1, .5, .4 j , −.2, .1j ) and m = 4.
184 ◾ STEM Problems with Mathcad and Python

FIGURE 7.31 Stars with number of peaks from four to nine.


Patterns on a Complex Plane ◾ 185

FIGURE 7.32 “Magic” curves.

Note also that as the lengths of the tuples a, b increase, the number of curves generated
increases rapidly, for example, if the length of the tuple is fve and qmax = 5, the number
of generated curves is 5,040, and at length 7, the number of drawings increases to 151,200.
Terefore, it is recommended to generate not all, but only selected pages of pattern galleries.

TASKS FOR THE READER

1. Try to reproduce the patterns generated in this chapter.


2. Can you classify the patterns generated by the spirograph?
3. Try to come up with and implement your own curve generator.
186 ◾ STEM Problems with Mathcad and Python

FIGURE 7.33 Hybrids of “stars” and “gears”.

FIGURE 7.34 Te infuence of the tuple a on the shape of the “magic” curves.
Patterns on a Complex Plane ◾ 187

( )
FIGURE 7.35 Curve gallery page for a = 1, .5, .4 j , −.2, .1 j and m = 4.
188 ◾ STEM Problems with Mathcad and Python

4. At the end of the chapter, a generator of curves is implemented, which have at least
an axis of symmetry of order m. Consider how to automate the selection of attractive
curves.
5. Try to come up with your own classifer for the galleries of curves implemented at the
end of the chapter.

REFERENCES
1. Spirograph: URL: [Link]
2. Farris F.A. Creating Symmetry. Te Artful Mathematics of Wallpaper Patterns (Princeton,
Princeton University Press, 2015), 247 p., ISBN 0-691-16173-9.
Chapter 8

Rectangle Mappings on
the Complex Plane

I n Chapter 7, we considered mappings of a segment of a line using the function of a


complex variable f(z), as a result of which we got a gallery of curves of varying degrees of
attractiveness. In this chapter, we will map rectangles in the complex z-plane to the com-
plex w-plane using the functions w = f(z).
The physics of conformal mappings is fairly simple. Imagine a rectangle of rubber with
a rectangular mesh applied to its surface. If we stretch the rubber without allowing it to
break, the mesh will distort, but the corners of the cells will not change.
The stretching of the rubber rectangle corresponds to the transformation f(z), and for
all points f ‘(z) ≠ 0.
A mapping f(z) is called multivalued if one value of z corresponds to two or more values
of f(z). The mapping √z is multivalued, for example, z = −1 correspond to f(z) = 1j and −1j.
If the mapping f(z) is multi-leaf, then several z will correspond to one value of f(z). In
this case, the cells will overlap. An example is the mapping z2. For this, for example, points
z = 1, −1 will correspond to f(z) = 1.
A mapping f(z) is conformal in a domain D if it is single-valued and angle-preserving; at
each point of this domain, it has a derivative f’(z) ≠ 0.
As before, we will be interested in the visualization of (z, w), but z = x + j ∙ y, and w = u + j ∙
v, so we need to represent the surface in four-dimensional space. As we live in three-dimen-
sional space, this is difficult for us to do, so we will have to look for various approaches that
allow us to do it.
First, we can, as mentioned above, apply a uniform mesh with lines parallel to the coor-
dinate axes on the originally displayed rectangle in the Z-plane and see how this mesh
will distort when displayed on the complex W-plane. All this can be done on the plane by
drawing the original and transformed shapes next to each other.
Second, we can paint over the cells of the transformed grid with colors selected depend-
ing on the f(z) values in the center of the cell. In this case, one can associate a color with

DOI: 10.1201/9781003228356-9 189


190 ◾ STEM Problems with Mathcad and Python

either the real part f(z).real, the imaginary part f(z).imag, or the absolute value | f(z) |. We
also have the choice of the colormap – the correspondence between the f(z) values and the
color, since more than 100 colormaps are built into the Python matplotlib library and their
number grows from version to version.
Te third way to render (z, w) is to draw a 2D surface in 3D space. In this case, [Link],
[Link], and [Link] are plotted along the coordinate axes, and color is used to display
[Link]. Naturally, [Link] can be used as the third coordinate axis, and the fll color can
be associated with [Link].
Getting a list of matplotlib colormaps is very simple:

import matplotlib as mpl


import [Link] as plt

cn = [Link]()
ver = mpl.__version__
print(f'number of colormaps in matplotlib {ver} is {len(cn)}')

We get the result:

Number of colormaps in matplotlib 3.4.2 is 166

With the help of matplotlib, we will implement all of the above methods. Te frst two
methods are implemented as the c_map function.
We divide the original rectangle into n cells along the coordinate axes. Tus, the original
rectangle is covered by n2 cells. When transformed using the f(z) function, the cell borders
become curvilinear, and the cell itself is flled with the color corresponding to the value of
the f(z) function at the center of the cell. We can use the absolute value, real or imaginary
parts, or even refuse to fll the cell altogether. To display the curvilinear boundaries of the
cell, we divide each of them into m parts.
Te color corresponding to the value of the function in the center of the cell is deter-
mined by extracting it from the colormap object.

%matplotlib inline
import numpy as np
import matplotlib as mpl
import [Link] as plt
def c_map(n=20, m=10, ab=(0,0,1,1), f=lambda z:z, Œ
args=(), cmap='binary', lw=1, kind='',
axis=False, figsize=None, alpha=1):
xmin, ymin, xmax, ymax= (0,0,1,1) if not ab else ab 
hx, hy = (xmax - xmin)/n, (ymax - ymin)/n Ž
nm = n*m
x = [Link](xmin, xmax, nm) 
y = [Link](ymin, ymax, nm)
X, Y = [Link](x, y)
Rectangle Mappings on the Complex Plane ◾ 191

Z = X + 1j*Y
W = f(Z, *args) 
Wc = f(Z+hx/2+1j*hy/2, *args)

# colors
cmap = [Link].get_cmap(cmap) ‘
if kind=='real':
Wc = [Link]
elif kind=='imag':
Wc = [Link]
elif kind=='abs':
Wc = [Link](Wc)
wmin, wmax = [Link](Wc), [Link](Wc)

# draw cells
if figsize:
fig = [Link](figsize=figsize)

nm = n * m
for i in range(0, nm, m): ’
for j in range(0, nm, m):
im, jm = i+m, j+m
im = im if im<nm else im-1
jm = jm if jm<n*m else jm-1
cell = [Link]([ “
W[i:im, j], [W[im,j]],
W[im, j:jm],[W[im,jm]],
W[im:i:-1, jm], [W[i,jm]],
W[i, jm:j:-1], [W[i,j]],
])

if kind:
color = cmap((Wc[i+m//2, j+m//2] - wmin)/\
(wmax - wmin)) ”
[Link]([Link], [Link], lw=0, •
color=color, alpha=alpha)
[Link]([Link], [Link], 'k-', lw=lw) 11
if not axis: 12
[Link]('off')

1. Te following arguments are passed to the function:


n is the number of cells into which the original rectangle is divided along the coor-
dinate axes;
m is the number of partitions on the side of the cell;
192 ◾ STEM Problems with Mathcad and Python

ab = (xmin, ymin, xmax, ymax) – coordinates of the vertices of the original


rectangle;
f – transformation function;
args is a tuple of additional arguments passed to the function;
cmap – colormap used to paint cells;
lw – line width for displaying cell borders;
kind – the way the cell is painted; allowed values:
'' – cells are not flled,
‘abs’ – fll color corresponds to the absolute value of the display result in the center
of the cell;
‘real’ – the color is determined by the real part of the function value in the center
of the cell; ‘imag’ – the color is determined by the imaginary part of the function
value in the center of the cell;
axis – setting axis = False suppresses the display of the coordinate axes and
digitizing;
fgsize – the size of the picture; if fgsize is None, the drawing object is not created,
which allows displaying the results of several function calls in one picture;
alpha – the nontransparency of the cell shading.
2. Unpacking the coordinates of the vertices of the original rectangle.
3. Determine the lengths of the sides of the cells of the original rectangle.
4. Prepare a Z array of cell vertices on the complex plane. Tis is done in order to per-
form the conversion without loops using NumPy tools.
5. We carry out transformations of the vertices of the cells W and their centers Wc.
6. We prepare the shading of the cells by creating a colormap object and transforming
the Wc values depending on the kind value. Next, we determine the minimum and
maximum values of wmin, wmax for the subsequent determination of the color of
each cell.
7. In cycles along the horizontal in the vertical axes, paint over the cells and draw their
borders.
8. For each cell, we form its curvilinear border.
9. Select a cell color from a colormap object.
10. Paint over the cell.
11. Draw the cell border with a line of a given thickness.
12. Turn of the display of axes and digitize.

Figure 8.1 demonstrates the capabilities of the above function.


Rectangle Mappings on the Complex Plane ◾ 193

FIGURE 8.1 Conformal mappings using elementary functions.

If we consider the mappings in Figure 8.1 from lef to right and from top to bottom,
then the frst one shows the original square covered with a 20 ∙ 20 grid, then the result of
mapping the original unit square using the √z function follows, for the third fgure, the z2
function is applied. In this case, the flling of the cells is carried out in accordance with the
value | z2 |, for the fourth fgure, the sin x function was used, and the flling was carried
out accordingly with the real part of the transformation result. Te tan z function is used
to demonstrate shading according to the imaginary part of the display result. Finally, in
the latter case, the arcsin z function is applied without shading. As mentioned above, the
transparency of the shading is determined by the alpha parameter, so that the shading is
not displayed, you need to set alpha = 0.
In the pre-computer era, conformal mappings were widely used to calculate electric
felds in a conductive medium, and a slide rule was the main computing tool used to multi-
ply complex numbers. Te results of the conformal mappings had to be drawn manually on
graph paper. One of the authors, while studying at university, and even afer, had to use this
technology, and the most important thing was the organization of calculations; in order to
reduce the possibility of errors, calculations had to be performed at least twice.
If the sides of the original square are electrodes to which potentials 0 and 1 are applied,
and the upper and lower sides are non-conducting boundaries, then the potential distri-
bution in the rectangle is described by the formula u(z) = x. Equipotentials (lines with the
same potential) and streamlines are straight lines. Equipotentials and streamlines are per-
pendicular to each other. If it is necessary to construct the feld distribution in the region
W, and there is a function w = f (z) that maps the original rectangle to the region W, and
f'(z) ≠ 0 in that region, then to construct the equipotentials and streamlines in this region,
194 ◾ STEM Problems with Mathcad and Python

it is sufcient to perform the conformal mapping of the original square [1]. To do this, you
need to choose a function that carries out the conformal mapping of the original rectangle
to the required area of the complex plane W.
Now let’s look at one more problem. Let a continuous diferentiable non-decreasing
function p(x), p(0) = 0, p(1) = 1, be given on the segment [0,1] of the real axis. How to fnd
a mapping such that the distribution of the potential on the interval [0, 1] would be p(x)?
We note right away that this problem does not have a single solution. Let’s show this
with an example. Let p(x) = x, then the condition of the problem is satisfed by any rectangle
of unit length, on the vertical sides of which electrodes are applied, and the horizontal sides
are non-conducting. Te only solution can be obtained if you set the resistance of this rect-
1
angle R = ˜s ˛ , where ˜s is the specifc surface resistance, h is the height of the rectangle.
h
We would like to fnd the transformation W = φ(Z) that maps the rectangle Z to the
region W = u + 1 j ˛ v, and the line segment z = x + 0j, x∈ [0,1] goes into the line segment
w = u + 0 j , u ˙[0,1], and the potential distribution in the domain W is equal to the
given pw ( x ) = f ( x ). If we apply the inverse transformation to f ( x ): f −1 ( x ), then we get
f −1 ( f ( x )) = x. Tus, to obtain a given distribution of the potential f(x), it sufces to apply
to the segment [0,1] the transformation ˜ ( z ) = f −1 ( z ), which maps [0,1] to [0,1]. To obtain
the domain W on the complex plane satisfying the conditions of the problem, we need to
apply the mapping f −1 ( z ), which must be conformal.
Everything is quite simple, as long as we use elementary functions. If we need to obtain
the quadratic distribution of the potential on [0,1], it is enough to use z as a mapping
function, for sin( x ) we will use arcsin( x ).
Tis problem is called the analytic continuation problem: we extend the real function
˜ ( x ) = f −1 ( x ) to the complex plane, checking the conformity condition ˜ ˝ ( z ) ˙ 0, z ˆZ.
To solve the problem, it is necessary to solve several subtasks:

1. We set the function f ( x ) to [0,1]. We do this with two arrays xd, yd. Here yd is the
required potential distribution.
2. We defne the function ˜ a ( x , a ), which approximates the function inverse to the
potential distribution. We require this function to admit continuation to the complex
plane, ˜ a ( 0,a ) = 0, ˜ a (1,a ) = 1, and the coefcients a require the defnition.
3. We set the initial rectangle of unit length and height h, carry out the mapping, and
check the inequality of the derivative of the mapping in the rectangle to zero. Te
result is a mapping of the rectangle Z to an area on the complex plane W, while the
segment [0,1] → [0,1].

Te analytic continuation is implemented by the function continuation:

%matplotlib inline
import numpy as np
import [Link] as plt
import matplotlib as mpl
Rectangle Mappings on the Complex Plane ◾ 195

from [Link] import curve_fit Œ


def continuation(xd, yd, f, fs, h=0.2, eps=2e-2,
figsize=(8, 4), n=1000, ms=3, stepx=20,
stepy=50, fontsize=14): 
xd, yd = [Link](xd), [Link](yd)
if ([Link](xd[0]) > eps Ž
or [Link](yd[0]) > eps
or [Link](1 - xd[-1]) > eps
or [Link](1 - yd[-1]) > eps
or len(xd) != len(yd)):
raise ValueError("Check xd, yd")

# approximation
args = curve_fit(f, yd, xd)[0] 

# conformal mapping
x, y = [Link](0, 1, n), [Link](0, h, n) 
X, Y = [Link](x, y)
Z = X + 1j * Y
W = f(Z, *args)
ws = [Link]([Link](fs(Z, *args)))

err = [Link]([Link](f(yd, *args) - xd))


err2 = [Link](f(yd, *args) - xd)

# visualisation
if ws>eps: ‘
fig = [Link](figsize=figsize)
yn = [Link](yd[0], yd[-1], n)
xn = f(yn, *args)
[Link](1, 2, 1)
[Link](xd, yd, "ko", ms=ms, label="xd(yd)")
[Link](yd, xd, "ks", ms=ms, label="yd(xd)")
[Link](yn, xn, "k-", label=r"$\varphi(x)$")
[Link]("x", fontsize=fontsize)
[Link]("y", fontsize=fontsize)
[Link](loc="best", fontsize=fontsize)
[Link](1, 2, 2)
[Link](yd, [Link](f(yd, *args) - xd), 'kD', ms=ms)
[Link](yd, [Link](f(yd, *args) - xd), 'k--', ms=ms)
[Link]("yd", fontsize=fontsize)
[Link]("|error|", fontsize=fontsize)
plt.tight_layout()

[Link](figsize=figsize) ’
[Link](1, 1, 1, aspect=1)
[Link](W[:, 0].real, W[:, 0].imag, "k-", lw=3)
196 ◾ STEM Problems with Mathcad and Python

[Link](W[:, -1].real, W[:, -1].imag, "k-", lw=3)


[Link](W[0, :].real, W[0, :].imag, "k-", lw=1)
[Link](W[-1, :].real, W[-1, :].imag, "k-", lw=1)
for i in range(0, n, stepx):
[Link](W[:, i].real, W[:, i].imag, "k-", lw=0.5)
for i in range(0, n, stepy):
[Link](W[i, :].real, W[i, :].imag, "k-", lw=0.5)

[Link]('off')

return err, err2, ws, W

1. In addition to the standard set of libraries, including matplotlib and NumPy, here we
import the curve_ft function, which performs approximation using arbitrary func-
tions, for example, polynomials.
2. Te arrays xd, yd are the dependence of the potential on the coordinate, f, fs
are the mapping function and its derivative, h is the height of the mapped rectangle,
eps is a constant used to check the derivative of the mapping for inequality to zero,
figsize is the size of the fgure, ms is the size of the marker when displaying the
dependence of yd on xd; stepx, stepy – the steps used to display the picture of
the feld, fontsize – the size of the font used to display the inscriptions in the fgures.
3. Next, we transform the data sequences in the arrays and, just in case, check their
dimensions, as well as the mapping [0,1] → [0,1]. If at least one condition is not met,
then ValueError exception is raised.
4. For the approximation, we use the curve _ fit function, to which we pass the
approximating function f and the data yd, xd. We remind you that the inverse
function is approximated. Function returns the approximation coefcients args.
5. We perform conformal mapping using the approximated inverse function of the
inverse function f(Z, *args). We assume that f(z) can be extended to the com-
plex plane. We form a grid on a rectangle Z of unit length and height h. At the same
time, using the derivative of the mapping, we check the condition that the derivative
of the mapping is not equal to zero. In addition, we calculate err – the maximum
absolute and err2 – the mean square error of approximation, since the NumPy
tools allow you to do this quite simply.
6. Everything that follows refers to rendering, which is performed only if the condition of
the non-zero derivative of the mapping is satisfed. In the lef fgure (Figure 8.2), markers
display the dependences yd(xd), the inverse function xd(yd), as well as the approxi-
mation of the inverse function. Te right fgure displays the approximation error.
7. We display the boundaries of the W region, equipotentials and streamlines. Te
boundaries of the area with potentials 0 and 1 are shown with thick lines (Figure 8.3).
Rectangle Mappings on the Complex Plane ◾ 197

FIGURE 8.2 Potential approximation u ( x ) = x + 0.5 * x * (1 − x ) with f4. On the lef graph, the direct
and inverse display function, on the right, the dependence of the absolute approximation error on
the coordinate.

FIGURE 8.3 Area W for the dependence in Figure 8.2 and h = 0.3. Tick lines correspond to elec-
trodes with potentials u = 0 and u = 1.

Te function returns the maximum absolute error, the root mean square error of the
approximation, the minimum absolute value of the derivative in the W region, and the
feld picture – an array of the mapped grid.
Te above function will not work if you do not specify an approximation function f and
its derivative fs. As examples, we give two types of approximation functions:

def f4(x, a2, a4):


return x + a2 * x*(1-x)+ a4 * x**2*(1-x**2)

def f4s(x, a2, a4):


return 1 + a2 *(1-2*x)+ a4 * (2*x-4*x**3)
198 ◾ STEM Problems with Mathcad and Python

Te function f4 depends on two unknown parameters a2, a4. Note that f4(0,…) = 0,
f4(1,…) = 1 for any values of a2, a4. Te function f4s is the derivative of f4 with
respect to x. We can increase the number of coefcients to be determined, for example:

def f6(x, a2, a4, a6):


return x + a2*x*(1-x)+a4*x**2*(1-x**2) +\
a6*x**3*(1-x**3)
def f6s(x, a2, a4, a6):
return 1 + a2*(1-2*x)+a4*(2*x -4*x**3) +\
a6*(3*x**2 - 6*x**5)

Nobody bothers to use trigonometric functions instead of polynomials:

def g4(x, a2, a4):


pi = [Link]
return x + a2 *[Link](pi*x) + a4 * [Link](2*pi*x)
def g4s(x, a2, a4):
pi = [Link]
return 1 + pi*a2 *[Link](pi*x) + 2*pi*a4 * [Link](2*pi*x)

Now let’s experiment by specifying diferent potential dependencies and approximating


functions, as well as the heights of the displayed rectangles h.
Let’s set the dependence of the potential on the coordinate: u( x ) = x + 0.5* x *(1 − x ).
Using f4(x) for approximation, we obtain (Figure 8.2)
Setting the height of the original rectangle to h = 0.3, we get the region W shown in
Figure 8.3.

FIGURE 8.4 Multi-leaf mapping for h = 0.9.


Rectangle Mappings on the Complex Plane   ◾    199

FIGURE 8.5 Approximation of the mapping u ( x ) = x − 0.6 * x * (1 − x ).

FIGURE 8.6 Area W for the dependency shown in Figure 8.5 and h = 0.3.

With an increase in h, it may turn out that in the region W the derivative of the mapping
function will become equal to zero and the mapping will become multi-leaf, as shown in
Figure 8.4. In fact, we wrote the continuation function in such a way that if at some
point W the derivative becomes less than the specified number of eps, then the rendering
is not performed. We had to set eps = 1e-5 to get Figure 8.4.
Such mapping has no physical meaning.
It makes sense to use sine for approximation if it is necessary that the electrodes with
potentials 0 and 1 are straight lines. For this, we have the g4 function. Function approxi-
mation u( x ) = x − 0.6* x *(1 − x ) is shown in Figure 8.5 and the result is shown in Figure
8.6.
We are not limited in any way in the choice of functions for approximation and we will
( )
choose the following dependence u( x ) = arctan ( a * ( x − 0.5 )) / arctan( a * 0.5 ) +1 / 2 , which
can be handled exactly by the inverse function:
200   ◾    STEM Problems with Mathcad and Python

FIGURE 8.7 ( )
Approximation of the mapping u ( x ) = arctan ( a * ( x − 0.5 )) / arctan ( a * 0.5 ) +1 / 2.

FIGURE 8.8 Area W for the mapping shown in Figure 8.7 and h = 0.3.

def fa(x,a):
return (1 + [Link](a*(x-0.5))/[Link](a*0.5))/2

def fas(x, a):


return a/[Link](a*(x-0.5))**2/[Link](a*0.5)/2

The result is shown in Figures 8.7 and 8.8. Exact treatment results in an error not exceed-
ing 10−15.
Increasing the complexity of the mapping does not always improve the results. Let’s go
back to the dependency shown in Figure 8.5. It would seem that adding two more terms to
the function should improve the accuracy of the approximation:

def g8(x, a2, a4, a6, a8):


pi = [Link]
return x + a2*[Link](pi*x) + a4 * [Link](2*pi*x)+\
a6*[Link](4*pi*x) + a8*[Link](6*pi*x)

However, the maximum error practically did not change, but the height h had to be reduced
to 0.1, as shown in Figure 8.9. As h increases, points appear where the derivative of the
mapping function is zero.
Rectangle Mappings on the Complex Plane ◾ 201

FIGURE 8.9 Area W for the dependency shown in Figure 8.5 and h = 0.1.

−1 j˜W
FIGURE 8.10 Region W shown in Figure 8.9 afer conformal transformation e on the lef and
e1 j˜W on the right.

So far, we have mapped the straight line segment [0,1] of the complex plane Z onto the
same segment of the plane W. If we perform the additional conformal mapping V = e −1 j°W ,
then the lower boundary of the area will be mapped to the inner arc of a circle with an
3
angle ˜ . In Figure 8.10, such a transformation is performed for ˜ = π. If you perform the
2
transformation V = e1 j°W , then the bottom border of the rectangle will become the outer
border of the area.
Perhaps the most important thing in analytic continuation is the selection of an approx-
imating function with a minimum sufcient number of parameters.
Let’s now return to attempts to render conformal mappings using color as the fourth
coordinate: u + 1j ˝ v = W ( x + 1 j ˝ y ).
We will do this using the function c_map3d:

%matplotlib inline Œ
import numpy as np
import [Link] as plt
import [Link] as cm
202 ◾ STEM Problems with Mathcad and Python

def c_map3d(Z,W, cname='jet', stride=1, elev=None,


azim=None, real=True, pic=111,
alpha=0.8, axis=False, fs=14): 

x, y = [Link], [Link] Ž
u = [Link] if real else [Link] 
v = [Link] if real else [Link]
v = [Link](v)
vmin, vmax = [Link](v), [Link](v)
v = (v - vmin)/(vmax - vmin)

cmap = plt.get_cmap(cname) 
ax = [Link](pic, projection='3d') ‘
ax.plot_surface(x, y, u, rstride=stride,
cstride=stride,
facecolors = cmap(v),
linewidth=0, alpha=alpha) Œ
if not axis: “
[Link]('off')
ax.view_init(azim=azim, elev=elev) ”
ax.set_xlabel('x', fontsize=fs) •
ax.set_ylabel('y', fontsize=fs)
ax.set_zlabel('u' if real else 'v', fontsize=fs)

1. We import the standard set of libraries.


2. Te c_map3d functions are passed: Z, W – two-dimensional arrays of meshes on com-
plex planes, cname – the name of the colormap, a standard set of colors that allows
you to match the color and value of a certain value on the segment [0,1]; stride – the
frequency of the grid when drawing a two-dimensional surface in three-dimensional
space; elev and axim - rotation of the surface relative to the horizontal and verti-
cal axes; setting these parameters allows you to look at the visualization results from
diferent points of view; real – a fag that allows to display along the vertical axis
[Link] if real == True and [Link] otherwise; pic the position of the picture,
setting this parameter allows you to display several surfaces in one picture; alpha –
opacity of the displayed surface; axis – fag that controls the display of coordinate
planes; fs – font size for axis labels. Te function displays a two-dimensional surface
in three-dimensional space, the fourth coordinate is displayed in color from a color-
map named cname.
3. Calculating the real and imaginary parts of the mesh on plane Z.
4. Depending on the value of the real parameter, we calculate the values of u, v on the
plane; the u value is displayed on the vertical axis, v is displayed in color from the
cmap colormap.
Rectangle Mappings on the Complex Plane ◾ 203

5. Retrieve a colormap object by its name.


6. Create a 3D drawing object and draw a surface in 3D space. Note that the display
color v is passed through a named parameter facecolor.
7. Solving the issue of displaying the coordinate axes.
8. Rotate coordinate planes, if necessary.
9. Displaying axis labels.

It remains for us to prepare the data and call the c_map3d function for W = Z ** 3.
n = 100
stride=5
xx = [Link](-1,1,n)
x, y = [Link](xx, xx)
Z = x +1j*y
W = Z**3

[Link](figsize=(13,13))
c_map3d(Z,W, stride=stride, cname='binary',axis=True, pic=221)
c_map3d(Z,W, stride=stride, cname='binary',axis=True, pic=222,
real=False)
c_map3d(Z,W, stride=stride, cname='binary',axis=True, pic=223,
azim=azim)
c_map3d(Z,W, stride=stride, cname='binary',axis=True, pic=224,
real=False, azim=azim)
plt.tight_layout()
[Link]()

Tis function is called four times to show how the surface view is afected by the display of
the real and imaginary parts of W, as well as the rotation of the surface about the vertical
axis (Figure 8.11).
Figure 8.12 visualizes the mapping using the logarithmic function W = log(Z). It should
be borne in mind that as Z → 0, W → ∞, which must be taken into account when preparing
data (choosing a grid).

TASKS FOR THE READER

1. Reproduce all chapter calculations in Jupyter Notebook or JupyterLab


2. See if you can implement conformal mappings using Mathcad
3. Perform conformal mappings of rectangular regions, specifying diferent polynomi-
als as the mapping functions.
204 ◾ STEM Problems with Mathcad and Python

FIGURE 8.11 We display W = Z**3. In the upper lef image, [Link] is plotted along the vertical
axis, and [Link] is displayed using the color from the binary colormap; on the top right fgure,
[Link] is plotted along the vertical axis, and [Link] is displayed in color, the fgures in the bot-
tom row are built similarly, but rotated not by the default angle of 60°, but by 120°.

4. Perform conformal mapping for the periodic function.


5. Try to perform conformal mapping on a multivalued function such as ∛Z. Draw side
by side all branches of the function. How do they difer from each other?
6. Te chapter considers the problem of analytic continuation of a function from the
segment [0, 1] to the complex plane. Try to fgure out what will happen to the analytic
continuation if you strive to improve the accuracy of the approximation by increasing
the complexity of the approximating function, for example, the polynomial.
Rectangle Mappings on the Complex Plane ◾ 205

FIGURE 8.12 We display W = log(Z) mapping, the values of [Link] are displayed on the lef on
the vertical axis, [Link] on the right; in the top row the coordinate planes are rotated by a default
angle of 60°, in the bottom row by 120°.

7. Te chapter deals with the task of visualization u +1jv = W ( x +1jy ). Te result is


obtained as a two-dimensional surface in three-dimensional space. Te surface is
flled with color from the colormap. Try experimenting with colormaps with jet,
Spectral, autumn, Paired and more colormaps.

REFERENCE
1. S.G. Krantz, Complex Variables: A Physical Approach with Applications. Second Edition
(London: CRC Press, 2019), ISBN 978-0-367-22267-3.
Chapter 9

Monte-Carlo: Shapes
and Ships

9.1 CARDIOID
Monte-Carlo simulation makes use of streams of random numbers to calculate the results
of mathematical models that are generally difficult or impossible to solve in more direct
ways. The method is often explained using the simple example of determining an approxi-
mation to the number, π, by scattering points randomly over a square within which is
inscribed a circle of unit radius (and hence has area = π). We’ll do something similar here,
except that instead of using a circle inscribed in a square, we’ll use the more interesting
shape of a cardioid (heart-shaped) inscribed in a rectangle.
The specific cardioid we’ll make use of is defined by the following parametric equations:

cos t cos2t sin t sin2t


x= − y= −
2 4 2 4

where x and y are its Cartesian coordinates, and t is an angle measured by a line pivoted
about the cusp of the cardioid (see Figure 9.1). The reason for using this particular cardioid
will become clear later.
Before using this to demonstrate the use of Monte-Carlo simulation, let’s calculate the
area of the cardioid analytically to see how the number π is involved. This is best done
using polar coordinates, where we start by taking a small triangle with one vertex at the
1
origin, as shown in Figure 9.2. The area of this triangle is approximately r∆θ × r , where
2
∆θ is an “infinitesimal” increment of angle, θ , so if we sum these areas over the range
0 ≤ θ ≤ 2π while taking the limit as ∆θ tends to zero, we can express the area, A, of the car-

r2
dioid as A =

0
2
dθ . Of course, we need to know how r depends on θ before we can do this.

DOI: 10.1201/9781003228356-10 207


208 ◾ STEM Problems with Mathcad and Python

FIGURE 9.1 (a) Cardioid. (b) Expanded region of the dotted rectangle shown in (a).

FIGURE 9.2 “Infnitesimal” polar triangle.

Since we know that r 2 = x 2 + y 2, this would be straightforward if x and y were expressed


in terms of ˜ . Unfortunately, they are expressed in terms of angle t, so we need to trans-
form the area integral from the ˜ -domain to the t-domain. To avoid potential errors in the
rather messy, multi-step process required for this transformation we make use of sofware
to do the “heavy lifing”1 here. Figure 9.3 shows how it can be done in Mathcad, where we
see that the area is given in terms of π as A = 3° / 8.
To estimate the area, A, and hence π, using Monte-Carlo simulation we frst enclose the
cardioid in a rectangle. In fact, because of the symmetry of the cardioid, we enclose just the
top half in a rectangle, estimate the area of that half and then double the result for the area
of the whole cardioid. Te limits of the enclosing rectangle, which is shown in Figure 9.4,
3 3 ˜ 3 3˝
are °˝ − , ˇ˙ for x, and ˛0, for y.
˛ 4 8ˆ ° 8 ˆ˙

1 To do this by hand is a straightforward, but tedious and error-prone procedure.


Monte-Carlo: Shapes and Ships ◾ 209

FIGURE 9.3 Analytical calculation of cardioid area (Mathcad 15).

FIGURE 9.4 Rectangle enclosing half the cardioid.

Te idea is to scatter many points at random within the rectangle. We expect that the
number of those points that land within the cardioid region, divided by the total number
within the rectangle, will be approximately equal to the area of the enclosed part of the
cardioid divided by the area of the rectangle. Since it is a trivial matter to calculate the area
of the rectangle, then, by multiplying it by the points fraction, we obtain an estimate of the
area within the cardioid. By equating the result to the true area of 3˜ / 8 and rearranging,
we get an estimate for the value of π. Figure 9.5 shows how this can be done in Mathcad
(note that we make use of the fact, derived from Figure 9.1b, that tant = y (t ) / ( x (t ) − 0.25 )
when deciding if a random point lies inside or outside the cardioid).
Te resulting estimate of π shown in Figure 9.5 is accurate to three signifcant fgures.
However, if we were to run the program again, we would almost certainly get a difer-
ent value, so we need to run it many more times in order to determine the accuracy of
our estimate. Figure 9.6 shows how this is done, where we see that our estimate of π lies
210 ◾ STEM Problems with Mathcad and Python

FIGURE 9.5 Monte-Carlo estimate of π (Mathcad 15).

between 3.1398 and 3.1417 to 95% confdence. Tese limits span the true value (3.1416 to 5
signifcant fgures).
In practice, there is no point in using a Monte-Carlo simulation to calculate π or the area
of a cardioid as they can be determined by other, more direct and more accurate methods.
Te purpose of the above calculations is simply to demonstrate the Monte-Carlo process.

9.2 MANDELBROT SET


However, we may ask if there are shapes for which their areas are difcult or impossible to
calculate by direct, analytical methods, so that a Monte-Carlo approach would be useful.
One that immediately springs to mind is the Mandelbrot set (see Figure 9.7). Tis has an
infnitely long perimeter that encloses a fnite area.
Tere is no known closed form analytical solution for the area of the Mandelbrot set,2 so
let’s have a go at calculating it using a Monte-Carlo approach. As with the cardioid, we’ll

2 Tere is an infnite series solution for the area. However, it converges incredibly slowly, taking 10118 terms to get the frst
two digits, according to Wolfram MathWorld ([Link]
Monte-Carlo: Shapes and Ships ◾ 211

FIGURE 9.6 Monte-Carlo estimates of π with 95% confdence limits. (Mathcad 15).

take advantage of the symmetry of the Mandelbrot set and enclose just the upper half in
a rectangle, doubling the resulting area to get the full area. We’ll use a rectangle with the
following limits: [ −1.8, 0.45 ] for x, and [0, 1.1] for y. Any thin strands of the set that fall
outside these limits provide a negligible contribution to the area at the level of accuracy to
which we will work here.
Te Mandelbrot set is defned in the complex plane as follows. A complex number, c, is
chosen. Further complex numbers, z, are generated from this using the iterative sequence
z n+1 = z n2 + c, where z 0 = 0. Te Mandelbrot set consists of those numbers, c, for which the
values of z never exceed 2.
In practice, we can’t keep iterating indefnitely, so we use a maximum number of 1,000
iterations to decide if c is in the set or not. Tis means that for all our Monte-Carlo points
that have values of c that lie in the Mandelbrot set, the maximum number of iterations
would be required. However, to speed up the simulation we now take advantage of the car-
dioid calculations we performed above. Te cardioid we defned earlier fts entirely within
the main “bulb” of the Mandelbrot set, so whenever c takes a value within that cardioid,
212 ◾ STEM Problems with Mathcad and Python

FIGURE 9.7 Mandelbrot set (low resolution).

we immediately increment our count of points in the set, rather than explicitly performing
the 1,000 iterations.
Figure 9.8 shows a Mathcad version of a single evaluation of the area. We can’t rely
on a single evaluation of course, so Figure 9.9 shows the calculations to determine the
best estimate and 95% confdence limits of the area. Wolfram MathWorld gives two pos-
sible values for the area, namely 1.50659177 ± 0.00000008, obtained by pixel counting, and
1.506484 ± 0.000004 obtained by statistical sampling (see [Link]
[Link]), so our limits cover these!

9.3 BATTLESHIPS
Monte-Carlo simulation can do much more than fnding the area of awkward shapes,
of course. It can help us to evaluate diferent possible strategies that we might adopt in
confict situations. As an example, let’s apply it to the, non-computer, peg-board game of
Battleship – see Figure 9.10.
In this two-player game, each player has fve ships (they are Carrier, Battleship, Destroyer,
Submarine and Patrol Boat in the Hasbro version of the game) that they place somewhere
on their own ten-by-ten square grid. Te ships each occupy a certain number of adjacent
grid positions (fve for the Carrier, four for the Battleship, three for the Destroyer, three
for the Submarine and two for the Patrol Boat) and can only be placed either horizontally
or vertically, not diagonally. Figure 9.11 shows the grid with an example placement of the
ships.
Monte-Carlo: Shapes and Ships ◾ 213

FIGURE 9.8 Monte-Carlo estimate of area of Mandelbrot set (Mathcad 15).


214 ◾ STEM Problems with Mathcad and Python

FIGURE 9.9 Monte-Carlo estimates of Mandelbrot set area with 95% confdence limits.

Each player takes turns to shoot, blindly, at his or her opponent’s grid by naming a
grid reference. Te player being shot at calls ‘hit’ or ‘miss’ as appropriate, then takes their
turn to “shoot” at their opponent’s grid. (In the standard version of the game, when a ship
has had all its grid points hit, the player states what ship has been “sunk”; however, the
instructions also allow for a harder version in which this is not required. Only the latter,
the harder version is considered here.) In the peg-board version of the game, both players
Monte-Carlo: Shapes and Ships ◾ 215

FIGURE 9.10 A battleship game layout.

FIGURE 9.11 Battleship grid.


216 ◾ STEM Problems with Mathcad and Python

insert a white peg for a “miss” or a red peg for a “hit” in a hole at the appropriate grid point
(the player taking the shot has a blank grid to record his or her successes and failures). Te
frst player to hit all the grid points occupied by ships is deemed to have destroyed their
opponent’s feet and hence wins the game. Tere are several variants of the procedure, but
this simple one is all we’ll consider here.
Let’s compare two diferent shooting strategies, one, naïve (or mindless!), the other, more
carefully thought out, to see how many shots each approach takes to destroy the enemy feet.
We’ll start with the naïve approach, in which we just shoot randomly all over the grid,
irrespective of what we hit or miss (though we’ll keep track of where we shoot and will
avoid shooting at the same grid point twice). We’ll assume our opponent has the ship
placements as shown in Figure 9.11, and play 105 games of mindlessly blasting away, aiming
at the grid points in a diferent random order each time. Te following Python program
does the calculations.

import numpy as np
# Position ships on grid

grid = [Link]((10,10))
grid[2,3:8] = 1 # Carrier
grid[5,5:9] = 1 # Battleship
grid[6:9,1] = 1 # Destroyer
grid[3:6,2] = 1 # Submarine
grid[8:10,6] = 1 # Patrol boat
grid = [Link]([Link](grid),(100,1)) # stack column-wise

# Shoot at random grid points


trials = 10**5
shotcount = [Link](trials)
for t in range(trials):
shuffle = [Link](100)
hits = 0
ix = 0
while hits < 17:
I = int(shuffle[ix]) # Select next random grid point
hits += grid[I] # Update number of hits as
appropriate
ix += 1 # Increment next grid point counter
shotcount[t] = ix # Record number of shots

We see a histogram of the shot count (i.e., the number of shots required to sink the enemy
feet) in Figure 9.12.
Since there are 17 grid points occupied by a feet, the minimum possible number of shots
to destroy it is 17. Te probability of doing that with the naïve random approach is negli-
gibly small! Te maximum possible number of shots is 100, and it is clear from Figure 9.12
that this is entirely possible! Te mean number of shots to sink the feet, obtained from the
calculations of the Python program, is approximately 95.4, which agrees with the expected
Monte-Carlo: Shapes and Ships ◾ 217

FIGURE 9.12 Results of naïve strategy.

number obtained from an analytical solution.3 However, this number of shots only sinks
the opposition feet about 42% of the time, so we’ll also use the median as a rough com-
parative measure of the average number of shots to sink the feet. As is seen from Figure
9.12, this is 97 shots for our naïve approach. Can we do better than this?
We certainly can if we picture the battle grid as having a checkerboard pattern of two
sub-grids, rather like a chess board with its alternating white and black squares. Since
the ships can only be placed horizontally or vertically, their adjacent susceptible positions
must lie on opposite sub-grids. Also, we note that each time we hit a ship, there will be
another part of the ship to the north, south, east or west of that grid point. Tat means we
should improve our hit rate by aiming the random shots at only one sub-grid (the “white
squares” in the program below), then shooting at adjacent compass points (which will tar-
get the other sub-grid) when we get a hit. Again, we avoid shooting at the same grid point
twice, which requires us to adopt a more complicated programming logic compared with
that of the naïve approach. Te following Python program does the calculations.

import numpy as np

# Calculate "black square" neighbor indices of "white square"


index, I
def neighbors(I):
column = int([Link](I/10))

3 Imagine the random shots as a linear sequence of positions, running from 1 to 100, rather than as a two-dimensional
matrix. With 17 possible hits, there are 18 possible groups of misses, ranging in length from a minimum of zero to a
maximum of 83. Let the sizes of these groups of misses be of length g i where i runs from 1 to 18. Te sum of the lengths
18

of all the groups of misses together with the number of hits must equal 100, so we have ˜g +17 = 100. Now, for an
i=1
i

infnite number of games, we expect the sizes of the gaps to average out to be equal to each other (i.e., g i = g , say, for all
i), so the previous expression becomes 18g +17 = 100, resulting in g ˜ 4.6 . With the last group of misses of size 4.6, the
last hit must be at position 95.4 on average (i.e., the expected number of shots to sink the feet is 95.4).
218 ◾ STEM Problems with Mathcad and Python

row = [Link](I,10)
west = (column-1)*10 + row
east = (column+1)*10 + row
north = column*10 + row-1
south = column*10 + row+1
if row == 0:
north = -1
if row == 9:
south == 100
return west, east, north, south

# Position ships on grid


grid = [Link]((10,10))
grid[2,3:8] = 1 # Carrier
grid[5,5:9] = 1 # Battleship
grid[6:9,1] = 1 # Destroyer
grid[3:6,2] = 1 # Submarine
grid[8:10,6] = 1 # Patrol boat
grid = [Link]([Link](grid),(100,1)) # stack column-wise

# Create a sub-grid of indices to "white squares"


u = [Link](0,8,5)
white = [Link]([u,u+11,u+20,u+31,u+40,u+51,u+60,u+71,u+8
0,u+91])

# Shoot at random on "white squares" + search neighbors on a hit


trials = 10**5
shotcount = [Link](trials)
for t in range(trials):
shuffle = [Link](white)
T = [Link](grid)
hits = 0
shots = 0
ix = 0
while hits<17:

I = int(shuffle[ix]) # Select next random white square


hit = grid[I] # Hit ship?
hits += hit # Update number of hits as
appropriate
shots += 1 # Update number of shots

if hit == 1: # If a grid is hit find its neighbors


west, east, north, south = neighbors(I)
# For each neighbor in turn, check it is on the grid
# and has not been looked at previously, then
# increment shots counter,
# increment number of hits as appropriate and
# record that the square has now been shot at.
Monte-Carlo: Shapes and Ships ◾ 219

if west>=0 and T[west]>-1:


shots += 1
hits += grid[west]
T[west] = -1
if east<=99 and T[east]>-1:
shots += 1
hits += grid[east]
T[east] = -1
if north>=0 and T[north]>-1:
shots += 1
hits += grid[north]
T[north] = -1
if south<=99 and T[south]>-1:
shots += 1
hits += grid[south]
T[south] = -1

ix += 1 # Increment next square counter


shotcount[t] = shots # Record number of shots

Te resulting number of shots to sink the enemy feet this time is shown as a histogram in
Figure 9.13.
Tis more thoughtful strategy is clearly superior, with a mean number of 70.7, and a
median number of 72 shots required to sink the enemy feet.
Te two strategies here have only been tested against the ship confguration shown in
Figure 9.11. Strictly, we should test them against many diferent confgurations. If we were
to do this, we would fnd that, although the fne detail would change from one confgura-
tion to another, the overall result would be similar, namely that the more thoughtful, sub-
grid strategy would outperform the naïve strategy. Are there other, even better, strategies?
We leave that as a question for the reader!

FIGURE 9.13 Results of more thoughtful strategy.


220 ◾ STEM Problems with Mathcad and Python

TASKS FOR THE READER

1. Use Monte-Carlo simulation to fnd the area of the shape between the x-axis and the
1 9 − 4x 2
function given by y ( x ) = between the limits x = −1.5 and x = +1.5.
2 13+ 8x
2. Suppose the above shape is rotated by 360o about the x-axis. Use Monte-Carlo simu-
lation to fnd the volume of the resulting shape.
3. Develop and implement yet another strategy for the game of Battleships.
Chapter 10

Pseudo-Parallelism

P arallel computing is a way of organizing programs to run as a set of interacting


simultaneous processes. Parallel computing can be performed both on separate pro-
cessors and on cores of the same processor. Operating systems organize quasi-parallel
execution of programs even on processors with one core, for example, when one program
is waiting for the user’s response, another program is running. Its execution is interrupted
when the user presses a keyboard key or clicks the mouse. This is what allows us to work
on our home computer and listen to music at the same time. In this chapter, we will talk
about something else, or rather, something completely different.
Operators in Mathcad and in Python are executed one after the other sequentially.1 But
sometimes it is necessary that they be performed in parallel, as it were, we will call this
pseudo-parallel computation. In fact, the program is executed sequentially, but for us, it
looks like parallel execution and is a “syntactic sugar”.2 This is what will be discussed in
the chapter.
In the first example (sorting), there is no special need for such calculations. There’s just
no extra variable used.

10.1 EXAMPLE 1. SORTING


Many sorting algorithms have been developed. In Wikipedia, you can find their names:
bubble sort, sort by mixing, gnome sort, insertion sort, merge sort, binary tree sort, Timsort
sort, counting sort, block sort, radix sort, sort by choice, Shell sort, comb sort, pyramidal
sort, smooth sort, quick sort, introspective sort, patience sort, recursive sort, silly sort,
pancake sort, permutations sort, etc.
These algorithms are implemented in different programming languages. We will also
try to do this, but in Mathcad, which is now widely used in schools and universities.

1 Python has libraries that allow you to parallelize calculations. Another thing is that parallel programming requires
certain skills, debugging parallel programs is quite difficult. In recent years, high-level libraries, such as Dask (https://
[Link]/), have appeared which allow to automate the distribution of processes between cluster nodes or desktop cores
to a large extent, using familiar NumPy and pandas APIs.
2 Syntactic sugar in programming languages are features, the application of which does not affect the behavior of the
program, but makes using the language more human-friendly.

DOI: 10.1201/9781003228356-11 221


222 ◾ STEM Problems with Mathcad and Python

FIGURE 10.1 Variables change their values.

Te basis of many sort algorithms is the exchange of numerical values of two variables.
In the BASIC programming language, for example, the swap(a, b) operator performs this
procedure. But in Mathcad, there is no such operator, but it is not difcult to implement it
by other means.
In Figure 10.1, it is possible to see two ways to implement the swap(a, b) operator in
Mathcad: traditional (“triangular” — using an auxiliary variable ab) and “exotic”, which
many Mathcad users do not guess—not through sequential assignment, but in some par-
allel mode, when the assignment operators are written in a vector form and are executed
independently of each other. Tis technology was discussed on the Mathcad user site
[Link]
Note. Afer using an auxiliary variable named ab, it’s better to get rid of it. To do this,
Mathcad Prime has a clear function—see Figure 10.1.
If there is a permutation operator swap(a, b) in an explicit (“triangular”) or matrix form,
then it is easy to write a function in Mathcad (see Figure 10.2), which probably implements
the most primitive sort algorithm, the essence of which is as follows.
For Python, all this is made even easier, allowing you to write the exchange of variable
values in one line:
a, b = b, a

Note also that the parallel execution of the lower part of Figure 10.1 produces an unde-
fned result, a may or may not receive a new value, depending on which statement is exe-
cuted frst.
Imagine a class of schoolchildren are told to form up in a line, and they do so in ran-
dom height order. Te teacher wants them in order of increasing height, so passes along
the line, from lef to right, swapping adjacent pairs of children wherever the lef child is
taller than the one to its right. Te teacher repeats this process until the whole line is in
height order. In Figure 10.2 70, “children” are represented by the elements of the vector, V.
Pseudo-Parallelism ◾ 223

FIGURE 10.2 Sorting “children” by “height”.

FIGURE 10.3 Interrupt sorting “children” by “height” with variable FRAME.

Te runif (r—random numbers, unif—uniform distribution) function randomly selects


their “heights” as values between 1 and 100. A for loop, with indicator, i, runs through the
elements of V, swapping adjacent pairs wherever the i-1’th element is greater than the i’th
element. Whenever a swap takes place, a fag is set to 1. Te for loop is embedded within
a while loop that continues to run the for loop until the fag remains at 0, which indicates
that the sort is complete.
We can insert another if statement in the program shown in Figure 10.2, followed by a
return statement, which will interrupt the execution of sorting the vector and return an
incompletely sorted vector. Tis process will be controlled by the FRAME variable—see
Figure 10.3.
224 ◾ STEM Problems with Mathcad and Python

Mathcad 15 has convenient animation tools, which can be used to visualize the sort
process. Unfortunately, Mathcad Prime has no such facility. However, we can, by chang-
ing the value of the FRAME variable, create a set of animation frames and then create an
animation from them using tools that are easy to fnd on the Internet. Tree frames of the
vector sorting process are shown in Figure 10.4.
Tis animation technique can also be useful in helping to debug a program, i.e., in fnd-
ing any errors in it.
With FRAME = 0 (the frst frame of the animation), we see the original unsorted line of
students (student heads). At FRAME = 700 (one next frame of the animation), we see that
the lowest and highest students were moved to their place. With FRAME = 1,100 (the next,
but not the last frame of the animation), we see that there is only one student lef who needs
to be moved to the lef to his place.
An animation named [Link], the three fles of which we see in Figure 10.3, is stored
at the book site.
Yes, in the program in Figure 10.2, you can do without the “pseudo-parallel” operators
combined in a vector. It is enough to enter an additional variable into the program—see
Figure 10.1.
To test our simplest sorting algorithm, implemented in the MySort function (see Figures
10.3 and 10.4), we generated a uniform distribution growth vector of students using the
built-in runif function. But in real students, growth obeys the law of the normal distribu-
tion—the Gaussian distribution.
Figures 10.5 and 10.6 show a sorting of 30,000 students using the built-in sort function
rather than the custom function MySort (see Figure 10.2). Te function with the name
MySort with a large number of students takes an unbearably long time. Creation of sort-
ing algorithms and programs, their optimization in terms of computation time, computer
memory size and other parameters is a very important branch of computer science. No
wonder Donald Knuth devoted a separate volume to sorting in his famous multivolume
“Te Art of Programming”.
Our sorting function called MySort uses only one “processor”—the teacher, who walks
along the line of students and rearranges some pairs. Tis explains the slowness of this
sorting. If you ask the students to line up according to their height, then many paral-
lel calculations will be performed simultaneously—the students themselves will compare
themselves with their neighbors and make the necessary permutations. Te fastest sorting
algorithms rely on multiprocessor machines that implement real rather than pseudo (see
chapter title) parallel computations.
Figure 10.5 sorts by student height with a uniform distribution, as seen from both the
histogram and the fnal graph showing students plotted by height, where we see a straight
slanted line.
Figure 10.6 sorts the students by height with a normal distribution, which is also dis-
played in both the histogram and the fnal graph showing students plotted by height, where
we see no longer a straight oblique line, but a curved curve reminiscent of cumulative
normal distribution.
Pseudo-Parallelism ◾ 225

FIGURE 10.4 Tree frames of animation for the simplest sorting procedure.
226 ◾ STEM Problems with Mathcad and Python

FIGURE 10.5 Sorting by “height” 30,000 “children” with uniform distribution.

We may remark that the choice of an interval for constructing a histogram of the
growth of adult men seems best suited, not by either the European centimeter or the
Anglo-American inch, but by the good old Russian vershok (about 4.45 cm or 1.75 inches)!
A Russian fathom is 7 English feet, a Russian arshin (see Chapter 3 “Reading fction and
solving linear equations”) is a third of a sazhen, and a vershok is one 1/16 of an arshin. In
the old days, the heights of people and horses (the height of a horse was measured at the
withers) were roughly around two arshins (approximately 142 cm).
So, students are divided into fve groups by height (fve bars of the histogram, fve fngers
on the hand), namely: short (six vershoks—169 cm and below), slightly shorter than aver-
age (7 vershoks—173 cm), average (8 vershoks—178 cm), slightly taller than average (9 ver-
shoks—182 cm) and tall (10 vershoks—187 cm and above). Here we have replaced numeric
constants with text constants, which are ofen used in fuzzy set theory.
In Python, it (our custom sorting program) looks very similar:

import random

def my_sort(v):
Pseudo-Parallelism ◾ 227

FIGURE 10.6 Sorting by “height” 30,000 “children” with normal distribution.

flag = True
n = len(v)
q = 0
while flag:
flag = False
q += 1
for i in range(n-1):
if v[i]>v[i+1]:
flag = True
v[i], v[i+1] = v[i+1], v[i]
return v, q

In a Jupyter Notebook, it is easy to determine the execution time of the program, and it is
enough to add a “magic” command to the beginning of the cell:

%%timeit
n =100
v = [i for i in range(n)]
228 ◾ STEM Problems with Mathcad and Python

[Link](v)
v, q = my_sort(v)

Te execution result will be:

574 µs ± 1.83 µs per loop (mean ± std. dev. of 7 runs, 1000 loops
each)

We get statistics on the program execution time.


Python has a built-in sort method for sorting lists. Let’s compare their performance
with what we did above.

%%timeit
n =100
v = [i for i in range(n)]
[Link](v)
[Link]()

We got the expected result:

28.8 µs ± 101 ns per loop (mean ± std. dev. of 7 runs, 10000 loops
each)

Te built-in tools give an acceleration of almost 20 times, which once again illustrates
the good old maxim: “don’t reinvent the wheel”, that is, use the tools of the Python ecosys-
tem, if there are no obviousw contraindications.

10.2 EXAMPLE 2. THE PURSUIT PROBLEM


A hare runs across the feld, and a wolf is chasing him. What will be the trajectory of the
wolf (pursuit curve)? How it will be related to the trajectory of the hare?
Tis task has an important practical (military) application: an anti-aircraf missile or an
interceptor aircraf fies to the target, choosing a certain optimal path. Tis application is
not just important—it is a matter of life and death.
On the Internet, you can fnd many descriptions of the formulation and solution of this
problem. At the same time, it is usually extremely simplifed: the hare runs in a straight
line, and a wolf runs out from the side of it and runs afer the hare, focusing not on its
intelligence or scent, but on sight—the wolf runs strictly at the hare. Te speed of the wolf
is naturally higher than the speed of the hare, and these two quantities are constant over
time. Researchers of this problem, as a rule, try to fnd its analytical solution—they are
looking for a mathematical expression to describe the trajectory of a wolf’s running, which
results in many complex transformations and explanations to them, in which the uniniti-
ated in the intricacies of higher mathematics quickly get confused, lose the thread of rea-
soning and interest in the problem.
Pseudo-Parallelism ◾ 229

FIGURE 10.7 Analytical solution of a particular pursuit problem.

In Figure 10.7, an analytical solution to the particular problem of the pursuit is shown,
when a hare runs strictly in a straight line, and a wolf runs out onto it from the side (at our
top).
But nowadays we more and more ofen use not analytical, but numerical methods for
solving mathematical problems. Tis, alas, somewhat reduces the elegance of the solution,
but opens up other interesting and no less elegant possibilities, in particular, for animated
illustration of solutions, for their greater attachment to reality.
Te problem of a wolf chasing a hare can be solved not only by compiling “terrible”
diferential equations but also in another way—through the implementation of a simple
diference scheme. And the diference, as you know, is the forerunner of the diferential—
a diference that tends to zero, but does not reach zero (the main tool of mathematical
analysis is calculus). Diferential equations are solved numerically through the compilation
230 ◾ STEM Problems with Mathcad and Python

FIGURE 10.8 Algorithm for a wolf chasing a hare.

of these very diference schemes. So, let’s do the same, we will not compose a diferential
equation describing the running of a wolf afer a hare, which, as a rule, cannot be solved
analytically, but go back to the origins—to these very diference schemes.
Figure 10.8 shows a diference scheme for solving the problem of a wolf and a hare. Te
central element of this numerical method is the angle φ, the angle of the direction that
the wolf orientates itself in pursuit of the hare (see this angle in Figure 10.8). Tis angle—
through its cosine and sine—is used to calculate the increment of the wolf’s path in the
horizontal (more precisely, lef) and vertical (right) directions—the values of the next i-th
values of the vectors Xwolf and Ywolf. And before that, you need to fll in the corresponding
vectors Xhare and Yhare (in our problem, the hare runs in a circle with a radius R). And that’s
it! And no puzzling diferential equations and their solutions—numerical or analytical!
Te main thing here is the pseudo-parallel execution of three operators, combined in two
vectors. By the way, the operators in these two vectors can be swapped. Te result of the
calculation will not change in this case. Tis is one of the consequences of our “parallel”
computing.
In Figures 10.9 and 10.10, you can see two frames of animation of such a pursuit: a hare
(a rag hare for training dogs) runs in a circle, starting from “twelve o’clock” (X0 = 0, Y0 = R),
if by a circle we mean dial hours. From the “nine hours” (X0 = −R, Y0 = 0), a wolf runs out
simultaneously with the hare, runs strictly at the hare and afer 289 seconds (Figure 10.10)
catches it according to... a “greedy” algorithm without any optimization. And the pursuit
problem is an optimization problem where you can minimize the pursuit curve length,
chase time, or something else. So, if you minimize the time a wolf runs afer a hare, then
you need to choose a straight-line route for the wolf, having calculated in advance the coor-
dinates of the point where their fatal meeting will take place. Such a chase will not last 289
seconds (see Figure 10.10), but 200 seconds. If we minimize not the time, but the length of
the pursuit curve, then the wolf just needs to sit in ambush at “nine o’clock” and wait for
the hare to come running into its mouth.
Te book’s website contains an animation named [Link], two frames of
which are shown in Figures 10.9 and 10.10.
Pseudo-Parallelism ◾ 231

FIGURE 10.9 A wolf chasing a hare.

FIGURE 10.10 Te wolf caught the hare.

In Figure 10.7, by the way, there is a dashed curved line representing the analytical solu-
tion to the pursuit problem when the hare is running in a straight line. Tis curve coincides
with a thicker solid line—the solution to the pursuit problem according to the diference
scheme shown in Figure 10.8. Te coincidence of these two lines, dotted and solid, indi-
cates the high accuracy of our model.
232 ◾ STEM Problems with Mathcad and Python

FIGURE 10.11 Te wolf will never catch the hare.

Figure 10.11 shows a case where the speed of the wolf is less than the speed of a hare
running in a circle. Te wolf runs along an intricate spiral onto the trajectory of a circle,
the radius of which is easy to calculate, taking into account that the wolf and the hare will
have the same angular velocities, but diferent linear velocities.
In the situation shown in Figure 10.11, we can recommend the wolf to interrupt the
chase, stop running, catch his breath, and then catch the hare by running toward him. If
the wolf obeys us, then the trajectory of its run can be as follows—see Figure 10.12.
Tis is what is implemented in Figure 10.12. Te wolf and the hare make 8,820 jumps
each (n). Te jump of the wolf is shorter than the jump of the hare, since the speed of the
wolf is lower than the speed of the hare. Te trajectory of the wolf’s running should reach a
circle (see Figure 10.11), but the wolf stops at the 4,640th (n1) jump, and waits for the hare to
approach it, making 8,420 jumps (n2). It is enough to insert the if function into our “vector-
ized”, “parallel” operators to solve such a task.
In general, the constants vhare and vwolf can be made functions of some arguments in
order to solve some more complex interesting functions. Te speed of a hare can, for exam-
ple, depend on the distance to the wolf—the hare will “add gas” when the wolf is at a dan-
gerous distance, and then will slow down, as if teasing the wolf…
By generating diferent values for the Xhare and Y hare vectors (see Figure 10.8), very
intricate wolf paths can be obtained. You can, for example, let a hare go not along a
round, but along a square path, and see how the wolf will run at diferent speeds—con-
stant or variable. You can go from plane to space and replace the wolf with a hawk that
hunts a hare.
Pseudo-Parallelism ◾ 233

FIGURE 10.12 Te slow wolf will pause its pursuit and catch the hare.

A more detailed description of the diference scheme solution to the pursuit problem
can be found here [Link]
On the Mathcad users site, the problem has a discussion thread: [Link]
com/t5/PTC-Mathcad/Wolf-and-hare-one-old-problem-with-simple-Mathcad-solution/
m-p/574235.
Note. Te solution to the pursuit problem will depend on the number of partitions. In
some cases, instability may appear.
234 ◾ STEM Problems with Mathcad and Python

10.3 EXAMPLE 3. PANDEMIC


At present, humanity, like a hare, is running away from the “new dire wolf”—from the
virus. Let’s simulate the development of the epidemic.

Faust
What’s that white spot on the water?
Mephistopheles
A Spanish Tree-master, clearing the sound,
Fully laden, Holland-bound.
Tere hundreds sordid souls abord her,
Two monkeys, chests of gold,
A lot of fne expensive chocolate,
And a fashionable malady:
bestowed on your kind recently.
[Link] SCENES FROM FAUST translated by Alan Shaw

Tree hundred people infected with a virus arrive in a city of 100 thousand inhabitants.
Here, following the epigraph,3 it is tempting to write that “Tere hundreds sordid souls
abord her” are arriving. But, frstly, not all the entire crew of the Spanish ship was infected
with a “fashionable malady”, and secondly, not all the infected were “sordid souls”: many
people simply heard Pushkin’s lines in our difcult coronavirus times—they just ask for
the epigraph in this article on the mathematical model of an epidemic or, as is now custom-
ary to say, on the digital twin of an epidemic.
So, in a city with a population of one hundred thousand people, 300 infected people
arrive on day zero.4 In the Mathcad calculation shown in Figure 10.1, this event was
recorded by the three operators of the frst line: to the healthy, infected and sick vectors
are assigned the values 100,000, 300 and 300. Te numbers can be “played with”—you can
set other values and see the result on the epidemic. For this you need to fll in the remain-
ing elements of these three vectors. We do this, and the model, (which is the simplest, we
should emphasize) will solve the problem.
Te second line of the calculation in Figure 10.13 sets the value of the Stickiness variable
(factor), which represents the ease of transmission of the virus from infected to healthy

3 In 1830 Alexander Pushkin, the author of the epigraph lines, was quarantined for 3 months in the village of Bolshoe
Boldino, during a cholera epidemic that swept Moscow. “Te Boldino autumn of 1830 is the most productive creative
time in the life of A.S. Pushkin. Te retreat on the estate of Bolshoe Boldino due to the announced cholera quarantine
coincided with the preparations for the long-awaited marriage to Natalia Goncharova. During this time, work was com-
pleted on “Eugene Onegin”, the cycles of “Te Belkin Tales” and “Little Tragedies”, the poem “A little House in Kolomna”
and 32 lyric poems were written. Incidentally, there was written “A Feast in time of Plague”, which is also “widely heard
in our difcult coronavirus times.”
4 Te numbering of the elements of vectors and matrices in the Mathcad environment starts by default from zero. Tis
number is stored by the ORIGIN system variable. An old joke. Programmers were drafed into the army in a newly
created computer troops, made to stand in a line and ordered: “Settle in order!” Te outermost programmer shouted
“Zero!”, the next shouted “First”, and the next one asked: “What system should I use to count? ”By binary, octal, decimal
or hexadecimal?” Mathematicians, following programmers, begin more and more ofen to number the elements of vec-
tors and matrices not from one, but from zero.
Pseudo-Parallelism ◾ 235

FIGURE 10.13 One of the simplest mathematical models on the dynamics of an epidemic.

people and largely determines the nature of the dynamics of the epidemic. Next, the
Range Variable Day is introduced into the calculation for sorting the days of the epidemic
dynamics—from zero to thirty-seventh (this fgure can be changed in the calculation). Te
range variable is a protovector, so to speak: in the elements of a full-fedged vector, the val-
ues can be stored in any order, while the values in a range variable can be associated with
an arithmetic progression. When a range variable is entered into the calculation, its frst
value, its second value and its last value are set. If the second value is not specifed, then by
default it will difer from the frst by minus or plus one. Te range variable was introduced
in Mathcad in the very frst versions of this package when there were no programming
tools included (see below). Now these tools make it possible to introduce these protovectors
and not only the range variable into the calculation.
Te epidemic dynamics model is as follows: the number of people infected on the cur-
rent day (Day + 1) is proportional to the product of the number of healthy people and the
number of sick people on the previous day (Day). Te coefcient of proportionality is equal
to the Stickiness (see footnote). Te number of sick people on the current day is the sum of
the infected people on all the previous days. Te number of healthy people on the current
day is the number of healthy people minus the number of people infected on the previous
day.
236 ◾ STEM Problems with Mathcad and Python

Vectors in a Mathcad environment can be not only variables (see above), but also opera-
tors in a sense: the execution order of the operations can be determined by a vector. In our
calculation, the flling of the Healthy, Infected and Sick vectors is carried out not by three
separate assignment operators, but by one vector operator with three elements. Tis tech-
nique allows a user to execute these statements in parallel.5 Without this, the execution of
the frst stand-alone operator InfectedDay + 1: = ... would be interrupted by an error message,
because the Sick vector is not yet flled, but it is not possible to fll it either. It is possible to
break this vicious circle through pseudo-parallel computation of operators.6 Or through
programming—see footnote 6.
Te graph in Figure 10.13 visualizes the contents of three flled vectors: on the 27th day
of the epidemic, the maximum number of infected per day is shown—7,496 people7 (max
function). Tis day is visible on the bottom curve of the graph, and it can be calculated
also using another function built into Mathcad—the match function, which returns the
index of a given element in a vector. Te number 27 below is enclosed in square brackets.
Te brackets indicate that this is not a scalar, but a vectort with one element. In fact, the
Infected vector can include several elements of a given value. If this is the case, the match
function will return a vector with more than one element.
In Python, the epidemic model is implemented using the epidemy_model function.:

%matplotlib inline Œ
import numpy as np
import [Link] as plt
def epidemy_model(days=37, healthy0=100000,infected0=300,
sick0=300, stickness=3e-6):
d = [Link]((3, days+1),dtype=np.int64) 
d[:,0] = infected0, sick0, healthy0
infected, sick, healthy = d[0,:], d[1,:], d[2,:] Ž
for day in range(0, days):
d[:,day+1] = \
[Link]([stickness*healthy[day]*sick[day],
[Link](infected)[day],
healthy[day] - infected[day]],
dtype=np.int64)
return infected, sick, healthy 

5 Our vectors can also be flled through the programming tools that Mathcad is equipped with—through a loop with
a parameter (for statement). But only the paid for version of Mathcad has programming. Te calculations presented
in this article can be carried out in the free version of this mathematical program—in the environment of Mathcad
Express. A person who wants to work with Mathcad downloads its full version from the site [Link]
en, works with her for a month, and then he has a shortened version of this package if he has not purchased a license for
the full version.
6 Ofen in programming, it is necessary to swap the values in two or more variables. Here usually one or more auxiliary
variables are called for help: c: = a a: = b b: = c. However, in the Mathcad environment, you can do something simpler: (a
b): = (b a), using a matrix with one row and two columns (“horizontal vector”). Few users of Mathcad know about this
feature (parallel execution of statements).
7 Tis number is rounded to the nearest integer. In principle, in our calculation, the Mathcad built-in function round
should be used to round of its argument to a given value.
Pseudo-Parallelism ◾ 237

1. We will perform calculations using the NumPy library, and draw a graph using mat-
plotlib, for which we import them. Te functions are passed the same named argu-
ments as in Mathcad, so we do not repeat the information about their purpose.
2. Create array d—a two-dimensional array, the frst line of which is infected, the
second—sick, the third—healthy. We initialize them with the zero day values obtained
in the function header. Please note that we have to set the datatype of the array, since
by default we will receive arrays with foating point numbers.
3. To make it more convenient to work, we create views—one-dimensional arrays
infected, sick and healthy.
In a daily cycle, we calculate the number of infected, sick and healthy in 1, 2, and
subsequent days. Note that we are working with slices of NumPy arrays with the
number of elements equal to 3. We calculate the sum using the universal NumPy
function cumsum, which returns an array of the total number of infected, starting
from day zero.
4. Te function returns arrays of the number of infected, sick and healthy by day.

Just like in Mathcad, we will draw how the number of infected, sick and healthy changes
by day, but we will do it on a logarithmic scale:

infected, sick, healthy, = epidemy_model()


[Link](infected,'k:', lw=3, label='Infected')
[Link](sick,'k--', lw=3, label='Sick')
[Link](healthy, 'k-', lw=3, label='Healthy')

[Link]('log')
[Link]('day')
[Link](loc='best')
[Link]()

In this code snippet, we call a function with default parameter values, then draw the
dynamics of the incidence rate by day, set the logarithmic scale along the ordinate axis,
display the legend, the grid and get an unexpected result (Figure 10.14).
Recall that on day zero, 300 infected and sick people arrived in the city.
So, the next 2 days, the number of infected decreased to 89 and increased on the third
day to 116. Tis suggests whether there is a critical number of infected and sick on day zero,
which does not lead to an epidemic with other parameters fxed. It turns out that it is equal
to three. But with the number of infected four, the entire city will be infected, only the time
of complete infection will increase to 60 days.
Te mathematical model of the epidemic presented in Figure 10.13, we repeat, is sim-
plifed as much as possible. But it can be supplemented and developed by introducing
additional vectors, taking into account, for example, mortality from the viral disease or
(on the contrary, and fortunately) a cure for it and the acquisition of immunity. Someone
will be evacuated from the infected area, etc. And consequently, the value of Stickiness
238 ◾ STEM Problems with Mathcad and Python

FIGURE 10.14 Morbidity dynamics on a logarithmic scale at infected0 = sick0 = 300.

can also change. It can also be represented by a vector with diferent values for diferent
days. Figure 10.15 shows the following calculation: on the seventh day of the dynamics of
the epidemic, the city authorities take some preventive measures—they prescribe wear-
ing masks, impose restrictions on the movement of people (quarantine) and so on, that
is, they sharply (by a step) reduce the value of the Stickiness variable from 2·10−5 to 3·10−6.
Due to this, it is possible to prevent the explosive nature of the epidemic. It should be noted
that the epidemic dynamics model described is very sensitive to the value of the Stickiness
variable. It is only necessary to slightly change this value—and you can get negative or
unacceptably large values in the vectors Healthy, Infected and Sick.
From a diference scheme, it is possible to move to a system of diferential equations and
to generate functions that return the number of healthy, infected and sick people at difer-
ent points in time instead of discrete values in vectors.
It should also be noted that the solutions in Figures 10.13 and 10.15 concerned a problem
with initial conditions (Cauchy problem). But in real life, we cannot know the number of
infected people on the initial day. We can only know the number of healthy people on the
initial day and the number of sick people on a particular day of the epidemic. In this case, it
is necessary to solve not a Cauchy problem, but a boundary-value problem. It can be solved
in our model by the shooting method: set the initial value of sick people, watch how it difers
from the value of sick people set at the other end of the interval (short-fight) and adjust the
“angle of the gun”—set a new initial value of sick people.
On Mathcad Users Site [Link]
math/td-p/654378, it is possible to see more complex patterns of the epidemic.
Authors once described an epidemic dynamics model. Tis model was expanded and
applied to the description of the dynamics of the fnancial pyramid, where the number of
people who bought shares of a rogue company on the current day was also proportional
to the number of people who bought (sick) and to the number of people who did not buy
(healthy) on the previous day.
Pseudo-Parallelism ◾ 239

FIGURE 10.15 Improved mathematical model of the epidemic dynamics.

TASKS FOR READERS

1. Reproduce the calculations performed in the chapter


2. Investigate under what conditions the hare will not fall into the paws of the wolf
3. Using the simplest model, try to fnd out if there is a critical level of Stickiness that
does not allow an epidemic to develop.
Chapter 11

A Catenary: To Step
or Ride Over?

S omeone is riding a bicycle, and ahead of them is an obstacle (Figure 11.1)—a chain
suspended on posts. The rider can, of course, stop and step over the chain, at the same
time lifting his/her “iron horse”.1 But because of laziness or mischief, he/she doesn’t slow
down and get off the bike, but aims it at the lowest point of the chain, having estimated in
advance by eye that the length of the chain has led to a low enough center for this small
road adventure.
Or the rider can act in a more intelligent and interesting way: get off the bike, measure
the values of H (the height of the posts), L (the distance between them) and h (the ground
clearance of the sagging chain), and then decide whether to step over the chain or still ride
the bike over it. The selection criterion is as follows—is it possible to press the chain to the
ground if the wheels hit the middle of it? Otherwise: which is longer—a half of a chain or
a hypotenuse of a right-angled triangle with legs H and L/2.
To calculate the length of a curve, it is necessary to know its equation, the formula. To
the question of the shape of the curve drawn by the sagging chain, the vast majority of
people will answer that it is a parabola. And there is nothing surprising here—even the
great Galileo once thought so and in one of his treatises specified drawing this flat second-
order curve using a sagging chain. The parabola comes to mind because all of us in school
in mathematics lessons studied the quadratic equation and looked for its roots not only
analytically through formulas with discriminant and square root, but also graphically,
marking the points where the parabola intersects the abscissa axis. The quadratic equa-
tion is even immortalized in the cult film of another great Italian, Federico Fellini, in the
film “Amarcord”: we can see a math teacher asking a student to finish solving a quadratic
equation with chalk on a blackboard. Nowadays, such an operation is more and more often
carried out on a computer, tablet, or smartphone. Figure 11.2 shows the solution to the
problem in the environment of the physical and mathematical program Mathcad, which

1 Aluminum, titanium, fiberglass, composite.

DOI: 10.1201/9781003228356-12 241


242 ◾ STEM Problems with Mathcad and Python

FIGURE 11.1 Chain on posts.

FIGURE 11.2 Solving a quadratic equation in the Mathcad environment.

we will also use to solve the problem of a cyclist overcoming a sagging chain. Te answer is
given both exactly (in radicals) and approximately (to three decimal places). In the graph,
the roots of the quadratic equation are marked. A chain is suspended from these roots.
Figure 11.3 shows the solution to the problem of a cyclist who has slowed down to think
about a sagging chain with measured values of the parameters of the fence H, L and h
(see the table at the beginning of the calculation). A parabolic function called y, with an
A Catenary: To Step or Ride Over? ◾ 243

FIGURE 11.3 Solution of the problem of a cyclist and a chain fence (parabola).

argument x and with two parameters a and h is introduced into the calculation: we, fol-
lowing Galileo and guided by our school memory, assumed that the chain sags along a
parabola! Te canonical equation of the parabola looks somewhat diferent—y = 2p x2 and
has only one parameter p, but we have changed this equation taking into account that our
Cartesian coordinates will not be at the top of the parabola, but on the ground—at a dis-
tance h from the lowest point parabolas. Te parameter h in our case is given (10 cm), and
the parameter a is easy to calculate through the solution of the parabola equation. To do
this, we used the solve operator (see also Figure 11.2). Afer that, it is possible, by means of
a defnite integral,2 to calculate the length of the segment of the chain S hanging between
the two posts, and compare it with the minimum required length Smin for passing through
the chain when the latter is pressed to the ground by the bicycle wheels. Te computer tells
us that it is impossible to ride over the chain—it can be torn, the posts can be pulled up/
bent, or, in general, the prospect of falling of the bike is likely!

2 Of course, you can “take” it manually and work further with the analytical equation, but let the computer do it, unno-
ticed by us. Calculators have taught us to count in our head or in a column on paper. Computers are gradually weaning
us of calculating derivatives, integrals, limits, simplifying expressions (see the frst operator in Figure 11.3), and so on.
Good or bad—a special conversation. Konstantin Levin (alter ego of Leo Tolstoy—see epigraph), apparently, had prob-
lems with diferential calculus—he could not calculate integrals.
244 ◾ STEM Problems with Mathcad and Python

FIGURE 11.4 Solving the problem of a cyclist and a chain fence (a catenary).

Galileo (1564–1642) at the end of his life admitted that he was wrong when he believed
that the chain sags in a parabola. Te catenary formula (a catenary—this is the name of
the curve along which the chain sags) was derived simultaneously and independently by
Leibniz (1646–1716), Huygens (1629–1695) and Johann Bernoulli (1667–1748) only in 1691.
In Figure 11.4, we solved the problem of a cyclist and a chain fence in a new way, specifying
that the chain sags not along a parabola, but along this very chain line.
Te canonical catenary equation looks like this: y = a cosh(x/a), where cosh—is the
hyperbolic cosine, cosh(x) = (ex + e−x)/2. Te equation has only one parameter a, but we, as
in the case of the parabola, changed it taking into account the fact that our Cartesian ori-
gin is still on the ground at a distance h below the lowest point of the catenary.
To fnd the value of parameter a, we used the Mathcad built-in function root, designed
for numerical search for the zero of an expression using the secant method and requiring
the frst guess. In the solution in Figure 11.3, we used symbolic tools.
Comparing the solutions presented in Figures 11.3 and 11.4, we can draw the follow-
ing conclusion: knowledge of mathematics, in particular, understanding of the fact that
the chain sags not along a parabola, but along a catenary line, allowed us to successfully...
overcome the obstacle in the form of a sagging chain on a bicycle.
By the way, the bike has its own chain, which a cyclist needs to be able to properly
adjust—set the desired sag on it so that it is not too tight, but does not jump of either.
Figure 11.5 shows the solution to the problem of the shape of two halves of a chain,
which is pressed to the ground by a bicycle wheel. Another parameter has been added to
the catenary formula—the abscissa of the minimum point xh. Te ordinate of the lowest
point of this line is the parameter h already known to us. Te solution is reduced to the
numerical search for the root of a system of three transcendental equations describing the
sagging of the right branch of the chain pressed to the ground (the problem is symmetric
about the ordinate3). Te frst equation in the system is the equation for the length of the

3 Te reader can break this symmetry and solve the problem for the case when the bicycle does not move the chain strictly
in the middle. An even more interesting problem: the contact of a bicycle wheel with a chain is not a point, but an arc of
a circle—a section of a wheel tire. Te chain can also be suspended from posts of diferent heights. Te strength calcula-
tions of the chain will also be interesting.
A Catenary: To Step or Ride Over? ◾ 245

FIGURE 11.5 Solution of the problem of a chain pressed to the ground by a bicycle wheel.

catenary. Te S value was calculated earlier in the problem shown in Figure 11.4. Te sec-
ond and third equations are the equations for fxing the chain segment to the lef at the
ground and at the top of the right column. Te system of equations is solved numerically,
which requires a frst approximation for the unknowns a, h and xh.
Figure 11.6 shows two graphs—a graph of an undisturbed sagging chain, the calculation
of its parameters is shown in Figure 11.4, and the graph of the chain when pressed down
by the bicycle wheel (calculation in Figure 11.5). By the way, if someone superimposes a
parabola graph on the frst graph (undisturbed catenary), then these graphs will practically
coincide. Diferences will be noticeable only with more signifcant chain slack. So Galileo
was not far from the truth when he argued that the chain sags in a parabola. Moreover, we
are dealing with a real chain of real thickness, and not with an ideal “thin absolutely fex-
ible inextensible thread”.
Te dotted lines in the lower graph of Figure 11.6 are the same hypotenuses of the two
right-angled triangles that we mentioned at the beginning of the chapter. Te solid line is
the hanging halves of the chain (see footnote 5).
As the reader understands, the considered problem has quite an important practical
application—the calculation of aerial ropeways.
Now let’s remove the assumption that the chain is pressed to the ground in a point—we
set the actual value of the radius of the circular section of the tire of a wheel or ... the roller
246 ◾ STEM Problems with Mathcad and Python

FIGURE 11.6 Chain pressed to the ground by a bicycle wheel.

of an aerial cable car and calculate the parameters of the chain with a round weight in the
middle. Te scheme of the problem is shown in Figure 11.7.
A round object with radius R and mass massR is placed on a chain with linear specifc
gravity massc and length S, suspended on two identical posts of height H, spaced from each
other at a distance L (see Figure 11.1). How will such a chain hang?
Another built-in function of the Mathcad package will help us solve this problem—the
Minimize function, which returns the coordinates of the lowest point of the chain, fulfll-
ing certain constraints (equality and/or inequality).
It is known that any mechanical system spontaneously brings itself into such a static
position in which its potential energy will be minimal (the Lagrange – Dirichlet principle).4

4 Tis is a problem of mechanical stability (static) that was further investigated by the Russian mathematician Alexander
Lyapunov. Lagrange is considered a French mathematician. But he was born where Italy is now. We can conditionally
consider him the third great Italian (afer Galileo and Fellini) listed in this chapter.
A Catenary: To Step or Ride Over? ◾ 247

FIGURE 11.7 Scheme of the problem of a wheel of a bicycle running over a sagging chain.

If we calculate the potential energy (product of weight and height) of each link of the actual
sagging chain shown in Figure 11.1 and then sum up these values, it turns out that the
resulting sum will be minimal only for the catenary function.5 Te chain can be pressed to
the ground (Figure 11.6), by the wheel of our bicycle, for example, and then released—the
chain links in the bundle will oscillate for some time,6 transforming their energy from
potential to kinetic and vice versa, until the energy spent on pressing the chain to the
ground dissipates, i.e., it turns into heat. If someone hangs something to the chain, then the
whole structure will take a shape that will also meet the principle of minimum potential
energy.
Let us solve the problem of a chain with a wheel running over it. Or a more practi-
cal problem, namely the problem of a chain along which a roller rolls (a rope to which is
attached a booth with people or a trolley with a load).
It is deemed that a problem is almost solved when the user auxiliary functions necessary
for solving the problem are created and tested. Figure 11.8 shows how the following user
functions are included in the calculation.

1. Te catenary function with one argument x and three parameters a, h and xh.
2. Te function of the derivative of the catenary with respect to the argument x (the
function has only two parameters a and xh).
3. Te function that returns the length of the catenary from the value of the argument
x1 to the value of x2.

5 Tis is a problem of the calculus of variations. Another well-known example from this area of mathematics is to deter-
mine the profle of the slide in which the ball will roll in the shortest possible time (brachistochrone curve).
6 Tis, by the way, is another interesting problem requiring the solutions not just of equations, but of diferential equations.
248 ◾ STEM Problems with Mathcad and Python

FIGURE 11.8 Auxiliary functions of the problem of a bicycle wheel running over a sagging chain.

4. Te function that returns the ordinate of the center of gravity of the catenary line
segment from the value of the argument x1 to the value of x2.
5. Te function describes the lower half of a circle with one argument x and two param-
eters R (the radius of the circle that touches the chain) and hR (the ordinate of the
center of the circle).
6. Te function of the derivative of the function describes the lower half of the circle
with respect to the argument x (there is only one parameter R).
7. Te function that returns the length of the arc of the lower half of the circle from the
value of the argument x1 to the value of x2.
8. Te function that returns the ordinate of the center of gravity of the arc of the lower
half of the circle from the value of the argument x1 to the value of x2. Here it was
is possible to use the well-known formula R = sin(α)/α, where α is half of the open-
ing angle of the circular arc, but it is better to leave the basic formula with an inte-
gral. Tis formula is remembered and understood by almost everyone, and there is
no need to remember all formulas for specifc curves. Let the computer fgure out
the right formula for the right curve! Tis remark also applies to the formula for
A Catenary: To Step or Ride Over? ◾ 249

FIGURE 11.9 Input data and potential energy function for the problem of a bicycle wheel running
over a sagging chain.

the length of the catenary (see paragraph 4 above). Te same technique could be
applied to formulas for derivatives (items 2 and 6), but we calculated the derivatives
ourselves.7

Figure 11.9 shows how specifc numerical input data are entered into the calculation and
how the main user function, not an auxiliary one, denoted PE (potential energy) with fve
arguments is created, whose essence is shown in Figure 11.7 (only the argument a is not
marked in this fgure, i.e. the “Steepness” of the catenary). If our chain is loaded strictly in
the middle, then it seems to be divided into two separate chains, symmetrical about the
ordinate axis. Te catenaries describing these chains will have the same parameters a and
h, while the parameters xh will have the same absolute value, but diferent sign. Te same
condition applies to one more desired value i.e. the value of x (abscissa of the point of sepa-
ration of the chain from the circle).
Te operator forming the objective function of the calculation sums up four potential
energies: the energy of the lef branch of the sagging chain from −L/2 to −x, the energy of
a round object, the energy of a chain pressed against a circle from −x to x, and the energy
of the right branch of the chain from x to L/2. In principle, it is possible to consider only
the energy of one branch of the chain (right or lef), doubling it. However, our approach
is easier to understand and generalize: to take into account, for example, the fact that the
posts can have diferent heights, and the circle (roller) rolls along the chain (rope). Te
constant g (free fall acceleration) can, of course, be removed, but in this case, the phys-
ics of the problem will disappear, and only its mathematics will remain. Te reader, of
course, noticed that in the calculation we use physical quantities and their units, and this
aspect should be mentioned at the very beginning of the chapter. Tis technique, on the
one hand, simplifes calculations, eliminates the need to recalculate units of measurement,
and, on the other hand, prevents possible errors in formulas associated with incorrect units
of measurement. If, for example, in the formula for the length of a curve, we had missed a

7 Sometimes it is useful to train the brain, sitting at the calculator, to do arithmetic calculations in the mind. Sometimes
it is useful for the same purposes, sitting at the computer, to make algebraic transformations on a piece of paper!
250 ◾ STEM Problems with Mathcad and Python

FIGURE 11.10 Solution of the problem of a wheel of a bicycle running over a sagging chain.

two in the power of the derivative, then without working with the units of measurement,
we would have received a wrong answer. Instead, our calculation is interrupted by the error
message—“Incompatible units!”. Two, by the way, must be put in the power of one in the
formula for the length of the curve. Tis will not afect mathematics in any way, but it will
return the “physics”, or rather, the geometry of the problem. Otherwise, we have one leg
squared, and the second in the frst degree. Not good!
So, we have formed a classical optimization problem with an objective function and opti-
mization parameters—with objective function arguments. Te third, but optional part of
this problem are the constraints. We need them and they are written in the form of equali-
ties (equations) in the corresponding area of the Solve block (see Figure 11.10).
First, in the Solve block, the initial approximations of the solution are set, for which the
corresponding potential energy of our mechanical system is 48.436 J. Ten the following
constraints are introduced.

• Te specifed chain length does not change, but only divided into three length com-
ponents i.e. the length of the lef chain branch, the length of the chain under the cir-
cumference and the length of the right chain branch. As an aside, it would be possible
to include the elastic modulus of the chain or of the rope material and consider the
elongation in tension.
• For the abscissa equal to x, the chain line and the circle are joined.
A Catenary: To Step or Ride Over? ◾ 251

FIGURE 11.11 Tree graphs for three masses of a bicycle wheel running over a sagging chain.
252 ◾ STEM Problems with Mathcad and Python

FIGURE 11.12 Te chain and the great circle.

• At the same point x, there is no break, i.e. the values of the derivative of the catenary
line and of the derivative of the lower half of the circle coincide.
• Te chain is fxed to the top of the right post.

Te last three equations can be projected onto the lef half of our mechanical system.
However, we repeat, it is symmetric, and these equations will be superfuous, although the
solution will become clearer.
Te Mathcad’s built-in Minimize function returned the values of the fve unknowns,8
so that the target function PE took the minimum value (it decreased from 48.436 to 41.3 J),
and the constraints were met—four equalities turned into four identities—identities, tak-
ing into account the accepted accuracy of the numerical solution method. And the accu-
racy of the calculation can be taken as maximum, without leading to a calculation error.
In Figure 11.11, it is possible to see the graphical display of three solutions for three dif-
ferent loads. Te zero load trivial solution is not shown here. In this case, we will see on
the graph only one freely sagging chain, which is touched from above by the circle at its
lowest point. Tis case provides another confrmation of the correctness of the solution to
our problem. However, this fact will take place only when at the lowest point the radius of
curvature of the catenary is greater than the radius of the circle. If we increase the radius of
the circle R, decrease the value of L and/or increase the length of the chain S, then we can
come to the confguration shown in Figure 11.12, i.e. the circle, despite its “weightlessness”,
pushes the chain.

ASSIGNMENT TO THE READER


Solve such a problem. Not a bicycle, but a car runs over a chain.

8 And we have only four equations! But the ffh equation is “hidden” in the objective function PE.
Chapter 12

Round and Round

T he wheels on the bus go round and round according to the children’s nursery song.
However, that doesn’t mean the wheels themselves are normally round. If they were,
they would apply infinitely high pressure to the road surface. This came home to me while
staring disconsolately at a flat tire! A flat tire, of course, is definitely not round, but I real-
ized that, even when re-inflated, it would still have a flat section in contact with the ground.
Strangely, it looks round to a casual glance, but closer examination shows it not to be. I
wondered just how round a normally inflated car tire is. Does this thought even make
sense? Is there a measure of roundness? As it happens there is. Or, rather, there are! That is,
there are several possible measures of roundness in common use [1].
Let’s look at one using another roundish object that’s not quite circular; namely, the UK
50 pence coin. This is an equilaterally curved heptagon. In other words, it has seven equal
sides which are curved in the form of a segment of a circle. Like a circle it has a fixed diam-
eter, but clearly it isn’t as round as a circle. On the other hand, equally clearly, it is rounder
than a regular heptagon. So just how round is it? How can we quantify its roundness?
We could start by drawing a large circle that completely surrounds the coin and then
shrink it until it is as small as possible while remaining outside the coin. It may touch the
coin but must not cut through it. The resulting circle is called the minimum circumscribed
circle (MCC) (Figure 12.1).
Now we draw a small circle within the curved heptagon and expand it until it is as large
as possible consistent with not cutting through. The resulting circle is called the maximum
inscribed circle (MIC) (Figure 12.2).
The difference here between the radius of the MCC and that of the MIC is defined to
be the roundness of the coin. With Mathcad, it’s a straightforward matter to calculate the
radius of the MCC to be:

d
rMCC =
2cos(θ / 4 )

DOI: 10.1201/9781003228356-13 253


254 ◾ STEM Problems with Mathcad and Python

FIGURE 12.1 Minimum circumscribed circle.

FIGURE 12.2 Maximum inscribed circle.

where d is the fxed diameter of the curved heptagon, and ˜ is the angle 2π/7 radians (see
Figure 12.3 for the parameter defnitions and calculation of roundness).
Te calculations are also straightforward in Python – see Figures 12.4 and 12.5 – where
the symbolic solutions are given in a diferent, but equivalent form, as is seen from:

2d 1 2d 1 d d
˙ ˙ ˙
2 cos(˜ / 2 ) + 1 2 2cos (˜ / 4 ) − 1 + 1
2
2 cos (˜ / 4 )
2 2cos(˜ / 4 )

Te radius of the MIC is simply rMIC = d − rMCC, so, given that d is 27.3 mm, the roundness of
a 50 pence coin is approximately 0.7 mm. Note that the measure of roundness has dimen-
sions of length, and that similar shapes of diferent sizes have diferent measures of round-
ness. For example, the UK 20 pence coin has a smaller roundness than that of the 50 pence
coin, because, though they are the same shape, the 20 pence coin has a smaller value of d.
Had we applied this procedure to a perfect circle, where the MCC and MIC have iden-
tical radii, we would have found the circle to have zero roundness! Tough this might
initially seem perverse, the measure is really one of deviation from roundness of course, so
zero for a perfect circle is quite sensible.
Te 50 pence coin is nicely symmetrical such that the centers of the MCC and the MIC
are coincident. For more general shapes, this won’t be so. In these cases, having constructed
the MCC, we would then construct the MIC that is based on the same center as that of the
MCC. Te diference between the radius of this and that of the MCC then defnes a value
Round and Round ◾ 255

FIGURE 12.3 Roundness of 50 pence coin. (Mathcad 15.)

of roundness, known as the MCC roundness. Similarly, having constructed the MIC, we
would construct a MCC based on the same center as that of the MIC and use the diference
in radii as the MIC roundness. In general, these two measures will be slightly diferent. Te
larger of the two is referred to as the minimum zone circle (M12C) roundness.
We can illustrate this situation using our wheel. Figure 12.6 shows a wheel shape com-
prising a large circular arc with a fattened bottom (I’m assuming any distortion due to
the fattening appears in the out-of-page direction, so the remaining curve is still part of a
circle). Te relationship among the parameters indicated in Figure 12.6 is, of course:

w
˜ = sin −1 ˙˛ ˘ˆ (12.1)
˝ Rˇ

where R is the radius of the wheel and 2w is the length on the ground of the fat section.
256 ◾ STEM Problems with Mathcad and Python

FIGURE 12.4 Radius equations for 50 pence coin. (Python in Jupyter notebook.)

FIGURE 12.5 Solve radius equations. (Python in Jupyter notebook.)


Round and Round ◾ 257

FIGURE 12.6 Flattened circle.

FIGURE 12.7 MCC of fattened circle.

Te MCC surrounding this shape is simply the full circle without the fat section, as
shown in Figure 12.7. Te radius, RC , is just R. Te largest inscribed circle, based on the
same center as that of the MCC (shown as the open circle in Figure 12.7), also shown in
Figure 12.7, has radius rI − RC cos˜ . Te MCC roundness of this shape is therefore:

Round MCC = RC (1 − cos˜ ) (12.2)


258 ◾ STEM Problems with Mathcad and Python

FIGURE 12.8 MIC of fattened circle.

On the other hand, if we start with the MIC, we can fnd one with a radius, rI* , that is slightly
larger than rI (see Figure 12.8). Tis circle’s center (shown by the solid circle in Figure 12.8)
˜ R
is ofset vertically above that shown in Figure 12.5 by a distance = C (1 − cos° ). Tis
2 2
results in expressions for rI* and RC* (the radius of the MCC based on the same center as
2
˙ 2 ˜˘
that of the MIC) of rI* = RC − ˜ / 2 and RC* = w + ˇ RC −  respectively. So, the MIC
ˆ 2
roundness of this shape is:

2
˜ ˙ ˜˘
Round MIC = − RC + w 2 + ˇ RC −  (12.3)
2 ˆ 2

Typical values for a family saloon car might be 2R = 37 cm and 2w = 13 cm, so from equa-
tions (12.1)–(12.3) we have ˜ = 20.57°, an MCC roundness value of 1.179 cm and an MIC
roundness value of 1.143 cm. Te minimum zone circle roundness is therefore 1.179 cm.
Round and Round ◾ 259

Now I doubt that anyone is really very interested in knowing exactly how round a 50
pence coin or a car wheel is! Te measures exist primarily for application to those devices
that are supposed to be perfectly round. Since nothing is manufactured or machined to
mathematical perfection, tolerances on roundness are usually specifed using one of the
several possible defnitions. It can be important to know just how round an item is. An out-
of-tolerance shaf spinning at high speed might lead to unwanted vibrations or damage.
Te Presidential Commission into the Space Shuttle Challenger disaster concluded that
a contributory factor to the accident was the fact that: “… signifcant out-of-round condi-
tions existed between the two segments joined at the right Solid Rocket Motor af feld joint
(the joint that failed).” [2].
In reality, we are unlikely to be able to calculate the roundness of a manufactured com-
ponent from the sort of formulae used above. Te actual shape is likely to be described by a
number of discrete points obtained from a coordinate measuring machine. Te roundness
is then calculated by means of best-ft circles. In addition to the above measures, another
possible roundness measure is obtained by calculating the best-ft circle to all the points
and then fnding the maximum absolute deviation of any point from this circle.
Normally, the data points would be described by a set of Cartesian x and y values, mea-
sured from an arbitrary, but fxed datum. Te equation of a circle is usually written as:

( x − x c )2 + ( y − yc ) = R 2
2

where there are three unknowns, x c , yc and R to be found. At frst sight, it looks like a non-
linear regression technique might be required to fnd these values. However, it is likely that
in practice this equation would be re-written in the form:

ax + by + c = x 2 + y 2 (12.4)

with:

a = 2x c b = 2yc c = R 2 − x c2 − yc2 (12.5)

Te constants a, b and c can now be obtained using equation (12.4) by a standard linear
regression technique as follows:

˛ x1 y1 1 ˆ ˛ x12 + y12 ˆ
˙ ˘ ˙ ˘
M=˙ … … … ˘ v=˙ … ˘
˙ xn yn 1 ˘ ˙ x2 + y2 ˘
˝ ˇ ˙˝ n n
˘ˇ

° a ˙
˝ ˇ
M×˝ b ˇ=v
˝˛ c ˇˆ
260 ◾ STEM Problems with Mathcad and Python

FIGURE 12.9 Best ft to circle data. (Mathcad 15.)

Te values of a, b and c are obtained from the equation above by using a method such as
Mathcad’s lsolve(M, v) routine. Ten the desired constants x c , yc and R can be obtained
by appropriate rearrangements of the equations in (12.5), and from these, the roundness
is calculated. A simple example is shown in Figures 12.9 and 12.10, where the plotted data
looks to be a perfect circle by eye, but, in fact, has a non-zero roundness (only a few of the
100 pairs of data values used are shown explicitly in Figure 12.9).
Te Python equivalent calculations are shown in Figure 12.11, where the Numpy linear
algebra routine, lstsq, has been used to do the least squares best ft to the circle data.
Round and Round ◾ 261

FIGURE 12.10 Calculation of roundness from circle data. (Mathcad 15.)

FIGURE 12.11 Calculation of roundness from circle data. (Python in Jupyter notebook.)
262 ◾ STEM Problems with Mathcad and Python

TASKS FOR THE READER


1. What is the minimum zone circle roundness of a hexagon of 10 cm maximal dimeter?
2. Te earth’s orbit about the sun is almost circular. Choose a measure of roundness and
calculate earth’s orbit roundness. (Assume semi-major axis is 149.6*106 km, semi-
minor axis is 149.5*106 km).
3. Draw a circle by hand on squared paper. Measure the x and y distances (from an arbi-
trary origin) of 20 points spaced roughly equally around the perimeter of the circle.
Determine the minimum zone circle roundness of your circle.

REFERENCES
1. ISO 12181-1:2011. Geometrical product specifcations (GPS) – Roundness – Part 1: Vocabulary
and parameters of roundness. Obtainable from [Link]
logue_tc/catalogue_detail.htm?csnumber=53620
2. Report of the Presidential Commission on the Space Shuttle Challenger Accident. See http://
[Link]/about/assets/nasa_report.pdf
Chapter 13

Iterations and Fractal Sets


of Mandelbrot and Julia

I n applied mathematics, the method of successive approximations is often used when


an initial approximation x0 is chosen, which is then iteratively refined using the formula:

xi +1 = θ ( xi ) , i = 0, 1, … (13.1)

The process continues until | xi + 1 − xi | becomes less than a predetermined number ε.


As an example, consider the solution of the equation f(x) = 0 by Newton’s method for the
function f(x) having a continuous first derivative. Expand f(x) in a Taylor series near the
point xi, choosing xi + 1 so that:

df ( xi )
f ( xi +1 ) = f ( xi ) + ( xi+1 − xi ) = 0, i = 0, 1, … (13.2)
dx

The expression for the next approximation for solving the equation is easy to obtain from
equation (13.2):

f ( xi )
xi +1 = xi − , i = 0, 1, … (13.3)
df ( xi )
dx

To find the root, the derivative must be nonzero. It is known that if the process of iterative
refinement for Newton’s method converges, then the number of significant digits in the
root of the equation doubles at each iteration [1]. We can easily “reinvent the wheel” by
writing a function to solve algebraic equations using Newton’s method, although every-
thing that is needed for this is in the [Link] Python ecosystem library.
Below is the source code for the newton function, our “bike”:

DOI: 10.1201/9781003228356-14 263


264 ◾ STEM Problems with Mathcad and Python

def newton(f, fs, x0, args=(), ε=1e-6, maxiters=100):


for iters in range(maxiters+1):
x = x0 - f(x0,*args)/fs(x0, *args)
if abs(x - x0) < ε:
break
x0 = x
if iters < maxiters:
return x, iters
else:
return None, maxiters

To fnd the root of the function we pass: f is the function, fs is its derivative, x0 is the initial
value of the root, args is a tuple of additional arguments passed to f and fs, ε is the permis-
sible change in the value of the root per iteration, which serves to stop the iterative process
of refning the root; maxiters is the maximum number of iterations.
Te function returns the values of the root and the number of iterations required to ful-
fll the condition | xi + 1 − xi | < ε, provided that the process of refning the value of the root
converges. Otherwise, the function returns None and maxiters.
As an example, let’s solve the equation cos(x) = x.

from math import sin, cos


f = lambda x: x - cos(x)
fs = lambda x: 1 + sin(x)
(newton(f, fs, 0.), newton(f, fs, 0., ε=1e-12),
newton(f, fs, -8.))

Te results of three calls to the newton function are:

((0.7390851332151607, 4), (0.7390851332151607, 5),


(0.7390851332151607, 11))

Tus, if the initial approximation is chosen successfully, then the iterative refnement
process converges rather quickly. Here we immediately note that the “bike” we invented
is a toy, for practical tasks, it is necessary to use proven tools from the Python ecosystem.
It would seem what the unexpected can happen in the iterative process xi + 1 = f(f(… f(x0)).
It looks like there are just two possibilities, namely that the iterations can either converge
or diverge. However, this is not so and we will show this on a simple mapping, called the
logistic map1:

xi+1 = r ˝ xi ˝(1 − xi ) , i = 0,1,,0 < r < 4;0 ˇ xi ˇ 1. (13.4)

Formula (equation 13.4) describes how population size changes over time. Here xi is the
size of the population in the i-th year, r is a parameter characterizing the rate of population
1 Logistic map. URL: [Link]
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 265

FIGURE 13.1 Geometric interpretation of a logistic mapping.

growth. Te transformation is discrete, i.e., the population size changes once a year. Despite
its simplicity, it has nontrivial behavior, as will be shown below. It would seem that with
increasing i the value xi should tend to either a fxed value or infnity. However, this is not
the case, the behavior of xi depends on r and is more complex than one might think. Te
logistic mapping has a useful geometric interpretation as shown in Figure 13.1.
Let’s set, for example, r = 3, x0 = 0.8, construct in the fgure a curve y(x) = r ∙ x ∙ (1 − x) and
a straight line y(x) = x.
Let’s start with the initial value x0 and calculate x1 = r ∙ x0 ∙ (1 − x0), connect the points
(x0, 0) and (x0, x1) with a dashed line. To perform the second iteration – transition to point
x2 – connect the points (x0, 0) and (x0, x1) with a horizontal dashed line, then calculate x2 =
r ∙ x1 ∙ (1 − x1), draw a vertical line (x1, x1), (x1, x2). Tis process can be continued by using
the visual representation of the points x0, x1, x2, x3, ...
Te evolution of individual values x(t) and the entire array x can be easily tracked using
the log_map function:

import numpy as np
import [Link] as plt
def log_map(r, n=1001, iters=500, x0=0.5, m=0,
figsize=(10, 8), fs=12):
x = [Link](0, 1, n) ❶
data = [Link]((iters, n)) * x
# mapping
for i in range(1, iters): ❷
data[i] = r * data[i - 1] * (1.0 - data[i - 1])
fig = [Link](figsize=figsize) ❸
# x0 evolution
i0 = int(x0 * n)
x00 = x0 = data[m, i0]
266 ◾ STEM Problems with Mathcad and Python

y0 = data[m, i0] if m else 0.0


ax = plt.subplot2grid((2, 2), (0, 0)) ❹
[Link](data[0], data[1], "k-", lw=3, label=f"r={r}")
[Link](data[0], data[0], "k-", lw=1)
[Link](loc="best", fontsize=fs)
for i in range(m, iters):
x1 = r * x0 * (1 - x0)
[Link]([x0, x0], [y0, x1], "k--", lw=1)
[Link]([x0, x1], [x1, x1], "k--", lw=1)
x0 = x1
y0 = x1
ax.set_xlabel("$x$", fontsize=fs)
ax.set_ylabel("$y(x)$", fontsize=fs)
# x0(t)
ax = plt.subplot2grid((2, 2), (0, 1)) ❺
t = [Link](m, iters, iters - m)
[Link](t, data[m:, i0], "k-", label=f'$x_0$={x00:6.3}')
ax.set_xlabel("$t$", fontsize=fs)
ax.set_ylabel("$x_0(t)$", fontsize=fs)
[Link](loc='best', fontsize=fs)
# x[:] evolution
ax = plt.subplot2grid((2,2), (1,0), colspan=2) ❻
for i in range(m+1, iters):
[Link](data[0], data[i], 'k-')
[Link]('$x_0$', fontsize=fs)
[Link]('$x_i$', fontsize=fs)
plt.tight_layout()

Te function is passed the value of r – the coefcient in the formula (equation 13.4), n – the
number of partitions of the segment [0,1], iters – the number of iterations (applications of
the formula (equation 13.4)), x0 – the initial value of x. Te rest of the parameters relate to
the visualization of the iterative process: m is the initial number of the iteration for which
the visualization is performed and figsize is the size of the picture.

1. Data preparation takes four lines: we create NumPy arrays: x – coordinates along
the abscissa, data – the results of the transformations are stored in this array at all
iterations.
2. Here we perform calculations using the formula (equation 13.4) and store them in the
data array.
3. Create a fgure and prepare data for rendering.
4. We render the visualization on an irregular grid containing two rows and two col-
umns. In the frst picture of Figure 13.2, located in the upper lef corner of the grid,
we display the evolution of x0.
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 267

FIGURE 13.2 Logistic mapping for r = 1.

5. In the second picture, in the upper right corner, we display the dependence of x0 on
the number of iterations.
6. Te picture located in the second row is starched by two columns. It displays the evo-
lution not of x0 – of one point, but of an array x since the NumPy tools allow you to
do this.
7. Call the tight_layout function so that the labels on the coordinate axes do not “run
over” the pictures.

Te above function will allow us to fgure out how the logistic mapping behaves when r
changes. For r < 1 (Figure 13.2) the process converges to zero for any x values.
For 1 < r ≤ 2 and 0 < x0 ≤ 1 there is fast monotonic convergence to maximum value (r − 1)/r
(Figure 13.3).
At 2 < r ≤ 3 (Figure 13.4), the convergence reaches the same value, (r − 1)/r, but is oscilla-
tory in nature.
Te convergence at r = 3 is very slow, but at 3 < r < 1 + √6 = 3.4495 periodic fuctuations
are observed (Figure 13.5).
Tis is where the argument m comes in handy, setting a value close to the number of
iterations, we can “cut of” the transient process at the early iterations (Figure 13.6).
268 ◾ STEM Problems with Mathcad and Python

FIGURE 13.3 Mapping for r = 2.

FIGURE 13.4 Mapping for r = 2.8.


Iterations and Fractal Sets of Mandelbrot and Julia ◾ 269

FIGURE 13.5 Mapping for r = 3.1.

FIGURE 13.6 Two stable states for r = 3.1, iters = 500, m = 400.
270 ◾ STEM Problems with Mathcad and Python

FIGURE 13.7 Four stable states for r = 3.1, iters = 500, m = 450.

For r < 1 + √6, two more stable states appear (Figure 13.7).
For r > 3.54, the number of stable states increases to eight, then to 16, and so on…
At r > 3.57, the display begins to behave chaotically (Figure 13.8), the number of stable
states increases sharply.
However, this does not mean that as r increases, “islands of order” will not appear;
Figure 13.9 shows one of such islands.
At 3.57 < r < 4.0, the process exhibits chaotic behavior (Figure 13.10).
Note that for 0 < r < 4 transformation (equation 13.4) maps the segment [0,1] onto itself,
but for r > 4 the mapping is carried out on the entire numerical axis and diverges except for
the points x0 = 0 and x0 = 1.
For a visual representation of how the mapping (equation 13.4) behaves for diferent val-
ues of r, we construct a bifurcation diagram.2 Te values of r are plotted on the abscissa of
the bifurcation diagram, and on the ordinate are all possible values obtained using formula
(equation 13.4) with the number of iterations tending to infnity. Below is the source code
for the bifur_diag function that draws the diagram.

2 Bifurcation diagram. URL: [Link]


Iterations and Fractal Sets of Mandelbrot and Julia ◾ 271

FIGURE 13.8 Chaotic behavior for r = 3.575.

FIGURE 13.9 "Island of order" for r = 3.774.

def bifur_diag(n=1000, iters = 501, r_start=2.8, r_finish=4.,


figsize=(8,6)):
rs = [Link](r_start,r_finish, n)
fig = [Link](figsize=(8,6))
x0 = [Link](0.001, 0.999, n)
272 ◾ STEM Problems with Mathcad and Python

FIGURE 13.10 Dynamic chaos at r = 3.999.

FIGURE 13.11 Bifurcation diagram for 2.8≤r≤4.0.

for r in rs:
x = x0
for i in range(iters):
x = r*x*(1-x)
[Link]([r]*n, x, 'k.', ms=0.1)
[Link](r_start, r_finish)

Te function is passed n – the number of partitions of the segment [0,1], iters – the number
of iterations, r_start, r_fnish – the initial and fnal values of r, and fgsize – the size of the
picture.
In the body of the function, the arrays rs and x0 are formed, which are used to calcu-
late all possible states, which are displayed on the bifurcation diagram with dot markers.
Figure 13.11 shows the bifurcation diagram with the default values of the parameters of the
bifur_diag function.
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 273

FIGURE 13.12 Bifurcation diagram for 3.54≤r≤3.8.

FIGURE 13.13 Bifurcation diagram for 3.737 ≤ r ≤ 3.746.

It clearly displays the behavior of the mapping: for r ≤ 3, the mapping has a single stable
state, for 3 < r < 3.57, there are two, four states, and so on. For r > 3.57, chaos ensues, as
shown in Figure 13.12.
At the same time, the diagram shows that, along with chaos, there are islands of rel-
ative order with a limited number of states, for example, on the segment [3.739, 3.740]
(Figure 13.13).
From Figures 13.11–13.13 it can be seen that the mapping is self-similar and represents
alternating sections of relative order, with a limited number of states, and dynamic chaos.
Let’s return to Newton’s method and try to relate the number of iterations required to
calculate the root of the equation with the initial approximation. Obviously, the further the
initial approximation is from the root, the more iterations we need to achieve a given accu-
racy. We will do this on the complex plane by linking the number of iterations required to
274 ◾ STEM Problems with Mathcad and Python

satisfy the condition xi+1 − xi < ˜ , where xi is the value of the root calculated at iteration i,
˜ is a predetermined small number. Te position of the initial approximation is set on the
complex plane, and the number of iterations required to calculate the root is associated
with the color. Te problem of the regions of attraction of the roots of algebraic equations
was frst solved by Gaston Julia in 1917 while in hospital afer a serious injury. Unlike us, he
did not have computer visualization available, with the help of which it is possible to fnd
out the structure of the areas of attraction of the roots of algebraic equations.

%matplotlib inline
import numpy as np
import [Link] as plt
def areas_of_attraction(f=lambda z:z**3-1,
fs=lambda z:3*z**2, n= 200, m=5,
args=(), area=(-1., -1., 1.,1),
iters=200, ε=1e-10, cmap='binary',
figsize=(8,6)):
xmin, ymin, xmax, ymax = area ❶
x = [Link](xmin, xmax, n)
y = [Link](ymin, ymax, n)
X, Y = [Link](x, y) ❷
Z = X +1j*Y
I = [Link]((n,n), dtype=np.int32) ❸
for i in range(n):
for j in range(n):
root, it = newton(f, fs, x0=Z[i,j], \ ❹
args=args, maxiters=iters, ε=ε)
if not (root is None):
I[i,j] = it ❺
[Link](figsize=figsize)
cb = [Link](I, cmap=cmap)
[Link](cb)
[Link]( [Link](0, n, m+1), \ ❻
['{0:4.3f}'.format(xmin+(xmax-xmin)*i/m) \
for i in range(m+1)])
[Link]( [Link](0, n, m+1), \
['{0:4.3f}'.format(ymin+(ymax-ymin)*i/m) \
for i in range(m+1)])
Te areas_of_attraction function is passed the function f, its derivative fs, n is the number
of partitions along the coordinate axes of a rectangle on the complex plane with initial
approximations, m is the number of partitions for digitizing the coordinate axes, args is
a tuple of additional parameters to be passed to the functions f, fs, iters is the maximum
number iterations, area is a tuple with the coordinates of the vertices of the rectangle with
initial approximations on the complex plane, ε is the change in the value of the root per
iteration, which serves to stop the iterative process of refning the root, cmap is the mat-
plotlib colormap used to visualize areas of attraction, fgsize is the size of the fgure.
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 275

FIGURE 13.14 Visualization of areas of attraction for the equation z3 – 1 = 0; colormap: binary.

1. Te frst thing that is done in the function is to unpack the area parameter to defne
the vertices of the rectangle with initial approximations on the complex plane.
2. We form two-dimensional arrays of initial approximations of roots on the complex
plane.
3. We prepare an array with the number of iterations for calculating the roots with a
given precision ε.
4. In the loop, using initial approximations, we solve the equation f(z) = 0 by Newton’s
method. We store in array I the number of iterations required to solve the equation.
5. Visualizing areas of attraction.
6. Digitizing on the coordinate axes.

Te calculation results for the equation z3 − 1 = 0 are shown in Figure 13.14. Note that the
relationship between color and the number of iterations required to solve the equation
with a given precision is displayed on the color bar.
It should be noted that the areas of attraction are self-similar, for this it is enough to look
at Figure 13.15, which shows a part of Figure 13.14 on an enlarged scale.
Te appearance of the areas of attraction depends greatly on the colormap used.
Figure 13.16 shows the structure of the areas of attraction for the equation z5 + 1 = 0 for the
“contrast” colormap: Paired.
Figure 13.17 shows the structure of the areas of attraction for the equation z3 = z, and
Figure 13.18 is the same, but on an enlarged scale.
276 ◾ STEM Problems with Mathcad and Python

FIGURE 13.15 Self-similarity of the structure of domains of attraction for the equation z3 – 1 = 0;
colormap: binary.

FIGURE 13.16 Areas of attraction for equation z 6 + 1 = 0 and Paired colormap.

We present two more areas of attraction for the equations z3 − 2z + 2 = 0 (Figure 13.19)
and z5 + 3j = 1 (Figure 13.20).
It can be seen from these fgures that as the complexity of the equation increases, so does
the complexity of the areas of attraction of the roots.
In 1993, everything fell apart in Russia, but nevertheless, the publishing house MIR,
which specialized in the publication of scientifc literature in the USSR, published a trans-
lation of the book [2] in hardcover and with color illustrations. Against the backdrop of
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 277

FIGURE 13.17 Areas of attraction for equation z3 = z using the binary colormap.

FIGURE 13.18 Areas of attraction for the equation z3 = z at a fner scale; binary colormap.

the disorder and chaos of everyday life, this book served as an example to the authors that
chaos can create order. Let’s go back to the mapping on the complex plane

z i+1 = f ( z i , c ) , i = 0, 1, 2… (13.5)

where zi = xi + 1j∙yi, and the rectangle on the complex plane is given by the tuple rect = (xmin,
ymin, xmax, ymax).
Let us fx c, choose M > 1 c, and we will sequentially execute (13.5) for i = 0,1,2… For
each i we calculate r = | f(zi, c) |. If r > M, then choose color i from colormap P containing K
278 ◾ STEM Problems with Mathcad and Python

FIGURE 13.19 Areas of attraction for equation z3 – 2z + 2 = 0 and colormap: binary.

FIGURE 13.20 Areas of attraction for equation z5+3j = 0 and colormap: binary.

colors, i < K. If i == K, then select the color with number 0 from the colormap. If neither of
these conditions are met, then we carry out (13.5).
Tis algorithm is performed for all z0 ∈ rect. Te result is an array of colors that are easy
to visualize. So in one paragraph, we describe the algorithm for constructing Julia sets.
Using the NumPy library allows you to write it compactly:

%matplotlib inline
import numpy as np
import [Link] as plt
import datetime
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 279

def julia_set(f=lambda z,c:z**2+c, c=0, rect=(-1,-1,1,1),


n=500, M=100, K=200, cmap='binary',
figsize=(6,6), colorbar=False): ❶
t0 = [Link]() ❷
xmin, ymin, xmax, ymax = rect ❸
x = [Link](xmin, xmax, n) ❹
y = [Link](ymin, ymax, n)
X, Y = [Link](x, y)
Z = X + 1j*Y
colors = [Link]((n, n), dtype=np.uint16) ❺
for k in range(M): ❻
Z[colors==0] = f(Z[colors==0], c)
r = [Link](Z)
colors[np.logical_and(r>=M, colors==0)] = k % K

dt = [Link]() - t0 ❼
dt = dt.total_seconds()

fig = [Link](figsize=figsize) ❽
im = [Link](colors, aspect='auto', cmap=cmap,
vmin=0, vmax=K)
if colorbar:
[Link](im)
[Link]('off')
[Link]()
return dt

1. Te following arguments are passed to the julia_set function: f – the function for
which the transformations are performed, by default, f(z) = z2 + c, c – a constant spec-
ifed by the user, rect = (xmin, ymin, xmax, ymax) – a rectangle on complex plane
being transformed, n is the number of partitions of the sides of the rectangle, M is the
number used in the algorithm for constructing the Julia set to complete the iterative
process and at the same time the maximum number of iterations. K is the number
of colors in the colormap, cmap is the name of the colormap, fgsize is the size of the
picture, colorbar – specifes the display of the colorbar.
2. Setting an initial value for measuring the time of the Julia set calculation.
3. Unpacking the coordinates of the vertices of the rectangle.
4. Cover the rectangle with a grid.
5. Preparing an array of colors to display the Julia set.
6. We perform mappings to construct the Julia set. Please note that calculations are
performed only with those array elements that were not previously painted. When
choosing a color index, we used the remainder afer division, k% K, to go beyond the
declared number of colors K.
280 ◾ STEM Problems with Mathcad and Python

FIGURE 13.21 Julia set for �(�) = �2 +�, � = 0.

7. Calculating the time in seconds to compute the Julia set.


8. To display Julia set, we used the function imshow, which maps the values of the array
elements to the colors of the cmap colormap. Note that if you use a large number of
colormap colors, the picture becomes pale, so either you have to use K < 50, or use
contrast colormaps, for example, prism.

As the frst example of a Julia set, we use f(z) = z2 and obtain concentric circles (Figure 13.21).

julia_set(c=0, rect=(-1,-1, 1,1), cmap='binary',


figsize=(7,6), K=20, M=200, colorbar=True)

Nonzero values of c deform the Julia set. So on Figure 13.22 c = 0.2, and on Figure 13.23
с = 0.5j
In Figure 13.21 the border between white and black is a circle of unit radius. Any change
in c destroys this symmetry, as shown in Figures 13.22 and 13.23. Moreover, as the absolute
value of c increases, the Julia set becomes multiply connected (Figure 13.24).
We can but admire the abilities and imagination of G. Julia, who, in not the easiest days
of his life, managed to describe the nontrivial structure of fractal sets without resorting to
visualization tools. We will only be interested in their construction and visualization, so
we borrowed from [2] the sets of c and rect values, which we brought into the get_julia_
data function:

def get_julia_data(v):
data =(
((-0.12375,0.56508), (-1.8,-1.8, 1.8,1.8)), #0
((-0.12,0.74), (-1.4,-1.4, 1.4,1.4)), #1
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 281

FIGURE 13.22 Julia set for �(�) = �2 + �, � = 0.2, rect = (−1.5, −1.5, 1.5, 1.5).

FIGURE 13.23 Julia set for �(�) = �2 + �, � = 0.5j, rect = (−1.5, −1.5, 1.5, 1.5).
282 ◾ STEM Problems with Mathcad and Python

FIGURE 13.24 Julia set for �(�) = �2 + �, � = 1 + 1j, rect = (−2, −2, 2, 2).

((-0.481762,-0.531657), (-1.5,-1.5, 1.5,1.5)),#2


((-0.39054,-0.58679), (-1.5,-1.5, 1.5,1.5)),#3
((0.27344,0.00742), (-1.3,-1.3, 1.3,1.3)),#4
((-1.25,0.0), (-1.8,-1.8, 1.8,1.8)),#5
((-0.11,0.6557), (-1.5,-1.5, 1.5,1.5)),#6
((0.11031,-0.67037), (-1.5,-1.5, 1.5,1.5)),#7
((-0.0,1.0), (-1.5,-1.5, 1.5,1.5)),#8
((-0.194,0.65557), (-1.5,-1.5, 1.5,1.5)),#9
((-0.15652,1.03225), (-1.7,-1.7, 1.7,1.7)),#10
((-0.74543,0.11301), (-1.8,-1.8, 1.8,1.8)),#11
((0.32,0.043), (-2.0,-1.5, 2.0,1.5)),#12
((-0.12375,0.56508), (-2.0,-1.5, 2.0,1.5)),#13
((-0.39054,-0.58679), (-1.5,-1.5, 1.5,1.5)),#14
((-0.11,0.67), (-2.0,-1.5, 2.0,1.5))#15
)

v = v % len(data)
c = complex(data[v][0][0], data[v][0][1])
rect = data[v][1]
return c, rect

An integer v is passed to the function – the number of the variant, the c and rect, which can
be used to display Julia sets, are returned.
In particular, for v = 4 we get (Figure 13.25):
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 283

FIGURE 13.25 Julia set for �(�) = �2 + �, � = 0.27344 + 0.00742�, rect = (−1.3, −1.3, 1.3, 1.3).

c, rect = get_julia_data(4)
julia_set(c=c, rect=rect, cmap='binary',
figsize=(6,6), K=20, M=255)

Julia fractal sets are self-similar; it is interesting to look at them at any scale, in
Figure 13.26 we give the upper quarter of Figure 13.25.
Figures 13.27 and 13.28 show the Julia sets for variant 10. Figure 13.27 highlights the
central part of the fgure.

c, rect = get_julia_data(10)
julia_set(c=c, rect=(-1.3, -1.3, 1.3, 1.3), cmap='binary',
figsize=(6,6), K=10, M=255)

Figures 13.29 and 13.30 shows Julia sets for variant 1.


Until now, we have only used quadratic functions, but there are many other transforma-
tions [3, 4] for which attractive fractals can be visualized. Figure 13.31 builds the Julia set
z3 z2
for the function f ( z ) = z 4 + + 3 + c.
z +1 z + 4z 2 + 5
Nothing prevents us from using non-integer degrees in formulas for calculating Julia sets,
for example, in Figures 13.32 and 13.33 we used the Julia set for the function f ( z ) = z 6.1 + c.
Te construction of Mandelbrot sets difers from the construction of Julia sets only in
that the rectangle is constructed from the values of c [5]. To construct Mandelbrot sets, two
functions are written, the frst of which is passed the number of the variant, it returns the
coordinates of the vertices of the rectangle:
284 ◾ STEM Problems with Mathcad and Python

FIGURE 13.26 Julia set for �(�) = �2 + c, c = 0.27344 + 0.00742�, rect = (−.2, −.2, .9, .9).

FIGURE 13.27 Julia set for �(z) = z2 + c, c = −0.15652 + 1.03225j, rect = (−1.3, −1.3, 1.3, 1.3).
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 285

FIGURE 13.28 Julia set for �(z) = z2 + c, c = −0.15652 + 1.03225j, rect = (−.3, −.3, .3, .3).

FIGURE 13.29 Julia set for �(z) = z2 + c, c = −0.74543 + 0.11301j, rect = (−1.6, −1.6, 1.6, 1.6).
286 ◾ STEM Problems with Mathcad and Python

FIGURE 13.30 Julia set for �(z) = z2 + c, c = −0.74543 + 0.11301j, rect = (−.08, −.08, .08, .08).

z3 z2
FIGURE 13.31 Julia set for f ( z ) = z 4 + + 3 + c , c = .5 + .71j,rect = ( 0.2,0.3,0.6,0.7 ).
z +1 z + 4z 2 + 5
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 287

(
FIGURE 13.32 Julia set for f ( z ) = z 6.1 + c,c = 0.6 + 0.55 j,rect = −1.2, − 1.2,1.2, 1.2 .)

( )
FIGURE 13.33 Julia set for f ( z ) = z 6.1 + c,c = 0.6 + 0.55 j,rect = 0.5, 0.5, 0.7,0.7 .
288 ◾ STEM Problems with Mathcad and Python

def get_mandelbrot_data(v):
data =(
(-2.5, -1.5, 0.75, 1.5), #0
(-0.19920,-0.12954, 1.01480,1.06707), #1
(-0.95,-0.88333, 0.23333, 0.3),#2
(-0.713,-0.4082, 0.49216,0.71429),#3
(-1.781,-1.764, 0.0, 0.013), #4
(-0.75104,-0.7408, 0.10511,0.11536),#5
(-0.74758,-0.74624, 0.10671, 0.10779),#6
(-0.74591, -0.74448, 0.11196, 0.11339),#7
(-0.745538, -0.745054, 0.112881, 0.113236),#8
(-0.745468, -0.745385, 0.112979, 0.113039),#9
(-0.7454356, -0.7454215, 0.1130037, 0.1130139),#10
(-1.254024, -1.252861, 0.046252, 0.047125),#11
)
return data[int(v) % len(data)]

Te second function calculates and renders the Mandelbrot set for the given rectangle rect.

def mandelbrot_set(f=lambda z:z**2,


rect=(-2.25,0.75, -1.5, 1.5),
n=500, M=200, K=20, cmap='binary',
figsize=(6,6)):
t0 = [Link]()
xmin, ymin, xmax, ymax = rect
x = [Link](xmin, xmax, n)
y = [Link](ymin, ymax, n)
X, Y = [Link](x, y)
z = [Link]((n, n), dtype=np.complex128)
C = X +1j*Y
colors = [Link]((n, n), dtype=np.uint16)

for k in range(M):
z[colors==0] = f(z[colors==0])+C[colors==0]
r = [Link](z)
colors[np.logical_and(r>=M, colors==0)] = k%K
dt = [Link]() - t0
dt = dt.total_seconds()
fig = [Link](figsize=figsize)

im = [Link](colors, aspect='auto', cmap=cmap, v


min=0, vmax=K)
[Link]('off')
return dt

Te functions for constructing Julia and Mandelbrot sets have the same parameters, so we
do not comment on the source code of the mandelbrot_set function. Te main diference
is that a two-dimensional array of values is built for values of c. Figure 13.34 shows the
classic Mandelbrot set.
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 289

FIGURE 13.34 Mandelbrot set for rect = (− 2.0, −1.2,0.5,1.2), colormap: binary.

FIGURE 13.35 Mandelbrot set for rect = (−0.1992, 1.0148, −0.12954, 1.06707), colormap: binary.

Self-similarity persists for parts of the Mandelbrot set (Figure 13.35).


Te visual impression depends on the number of colors used in the colormap.
Figures 13.36 and 13.37 show the same region of the Mandelbrot set for the number of
colors K = 10 and K = 100, respectively.
290 ◾ STEM Problems with Mathcad and Python

FIGURE 13.36 Mandelbrot set for rect = ( −0.7454356,0.1130037, −0.745415,0.1130139 ) , colormap:


binary, K = 10.

FIGURE 13.37 Mandelbrot set for rect = ( −0.7454356,0.113007, −0.7454215,0.1130139 ) , colormap:


binary, K = 100.
Iterations and Fractal Sets of Mandelbrot and Julia ◾ 291

QUESTIONS AND TASKS


1. Reproduce all the layout of a chapter in Jupyter Notebook or JupyterLab.
2. Consider whether it is possible to visualize Julia and Mandelbrot fractal sets using
Mathcad.
3. Try using widgets to write an interactive application for visualizing Julia fractal sets
in Jupyter Notebook (task of increased complexity).
4. Try using widgets to write an interactive application in Jupyter Notebook for visual-
izing fractal Mandelbrot sets (task of increased complexity).
5. Explore how the imaginary part of c afects the Julia set for the map f ( z ) = z 2 + c.
6. Construct Julia sets for f ( z ) = z 2 + z − 1.
7. Plot the Manderbrot set for f ( z ) = z 2 + z + c.
8. Construct a family of Mandelbrot sets for the mapping f ( z ) = z 3 + cz 2 + z.
2
˙ z2 + 2˘
9. Construct the Julia set for f ( z ) = ˇ
ˆ 2z +1
10. Construct the Julia set for f(z) = z + c (1 + 1j)z4 + z for diferent real c.
5

REFERENCES
1. R. E. Bellman and R. E. Kalaba, Quasilinearization and Non-Linear Boundary Value Problems
(N.-Y.: ElsevierSpringer, 1965).
2. H.-O. Peigen, P.H. Ritcher, Te Beauty of Fractals. Images of Complex Dynamical Systems
(Berlin: Springer-Verlag, 1986, ISBN 978-3-642-61717-1).
3. V. S. Sekovanov, Holomorphic Dynamics: Textbook (Sanct Peterburg: Lan’London: Lan’, 2021,
ISBN 978-5-8114-7563-6) (in Russian).
4. М. МсGudvin. Julia Jewels. Exploration of Julia Sets. URL: [Link]
julia/[Link].
5. B. B. Mandelbrot. Te Fractal Geometry of Nature (Updated and Augmented). W. H. Freeman
and Co., 1983 (Revised edition of Fractals c. 1977).
Chapter 14

Water Digital Twin:


Cloud Functions, Correct
Temperature Units

M oliere’s philistine in the nobility was very surprised when he learned that for
40 years he did not just speak, but spoke in prose. The first author of this book was
also surprised when he realized that for almost 20 years he had been creating with his col-
leagues, not just a package of applied programs and cloud functions for calculating the
thermophysical properties of water and steam under the brand name WaterSteamPro (see
[Link]), but the digital twin of water. Water and water vapor are known to be very
important substances for life. It is not for nothing that water is being looked for on distant
planets as the first sign of possible life.
Digital Twin is a fashionable and relatively young term associated with the fourth indus-
trial revolution (Industry 4.0). Until recently, one spoke in a simpler and more understand-
able way—of a mathematical model of an object or a process. Now, if a mathematical model
of an object is implemented on a computer, then it is deemed to be the digital twin of a
physical object or process. Here, of course, you can argue about the term, but let’s see what
has been said.
What are digital twins for?
Consider some specific examples. A ship is flying in near space, and needs to be trans-
ferred to a higher orbit (see Chapter 5 “Comet of 1811: Let's check harmony with algebra”).
For reassurance, this operation is first carried out on the digital twin of the spacecraft,
making sure that everything is conceived correctly, and only then on the actual ship—
on the “physical” twin of the digital object. Soon, people might acquire their own digital
counterparts. I come to the clinic, and there the necessary medical procedures are first
tested on my digital twin, before being implemented on me!

DOI: 10.1201/9781003228356-15 293


294 ◾ STEM Problems with Mathcad and Python

FIGURE 14.1 Reference to Mathcad-sheet.

But let’s get back to earth and talk about the digital twin of water in relation to well-
known and little-known facts and statements! Man, by the way, is 60%–80% water. So, by
creating a digital twin of water, we are creating a digital twin of a person.
Let’s integrate the digital twin of water into the Mathcad engineering supercalculator
and into the Python ecosystem, make simple calculations, build graphs and see what's
what.
Once upon a time, the unit of capacity, a liter, was defned as follows: a liter is the volume
occupied by one kilogram of water under normal conditions. Let’s assume that normal
(room, laboratory) conditions are 18°C and one physical atmosphere (760 mm Hg).
Te functions that return the thermophysical properties of water and water vapor can
be made visible in Mathcad in diferent ways. One of them requires a link to another
Mathcad-sheet from the working document of the “good old” Mathcad 15, where the nec-
essary functions are specifed—see Figure 14.1.
As you can see from the information in the dialog box shown in Figure 14.1, a link
can be made either to a fle stored on the user's computer or to a fle stored in a corporate
(university, for example) computer network. But you can use an undocumented trick and
link to a fle on the Internet. For example, a Mathcad fle named [Link] stored at the
“author's” Internet address [Link] If you click on the created link (it is
shown at the bottom of Figure 14.1), then a Mathcad fle named [Link] will open, the
start of which is shown in Figure 14.2.
A Mathcad fle named [Link] stores in the “cloud” about 50 “cloud” functions that
return the thermophysical properties of water and steam. One of them named wspDPT
and with arguments P (pressure) and T (temperature) is stored in a collapsed area named
Density of water and steam as function of pressure and temperature, at the bottom of
which is shown a test call of this function with European and American units. We do
Water Digital Twin: Cloud Functions, Correct Temperature Units ◾ 295

FIGURE 14.2 Start of a Mathcad fle named [Link].

not show the function itself, called wspDPT, but only say that it was created according to
the instructions (Guidelines) of the International Association for the Properties of Water
and Steam (see [Link] By the way, a Mathcad
fle named [Link] can be downloaded—saved on your computer for future reference.
Tis is done when your computer's Internet connection is unreliable and is interrupted
frequently.
If a function named wspDPT has become visible in the working document, then it can be
called to set the values of the arguments and get the values of the function. And the fact that
296 ◾ STEM Problems with Mathcad and Python

FIGURE 14.3 Change in density of water at fxed room temperature and diferent pressures.

the function becomes visible in the working document, is evidenced by the second line in
Figure 14.3, where it is seen that the function named wspDPT takes two arguments, pressure
and temperature, respectively, and returns a parameter with dimensions Length−3 × Mass,
that is, density.
Figure 14.3 shows the calculation of the pressure at which water at 18°C will have a den-
sity of 1,000 kg/m3 (1 kg/L). Te wspDPT function of the author's package WaterSteamPro
is used, which, with a certain degree of convention, can be considered the digital twin of
water, a digital twin of its thermophysical properties. Figure 14.3 solves the inverse prob-
lem—it fnds the value of pressure, given that of density and temperature. To do this, use
the root function built into Mathcad, which uses a half-division algorithm in the interval
of 20–100 atmospheres.
It is debatable whether 18°C is standard, but 31 atmospheres is certainly not standard
pressure. Tis says, at this pressure, water at room temperature will have a “standard”
density of 1 kg/L.
Now one liter is not the volume of a kilogram of water under normal conditions, but
simply one-thousandth of a cubic meter. Note that a liter is a unit of capacity, and a cubic
meter is a unit of volume.
But the Mathcad package does not go into such metrological nuances and considers that
the liter and cubic meter are units of volume.
Water is conventionally considered to be an incompressible liquid. We emphasize—con-
ditionally! Te density of water is weakly dependent on pressure (Figure 14.3), but strongly
dependent on temperature. What do we mean by strongly?
Do you know why even in the coldest winter rivers and lakes do not freeze to the bottom,
but only remain covered with a layer of ice on the surface? Te answer to this question is
long. Tere are many factors that need to be taken into account to answer it. In particular,
you need to know what the water temperature is at the bottom of ice-covered reservoirs.
Let's plot the change in the density of water at atmospheric pressure versus temperature,
starting from 0°C to 10°C.
Water Digital Twin: Cloud Functions, Correct Temperature Units ◾ 297

Figure 14.4 plots the change in water density versus temperature at a standard pressure
of one atmosphere. Te maximum density of water (almost a kilogram per liter) occurs at
4°C. We noted this fact with a special symbol because this is a very important property of
water. Tanks to it, as well as the unique fact that the density of ice is less than the density
of water, our reservoirs do not freeze to the bottom in winter.
Te point of maximum water density in Figure 14.4 is also defned using the function
root, the frst argument of which is not the function wspDPT itself, but its partial deriva-
tive with respect to temperature. For a continuous and smooth function at its maximum
(minimum or infection), the frst derivative is equal to zero—the tangent at this point is
horizontal.
Te point of maximum density of water, noted in Figure 14.4, is well known. But almost
no one knows about another similar point in the water—see Figure 14.5. It turns out that
the isobaric specifc heat capacity Cp of water at normal pressure occurs in the tempera-
ture range of warm-blooded animals, which, as we have already noted, are more than half
composed of water. So it can be argued that the temperature of warm-blooded animals
is that temperature, which requires less energy to maintain. Here, of course, we can also
talk about the fact that the speed of biological processes increases with increasing tem-
perature, that the heat exchange of an animal with the environment also depends on the

FIGURE 14.4 Change in the density of water at a fxed normal pressure and at diferent temperatures.

FIGURE 14.5 Change in the specifc isobaric heat capacity of water at a fxed standard pressure
and at diferent temperatures.
298 ◾ STEM Problems with Mathcad and Python

temperature of the skin, that living organisms cannot withstand too high temperatures.
But the fact remains. About 4° is the temperature for the maximum density of water (see
Figure 14.4), and about 40° is that for the minimum specifc isobaric heat capacity of water
at atmospheric pressure (Figure 14.5).
Figure 14.5 also shows that the specifc isobaric heat capacity of water, expressed in terms
of calories rather than joules, is unity at normal pressure at two diferent temperatures—
about 18°C and about 68°C. What is a calorie? Tis is the amount of energy required to
raise the temperature of 1 g of water by 1 K. And at what temperature and at what pres-
sure—see Figure 14.5.
Many are trying to expel calories from heat engineering and heat power engineering,
replacing them with joules, but this is not very successful. In some countries, millimeters
of mercury have not been removed from weather reports, nor calories from food packages.
If a calorie is converted into a unit of energy in SI units, you get about 4.19 J. Let's remem-
ber this fgure! (March 14 is celebrated in many countries of the world as a holiday of
mathematics—the approximate value of the number π is 3.14. On this day, interesting and
instructive classes in mathematics—the queen of sciences—are held at schools and univer-
sities. You can suggest celebrating the Day of Heating Engineers on April 19 of every year!)
Above, we downloaded the [Link] fle and executed its functions locally on the com-
puter, but you can also call WaterSteamPro functions on the server, transmitting requests
and receiving responses over the Internet. Let's show how this can be done in Python. Te
watersteampro module was developed for this. Tere are only two functions in the module:
py_wsp_dsc, which allows you to get a description of the function, input arguments, values
returned by functions in English and Russian, and py_wsp, a function that addresses the
above, passes the values of arguments to it and receives the result. As an example, we get a
description of the wspDPT function in English:

from watersteampro import py_wsp, py_wsp_dsc


dsc = py_wsp_dsc('wspDPT', lang='en')
print(dsc)

Te wspDPT function description is displayed as follows:

WaterSteamPro function:
wspDPT: density = F(pressure, temperature)

Arguments:
p - Pressure, default value:100000 Pa
t - Temperature, default value:373,15 K

Function returns:
Density, default value:0,589636754062471 kg/m3

WaterSteamPro function wspDPT: density [kg/m3] as function of


pressure p [Pa], temperature t [K].
Water Digital Twin: Cloud Functions, Correct Temperature Units ◾ 299

The range of the validity is within that described in IF-97. The


function wspWATERSTATEAREA2 is used to determine the IF-97 region.
Then the necessary function (wspDxPT) is used.

Function descriptions allow you to fnd out what arguments, and in what units, must be
passed to functions, and what parameters, and in what units, they return:
Reading the descriptions is necessary because there is no automatic unit conversion in
Python.
To call the wspDPT function, the pressure must be converted from atmospheres to
Pascals and the temperature from Celsius to Kelvin. Tis function returns the density in
kg/m3. Let us write the function wspDPTac, which we will later use to solve the equation,
and we will transfer the pressure in atmospheres, and the temperature in degrees Celsius:

def wspDPTac(p, t):


'''
Calculate the density by specifying the pressure in
atmospheres and temperature in Celsius degrees
'''

p = p * 101325 # converting atm in Pascali


t = t + 273.15 # converting degrees Celsius to Kelvin

return py_wsp('wspDPT', p=p, t=t)# return density in kg/m3


We need to determine what pressure p the density of water d will correspond to for a given
temperature t. Let's make an equation to determine the pressure:

def eq1(p, t, d):


'''
The equation:
p - water pressure in atmospheres
t - water temperature
d - density of water in kg/m3 '''
return wspDPTac(p, t) - d

It is worth doing some preliminary research to solve this equation by plotting density ver-
sus pressure at a fxed temperature:

%matplotlib inline
import numpy as np
import [Link] as plt
n = 50
t = 18
pp = [Link](1,50, n) # array of pressures from 1 to 50 atm
dd = [Link](n) # density array
for i in range(n):
dd[i] = wspDPTac(pp[i], t)
300 ◾ STEM Problems with Mathcad and Python

FIGURE 14.6 Approximate determination of pressure for density d = 1,000 kg/m3, t = 18oC.

Te plot of density versus temperature is easy to plot for t = 18oC, an approximate value of
pressure at a density equal to d = 1,000 kg/m3 can be determined by drawing a horizontal
dotted line (Figure 14.6).
We determine the exact pressure value by solving, as in Mathcad (Figure 14.3), the
equation defned in the Python function eq1 above by the method of half-division of the
interval:

from [Link] import bisect


p1000 = bisect(eq1, 30, 32, args=(18, 1000))

Te function that implements the method of half-division (bisection) is passed a func-


tion that returns the residual eq1, the interval at which the root of the equation is localized,
we can easily determine it from Figure 14.6, and a tuple of additional parameters: tempera-
ture and density. Te solution to the equation is p1000 = 31.1357. Tis allows us to plot the
exact solution to this equation on a graph (Figure 14.7).

[Link](figsize=(6,4))
[Link](pp, dd, ‘k-’, lw=3)
[Link](‘p, atm’, fontsize=14)
[Link]([pp[0], pp[-1]], [1000,1000], ‘k--’)
[Link]([p1000, p1000], [998.5,1001], ‘k--’)
[Link](‘$d,\ kg/m^3$’, fontsize=14)
[Link](lw=0.5)

Let us now consider how the density of water changes with a change in temperature at a
constant pressure p = 1 atm (Figure 14.8)

tt = [Link](0, 10, n)
dd2 = [Link](n)
for i in range(n):
Water Digital Twin: Cloud Functions, Correct Temperature Units ◾ 301

FIGURE 14.7 Exact solution of the pressure equation for density d = 1,000 kg/m3, t = 18oC.

dd2[i] = wspDPTac(1, tt[i]) # Calculate density


[Link](figsize=(6,4))

[Link](tt, dd2, ‘k-’, lw=3)


[Link](‘$t,\ ^o C$’, fontsize=14)
[Link](‘$d,\ kg/m^3$’, fontsize=14)
[Link](lw=0.5)

From Figure 14.8 it can be seen that the maximum density of water lies close to 4°C. We
would like to accurately determine this value by calculating the maximum of the function
shown in Figure 14.8.
Te [Link] library contains a large number of tools for solving problems of
fnding the extremum of functions. Our case is the simplest, you need to determine the
maximum function of one variable, for which you can use the minimize_scalar function.

FIGURE 14.8 Dependence of water density on temperature.


302 ◾ STEM Problems with Mathcad and Python

FIGURE 14.9 Accurate determination of temperature corresponding to the maximum density of


water.

However, using this function, one would fnd the minimum rather than the maximum,
which we must take into account when constructing the function.

from [Link] import minimize_scalar


def fmin(t, p):
return 1000-wspDPTac(p, t) # minus due to the maximum
tmax = minimize_scalar(fmin, bracket=(2., 5.), args=(1.,)).x

Here the function fmin has to be used in order to solve the minimization problem. In
addition to fmin, the minimization function is passed the parameters, bracket—the seg-
ment on which the extremum of the function is located, and args—additional parameters.
In our case, the additional parameter is pressure. Te function returns, in particular, the
value of the frst parameter fmin corresponding to the extremum, tmax = 3.963. It remains
for us to plot this value on the graph (Figure 14.9).
To analyze the dependence of the heat capacity of water on temperature, we will use
the WaterSteamPro wspCPPT function, but we will have to explicitly carry out unit
conversions:

def wspCPPTac(p, t):


‘’’
p - pressure in atmospheres
t - temperature in degrees Celsius
The function returns the specific isobaric heat
capacity in kcal/(kg K)
‘’’
p = p * 101325 # converting atmospheres into Pascal
t = t + 273.15 # converting degrees Celsius to Kelvin
# return heat capacity in kcal/(kg ·K)
return py_wsp(‘wspCPPT’, p=p, t=t) * 23.885/100000
Water Digital Twin: Cloud Functions, Correct Temperature Units ◾ 303

We build the dependence of heat capacity on temperature at a pressure of 1 atm


(Figure 14.10).

tt = [Link](0, 80, n)

cp = [Link](n)

for i in range(n):
cp[i]= wspCPPTac(1, tt[i])

[Link](figsize=(8, 6))
[Link](tt, cp, ‘k-’, lw=3)
[Link]([tt[0], tt[-1]], [1,1], ‘k--’)
[Link](‘$t,\ ^o C$’, fontsize=14)

[Link](‘$c_p,\ kcal/(kg·K)$’, fontsize=14)


[Link](lw=0.5)

It can be seen from the fgure that two temperatures correspond to a unit heat capacity.
Let's try to pinpoint them by making the the equation defned by the Python function eq2
below using the data from Figure 14.10.

def eq2(t,p, cp):


return wspCPPTac(p, t) - cp

t11 = bisect(eq2, 16,22, args=(1,1))


t12 = bisect(eq2, 60,70, args=(1,1))

Te exact temperatures are t11=17.509, t12=67.776.

FIGURE 14.10 Dependence of heat capacity on temperature at a pressure of 1 atm.


304 ◾ STEM Problems with Mathcad and Python

FIGURE 14.11 We plot the exact temperature values that correspond to a unit heat capacity at a
pressure of one atmosphere.

We can plot the exact values of the corresponding temperatures on the graph
(Figure 14.11). Tis time we will do it with markers.

# Calculate the heat capacities


cp11, cp12 = wspCPPTac(1, t11), wspCPPTac(1, t12)
[Link](figsize=(8, 5))
[Link](tt, cp, ‘k-’, lw=3)
[Link]([tt[0], tt[-1]], [1,1], ‘k--’)
[Link](‘$t,\ ^o C$’, fontsize=14)

[Link](‘$C_p,\ kcal/(kg·K)$’, fontsize=14)


[Link](lw=0.5)

[Link]([t11, t12], [cp11, cp12], ‘ko’, ms=10)

14.1 AFTERWORD WITH THE TITLE P v = T


“Well, well, electricity and heat are one and the same, but is it possible to put one
quantity instead of another in the equation for solving the problem? No. So, what
then? Te connection between all the forces of nature is already felt by instinct ... ”
Leo Tolstoy “Anna Karenina”

Automatic recalculation of units of measurement of physical quantities in some modern


sofware environments not only facilitate and accelerate the work, eliminating a number
of errors, but also allow us to take a fresh look at some physical laws, for example, the ideal
gas law. As we show below, a consequence of this is a new relationship to the basic physical
quantity of temperature.
Water Digital Twin: Cloud Functions, Correct Temperature Units ◾ 305

Te title of the aferword of this chapter is doubly unusual. First, it consists only of a
short formula, and second, as the prescribed equation of state for an ideal gas it is given
without the traditional letter R—without a universal gas constant.
Imagine that you open a physics textbook and see the formula ma = k F, with the expla-
nation that this is a mathematical representation of Newton’s second law, where m is mass,
a is acceleration, F is force, and k is the universal force constant... You, of course, would
be surprised and say that there should not be any letter k in this formula. But you would
be answered in the sense that the constant k serves to translate the force expressed in
kilograms-force (an auxiliary force unit) into newtons (the base force unit). People have
long been accustomed to expressing force in kilograms-force, and not in some “incompre-
hensible” newtons. Tat is why this formula contains the value k, called a universal force
constant. Force can be expressed in other common units—in dynes, in pounds-force, and
so on. But all of them would frst have to be converted into kilograms-forces, and only then
inserted into the formula m a = k F.
But if we open a textbook on classical thermodynamics (the main object of this book
chapter)—one of the branches of physics, then in reality we will see a similarly “burdened”
formula (the equation of state for an ideal gas) pv = RT, where p is pressure, v is specifc
molar volume (the inverse value of the density with which we worked above), T is tem-
perature, and R is a universal gas constant used to convert kilograms-force, sorry, degrees
Kelvin, again sorry, kelvin into the correct units of temperature. For which ones—see
below.
To justify such an unusual section title, we will not go into the physical essence of the
concept of temperature (or rather, we will postpone it for later), but will compute the solu-
tion to a simple problem from the feld of thermodynamics of ideal gases.
Task: You need to pump up the wheel of your bike. Te question is how many strokes
with a piston bicycle pump need to be done in order to raise the tire pressure from one
atmosphere to fve atmospheres. Figure 14.12 shows the diagram of the problem, and
Figure 14.13 shows its solution, modernized by the author, as computed by Mathcad.
We make three assumptions. (1) Te bicycle tube is a torus that does not change its vol-
ume when infated (the tire is quite rigid—the process is isochoric). (2) Te air temperature
in the chamber and pump does not change. Due to heat exchange with the environment,
the air has time to cool down to the ambient temperature at each pump stroke (isothermal
process). To do this, you need to infate the bicycle wheel very slowly and smoothly. (3)
Tere is no air leakage from the pump.
Figure 14.13 shows the successive approximation procedure. Te number of pump
strokes n is set, which is corrected depending on the calculated value of the tire pressure pn.
Te calculation specifes the geometric dimensions of the bicycle tire and bicycle pump.
A tire is a torus with a small radius r and a large radius R, and a pump is a cylinder with
a diameter d and a height H (pump stroke). Te values of r, R, d and H allow you to calcu-
late the volumes of these geometric bodies (6.477 L and 283 mL). We can see that Mathcad
works with units of physical quantities, which makes the calculations readable, eliminat-
ing many possible errors and ensuring you select the correct formulas. Te pressure p0
and the ambient temperature T0 are included in the calculation. Te pressure is entered in
306 ◾ STEM Problems with Mathcad and Python

FIGURE 14.12 Scheme of the task of pumping a bicycle wheel.

FIGURE 14.13 Calculation of the process of infating a bicycle wheel.

physical atmospheres (1 atm = 760 mm Hg), which are immediately converted into pascals
(the basic unit of pressure in SI, which Mathcad uses by default—see also footnote 2). Te
value of the variable T (18°C) is frst converted to the Kelvin scale (absolute thermody-
namic temperature 18 + 273.15 = 291.15—this is done directly by Mathcad), and then addi-
tionally multiplied by the universal gas constant R = 8.314 J/mol/K. Te result (2421 J/mol)
Water Digital Twin: Cloud Functions, Correct Temperature Units ◾ 307

is printed by default, but the user has the right to replace this unit of temperature with the
more familiar Kelvin, Celsius, Rankine and Fahrenheit.
Te universal gas constant R has, as it were, moved from the ideal gas equation of state
to a tool for entering the temperature calculation. Tis is not just a computational trick—it
is the restoration of physical justice, so to speak. Tis will be discussed below.
Afer entering the initial data, the initial amount of air in the bicycle wheel chamber xo,
in moles, is calculated.1 Further, the second assumption in the problem, that the process is
isothermal, is something of a simplifcation. Te temperature of the air during its compres-
sion will still rise by 10°C (10 k). Afer that, the pressure in the bicycle wheel chamber afer
88 pump strokes is calculated through the “de-energized” ideal gas equation. And nowhere
in the calculations is the value of R, the universal gas constant, visible. We note in pass-
ing that this speeds up the calculations—the R value is only used to enter the temperature
value to convert kelvin to joules per mol.
But back to the physics of the problem.
Te fact is that in life and in physics, there is no temperature, but there is the energy of
molecules and other elementary particles, which is interpreted as temperature. In plasma
physics, in elementary particle physics, for example, temperature is ofen measured by
electron volts (one of the units of energy), implying that the amount of matter is a dimen-
sionless quantity. Mathcad, by default, works in SI, where there are seven basic units of
measurement, including temperature (kelvin) and amount of substance (mol). But physi-
cists in their calculations prefer to work with the CGS system (CGS—centimeter-gram-
second), where there are only three basic quantities (length, mass and time) and where the
temperature and amount of the substance are “a fight of fancy”.
Historically, it so happened that, frst in life, and then in physics (in metaphysics), the
empirical concept of temperature with diferent nominal degrees and scales appeared
(Fahrenheit—1724, Reaumur—1730, Celsius—1742, etc.), and only later (1834–1874) a
theoretical equation of state for an ideal gas was invented, which had to be adjusted to
“degrees”. Tis is where the mystery lurks about why temperature has become not just a
separate physical quantity, but a basic physical quantity in SI. It should be an auxiliary
value, which we have tried to show in this book. Tis is evidenced by the fact that afer
1968 the Kelvin degree was ofcially called the kelvin. Degrees were widely excluded from
metrology. Yes, Kelvin degree has been renamed to kelvin. But this looks like the “metrol-
ogy house” has not been completely cleaned up, but simply that the rubbish has been swept
under the carpet. By the way, the Rankine degree (the analogue of the Kelvin degree in the
USA) has remained a Rankine degree: there are no rankines (temperature units) in metrol-
ogy and none are expected.
For manual calculations and for calculations in sofware without tools for work-
ing with physical quantities (spreadsheets, programming languages), you can use
the old ideal gas equation with four variables—with two thermodynamic quantities

1 We don’t need to say “mass in kilograms”, but simply say “mass”. But in the case of the amount of substance, it is neces-
sary to clarify that this value is set in moles. Otherwise, the expression “amount of air” can be incorrectly interpreted as
a mass of air or a volume of air.
308 ◾ STEM Problems with Mathcad and Python

(pressure-volume-temperature) and one constant—a universal gas constant. Te transition


to calculations with modern physical and mathematical programs with tools for working
with physical quantities (Mathcad, Maple, Mathematica, SMath, etc.) allows you to return
true physics to calculations and fnally exclude Kelvin degrees (kelvin) from calculations,
not formally (“sweeping rubbish under the carpet”), but in essence. Users of these sofware
tools have the right to work with any unit of temperature—with the usual degrees or with
the correct joules divided by mol (see Figure 14.13). Or just with joules—see the title, where
the uppercase letter V (volume) is spelled out, and not the lowercase letter v (specifc molar
volume). Joule is not just a unit of energy, but a person, we recall, who was the frst to fnd
a connection between mechanical (and electrical—see the epigraph below the title) work
and thermal energy.
Te SI unit system is, frankly, a complete mess. We have already written about the kel-
vin, undeservedly raised to the power of the basic unit. Te basic unit of mass turned out
to be a multiple of kilo. Multiples are just things like ten, dozen or hundred. Te incom-
prehensible candela appeared, the units of currency, the amount of information were lef
behind. Te units of time remained non-decimal. Little-known, almost forgotten physi-
cists were awarded with named units, and honored luminaries were bypassed with this
distinction. Exactly seven basic physical quantities (mass, length, time, current strength,
amount of substance, luminous intensity and our temperature) are not based on physical
rationale, but rather on the magic of numbers: seven colors of the spectrum, seven notes of
a music scale, seven days of the week, seven wonders of the world, etc.
“A complete mess”—this is of course the author getting excited! Let's correct and say
that the SI unit system is extremely imperfect. But our world is also extremely imperfect!
In this regard, we recall an old joke about how one client waited a long time for the trousers
he’d ordered and rebuked the tailor, saying that the Lord God created the world in 7 days,
but that the tailor had been busy with the trousers for a month. Te tailor replied: “Look at
this World and look at my trousers!”
If we are not talking about an ideal gas, but about real substances—gases and liquids,
then to describe their properties, we can return the fourth variable to the equations of
state: not pv = T, but pv = k T, where the variable k depends on pressure and temperature
and changes from unity (ideal gas) to almost zero (incompressible liquid). Te reciprocal
of k is called the compressibility factor.
In Figure 14.14, the contour graph (lines of the same level) shows the dependence of
compressibility on pressure and temperature. Te graph was built-in Mathcad using
the author's program WaterSteamPro ([Link]). Te colors of the graph are from
Mathcad’s rainbow scheme: red represents large values of the k coefcient, close to one
(ideal gas, steam with low pressure and high temperature), while purple represents small
values close to zero (water under low pressure). In the middle of the Figure 14.14 lines of
one level merge into one, forming the so-called saturation line of water and steam, extend-
ing from the triple point, where ice, water and steam are simultaneously present, then the
critical point, where water ceases to difer qualitatively from steam.
Te author's package WaterSteamPro, which we described above, allows you to calcu-
late the thermophysical properties of not only water and steam but also gases. Tere is a
Water Digital Twin: Cloud Functions, Correct Temperature Units ◾ 309

FIGURE 14.14 Compressibility of water and steam depending on pressure and temperature.

FIGURE 14.15 Calculation of the process of compressing air in a bicycle chamber or in a compressor.

shortened cloud version of this package, the operation of which in Mathcad 15 is shown in
Figure 14.15.
In the Mathcad calculation in Figure 14.15, a reference is made to the Mathcad-sheet
with the name [Link], stored in the “cloud” at [Link] Afer such a
link in the working paper shown in Figure 14.15, functions created in Mathcad-sheet with
310 ◾ STEM Problems with Mathcad and Python

the name [Link] become visible. In particular, a function named wspgSGSPT will be
available, which returns the value of the specifc entropy of gas S with the GS specifcation
(we have dry air—a mixture of nitrogen and oxygen) at atmospheric pressure and a tem-
perature of 18°C (2.421 joules per mole of gas, if we recall our new unit of temperature).
Te value of the specifc entropy of the compressed air is not shown in the calculation for
two reasons. First, the unit of measurement of this quantity with the correct author's unit
of temperature J/mol will shock many heating engineers with its unusualness (mol/kg).
Tere are no Kelvin degrees, no Kelvin! Second, this value has no special physical mean-
ing since it depends on the accepted point of reference for this value. Te main thing here
is not specifc values, but the diference in specifc values. Te enthalpy value of gas also
means nothing. It is important to know the diference in enthalpies at diferent points of
the heat engineering process, for which graphic representation ofen used a diagram in the
coordinates “enthalpy—entropy” (Mollier diagram). Enthalpy grows—energy is supplied
to the system, entropy grows—the process is imperfect…
If the air is compressed ideally (isentropically), then its entropy will not change dur-
ing compression. Another function of the WaterSteamPro package—a function named
wspgTGSPS, returned the temperature (T) of ideally compressed air at a pressure of fve
atmospheres and the specifc entropy calculated above. Te result is 3.823 kJ/mol or more,
the usual 186.7°C (368.04°F). Tere is no place for Kelvin.
By the way, the Boltzmann constant in the author's modernized Mathcad has a molar
unit of measurement instead of the old familiar joule divided by kelvin. Tis is another
shock for heating engineers. And if we accept that moles are some dimensionless entities,
then the Boltzmann constant turns out to be a completely dimensionless quantity. Rather,
a value with a dimension of 1 (one). Tis is correct: real physical and mathematical con-
stants must be dimensionless quantities—the number π, the number e…
Chapter 15

Hydropower Thoughts
and Calculations when
Looking at a Banknote
or Spline Interpolation

L et’s start with interpolation from a distance.


Many banknotes of the world depict hydraulic structures. For example, bridges are
drawn on the euro. The bridges can also be seen on two Russian banknotes—for 2,000 and
5,000 roubles. And the modern ten-rouble bill depicts a special “bridge” (Figure 15.1)—the
dam of the Krasnoyarsk hydroelectric power station on the Yenisei River, which at one
time (from 1967 to 1971) was the world’s largest hydroelectric power plant.
Now the ten-rouble note of Russia is gradually going out of circulation, alas. It is being
replaced by coins of the same denomination.
It seems that a country’s banking system should be based on seven banknotes. In the
USSR, banknotes in denominations of 1, 3, 5, 10, 25, 50 and 100 roubles used to be in

FIGURE 15.1 Reverse of the ten-rouble banknote of Russia.

DOI: 10.1201/9781003228356-16 311


312 ◾ STEM Problems with Mathcad and Python

FIGURE 15.2 ATM digital twin.

FIGURE 15.3 Program for translating roman numbers to arabic.

circulation. In Europe, there are notes to the value of 5, 10, 20, 50, 100, 200 and 500 euros,
and in the USA notes to the value of 1, 2, 5, 10, 20, 50 and 100 dollars in circulation. In
modern Russia, there are 50, 100, 200, 500, 1,000, 2,000 and 5,000 roubles notes in circu-
lation. Te 5- and 10-roubles notes in this “magnifcent seven” were deemed superfuous.
Gradually, all the banknotes and coins of the world will turn out to be superfuous due to
the development of cashless payments and the emergence of cryptocurrencies!
Notes and coins are still in use, but if we want cash from our salary these days, we get
it from ATMs.
Incidentally, having mentioned ATMs, we can use Mathcad to simulate one, as shown
in Figure 15.2. You ask for the required amount (7,650 roubles, for example), and the ATM
gives you banknotes in denominations of 5,000, 2,000, 500, 100 and 50 roubles.
Te amount of money and its equivalent in banknotes and coins can be converted from
Roman to Arabic numbers. Te program in Figure 15.3 is a program that is essentially the
reverse of the program in Figure 15.2. It translates Roman numbers into Arabic numbers
and calculates the amount of money given to you by the ATM.
But back to hydroelectric power plants.
Hydropower thoughts and Calculations ◾ 313

Hydroelectric power plants are mentioned increasingly ofen in connection with the
problem of climate change. Hydroelectric power plants, unlike thermal power plants oper-
ating on fossil fuels, do not emit carbon dioxide into the atmosphere, thereby not con-
tributing to the greenhouse efect. On the contrary, hydroelectric power station reservoirs
absorb atmospheric carbon dioxide.
How does the hydroelectric power plant generate electricity?
Te overwhelming majority of people, even those with higher technical and hydraulic
engineering education, are likely to answer something along the lines of the following to
this question. A dam on the river is being built in order to create a head of water in front
of the turbine. Due to this pressure, the turbine rotor rotates and transfers the mechanical
energy of rotation to an electric generator, which generates an electric current. One way or
another, the keywords in the answer will be the words “water pressure”. Check yourself,
reader! How do you personally answer this question? Write your answer on a piece of paper
and only then read on!
People sometimes loathe to answer what they think might be a trick question, but even-
tually, they are likely to answer as described above, while expressing surprise—who, they
say, does not know the answer to such a “childish” question.
But a dam is a purely passive structure and it cannot “create pressure” in any way. Te
water pressure can only be created by a pump that consumes energy. Te dam does not
consume any energy. A hydraulic unit working in tandem with a dam can create a head
and pump water from the bottom up. Tis is how pumped storage power plants work,
alternately generating and consuming electricity. Tese days, some energy-efcient houses
both consume and generate electricity. In such houses, for example, gas is burned to heat
the house and at the same time to generate electricity (a kind of mini-CHP (combined
heat and power) with an OCR installation—with an organic Rankine cycle), the surplus of
which is fed into the network. Tere is the concept of the “prosumer”: an individual who
not only consumes electricity or heat (consumer) but also provides energy to the network.
Te correct answer to the question is as follows. Te dam is being built in order to
reduce the average fow rate of water in the river. Due to this, losses due to friction of the
water against the bottom of the river and against its banks are reduced as are those due to
the formation of eddies in the water fow itself. It is these energy losses, eliminated by the
dam, that are converted in the hydroelectric unit (hydro turbine plus an electric genera-
tor) into electricity. Te average water velocity in the river drops sharply due to the fact
that the channel cross-section increases signifcantly afer the construction of the dam
and the flling of the reservoir with water. (By the way, it is possible to reduce friction
losses and thereby obtain electricity without building a dam, and this will be discussed
below.)
Tis is a very surprising answer to many. Some people think that they are just being
made fun of. Some people think that you were taught physics poorly at school or university.
In such a situation, the author draws on a piece of paper something like Figure 15.4 and
gives the following explanation.
Water, due to the energy of the Sun, evaporates from the surface of the Earth and in the
form of rain and snow falls in the valleys, on the hills and in the mountains, and then fows
314 ◾ STEM Problems with Mathcad and Python

FIGURE 15.4 Water cycle in nature and hydroelectric power plants.

down the rivers.1 Part of the water seeps into the ground and fows through the springs
into rivers and lakes. Ten the water evaporates again and rises to the top. Similar pictures
(Figure 15.4) can be seen in “Natural Science” school textbooks with the explanation that
this is “the water cycle in nature.” Almost all the potential energy of the raised water is
spent on its friction against the bottom of the river and on its banks, in the generation of
vortices. If there were no friction and vortices, then the water would accelerate to incred-
ibly high speeds, demolishing everything in its path, so friction in the channel and eddies,
reduces the speed of the water at the mouth of the river to a reasonable level.2
A dam is built on the river. What has changed in it afer reaching a stable regime—afer
flling the reservoir? Te water consumption has reached the “pre-dam” level! Te water
velocity downstream at the mouth of the river remains almost unchanged. But the average

1 A lot of water “gets stuck” in the mountains in the form of glaciers. Climate change associated with the greenhouse
efect, which is mentioned in this chapter of the book, could lead to active melting of glaciers and an unacceptable rise in
sea levels.
2 Tere are mini-hydroelectric power plants without dams in the form of a stationary barge with a water wheel and an
electric generator that generates electricity from the kinetic energy of the fowing water. But the contribution of such
hydroelectric power plants to the global electricity balance is negligible.
Hydropower thoughts and Calculations ◾ 315

speed of water in the river and, consequently, losses due to friction of the water on the
channel have signifcantly decreased. It is these unaccounted losses that are collected by
the turbine of the hydroelectric power station, converting them into electricity! It can also
do this without the dam. How? Like this!
A pipe (water conduit) is laid along the bed of a mountain river or stream through which
a part of the river is passed. Tis part does not fow over the uneven and rocky bottom of
the river, but along the smooth pipe. Friction losses drop sharply, that the hydraulic turbine
installed at the lower end of the pipe (water conduit) “will not fail to use”. In Figure 15.4,
the fow of water on a river without a hydroelectric power station is depicted by a wavy line,
which at the mouth gradually ends at the sea. If this stream is placed in a smooth tube, then
it will be a huge fountain at the lower end of the pipe. Such “fountains”, by the way, can be
seen at the downstream of the dam, when the water from the reservoir is dumped by the
hydraulic units. Tis fountain can be said to be plugged with a small hydro turbine.
Damless hydroelectric power plants are currently becoming widespread as small, dis-
tributed energy facilities. A dam with a reservoir is not only quite expensive (see above)
but also a rather dangerous facility in areas where earthquakes occur or terrorists are
operating.
Why does the loss of water pressure depend on friction in an open river or a closed pipe?
Mainly from the speed of the water and from the roughness of the surface of contact of
the water with the bottom of the river or with the inner wall of the pipe. Where are these
losses going? Tey go to heat water and pipes (dissipation of valuable mechanical energy of
the frst kind—its transformation into less valuable energy of the second kind, into heat)!
Te formulas that can be used to calculate the head loss Δh and the pressure drop Δp
in a straight pipe with a circular cross section3 are quite simple—see Figure 15.5. Te fol-
lowing variables are in the formulas: l(el) is the length of the pipe, d is its diameter, v is the
velocity of the liquid or gas, g is the acceleration of gravity, and ρ is the density of the liquid
or gas. To the loss of pressure, Δh, due to friction, it is also necessary to add the value of the
height diference at the ends of the pipe. Te main difculty here is in calculating the fric-
tion coefcient, λ, which mainly depends on two dimensionless quantities—the Reynolds
number Re and the relative roughness of the inner pipe surface Δ (the ratio of the average
roughness height to the pipe diameter). At the beginning of the calculation, two functions
from the WaterSteamPro package are dimensioned. Te ρH2O function returns the den-
sity of water at atmospheric pressure as a function of temperature, and the μH2O function
returns the viscosity of water at atmospheric pressure as a function of temperature. In the
calculation shown in Figure 15.5, you can change the water temperature T and get a new
answer. Te water in the pipe may have a pressure diferent from atmospheric pressure, but
pressure, unlike temperature, has little efect on the density and viscosity of water.
3 Once upon a time in the newspaper “Poisk” (“Search”), in its April Fools’ issue, there was an article that pipes with
square cross-sections have less hydraulic resistance. Pumping the same amount of liquid or gas through square pipes
requires much less energy. Everything would be fne (April 1 is April 1), but afer a while, a letter from a pipe-rolling
plant came to the newspaper’s editorial ofce with a request to provide the addresses of the scientists who conducted
such studies. Te plant, they say, is ready to start the production of such “energy-saving” pipes. By the way, pipes with
an almost square cross-section are widely used in construction as load-bearing structures. We build fences at dachas
(country houses) from such pipes.
316 ◾ STEM Problems with Mathcad and Python

FIGURE 15.5 Calculation of the pressure loss in the pipe.

In the calculation shown in Figure 15.5, there is a link (Reference) at [Link]


[Link]/GDHB/La-De-Re-Formulas.xmcd15. Afer using such a link, the friction function
λfriction (Δ, Re) becomes available as though it were built-in to the worksheet.
Te λfriction function also has a cloud twin. If the reader opens the site at [Link]
[Link]/MCS/Worksheets/Hydro/[Link], then they will get to the author’s digital
twin of the so-called Nikuradze spoon—to the family of curves resembling spoons (a table
set of spoons) and showing the dependence of the coefcient of friction on the Reynolds
number and relative roughness (Figure 15.6). By changing the initial data (Re and Δ val-
ues) and pressing the Recalculate button, you can get a new value of the friction coefcient,
which appears in the formula in Figure 15.5.
Te characteristic graceful bending of the curves in Figure 15.6 is associated with the
fact that with an increase in the Reynolds number, the fuid fow regime changes from
laminar (where roughness has almost no efect on friction) to turbulent, bypassing the
transient, unstable regime. In a laminar fow without vortices, the layers of liquid or gas
move parallel to each other, and a certain lubricating flm forms at the inner surface of
the pipe, reducing the disrupting efect of roughness. Terefore, the surface roughness
has almost no efect on the coefcient of friction in this fow regime. Recall that Reynolds
number (dimensionless criterion) is the product of the pipe diameter by the cross-section
average velocity of the liquid or gas, divided by the so-called kinematic viscosity of the liq-
uid or gas. Kinematic viscosity is the normal (“dynamic”) viscosity divided by the density
of a liquid or gas.
Figure 15.7 shows what is stored in the function λ friction.
Into the program shown in Figure 15.7, there is a double interpolation method—one
spline interpolation and another nested linear interpolation. What’s going on in the
program?
Te built-in submatrix function removes the sidebar (vector X) and header (vector Y)
from the matrix M. Until then, the lines with the if and return statements make sure that
Hydropower thoughts and Calculations ◾ 317

FIGURE 15.6 Digital internet twin of Nikuradze spoon.

FIGURE 15.7 Double interpolation program.

the arguments of the λfriction function remain within the specifed Reynolds number and
relative roughness. Ten the submatrix function forms the matrix Z—the contents of the
matrix M without the “head” and sidebar. Matrix M stores the coordinates of individual
points of the family of curves shown in Figure 15.6. Further, along the columns of the
matrix Z from a loop with a parameter and spline interpolation, an additional row (vector
Z') is formed according to a given value of the relative roughness, which is absent in the
side of the table. Ten, by the last line of the program shown in Figure 15.7, by the gen-
erated vector Z' and by the vector X, not by spline interpolation, but by piecewise linear
318 ◾ STEM Problems with Mathcad and Python

interpolation, the required value of the friction coefcient is found from the value of the
Reynolds number, which is absent in the “head” of the table.
And why in the program in Figure 15.7 were two types of interpolation used? With lin-
ear interpolation everywhere we would not get smooth curves. However, splines can also
have their downside. Te curves in Figure 15.8 illustrate this.
In the top graph in Figure 15.8, an oscillation is visible—the scourge of spline
interpolation.
Te frst formula on the last line of Figure 15.5 shows that the coefcient of friction of
the water against the pipe wall depends on the velocity squared. But this is not entirely

FIGURE 15.8 Result of spline interpolation (upper graph) and piecewise linear interpolation.
Hydropower thoughts and Calculations ◾ 319

true if we take into account that the velocity appears both in the Reynolds number and in
the dependences shown in Figures 15.7 and 15.8. Te only indisputable fact is that with an
increase in speed, the losses for friction and for the formation of vortices grow. If you build
a dam on the river, then, we repeat, the cross-section of the river channel will expand, the
speed will drop, and the part of the friction losses eliminated in this way will turn into
electricity.
Electricity from the river can also be obtained without reducing the speed of the water,
by reducing the roughness of the surface over which the water fows. Many mini hydro-
electric power plants work on this principle.
Now we will show what piecewise linear and spline interpolation are.
Tere are works of fne art that are remarkable not only and not so much for the amus-
ing drawing or for the skill of the artist, but for the mystery that is hidden in them. Tis
secret is ofen not–immediately apparent; as a rule, the guides mention it; art critics inter-
pret it in the description of the picture in the albums and catalogues of exhibitions. A small
detail on another painting can show knowledgeable viewers the hidden original essence of
the picture and signifcantly expand the panorama of the message depicted in the picture.
Even more intrigue can be noted in those paintings that contain riddles with some
mathematical meaning. Tis is where science and art meet. Let’s look at one such “picture”.
Figure 15.9 is straightforward and does not pretend to be of any artistic value. It is cre-
ated from the following mathematical construction, which uses splines to interpolate
between the 12 discrete values that are shown as small red dots in the fgure.
It is necessary that the function can be calculated at intermediate points (interpolation)
or even beyond (extrapolation) [1]. We are faced with this problem when, for example, we
see tabular data on the density of a certain material depending on temperature in a refer-
ence book. Te table contains data for 10°C and 20°C, but we need to know the density at
15 degrees.
Figure 15.10 shows one possible interpolation between the dots of our tree image using
Mathcad. Te matrix Data with two rows and twelve columns, stores the discrete values
of some function. From this matrix, the vector X (frst row) and the vector Y (second row)

FIGURE 15.9 Te branch of a tree with leaves and fruits.


320 ◾ STEM Problems with Mathcad and Python

FIGURE 15.10 Piecewise linear interpolation.

are extracted. Te Mathcad built-in function named linterp (l—linear, interp—interpola-


tion) generates a user function named y, which can be used to calculate intermediate data
using the piecewise linear interpolation method. Te resulting dependence is displayed on
a graph—adjacent points are connected by straight line segments.
However, nature does not tolerate sharp or even obtuse angles! Te graph in Figure 15.10
has three faws: natural, aesthetic and mathematical. First, it is difcult to imagine any
property or some kind of process in living nature with such breaks in characteristics.
Second, the line in Figure 15.10 is just plain ugly. And third, if we want to determine the
local minima and maxima of a given functional dependence by numerical methods then
we will need the frst and maybe second derivatives. Here, the jagged character of the shape
makes that difcult.
In the pre-computer era, the angles in Figure 15.10 would have been removed with the
help of templates, called splines, applying them to adjacent points with diferent edges
(an amateur template—Figure 15.11). Tere were also more complex professional templates
with screws, by twisting which it was possible to change the curvature of the steel strip
(Figure 15.12).
Oddly enough, splines came to applied mathematics from shipbuilding, which the
British call naval architecture. For the manufacture of wooden sailing parts up to several
meters in size, it was frst necessary to outline their contours, for which a steel ruler, placed
between the studs driven into the workpiece, was used. Afer a pencil line was drawn along
the ruler, the part was cut out. It can be shown that the curve formed by the ruler between
the studs is just described by piecewise polynomials of the third degree.
Secondary interest in splines arose only in the early 60s of the 20th century, when, due
to the advent of computers and computer graphics, it became necessary to draw smooth
curves, and solving systems of linear algebraic equations became a simple problem.
Hydropower thoughts and Calculations ◾ 321

FIGURE 15.11 Plastic and wooden patterns.

FIGURE 15.12 Spring mold.

It is possible to use the letters l (linear), p (parabolic) or c (cubic) as a prefx * to the *


spline function. Tis does not afect the essence of the spline, and it remains cubic—adja-
cent points are connected by segments of curves of a third-order polynomial. Tese pre-
fxes determine the order of interpolation and extrapolation at the edges of a given point
interval. As a rule, Mathcad users work with the cspline function, which we have also done
in Figure 15.13.
322 ◾ STEM Problems with Mathcad and Python

FIGURE 15.13 Cubic spline interpolation.

FIGURE 15.14 Content of the vector k, which is generated by the cspline function.

How is spline interpolation done in Mathcad!? Afer all, adjacent points must be con-
nected by segments of curves of a third-order polynomial so that at the junctions the entire
interpolating function y(x) remains smooth.
Te *spline function returns a vector in which the frst three elements are service infor-
mation for the interp function, and the subsequent elements are the numerical values of the
interpolating function at the nodal points, as can be seen from Figure 15.14.
Knowing the numerical values of a cubic polynomial and its second derivatives at
two adjacent points, it is easy to fnd its four coefcients. To do this, it is necessary to
solve four equations with four unknowns—see Figure 15.15 where cp ( X , a, b, c , d ) is
aX 3 + bX 2 + cX + d .
Figure 15.15 shows how the coefcients of the cubic polynomial are found for the tenth
(j) and eleventh (j + 1) points. By changing the x values, you can get an interesting anima-
tion posted on the chapter site, three frames of which are shown in Figure 15.16.
In Figure 15.17, the segments of all the cubic parabolas are drawn and numbered, form-
ing the interpolating function y(x), shown in Figures 15.13 and 15.16.
Te thickets of cubic parabolas in Figure 15.17 can be “cut” to get what is shown in
Figure 15.18.
To the branch of the tree shown in Figure 15.18, it remains to add leaves and berries in
order to get a “work of fne art with a mathematical riddle”—see Figure 15.9.
Te same tools for data interpolation are available in other systems for perform-
ing scientifc and technical calculations, including the Python environment, where the
Hydropower thoughts and Calculations ◾ 323

FIGURE 15.15 Finding the coefcients of the ftting cubic polynomial.

[Link] library is used for this purpose. In particular, to carry out inter-
polation, it is enough to create an interpolating function and pass an array of values
along the abscissa axis, in which it is necessary to obtain values of interpolated data [2]:
intrp = interp1d(x, y, kind=kind)

ynew = intrp(xnew)

Here x, y are arrays of data along the abscissa and ordinate axes, xnew is an array of
values along the abscissa axis for which the interpolated values must be obtained, and kind
indicates which type of interpolation should be used. Te interp1d class allows for spline
interpolation of various orders. Figure 15.19 shows various zero-order polylines interpolat-
ing the data in Figure 15.10.
Figure 15.20 shows the results of interpolation by splines of various degrees.
In most practical cases, the best results are provided by the spline interpolation of third
degree, interpolation of higher orders contributes to the formation of artifacts, but in any
case, when working with data, it is recommended that computational experiments are
conducted to select interpolation parameters, especially since this requires a minimum of
efort.
Until now, we have only solved the interpolation problem, i.e., we drew curves through
a given set of points on the plane. It is possible to remove the requirement for the curves
to accurately pass through specifed points. Tis allows us to draw smoother curves than
those shown in Figure 15.20c and d. Tese problems are called approximation problems;
when solving them, one has to seek a compromise between the distance from the initial
data to the curve and its smoothness. Te Python environment uses the UnivariateSpline
class for this [3], which can be instantiated like this:

spl = UnivariateSpline(x, y, k, s)
324 ◾ STEM Problems with Mathcad and Python

FIGURE 15.16 Tree frames of the cube spline animation.


Hydropower thoughts and Calculations ◾ 325

FIGURE 15.17 Cubic parabolas ftting a table dependence.

FIGURE 15.18 Blank drawing of a tree branch (or Autumn Tree Branch).
326 ◾ STEM Problems with Mathcad and Python

FIGURE 15.19 Zero-order interpolation: (a) kind = ‘next’—next value, (b) kind = ‘previous’—previ-
ous value, (c) kind = ‘nearest’—nearest value.

FIGURE 15.20 Spline interpolation of various degrees. (a) 1st degree; (b) 2nd degree; (c) 3rd degree;
(d) 5th degree; (e) 7th degree and (f) 9th degree.

where x, y is a set of initial data along the coordinate axes, k is the degree of the spline,
k can take values from 1 to 5, and s is the allowable distance between the original data
and the approximating spline; at s = 0 the interpolation problem is solved. Te larger s, the
smoother the approximating curve becomes. Te calculation of the approximated values
is carried out as before:

ynew = spl(xnew)
Hydropower thoughts and Calculations ◾ 327

FIGURE 15.21 Approximation of the input data for diferent values of the parameter s.

FIGURE 15.22 Approximation of noisy data.

In Figure 15.21, we approximated the original curve for various values of the parameter s.
To obtain a satisfactory approximation result, the value of the parameter s must be
selected.
It is possible to go a little further, simulating the noise for the original data, for which we
interpolated the input data at 200 points and added “noise” to them—normally distributed
random numbers with a zero mean value and a standard deviation of 1.5. Te results of
approximating the noisy data are shown in Figure 15.22.
By varying s, a compromise can be reached between the smoothness of the curve and
the distance from the original data.
328 ◾ STEM Problems with Mathcad and Python

FIGURE 15.23 Extrapolation using various degree splines.

Solving interpolation and approximation problems allows one to obtain values on an


interval along the abscissa axis, where the data are specifed. To predict values outside this
interval, one has to solve the extrapolation problem. Solving such problems requires addi-
tional information about the behavior of the extrapolated function. In the simplest case, we
can assume that the extrapolated function does not change and its values coincide with the
value at the boundary of the segment on which the data are specifed. Another hypothesis
might be that the extrapolated function behaves linearly. In any case, the hypothesis about
the behavior of a function must be applied with eyes wide open; otherwise completely unex-
pected results can be obtained. Figure 15.23 shows a computational experiment for extrapo-
lating the initial data in Figure 15.10 using UnivariateSpline and splines of varying degrees.
Figure 15.23 shows how the extrapolated function behaves under various assumptions
about its behavior, including spline interpolation from zero to ffh degree and smoothing
by third degree spline. As we said before, the choice of the approximation method depends
on the available information and on the person making the decision.
Te Python environment does not lag behind Mathcad in this respect. If the depen-
dence shown in Figure 15.13, is denoted by f(x), then the function of two variables
g (, x y ) = f ( x ) ˝ f ( y ) can be represented as a two-dimensional surface in three-
dimensional space (Figure 15.24). For drawing, the coordinate values were set at 10,000
points on a regular 100 by 100 grid.
Spline surface interpolation can be done using grid data [5]. In this case, spline interpo-
lation can be carried out both on a regular grid and on an arbitrary set of points (x, y, z).
We’ll start with a regular grid. Figure 15.25 shows spline interpolation on a regular 10 by
10 grid.
It is evident that the reconstruction of the surface shape on a regular grid, even with a
small number of partitions, is quite satisfactory.
Everything changes signifcantly if interpolation is performed on a random set of points,
as shown in Figure 15.26.
Hydropower thoughts and Calculations ◾ 329

FIGURE 15.24 Function g(x, y).

FIGURE 15.25 Interpolation by splines of the function g(x, y) on a regular grid 100 by 100. (a)
Zero-order interpolation; (b) Piecewise linear interpolation; and (c) Cubic spline interpolation.
330 ◾ STEM Problems with Mathcad and Python

FIGURE 15.26 Interpolation g(x, y) on a random set of 100 points. (a) a random set of points at
which the interpolation was carried out; (b) zero-order interpolation; (c) piecewise linear interpola-
tion; and (d) cubic spline interpolation.

For a random set of points, it was not possible to reconstruct the surface over the entire
area; in those points where it was not possible to do this, the values of the function were
equated to zero. In addition, interpolation on an irregular grid results in artifacts.

TASK FOR READERS


Create a 3D spline interpolation program

REFERENCES
1. Polovko A.M., Butusov P.N. Interpolation. Methods and computer technologies for their
implementation. SPb.: BHV-Petersburg, 2002,—320 p.: With ill. (in Russian) URL: https://
[Link]/view/polovko-am-butusov-pn-interpolyaciya-metody-i-kompyuternye-
tehnologii-ih-realizacii_e938ef58445.html
Hydropower thoughts and Calculations ◾ 331

2. [Link].interp1d [Electronic Resource]. URL: [Link]


ence/generated/[Link]
3. [Link]. [Electronic Resource]. URL: [Link]
scipy/reference/generated/[Link] (Date of access 24.11.2020)
4. Termal calculations on a computer/Aleksandrov A. A., Aung Tu Ra Tun, Garyaev A. B. [et
al.]—Moscow: MPEI Publishing House, 2019.—447 p. (In Russian) ISBN 978-5-7046-2211-6.
URL: [Link]
5. [Link] [Electronic Resource]. URL: [Link]
ence/generated/[Link]
Chapter 16

Cellular Automatons

C onsider the following simple situation: there is a rectangular array of elements


(cells), each element of the array has a state, for example 0/1 or live/dead. In general,
array elements can be in arbitrary states.
At time zero, the elements of the array are in some initial state. In the first and subse-
quent steps, the state of the elements changes depending on the environment of the given
element in the previous step. Such a construction is called a cellular automaton machine
[1]. Cellular automatons can be constructed on arrays of other dimensions, but in this
chapter, we will restrict ourselves to the two-dimensional case because of its clarity. In
general, an element of a two-dimensional array has eight neighbors, taking into account
the elements located above, below, to the right and left, as well as on the diagonals from
the given one. This neighborhood is called the Moore neighborhood. Naturally, array ele-
ments located in the zero, and last rows and columns of the array may have three and five
neighbors in the neighborhood.
If we ignore the diagonal elements, then the neighborhood is called the von Neumann
neighborhood; in this case, only elements located on the left, right, above and below the
given element are taken into account.
Let the rectangular array be filled in some way at time zero: it can be completely empty,
completely filled, the filled cells can be randomly distributed in the array. In the next step,
the state of a given array element depends on, firstly, whether this cell is filled or not, and,
secondly, on how many filled (empty) cells are in the vicinity of this one. Depending on
this, the state of the cell may remain unchanged, or a filled cell may appear in place of
an unfilled cell (element birth), or a filled cell may become empty (element death). Let’s
set simple rules for the birth/death/life of cells and observe the evolution of the state of
the array. In this, as usual, visualization and animation will help us. As it turns out, even
simple rules of birth/death of array elements lead to nontrivial behavior that generates
complex dynamic structures.
To simplify our life by always working with neighborhoods consisting of eight elements
for the Moore neighborhood and four elements for the von Neumann neighborhood, we
will use a simple trick called torus closure. Imagine a sheet of paper, fold the sheet along

DOI: 10.1201/9781003228356-17 333


334 ◾ STEM Problems with Mathcad and Python

FIGURE 16.1 A torus drawn with matplotlib.

FIGURE 16.2 Visualization of the initial state of a cellular automaton.

the long side, glue the edges of the sheet to form a cylinder. Ten we bend the cylinder
into a ring and glue the ends of the cylinder. Te resulting construction is called a torus.
Figure 16.1 shows a torus drawn using the matplotlib library.
If we split the rectangle that is converted into a torus into n parts along the horizontal and
vertical axes, then to close the torus, it is enough to calculate the indices of the array elements
using in Python the expressions i% n, j% n, and you do not need to think about the indices
going beyond the permissible boundaries. Te value of n will go to 0, 1 to n − 1, and so on.
In this case, the right border of the rectangle will go to the lef, and the top to the bottom.
Random flling of a rectangular array is shown in Figure 16.2. It is built using the function:
Cellular Automatons ◾ 335

def random_initial_state(n=10, cmap='binary'):


field = [Link](0,2,(n,n))
[Link](field, cmap='binary')
[Link]('off')
return field

We fgured out how to set the initial state of the cellular automaton and how to visualize
it. We now need something that transfers the automaton to the next state, assuming that
each element of it can be in one of two states: either 0 or 1. Te next state depends on the
state of the neighborhood of this element. If we include the element under consideration
in the neighborhood, then the number of transition options will be 25 = 32 for the von
Neumann neighborhood and 29 = 512 for the Moore neighborhood. Te behavior of a cel-
lular automaton can be described in a compact manner using a transition table. For the von
Neumann neighborhood, the current state of an automaton element can be represented as
a fve-digit binary number EWSNC, where E (East) is the state of the element located to
the right of the current one, W (West) is the state of the element to the lef of the current
one, S (South) is below, N (North) – top; C (Center) is the current item. Te current state of
each neighborhood (a fve-digit binary number from 0 to 31) corresponds to the next state
of the current item.
As an example, we give a table for the parity rule.
In Table 16.1, N is the number of the state of the neighborhood, C is the next state of the
given element. In some cases, the transition rule is easier to describe algorithmically, for
example, the parity rule is implemented in Python in one line:

C = 1 if N %2 == 0 else 0

Next, we will consider both ways of setting rules.


In his book [2] S. Wolfram classifed the rules when the neighborhood of a given ele-
ment of the cellular automaton is only the preceding row of the array, consisting of three
elements. In this case, the transition table can be displayed visually. In the frst line, we
will draw the previous states of the neighborhoods in the form of eight binary numbers
from 000 to 111. A flled square corresponds to one, and an empty square corresponds to
zero. Te next state is specifed by a number from 0 to 255, which is also used to number

TABLE 16.1 Parity Rule for Cellular Automaton


N EWSNC C N EWSNC C N EWSNC C N EWSNC C
0 00000 1 1 00001 0 2 00010 1 3 00011 0
4 00100 1 5 00101 0 6 00110 1 7 00111 0
8 01000 1 9 01001 0 10 01010 1 11 01011 0
12 01100 1 13 01101 0 14 01110 1 15 01111 0
16 10000 1 17 10001 0 18 10010 1 19 10011 0
20 10100 1 21 10101 0 22 10110 1 23 10111 0
24 11000 1 25 11001 0 26 11010 1 27 11011 0
28 11100 1 29 11101 0 30 11110 1 31 11111 0
336 ◾ STEM Problems with Mathcad and Python

FIGURE 16.3 A visual representation of rule 42 and the results of modeling a cellular automaton
of S. Wolfram with a random initial distribution of elements.

the rules. Te rule number is represented as a binary number, for example, rule number
42 corresponds to 4210 = 001010102. Te binary number of the rule is displayed as flled and
empty squares in the bottom line.
To simulate the behavior of a Wolfram cellular automaton, it is enough to set the initial
state—fll in the zero row, this can be done either randomly or manually; and then to cal-
culate the states of the elements in subsequent rows. A visual representation of rule 42 and
the results of modeling an automaton obeying this rule under random initial conditions
are shown in Figure 16.3.

%matplotlib inline
import numpy as np
import [Link] as plt

def draw_rect(ax, x0, y0, w, h, value):


facecolor = 'white' if not value else 'black'
edgecolor = 'black'
ax.fill_between([x0, x0, x0+w, x0+w],
[y0, y0, y0, y0],
[y0, y0+h, y0+h, y0],
edgecolor='black', facecolor=facecolor)

def wolfram_pattern(ax, n, w=4, h=4, gap=2):


Cellular Automatons ◾ 337

EMPTY = -1
ZERO = 0
ONE = 1
nums = [Link]([[0,0,0], [0,0,1], [0,1,0], [0,1,1],
[1,0,0], [1,0,1], [1,1,0], [1,1,1]])
m = 32
v = [Link]((2, m), dtype=np.int32) * EMPTY
xs = [Link](m, dtype=np.int32)
x0 = 0
for i in range(m):
xs[i] = x0
x0 += gap + w

for i in range(8):
v[0, i*4:i*4+3] = nums[7-i]

s = f'{n:b}'
b8 = '0'*8
s = b8[:8-len(s)] + s
for i in range(8):
v[1, 4*i+1] = int(s[i])
# visualizization
for i in range(2):
for j in range(m):
x = xs[j]
y =gap + (h + gap)*(1-i)
if v[i, j]>=0:
draw_rect(ax, x, y, w, h, v[i, j])
ax.set_xlim(0, (w+gap)*m)
ax.set_ylim(0, 2*h + 3*gap)
[Link]('off')

def wolfram(ax, nx=100, ny=100, n = 42,


x = None, cmap='binary'):

num_string = f'{n:b}'
ls = 8 - len(num_string)
num_string = '0'*ls + num_string
num_array = [Link](list(num_string), np.uint8)
keys = ((1,1,1), (1,1,0), (1,0,1), (1,0,0),
(0,1,1), (0,1,0), (0,0,1), (0,0,0))
table = dict(zip(keys, num_array))

if not (x is None):
nx = len(x)
x = [Link](x)
338 ◾ STEM Problems with Mathcad and Python

field = [Link]((ny, nx), dtype = np.uint8)


if x is None:
x = [Link](0,2, nx)
field[0, :] = x

for i in range(0, ny-1):


for j in range(nx):
vicinity = (field[i, (j-1)%nx], field[i, j%nx],
field[i, (j+1)%nx])
field[i+1, j] = table[vicinity]

[Link](field, cmap = cmap)


[Link]('off')

def wolfram_automaton(n, nx=100, ny=100, x=None,


cmap='binary',
w=6, h=0.5):
h += w
fig = [Link](figsize=(w, h))
ax1 = fig.add_axes([0.0, 1-(h-w)/w, 1, (h-w)/w])
ax2 = fig.add_axes([0, 0., 1, 1-(h-w)/w])
wolfram_pattern(ax1, n)
wolfram(ax2, n=n, x=x, cmap=cmap)

Te behavior of cellular automaton is visualized using the following functions: draw_rect,


wolfram_pattern, wolfram, and wolfram_automaton.
Te frst function, draw_rect, is designed to render unpainted and flled rectangles, it is
passed ax – the matplotlib axes object, x0, y0 – the lower lef corner of the rectangle, w, h -
the width and height of the rectangle, and value – the checkbox responsible for flling the
rectangle (the rectangle remains unpainted, if value == 0). Shading is carried out in black.
Te wolfram_pattern function visualizes the rule, as shown at the top of Figure 16.3. It,
like the previous function, is passed ax – the matplotlib axes object, n – the rule number, w,
h – the width and height of the rectangles for visual display of the rule, gap – the distance
between the rectangles.
Te wolfram function is responsible for displaying the cellular automaton. It is given ax
– the matplotlib axes object, nx, ny – the number of elements along the x and y axes, n – the
rule number, x – the initial condition (flling the zero line; if x is None, then flling the zero
line is carried out randomly, otherwise array x is used); cmap – the matplotlib colormap
used when visualizing the behavior of a Wolfram cellular automaton.
Te wolfram_automaton function displays a rule and a cellular automaton in one fgure.
It is given n – the number of the rule, nx, ny – the number of elements along the coordi-
nate axes, x – the initial condition (flling the zero line of the array), cmap – the matplotlib
colormap, w – the width of the drawing, h – the height of the panel in which the rule is
visually displayed.
S. Wolfram described and classifed the behavior of all 256 cellular automata [2, 6]. Te
frst class provides a transition to a steady state (Figures 16.4 and 16.5).
Cellular Automatons ◾ 339

FIGURE 16.4 Rule 40. Transition to a steady state. Deterministic initial condition.

FIGURE 16.5 Rule 40. Transition to a steady state. Random initial condition.

FIGURE 16.6 Rule 3. Stable structure. Deterministic initial condition.

Te second class consists of stable and periodic structures. Rules 3 (Figures 16.6 and
16.7) and 50 (Figures 16.8 and 16.9) are given as examples.
Te third class includes cellular automaton with chaotic behavior, including the genera-
tion of fractal structures. We start with the Sierpinski napkin fractal, which is reproduced
in various versions by rules 18, 22, 60, 90, 102, 126, 129, 146, 150, 182 and 218. Here we
reproduce only automaton obeying rules 18 (Figures 16.10 and 16.11) and 129 (Figures
16.12 and 16.13).
Te fourth class gives rise to complex structures that can interact with each other, but
there are no periodic patterns. An example is rule 45 (Figures 16.14 and 16.15).
Rule 30 demonstrates both chaotic behavior under deterministic initial conditions
(Figure 16.16) and periodic under specially selected initial conditions (Figure 16.17) [7].
340 ◾ STEM Problems with Mathcad and Python

FIGURE 16.7 Rule 3. Stable structure. Random initial condition.

FIGURE 16.8 Rule 50. Periodic structure. Deterministic initial condition.


Cellular Automatons ◾ 341

FIGURE 16.9 Rule 50. Periodic structure. Random initial condition.

FIGURE 16.10 Rule 18. Sierpinski napkin. Deterministic initial condition.


342 ◾ STEM Problems with Mathcad and Python

FIGURE 16.11 Rule 18. Sierpinski napkin. Random initial condition.

FIGURE 16.12 Rule 129. Sierpinski napkin. Deterministic initial condition.


Cellular Automatons ◾ 343

FIGURE 16.13 Rule 129. Sierpinski napkin. Random initial condition.

FIGURE 16.14 Rule 45. Complex behavior of the cellular automaton. Deterministic initial
condition.
344 ◾ STEM Problems with Mathcad and Python

FIGURE 16.15 Rule 45. Complex behavior of the cellular automaton. Random initial condition.

FIGURE 16.16 Rule 30. Complex behavior of the cellular automaton. Deterministic initial condi-
tion (1 in the middle of the array zero line, other elements are zero).
Cellular Automatons ◾ 345

FIGURE 16.17 Complex behavior of the cellular automaton. Deterministic initial condition x=[0,
0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,0,1,1]*8.

Let us now turn to more general rules for constructing cellular automatons, when the
next state of a given element depends on the complete Moore or von Neumann neighbor-
hood, and not on the preceding line, as was the case for S. Wolfram’s automata. In this case,
we will have to consider the behavior of the automaton in two-dimensional space, as it was
done earlier, but in three-dimensional space. It is not very convenient to visualize three-
dimensional states, so we will use animation, taking time as the third coordinate, since it
is not difcult to create animation using Python and matplotlib.
We will use the algorithmic formulation of the rules, which in some cases, for example,
the parity rule, is much more compact than the tabular one. Te disadvantage of algorith-
mic formulation of rules is the need to write code for each rule separately.
Animation implies the need to calculate each frame, display the frame to the user and
move to the next frame. Te time for calculating the image for each frame and display-
ing it should be such that the viewer does not notice the transitions between frames, the
lower limit of the frame rate is 6 ... 10 frames per second. All this imposes signifcant
restrictions on the animation source code since Python is an interpreted language and
loops are slow. Tis leads to the fact that any complex animation associated with scientifc
visualization has to either be optimized using the NumPy and/or Numba libraries or to
form a set of frames before the animation starts. Another way is to assemble the anima-
tion in the background into a video fle using, for example, the free fmpeg utility. For
our purposes – visualization of the behavior of cellular automaton – tools NumPy, SciPy
and matplotlib are enough; they allow you to display animation in real time, even on low-
power computers.
We will develop an interactive Jupyter Notebook application in order to set up computa-
tional experiments with diferent rules, initial conditions and environments.
346 ◾ STEM Problems with Mathcad and Python

We’ll start by importing the necessary libraries and creating masks that would allow us
to work with the von Neumann and Moore neighborhoods.

%matplotlib inline
import numpy as np
import [Link] as plt
from [Link] import convolve
from ipywidgets import widgets
from [Link] import display, clear_output
from time import sleep

# vicinities
mask_m = [Link]([[1,1,1],[1,0,1],[1,1,1]])
mask_n = [Link]([[0,1,0],[1,0,1],[0,1,0]])

We will try to speed up the calculations using the array capabilities available in SciPy, for
which we import the convolve function, which we use to calculate the number of elements
in the vicinity of a given one, but we will do this in one line for all array elements at once.
We’ll need Jupyter widgets to build the user interface as well as a sleep function to delay
the animation frame in front of the user’s eyes for a specifed amount of time.
To simulate the evolution of the elements of a fnite automaton, we use two functions:
next_step to calculate the state of the cellular automaton at the next step, and model to
simulate the behavior of the automaton for various rules, neighborhoods and initial states.

def next_step(rule, current, aux, nxt, mask):


aux[1:-1, 1:-1] = current
aux[-1, :] = aux[1, :]
aux[0, :] = aux[-2, :]
aux[:, -1] = aux[:, 1]
aux[:, 0] = aux[:, -2]
c = convolve(aux, mask, method = 'direct', mode = 'valid')
nxt = rule(current, c, nxt)
return nxt

def model(n, nt, rule, mask, init):


na = n + 2
aux = aux = [Link]((na, na), dtype=np.int16)
data = [Link]((n, n, nt+1), dtype=np.int16)
data[:,:,0] = init
for i in range(1, nt+1):
data[:,:, i] = next_step(rule, data[:,:,i-1],
aux, data[:,:,i], mask)
return data

Te next_step functions are passed the following: rule is a function for calculating the next
state of the automaton, current is an array containing the current state, aux is an auxiliary
Cellular Automatons ◾ 347

array, nxt is an array containing the state of the automaton at the next step, mask is an
array with data about the used neighborhood of the element. Te function returns an array
with the state of the automaton at the next step.
We’ll have to use the additional aux array to get an array containing the number of
elements in the neighborhood using convolve. To do this, we will perform a closure on
the torus, transferring to the additional rows and columns of the aux array the rows and
columns located at opposite sides of the rectangle. Tis allows us to call the function rule,
which calculates the state of the elements of the cellular automaton at the next step. Passing
arrays to the function as arguments is due to the fact that we do not create additional two-
dimensional arrays at each step of modeling.
Te model functions are passed n – the dimensions of the automaton array along the spa-
tial axes, nt – the number of simulation steps, rule – the function that implements the tran-
sition of the automaton to the next state, mask – the used neighborhood of the automaton
elements, and init – a two-dimensional array with the initial state of the cellular automaton.
Te function returns a three-dimensional data array containing all nt states of the cellular
automaton. Tus, all data for displaying the animation is calculated before it starts.
In the function, memory is allocated for the aux and data arrays, the initial state of the
automaton is written to data, afer which all its states are calculated sequentially. We have
two things to do: implement the rules by which the states of the automaton are calculated
and develop an interactive application to visually represent these states.
Here we present several implemented rules, the list of which can be easily supplemented.

def parity(current, c, next):


next[:, :] = [Link](c%2, 1, 0)
return next
def parity1(current, c, next):
next[:, :] = [Link](c%2, 0, 1)
return next
def tri(current, c, next):
next[:, :] = [Link](c%3, 0, 1)
return next
def game_of_life(current, c, next):
next[:, :] = current[:, :]
birth_condition = (current == 0) & (c == 3)
condition_of_dying = (current == 1) &((c<2) | (c>3))
next[birth_condition] = 1
next[condition_of_dying] = 0
return next

All rules have a single interface, they are passed: current – an array of the current state of
the automaton, c – an array whose elements contain the number of neighbors of this ele-
ment and next – an array in which the next state of the automaton is formed. Te function
returns an array with the next state of the automatom. We have implemented the parity
348 ◾ STEM Problems with Mathcad and Python

function, which spawns a new element if the number of adjacent elements is even; parity1 –
a new element in the next step is generated when the number of adjacent elements to this
one is odd, otherwise there is no element in this cell in the next step. Te rule, tri, gener-
ates elements in the next step only if the number of elements in the neighborhood is not a
multiple of three.
A somewhat more complex rule is used in Conway’s Game of Life [9]: an element is born
at the next step (this element is absent at the current step) only if the number of adjacent
elements is three. In turn, the element dies in the next step if the number of adjacent ele-
ments is less than two or more than three. Note how using boolean arrays and indexing
them allows you to write the rule compactly.
It remains for us to develop an interactive application that will visually analyze the
states of the cellular automaton, save some of them in the fle system, and start animation.
All this will be done in the Jupyter Notebook or JupyterLab environment.

def app(n=200, nt=200, init=0, rule=parity,


mask=mask_n, interval=0.01): ❶
#data
zero_frame = [Link]((n, n), dtype=np.int16)
# initial comditions
if not init: ❷
zero_frame[n//3:2*n//3, n//3:2*n//3] = 1
elif init==1:
zero_frame[n//3:2*n//3, n//3:2*n//3] = 1
zero_frame = 1 - zero_frame
elif init==2:
zero_frame = [Link](0, 2, (n, n))
elif init==3:
x = [Link](0, 1, n)
X, Y = [Link](x, x)
W = ((X-0.5)**2 +(Y-0.5)**2)<=0.1
zero_frame[W] = 1
elif init==4:
x = [Link](0, 1, n)
X, Y = [Link](x, x)
W = ((X-0.5)**2 +(Y-0.5)**2)<=0.1
zero_frame[W] = 1
zero_frame = 1 - zero_frame
elif init==5:
zero_frame[n//2, n//2-1:n//2+2]=1
else:
zero_frame[n//2, n//2] = 1

data = model(n, nt, rule, mask, zero_frame) ❸

# widgets
w_out1 = [Link](layout={'width':'50%'}) ❹
Cellular Automatons ◾ 349

w_out2 = [Link](layout={'width':'50%'})

w_frame_label = [Link]('frame:')
w_frame = [Link](min=0, max=nt, value=0,
continuous_update=False)

w_anim = [Link](description='Animate',
button_style='primary')
w_save = [Link](description='Save',
button_style='primary')
# layout
with w_out1: ❺
display(
[Link]('<h3>Cell Automaton</h3>'),
[Link](f'n = {n}; nt = {nt}; init={init}'),
[Link]([w_frame_label, w_frame]),
[Link]([w_anim, w_save])
)

display([Link]([w_out1, w_out2]))

# handlers
frame = 0
def display_frame(change): ❻
frame = w_frame.value
with w_out2:
clear_output(wait=True)
[Link](figsize=(6,6))
[Link](data[:,:,frame], cmap='binary')
[Link](f'frame:{frame:3d}')
[Link]('off')
[Link]()
def animate(b): ❼
for frame in range(nt+1):
with w_out2:
w_frame.value = frame
clear_output(wait=True)
[Link](figsize=(6,6))
[Link](data[:,:,frame], cmap='binary')
[Link](f'frame:{frame:3d}')
[Link]('off')
[Link]()
sleep(interval)
def save(b): ❽
with w_out2:
clear_output(wait=True)
[Link](figsize=(6,6))
350 ◾ STEM Problems with Mathcad and Python

frame = w_frame.value
[Link](data[:,:,frame], cmap='binary')
[Link](f'frame:{frame:3d}')
[Link]('off')
[Link](f'frame {frame:3d}.png', dpi=300,
facecolor='white');
[Link]();
w_frame.observe(display_frame) ❾
w_anim.on_click(animate)
w_save.on_click(save)

# initial frame
display_frame(w_frame) ❿
return data 11

1. Te app function that implements the interactive application is passed the follow-
ing: n is the number of elements of the cellular automaton along the coordinate axes,
nt is the number of simulation steps, init is the number of the initial state; rule is a
function that implements the transition from the current state to the next, mask is an
array specifying the neighborhood of the cellular automaton element, interval is the
time in seconds for which the image of the current state of the automaton is shown to
the user.
2. Te initial states are numbered: 0 – black square in the center of the cellular
automaton; 1 – white square in the center and black frame; 2 – random initial
state of the cellular automaton; 3 – black circle in the center; 4 – white circle in the
center; 5 – an initial state for demonstrating the periodic behavior of Game of Life;
any other number passed to the function causes a black point in the center of the
white box.
3. Pre-calculating the states of the cellular automaton and storing them in the data
array.
4. Creation of user interface elements: w_out1, w_out2 – display areas, in the frst of
which widgets will be placed, in the second display area states of the cellular automa-
ton and animation are shown (Figure 16.18).
5. Te layout of the user interface is carried out in two stages: widgets are displayed in
the frst output area, afer which the output areas are displayed next to each other.
6. Te main functionality of an interactive application is implemented using three
functions. Te display_frame function displays the state of the cellular automaton,
the state number (frame) is taken from the w_frame slider. Displaying the state of
the automaton includes the following steps used in other functions that visualize
the state of the automaton: clearing the second output area from the previous image,
creating an image object; display status; output of the header with the frame number;
Cellular Automatons ◾ 351

FIGURE 16.18 User interface for animating the behavior of cellular automaton.

turn of the display of digitizing along the coordinate axes. Tis function is automati-
cally called when the user moves the slider, w_frame.
7. Te animate function animates nt states of the cellular automaton. Simultaneously
with the animation, the w_frame slider engine is moved. Te procedure for display-
ing an animation frame is the same as described in the previous paragraph and dif-
fers only in the delay in displaying the animation frame for interval seconds using
the sleep function. Note also that all data for displaying the animation has been pre-
calculated to avoid unwanted delays between frames.
8. Te save function allows us to save images of the polygraphy quality of the states
of the cellular automaton in the fle system, if required. Tis is how the subsequent
drawings of this chapter were prepared.
9. For an interactive application to function, you need to associate user interface wid-
gets with the actions you perform. So the call to the display_frame function is associ-
ated with the movement of the slider engine, animate with the click of the w_anin
button, and save with the click of the w_save button.
10. Formation of the initial state of the automaton and displaying it in the second output
area.
11. Te function returns a three-dimensional data array with the states of the cellular
automaton.

To display Figure 16.18, it was enough to call the app function and move the slider with
the mouse:

data = app(init=3, n=200, nt=200, rule=tri)

We begin the analysis of the evolution of states of a cellular automaton with the parity
rule, and use a random uniform distribution of elements as the initial state. Figure 16.19
352 ◾ STEM Problems with Mathcad and Python

FIGURE 16.19 Te initial state of a cellular automaton with a uniform random distribution of
elements.

shows the initial state, Figure 16.20 shows the fnal state, and Figure 16.21 shows the depen-
dence of the concentration of “living” elements on the modeling step.
Te uniform random seed distribution does not produce noticeable visual efects, but
the deterministic seed distributions when using the parity rule give interesting results that
are easy to obtain with the app.
Unexpectedly, it turns out that when this rule is used, the symmetry of the initial state
is preserved. Indeed, using a black circle as an initial approximation leads to the states
depicted in Figure 16.23.
Using the von Neumann neighborhood gives, under the same initial conditions, no less
attractive states of the cellular automaton (Figure 16.24).
Te approach we have considered makes it easy to study various cellular automata, in
particular, Conway’s Game of Life. Figure 16.25 shows the initial and fnal states for this
cellular automaton.
It is much more interesting to consider not static pictures, but the animation of Game
of Life. Figure 16.26 shows the concentration of “living” elements from the modeling step.

n = [Link][0]
conc = [Link](data, axis=(0,1))/n**2
[Link](figsize=(6,6))
[Link](conc, color='black')
[Link]('nt', fontsize=14)
[Link]('concentration', fontsize=14)
Cellular Automatons ◾ 353

FIGURE 16.20 Final state of a cellular automaton with a uniform random distribution of elements
and the parity rule.

FIGURE 16.21 Dependence of the concentration of “living” elements on the modeling step when
using the parity rule and random initial distribution.
354 ◾ STEM Problems with Mathcad and Python

FIGURE 16.22 Modeling a cellular automaton operating according to the parity rule with an ini-
tial distribution in the form of a black square and a Moore neighborhood.

[Link]('log')
[Link]('log')
[Link](0.01,1)
[Link]()

Note how the concentration of “living” elements is calculated using the summation along
the axes of the array.
Cellular Automatons ◾ 355

FIGURE 16.23 Modeling a cellular automaton operating according to the parity rule with an ini-
tial distribution in the form of a black circle in the middle and the Moore neighborhood.

Note that when using a random initial distribution and a von Neumann neighborhood,
the states of a cellular automaton quite ofen go into a periodic regime with a period from
4 to 6.
Tere are various generalizations of Game of Life associated with the use of various
interacting elements [10].
356 ◾ STEM Problems with Mathcad and Python

FIGURE 16.24 Modeling a cellular automaton operating according to the parity rule with an ini-
tial distribution in the form of a black circle in the middle and the von Neumann neighborhood.

QUESTIONS AND TASKS


1. Reproduce all the layout of the chapter in Jupyter Notebook or JupyterLab
2. Try to fnd the same automaton states generated by the app.
3. Try to fnd periodic sequences of states of cellular automata generated by the app.
Cellular Automatons ◾ 357

FIGURE 16.25 Simulation of Conway’s Game of Life cellular automaton with random initial dis-
tribution and Moore neighborhood.

FIGURE 16.26 Dependence of the concentration of “living” elements on the modeling step.

4. Te chapter discusses the rules when the next state depends only on the previous one.
What needs to be done in order for the app to generate states that depend on several
preceding ones?
5. Try to fnd on the Internet, implement and conduct computational experiments with
rules diferent from those discussed in the chapter.
358 ◾ STEM Problems with Mathcad and Python

REFERENCES
1. T. Tofoli, N. Margolus. (1987). Cellular Automata Machines: A New Environment for Modeling.
MIT Press. ISBN 9780262200608.
2. [Link] S. A New Kind of Science (Champaign, Il, USA: Wolfram Media Inc., 2002), 1213
p. ISBN 1-57955-008-8.
3. H.-O. Peigen, P.H. Ritcher, Te Beauty of Fractals. Images of Complex Dynamical Systems
(Berlin: Springer-Verlag, 1986), ISBN 978-3-642-61717-1.
4. V. S. Sekovanov, Holomorphic Dynamics: Textbook (Sanct Peterburg: Lan’London: Lan’, 2021),
ISBN 978-5-8114-7563-6 (in Russian).
5. М. МсGudvin. Julia Jewels. Exploration of Julia Sets. URL: [Link]
julia/[Link]
6. Elementary Cellular Automata. URL: [Link]
7. Repeating Rule 30 patterns. URL: [Link]
8. B.B. Mandelbrot. Te Fractal Geometry of Nature (Updated and Augmented). W. H. Freeman
and Co. 1983 (Revised edition of Fractals c. 1977).
9. Conway’s Game of Life. URL: [Link]
10. Te Game of Life and the Modeling of Natural Selection. URL: [Link]
post/154015/ (in Russian)
Chapter 17

Arrays and Images

T he paradox of using Python for scientific and technical calculations is that, with all
its convenience and flexibility, Python is an interpreted language, and those actions
that in compiled languages such as C and C ++ are performed once at compilation are done
in Python many times during program execution.
Let’s illustrate this with a simple example by calculating the sequence of accumulated
sums of a segment of a Taylor series:
n

cs (n, k ) = ∑ i1 .
i =1
k (17.1)

It is not difficult to write a function in “pure” Python to calculate by formula (equation 17.1):

def cs1(n, k):


c_s = [1]
for i in range(2, n+1):
member = 1./i**k
c_s.append(c_s[-1]+member)
return c_s

cs1(10,3)

The result—the accumulated sum of the series c_s—we save as a list, the first element
of which is obviously equal to one. Subsequent members are calculated as the sum of
the next member of the series and the last item in the list of accumulated amounts. As a
result, we get:

[1, 1.125, 1.16203, 1.17766, 1.18566, 1.19029, 1.19321,


1.19516, 1.19653, 1.19753]

Let’s see how the calculation result (equation 17.1) depends for different n and k. You can
do this in Jupyter Notebook (JN) using a simple script:
DOI: 10.1201/9781003228356-18 359
360 ◾ STEM Problems with Mathcad and Python

FIGURE 17.1 Dependence of the accumulated sum of the series (Figure 17.1) on the number of
terms of the series n for diferent k.

%matplotlib inline
import [Link] as plt

ks = ( 1.4, 1.6, 2., 3)


styles = ('k-', 'k--', 'k-.', 'k:')
n = 1000000
ns = [i for i in range(1, n+1)]

for m, k in enumerate(ks):
cumsum = cs1(n,k)
[Link](ns, cumsum, styles[m], label=f'k={k}', lw=3)

[Link](loc='best')
[Link]('log')
[Link]()
[Link]('n', fontsize=14)
[Link]('cs1(n, k)', fontsize=14)

Te dependence of the accumulated amount on n and k is shown in Figure 17.1.


To measure the computation time in JN, it is enough to use the “magic” command,
which additionally collects statistics on the execution of the function:

%%timeit
cs = cs1(1000000, 3)

Te two % symbols in front of the “magic” command mean that its efect applies to the JN
cell. We get the following result:

319 ms ± 8.99 ms per loop (mean ± std. dev. of 7 runs, 1 loop


each)
Arrays and Images ◾ 361

Naturally, the result obtained depends on the performance of the computer. We obtained
an average cell execution time of 319 ms, and a standard deviation of 8.99 ms. To collect
statistics, the source code of the cell was executed seven times.
Perhaps the easiest way to speed up computations is to use the Numba – just-in-time
(JIT) compiler, which can be applied by importing the library and using the jit decorator,
as shown below. For the purity of the experiment, let’s make a copy of the original function
and rename it to cs2:

from numba import jit

@jit(nopython=True)
def cs2(n, k):
c_s = [1]
for i in range(2, n+1):
member = 1./i**k
c_s.append(c_s[-1]+member)
return c_s

Just two extra lines added to the function have a signifcant efect.

%%timeit
cs = cs2(1000000, 3)

Te execution of the cell is ten times faster:

30 ms ± 102 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

Let’s run a little ahead and implement the calculation of the cumulative sum of a series
using NumPy, which we will deal with later in this chapter.

import numpy as np

def cs3(n,k):
ks = [Link](1.,n, n)
c_s = [Link](1./ks**k)
return c_s

In this snippet, we implemented a NumPy import, which is usually aliased as np, and cre-
ated a NumPy array containing elements 1., 2., 3., n−1., N. Te cumsum function is used to
calculate the accumulated sum. We do not use loops. Measurement of the execution time
of a fragment:

%%timeit
cs = cs3(1000000, 3)
362 ◾ STEM Problems with Mathcad and Python

shows:

33.7 ms ± 227 µs per loop (mean ± std. dev. of 7 runs, 10 loops


each)

Tus, the use of NumPy, in this case, provided a performance improvement of almost
nine times.
Finally, let’s use NumPy and Numba together:

@jit(nopython=True)
def cs4(n,k):
ks = [Link](1.,n, n)
c_s = [Link](1./ks**k)
return c_s

Measurement of the execution time of a fragment:

%%timeit
cs = cs4(1000000, 3)

gives a performance increase of 46 times:

6.85 ms ± 27.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops
each)

Naturally, such results are not always possible. In addition, some time is spent on just-
in-time compilation, which we do not take into account here.
Tis example refects an approach to improving the performance of Python programs.
If we are not satisfed with the execution time of a code fragment, then we measure it and
try to apply Numba by reading the documentation beforehand. If that doesn’t give satisfac-
tory results, rewrite the snippet using NumPy. Te authors usually start with this. If the
result is not satisfactory then we apply Numba.
Te above does not exhaust the approaches to increasing the performance of programs
written in Python. Te slowest snippets can be rewritten in Cython, a language with a sub-
set of Python syntax, but allows compilation of C programs written in it.
Finally, you can rewrite critical snippets in C or Fortran and call the compiled functions
from Python.
Let’s not hide the fact that the above example was specially selected. Here we are faced
with a typical situation. Te Python core lacks arrays, and the lists used instead of them
are functional and fexible tools for solving computational problems. So in this example
we dynamically change the size of the list, the elements of the list can be objects of various
types. In the example, all the elements of the list are foating point numbers, but no one is
prevented from adding strings or even other lists to the list. Tis fexibility requires addi-
tional overhead from the Python interpreter. Tis is not the only “bottleneck” of Python,
Arrays and Images ◾ 363

but when solving computational problems, you most ofen have to deal with it, because
most computational tasks require working with arrays. When solving computational prob-
lems, we most ofen have to solve systems of algebraic equations, draw graphs, and we can-
not do without arrays!
At the same time, from the very beginning of the development of the programming
system, Python had thoughtful and simple interfaces for calling procedures and functions
written in other programming languages, including C and Fortran, for which there are
large, fast libraries that have been maintained for decades to solve scientifcal and engi-
neering problems, and work with arrays is carried out quickly, because for C and Fortran,
an array is a memory area, all the elements of an array are of the same type, their size does
not change during program execution. A foating point number, for example, always takes
eight or four bytes, and this is set when the array is created. All this allows you to process
arrays quickly.
Te only inconvenience is that when directly calling procedures and functions, you have
to pass a large number of arguments... Tus, we would really like to be able to work with
familiar Python tools on the one hand, and on the other hand to have all the power and
performance of the libraries for solving scientifc and technical problems written in com-
piled languages.
Tis is precisely why NymPy – Numerical Python was created, which is based on
convenient and simple tools for working with arrays. Previously, almost everything that
was needed to solve scientifc and technical problems was concentrated in this library,
but now it is believed that NumPy’s area of responsibility is working with arrays, and the
means for solving scientifc and technical problems should be located in specialized librar-
ies, for example, SciPy – Scientifc Python, skilearn – basic machine learning methods,
matplotlib – scientifc visualization, etc…
All of the libraries listed above and many others “know how” to work with NumPy data
structures.
For us, NumPy is a convenient interface for working with arrays, for example, NumPy
has convenient tools for creating and manipulating arrays and their parts – slices, as a
whole. Most of the manipulations with arrays are done in one line and without loops.
Finally, NumPy is a user-friendly and simple interface for working with the Python eco-
system. In most cases, to solve scientifc and technical problems, it is enough to fnd the
required tools on the Internet, read how to use them (this is the most boring part of the
process), install these tools and use them to solve the task at hand!
We are far from making this chapter a complete and comprehensive guide to NumPy.
For this, more than one book has been written [1–4]. Our goal is to provide a concise and
visual guide that will make the Python source code in this book understandable. To make
it more obvious, remember that grayscale images are two-dimensional arrays, and color
images are three-dimensional arrays. As soon as we move from one-dimensional arrays to
two-dimensional, we immediately start rendering them.
To work with NumPy, just import this library. You can create a NumPy array from any
Python sequence, such as a list. Tis is done using the [Link] factory function. Following
is an example of converting a list to an array and back to a list:
364 ◾ STEM Problems with Mathcad and Python

import numpy as np

a = [Link]([1, 2, 3])
l = list(a)
a, type(a), l, type(l)

We get:

(array([1, 2, 3]), [Link], [1, 2, 3], list)

We specifcally ran this example to show that NumPy arrays are not lists or tuples, but
special objects.
Now we need to show what happens if we try to convert a list whose elements have dif-
ferent data types, for example, boolean, integer and foating-point numbers:

a = [Link]([True, False, 2, 3.0])


a

We will get an array containing foating point numbers:

array([1., 0., 2., 3.])

Remember that all elements of a NumPy array must be of the same type. When creating
a NumPy array, the following implicit conversion rule applies:

boolean ˜ integer ˜ float ˜ complex ˜


. string

Tus, if at least one element of the list or tuple being converted into an array is a string,
then all the elements of the array will become strings, four bytes are reserved for each char-
acter (nothing can be done, Unicode is used), and the string length of the array element is
equal to the maximum length of the string in the list:

a = [Link](['a', 'bc', 'def'])


a, [Link], [Link], [Link], [Link]

In this case, we use the attributes built into NumPy that allow us to fnd out the size of
an array element (itemsize), the number of elements in the array (size) and the number of
bytes occupied by the array in RAM (nbytes):

(array(['a', 'bc', 'def'], dtype='<U3'), 12, 3, 36, dtype('<U3'))

Te type of an array can be determined using the dtype attribute.


Zen of Python [5] says that ‘Explicit is better than implicit’, so we will set the type of
array elements explicitly by passing a named parameter dtype to the factory function, for
example, to create a complex array from a list, it is enough to do:
Arrays and Images ◾ 365

a=[Link]([1,2,3], dtype= complex)


a

As a result, we get:

array([1.+0.j, 2.+0.j, 3.+0.j])

In this regard, we will give a brief overview of the types used in NumPy arrays. Let’s
start with boolean arrays.

a = [Link]([0, 1], dtype= bool)


a, [Link], [Link], [Link], [Link]

Te elements of boolean arrays take values False, True, and occupy one byte in RAM:

(array([False, True]), 1, 2, 2, dtype('bool'))

NumPy supports a set of signed integer types, let’s create an array containing single-
byte signed integers:

a = [Link]([-2, -1, 0,1,2], dtype=np.int8)


(a, [Link], [Link], [Link],
[Link],[Link]([Link]).min, [Link]([Link]).max)

Here we have shown how you can fgure out the minimum and maximum values for inte-
ger types.

(array([-2, -1, 0, 1, 2], dtype=int8), 1, 5, 5,


dtype('int8'), -128, 127)

Signed two-byte integers:

a = [Link]([-2,-1, 0, 1,2], dtype=np.int16)


(a, [Link], [Link], [Link],
[Link],[Link]([Link]).min, [Link]([Link]).max)

Result:

(array([-2,-1, 0, 1, 2], dtype=int16),


2, 5, 10, dtype('int16'), -32768, 32767)

Arrays with four-byte integers are specifed using the types int and np.int32:

a = [Link]([-2,-1, 0, 1,2], dtype=np.int32)


(a, [Link], [Link], [Link],
[Link],[Link]([Link]).min, [Link]([Link]).max)
366 ◾ STEM Problems with Mathcad and Python

As a result, we get:

array([-2, -1, 0, 1, 2]), 4, 5, 20, dtype('int32'),


-2147483648, 2147483647)

Arrays with 8-byte integers are specifed using the np.int64 type:

a = [Link]([-2,-1, 0, 1, 2], dtype=np.int64)


(a, [Link], [Link], [Link],
[Link],[Link]([Link]).min, [Link]([Link]).max)

Result:

(array([-2,-1, 0, 1, 2], dtype=int64), 8, 5, 40,


dtype('int64'),
-9223372036854775808, 9223372036854775807)

When solving problems, it is ofen necessary to set large arrays, in this case it is advisable
to pay attention to the minimum and maximum allowable values that the arrays must con-
tain. If you are sure that the values of the array elements do not exceed 100, then it makes
sense to create arrays with the np.int8 type, reducing the amount of memory occupied by
four times compared to np.int32.
By analogy with signed integers, you can use unsigned integers by adding a u before the
int when specifying the type. Here we give examples only for np.uint8 and np.uint16:

a = [Link]([-2,-1, 0, 1, 2], dtype=np.uint8)


(a, [Link], [Link], [Link],
[Link],[Link]([Link]).min, [Link]([Link]).max)

An unsigned 1-byte integer stores numbers from 0 to 255. Note how negative numbers are
converted:

(array([254, 255, 0, 1, 2], dtype=uint8),


1, 5, 5, dtype('uint8'), 0, 255)

Arrays with unsigned single-byte integers are used to encode images.


Do the same with an array containing unsigned double-byte integers:

a = [Link]([-2, -1, 0, 1, 2], dtype=np.uint16)


(a, [Link], [Link], [Link],
[Link],[Link]([Link]).min, [Link]([Link]).max)

Result:

(array([65534, 65535, 0, 1, 2], dtype=uint16),


Arrays and Images ◾ 367

2, 5, 10, dtype('uint16'),
0, 65535)

Again, pay attention to converting negative numbers!


Floating point array elements can be either 4 bytes if dtype = np.foat32 or 8 bytes if
dtype = np.foat64 or dtype = foat.

a = [Link]([-2e-10, -1, 0, 1, 2e20], dtype=np.float32)


(a, [Link], [Link], [Link],
[Link],[Link]([Link]).min, [Link]([Link]).max)

Result:

(array([-2.e-10, -1.e+00, 0.e+00, 1.e+00, 2.e+20],


dtype=float32), 4, 5, 20, dtype('float32'),
-3.4028235e+38, 3.4028235e+38)

For 8-byte foating point numbers, everything is the same except for the range of values:

(array([-2.e-10, -1.e+00, 0.e+00, 1.e+00, 2.e+20]),


8, 5, 40, dtype('float64'),
-1.7976931348623157e+308, 1.7976931348623157e+308)

Complex numbers can have both 4-byte (dtype = np.complex64) and 8-byte (dtype = np.
complex128) real and imaginary parts, double-precision foating numbers are used by
default.

a = [Link]([-2e-10, -1, 0, 1, 2e20], dtype= complex)


(a, [Link], [Link], [Link], [Link])

JN cell execution result:

(array([-2.e-10+0.j, -1.e+00+0.j, 0.e+00+0.j, 1.e+00+0.j,


2.e+20+0.j]),
16, 5, 80, dtype('complex128'))

As a reminder, string arrays use the same number of four-byte characters for each element;
for characters that are not on the keyboard, you can use Unicode characters, \uXXXX,
where X is hexadecimal digit 0 - F, for example:

a = [Link](['abc', '\u277C\u277D\u277E\u277F'])
a, [Link], [Link], [Link]

Cell execution result:

(array(['abc', '❼❽❾❿'], dtype='<U4'), dtype('<U4'), 16, 32)


368 ◾ STEM Problems with Mathcad and Python

Until now, we have dealt only with one-dimensional arrays, but it is not difcult to cre-
ate multidimensional arrays.:

a = [Link]([[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10, 11, 12]],
dtype= np.int32)
a, [Link], [Link], len(a)

Here, we showed how to determine the number of dimensions of an array (attribute


ndim) and the dimensions of an array (attribute shape). As with Python sequences, the
len function is defned on arrays, which returns the number of elements along the zero
dimension:

(array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]]),
2, (3, 4), 3)

So far, we have created arrays using the [Link] factory function, which is not possible
for arrays containing thousands or millions of elements. Tat is why NumPy has a large
number of functions that allow you to create arrays. Let’s list some of them. Te zeros and
ones functions are used to create arrays flled with zeros or ones, respectively. For one-
dimensional arrays, these functions are passed the number of elements, and for multidi-
mensional arrays, a tuple with the numbers of elements by dimensions. As an example, let’s
create a two-dimensional array flled with the number 42:

a = [Link]((2,5)) * 42
a

Te zeroth element of the tuple passed to the zeros and ones functions is the number of
rows in the array, and the frst is the number of columns. Te result of executing the cell is:

array([[42., 42., 42., 42., 42.],


[42., 42., 42., 42., 42.]])

Te same result can be obtained using the [Link] function:

a = [Link]((2,5)) + 42

An analogue of the range of “pure” Python is the arange function:

a = [Link](6)
a
Arrays and Images ◾ 369

When you pass it a single argument, for example 6, it creates an array containing a sequence
of integers from 0 to 5:

array([0, 1, 2, 3, 4, 5])

Tis function can be passed the initial, fnal value, step and type of array elements:

a = [Link](1, 12, 2, dtype=np.complex128)


a

Just like range, the fnal element is not included in the array:

array([ 1.+0.j, 3.+0.j, 5.+0.j, 7.+0.j, 9.+0.j, 11.+0.j])

In our opinion, it is much more convenient to use the linspace function, which is passed
the initial and fnal values of the array elements and the number of array elements:

a = [Link](0, 1, 6, dtype=np.float64)
a

As a result, we get:

array([0. , 0.2, 0.4, 0.6, 0.8, 1. ])

Te easiest way to get a square two-dimensional array with ones on the diagonal and
zero for the rest of the elements is using the [Link] function:

a = [Link](5, dtype=np.uint8)
a

As a result, we get:

array([[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 0, 1, 0],
[0, 0, 0, 0, 1]], dtype=uint8)

As discussed above, most of the libraries in the NumPy ecosystem work with NumPy
arrays. As an example, let us display the graph of the function y(x) = sin(x)/x, simulating
freehand drawing (Figure 17.2).

%matplotlib inline
import [Link] as plt

x = [Link](-5, 5, 1000)
y = [Link](x)
370 ◾ STEM Problems with Mathcad and Python

FIGURE 17.2 Simulate freehand drawing with the function y(x) = sin x/x.

with [Link]():
[Link](x, y,'k-', lw=3)
[Link]('x', fontsize=16)
[Link](r'y', fontsize=16)

Note that the [Link] function is passed an array of values, and it also returns an array.
Such functions are called universal, we will talk later about how to write them.
But now we come to images. Each pixel point is set by zero or one for a black and white
image (black corresponds to 0, and white corresponds to 11), if we want an image in gray-
scale, then the pixel value is specifed by a number from 0 to 255 (one byte) or a foating
point number from 0 to 1 (4 or 8 bytes). Accordingly, in a color image, each pixel element
corresponds to either three components: the intensities of red (r), green (g) and blue (b)
colors, or four bytes. In the latter case, the transparency (a) of the pixel is added to the rgb
components, with the minimum value corresponding to an opaque pixel, and the maxi-
mum value corresponding to a completely transparent pixel.
Tere are two images in the [Link] library that we will use when working with
arrays. Te frst image is a color portrait of a raccoon:

from [Link] import face


f = face()
[Link](f)
[Link]('off')
[Link], [Link]

Te face function call returns an array of the colored raccoon image represented in
Figure 17.3.

1 What actually needs to be defned is a convention that maps a number to a color.


Arrays and Images ◾ 371

FIGURE 17.3 Color image of a raccoon.

Te face function returns a three-dimensional array, the elements of the array are sin-
gle-byte unsigned integers:

((768, 1024, 3), dtype('uint8'))

Te array has 768 rows and 1,024 columns, each pixel corresponds to three bytes of red,
green and blue components.
Function call:

f = face(gray=True)
[Link], [Link]

allows you to get a two-dimensional array – a grayscale image:

((768, 1024), dtype('uint8'))

For its correct display of the image in grayscale, we have to specify the colormap, at the
same time turn of the display of the digitizing of the axes, otherwise, by default, we will
get an image in blue-green tones:

[Link](f, cmap='gray')
[Link]('off')

Te second image, available in [Link], is originally grayscale and is a two-dimensional


array (Figure 17.4).
As a result of executing JN cell:

from [Link] import ascent


asc = ascent()
372 ◾ STEM Problems with Mathcad and Python

FIGURE 17.4 Second image available in [Link].

[Link](asc, cmap='gray')
[Link]('off')
[Link], [Link]

get:

((512, 512), dtype('int32'))

Arithmetic and logical operations are defned on NumPy arrays, which are per-
formed element by element. Let’s create two arrays and perform basic arithmetic opera-
tions with them.:

a = [Link]([10, 20, 30, 40, 50])


b = [Link]([2, 3, 4, 5, 6])
a + b, a - b, a * b, a / b, a % b

Te result of the calculations is:

((array([12, 23, 34, 45, 56]),


array([ 8, 17, 26, 35, 44]),
array([ 20, 60, 120, 200, 300]),
array([5., 6.66666667, 7.5, 8., 8.33333333]),
array([5, 6, 7, 8, 8], dtype=int32),
array([0, 2, 2, 0, 2], dtype=int32))
Arrays and Images ◾ 373

It’s okay when the number of elements in the arrays is the same, let’s try to add two arrays
with diferent numbers of elements:

try:
[Link]([1,2,3]) + [Link]([4, 5])
except ValueError as ve:
print(ve)

When executing the fragment, an exception will be caught:

operands could not be broadcast together with shapes (3,) (2,)

We will discuss broadcasting below.


Comparison operations result in Boolean arrays:

a = [Link]([2,3,4,1])
b = [Link]([1,2,3,4])
a > b, a<=b, a==b

Te result of performing comparison operations:

(array([ True, True, True, False]),


array([False, False, False, True]),
array([False, False, False, False]))

Array can also be compared with scalar value:

a>=3

As a result, we get:

array([False, True, True, False])

Array elements are accessed in the same way as in “pure” Python, using indexing. For
array a, indexing its elements:

a[0], a[1], a[-1], a[-2]

will give the following result:

(2, 3, 1, 4)

Te elements of the array are indexed both from the beginning [0] and the end [−1].
You can access a sequence of array elements by passing either a sequence of indexes or
an array containing integer elements:
374 ◾ STEM Problems with Mathcad and Python

(a[[1,1, 0, 0, -1, -1]],


a[[Link]([1, 1, 0, 0, -1, -1], dtype=np.int16)])

Result:

(array([3, 3, 2, 2, 1, 1]), array([3, 3, 2, 2, 1, 1]))

It is imperative to ensure that the indices do not go out of range, otherwise an IndexError
exception will be thrown.

try:
er = a[100]
except IndexError as ie:
print(ie)

will result:

index 100 is out of bounds for axis 0 with size 4

An array can be indexed by a logical sequence or a logical array, but in this case the
dimensions of the source and logical arrays must be the same.

a[[True, False, True, False]]

Te result will be an array for which the indices are True:

array([2, 4])

Tis is a very useful feature that, in combination with logical operations, allows one to
select array elements that satisfy some condition, for example,

a[a>2]

Te result is:

array([3, 4])

Tis feature is widely used when working with NumPy arrays.


Tere is one small peculiarity when working with multidimensional arrays, let us
explain it with an example. Let’s create a list:

a2 = [[1,2,3], [4,5,6]]
a2[1], a2[1][1]

In the frst case, we have a list, and in the second we have a number:
Arrays and Images ◾ 375

([4, 5, 6], 5)

If, instead of a list, we work with an array, then indexing is possible, as accepted in other
programming languages, for example, Java and C #:

a2a = [Link](a2)
a2a[1], a2a[1][1], a2a[1, 1]

We get:

(array([4, 5, 6]), 5, 5)

When working with list, the expression a2[1, 1] will throw a Type Error and the message
‘list indices must be integers or slices, not tuple’.
Just like with sequences, we can work with slices. Recall that a slice is a part of an array
determined by the start and end indices and, possibly, a step, for example,

a[0:2], a[:2], a[1:3], a[1:-1], a[1:], a[:]

As a result, we will receive an answer that needs clarifcation.:

(array([2, 3]),
array([2, 3]),
array([3, 4]),
array([3, 4]),
array([3, 4, 1]),
array([2, 3, 4, 1]))

In the frst case, we get a slice that includes the zero and the frst element. In Python, the
last item to be indexed is not included in the slice. Te initial zero index before the colon
is optional. For the third example a [1: 3], the slice starts at a [1], the last element to include
is a[2], and a[3] is not included in the slice. In slices, you can specify elements with nega-
tive indices, so the slice a [1: −1] includes elements starting with a[1] and ending with the
penultimate element, the last element a[−1] is not included in the slice! To include the last
element in the slice, its index does not need to be encoded: a[1:]. A slice that matches the
entire array is encoded like this: a[:].
Slices can be used both to the lef and to the right of the assignment, for example:

a = [Link]([1,2,3,4,5,6,7,8,9,10])
a[1:3] = a[-2:]
a

As a result, we get:

array([ 1, 9, 10, 4, 5, 6, 7, 8, 9, 10])


376 ◾ STEM Problems with Mathcad and Python

FIGURE 17.5 Te upper right part of the image of a raccoon.

Let’s demonstrate how to work with slices using 2D and 3D arrays as examples.
Te top right quarter of the raccoon image is shown as follows (Figure 17.5):

fc = face()
h, w, c = [Link]
[Link](fc[:h//2, w//2:, :])

In a slice, we can set a step, for example, every tenth row and column of the array. To do
this, we just indicate the step afer the second colon in the slice (Figure 17.6).

[Link](fc[::10, ::10, :])

We deliberately set a large step to demonstrate the pixel structure of the image.
Nobody stops us from specifying a negative step, which is a convenient technique for
refecting an image relative to the vertical and horizontal coordinate axes (Figure 17.7):

[Link](asc[::-2, ::-2], cmap='gray')

So far, we have required that the structure of arrays or slices to the lef or right of the
assignment character be the same, but this requirement can be relaxed. It is enough that
the latter dimensions coincide or a scalar value is assigned. Tis is called broadcasting. Let
us explain this with examples, considering the valid assignments:

a1 = [Link]((2,3))
a2 = [Link]((2,4))
a3 = [Link]((2,2))
a4 = [Link]([1,2,3])
a5 = [Link]([4,5,6,7])
Arrays and Images ◾ 377

FIGURE 17.6 Demonstrating every tenth row and column of a raccoon image.

FIGURE 17.7 Demonstrating the rows and columns of the image in reverse order.

a1[:,:] = a4
a2[:,:] = a5
a3[:,:] = 42
a1, a2, a3
378 ◾ STEM Problems with Mathcad and Python

We get the following result:

(array([[1., 2., 3.],


[1., 2., 3.]]),
array([[4., 5., 6., 7.],
[4., 5., 6., 7.]]),
array([[42., 42.],
[42., 42.]]))

By the way, let’s consider a common error. Afer assignment

a3 = 42

the value a3 will become an integer 42. In order to assign 42 to all elements of the array, we
need to do the same as was done earlier:

a3[:,:] = 42

Let’s now draw the mesh using slices and without a single loop (Figure 17.8):

mesh = [Link]((501,601))
mesh[::20, :] = 0 # horizontal lines
mesh[:, ::20] = 0 # vertical lines
[Link](mesh, cmap='gray')
[Link]('off');

FIGURE 17.8 Draw the mesh using slices.


Arrays and Images ◾ 379

By assigning one array to another, we are not creating a copy of the array, the new array
refers to the contents of the assigned array:

a = [Link]([1,2,3,4])
b = a
a[0] = 100
a, b

As a result, we get:

(array([100, 2, 3, 4]), array([100, 2, 3, 4]))

To work with diferent arrays, we must explicitly create a copy:

a = [Link]([1,2,3,4])
b = [Link]()
a[0] = 100
a, b

Now we get the expected result:

(array([100, 2, 3, 4]), array([1, 2, 3, 4]))

Let’s look at a slightly more complex example by converting a raccoon grayscale to black
and white. First, let’s determine what the black and white colors correspond to in the rac-
coon image, and also determine the threshold for converting to black and white:

f = face(gray=True)
BLACK, WHITE = [Link](f), [Link](f)
THRESHOLD = (WHITE - BLACK) // 2
BLACK, WHITE, THRESHOLD

We get that 0 corresponds to black, 250 to white, the threshold for which all pixels above it
will be considered white, and below it as black, is 125 (Figure 17.9).

f[f>THRESHOLD] = WHITE
f[f<=THRESHOLD] = BLACK
[Link](f, cmap='gray')
[Link]('off')

We lowered the color resolution, in the original image, numbers from 0 to 250 were
used to encode pixels, and in the converted one only two numbers BLACK and WHITE,
but from an aesthetic point of view, the result was not very good, so we will return to this
problem at the end of the chapter using the Python ecosystem tools. Here it is important
for us that all transformations are performed using NumPy tools, and they are fast.
380 ◾ STEM Problems with Mathcad and Python

FIGURE 17.9 Black and white image of a raccoon.

A few words must be said about how NumPy arrays are stored in RAM. Due to the fact
that all elements of the array are of the same type and their size is the same, they are stored
directly one afer another, so access to the elements of the array is quick. But in addition,
for each array, additional information on the type of elements, dimensions, and the num-
ber of elements is stored in RAM. Tis allows us to quickly and easily resize arrays.

a = [Link](1, 20, 20, dtype= np.uint8)


[Link] = 4, 5
a

Here we didn’t do anything with the contents of the arrays, but we changed the informa-
tion about its dimensions, turning a one-dimensional array into a two-dimensional one:

array([[ 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
[16, 17, 18, 19, 20]], dtype=uint8)

Te same can be done using the reshape method, but this creates a new copy of the original
array:

b = [Link](5,4)
[Link], [Link]

We get:

((4, 5), (5, 4))


Arrays and Images ◾ 381

When changing dimensions, we must use valid values, otherwise a ValueError excep-
tion is raised:

try:
c = [Link](20,3)
except ValueError as ve:
print(ve)

Te result of executing the cell is the message:

cannot reshape array of size 20 into shape (20,3)

Converting a two-dimensional array to one-dimensional can be done in several ways:

[Link]=20,
c, d, e = [Link](20), [Link](1, 20), [Link]()
[Link], [Link], [Link], [Link]

Firstly, we can change the dimension by assigning a new value to the shape attribute,
and secondly, by using the reshape method and creating a copy of the array with the new
dimension. Please note that the dimensions (1, 20) and (20,) are diferent: in the frst case,
we have a two-dimensional array with 1 row and 20 columns, and in the second, a one-
dimensional array. Finally, you can use the fatten method to convert a multidimensional
array to one-dimensional and create a copy. Te ravel method turns a multidimensional
array into a one-dimensional array without creating a copy of it. As a result of executing
JN cell, we get:

((20,), (20,), (1, 20), (20,))

NumPy arrays can be combined horizontally and vertically to create new arrays. Let us
explain this with examples.

a, b = [Link](1,4,4), [Link](5,8,4)
c = [Link]([a, b])
d = [Link]([a, b, a])
c, [Link], d, [Link]

Te functions hstack and vstack, which concatenate arrays horizontally and vertically, are
passed sequences of arrays. As a result, we get:

(array([1., 2., 3., 4., 5., 6., 7., 8.]),


(8,),
array([[1., 2., 3., 4.],
[5., 6., 7., 8.],
382 ◾ STEM Problems with Mathcad and Python

[1., 2., 3., 4.]]),


(3, 4))

Te dimensions of the arrays by the dimension along which the union is performed must
match, otherwise a ValueError exception is raised:

a, b = [Link]([1,2]), [Link]([3,4,5])
try:
c = [Link]([a,b])
except ValueError as ve:
print(ve)

Te result is the message:

all the input array dimensions for the concatenation axis must
match exactly, but along dimension 1, the array at index 0 has
size 2 and the array at index 1 has size 3

NumPy has built-in constants and a large number of so-called universal functions.
Universal functions are understood as functions that perform actions on both scalar val-
ues and element-wise operations on arrays. All this makes the universal functions a conve-
nient tool for solving scientifc and technical problems. It is more convenient to use them,
rather than the functions of the standard library modules math and cmath. In this chapter,
we’ll restrict ourselves to a subset of built-in universal functions, but we’ll start with the
constants anyway:

np.e, [Link], [Link], [Link]

Here, along with Euler’s number and the ratio of the circumference of a circle to its
diameter, we have infnity and not a number. Te result of executing the cell is:

(2.718281828459045, 3.141592653589793, inf, nan)

Infnity can be used in arithmetic operations, for example 1/[Link] gives zero. Not a
number ([Link]) has proven to be a very handy tool for dealing with missing data. Te
array can be checked for the presence of infnity and [Link] in it, for example:

q = [Link]((np.e, [Link], [Link],-[Link], [Link]))


[Link](q), [Link](q)

gives the following result:

(array([False, False, True, True, False]),


array([False, False, False, False, True]))
Arrays and Images ◾ 383

Using these functions, you can “clear” an array of infnite and non-numeric values.

q[(~[Link](q))&(~[Link](q))]

Te ~ – operation is the negation of & – logical multiplication (AND operation), and


| - logical addition (OR operation). Te listed operations are ofen used when working
with arrays. Parentheses are used here to avoid remembering the precedence of logical
and comparison operations. When executing the above line of code with NumPy arrays,
we get:

array([2.71828183, 3.14159265])

Here we will cover only a few commonly used universal functions built into NumPy, for
a complete list of built-in functions, see the documentation published on the Internet. If
the name of the function is known, then information about its use can be obtained in two
ways. Te frst way is to output the docstring of the function, for example,

print([Link].__doc__)

Below is just a small portion of the documentation on the Heaviside function:

heaviside(x1, x2, /, out=None, *, where=True, casting='same_kind',


order='K', dtype=None, subok=True[, signature, extobj])

Compute the Heaviside step function.


Afer reading the documentation, let’s draw a graph of the function (Figure 17.10):

FIGURE 17.10 Heaviside function graph.


384 ◾ STEM Problems with Mathcad and Python

x = [Link](-5, 5, 10000)
y = [Link](x, 1)
[Link](x, y, 'k-', lw=3)
[Link]('x', fontsize=14)
[Link]('y = [Link](x, 1)', fontsize=14)

Documentation for NumPy constants, functions, and methods can be found easily on
the Internet. If the name of the function is unknown, then the question must be addressed
either to a general-purpose search engine, such as Google, or to a specialized one, such as
StackOverfow.
Te set of elementary NumPy functions is quite large. For example, with the natural log-
arithm [Link], you can calculate the logarithm to base 2 (np.log2) and base 10 (np.log10):

np.log10([Link]([0,1, 2, 10]))

gives the result:

array([ -inf, 0. , 0.30103, 1. ])

Tis set includes trigonometric, inverse trigonometric and hyperbolic functions such as:

np.arctan2(1,0), np.arctan2(1,1), np.arctan2(0,1)

resulting in:

(1.5707963267948966, 0.7853981633974483, 0.0)

Tere are several functions for rounding, the work with which will be illustrated with
an example.

d = [Link]([-3.81, -2.5123456, -1.389, -0.62345,


0.3, 1.2, 2.7])
[Link](d, 0), [Link](d), [Link](d), [Link](d)

Te result is shown below:

(array([-4., -3., -1., -1., 0., 1., 3.]),


array([-4., -3., -2., -1., 0., 1., 2.]),
array([-3., -2., -1., -0., 1., 2., 3.]),
array([-3., -2., -1., -0., 0., 1., 2.]))

Te mod function is passed two arguments, it returns the remainder of the division of the
frst argument by the second:

([Link]([Link]([7, 12, 3, -5]),[Link]([2,2,2,2])),


Arrays and Images ◾ 385

FIGURE 17.11 Function plots [Link], [Link] and [Link].

[Link]([Link]([7, 12, 3, -5]),2),


[Link](7, [Link]([2,3,4])))

Result:

(array([1, 0, 1, 1], dtype=int32),


array([1, 0, 1, 1], dtype=int32),
array([1, 1, 3], dtype=int32))

Figure 17.11 shows graphs of several functions. Here [Link] is sine, [Link] returns -1 if the
argument passed to the function is less than 0 and 1 if the argument is positive:

n = 1000
x = [Link](0, 3*[Link],n)
y = [Link](x)
[Link](x, y, 'k-', label='sin(x)', lw=3)
[Link](x, [Link](y),'k--', label='sign(sin(x))', lw=3)
[Link](x, [Link](y,0), 'k:',
label='heaviside(sin(x), 0)', lw=3)
[Link](loc='best')
[Link]('x', fontsize=14)
[Link]('y(x)', fontsize=14)

Te [Link] function allows us to sort arrays; for example, we will sort the array from the
previous example (sorting is performed in ascending order):

ysorted = [Link](y)
y[0], y[-1], ysorted[0], ysorted[-1]
386 ◾ STEM Problems with Mathcad and Python

Execution result:

(0.0, 3.6739403974420594e-16, -0.999988874475714,


0.999988874475714)

Te [Link] function allows us to remove duplicate elements from an array, leaving


unique ones:

s = [Link]([4, 5, 2, 6, 5, 2, 4, 3, 2, 1])
s = [Link](s)
s, [Link](s)

Result;

(array([1, 2, 2, 2, 3, 4, 4, 5, 5, 6]), array([1, 2, 3, 4, 5, 6]))

Now let’s turn to functions that accept arrays and return scalar values. Tese include
[Link], [Link], [Link], [Link]. While everything is clear with the frst two func-
tions, the last two return the indices of the minimum and maximum elements. Let’s apply
them to the array y from the above example:

[Link](y), [Link](y),[Link](y), [Link](y)

returns the result:

(-0.999988874475714, 0.999988874475714, 499, 166)

Te [Link] function returns True if at least one element of the array can be converted
to True. Recall that everything is converted to True in Python except 0, None, an empty
string, an empty list, or a tuple. If it is not, then the [Link] function returns False.
Te [Link]() function returns True only when all elements of the array are converted to
True, otherwise it returns False:

[Link](y), [Link](y)

gives the result:

(True, False)

Te [Link] and [Link] functions allow us to calculate the sum and product of array
elements, and [Link], [Link], [Link] are used to determine the mean, median, and
standard deviation of array elements. To illustrate how the last three functions work, let’s
generate an array of 100,000 normally distributed random numbers:

n = 100_000
r = [Link](0, 1, n)
[Link](r), [Link](r), [Link](r)
Arrays and Images ◾ 387

We get the following statistical values:

(0.0013454232036479651, 0.0028219078696115497, 0.9969168980897677)

Naturally, on other runs of the example, we will get slightly diferent values, as is always
the case when using random numbers.
Sometimes it is useful to get not a single sum or product of array elements, but arrays of
cumulative sums and products. Tis can be done using the [Link] and [Link]
functions:

a = [Link]([1,2,3,4,5])
[Link](a), [Link](a)

We get two arrays of accumulated sums and products:

(array([ 1, 3, 6, 10, 15], dtype=int32),


array([ 1, 2, 6, 24, 120], dtype=int32))

When working with NumPy, we try to avoid using loops. Below we show a technique that
allows one to construct two-dimensional arrays of all possible combinations of values of
two one-dimensional arrays. Tis technique is widely used when visualizing functions of
two variables. Tere is NumPy [Link] function for this.

nx, ny = 5, 6
x, y = [Link](0, 1, nx), [Link](0, 1, ny)
X, Y = [Link](x, y)
Z = X**2 + Y**2
x, y, X, Y, Z

By executing cell JN we get arrays:

(array([0. , 0.25, 0.5 , 0.75, 1. ]),


array([0. , 0.2, 0.4, 0.6, 0.8, 1. ]),
array([[0. , 0.25, 0.5 , 0.75, 1. ],
[0. , 0.25, 0.5 , 0.75, 1. ],
[0. , 0.25, 0.5 , 0.75, 1. ],
[0. , 0.25, 0.5 , 0.75, 1. ],
[0. , 0.25, 0.5 , 0.75, 1. ],
[0. , 0.25, 0.5 , 0.75, 1. ]]),
array([[0. , 0. , 0. , 0. , 0. ],
[0.2, 0.2, 0.2, 0.2, 0.2],
[0.4, 0.4, 0.4, 0.4, 0.4],
[0.6, 0.6, 0.6, 0.6, 0.6],
[0.8, 0.8, 0.8, 0.8, 0.8],
[1. , 1. , 1. , 1. , 1. ]]),
array([[0. , 0.0625, 0.25 , 0.5625, 1. ],
388 ◾ STEM Problems with Mathcad and Python

[0.04 , 0.1025, 0.29 , 0.6025, 1.04 ],


[0.16 , 0.2225, 0.41 , 0.7225, 1.16 ],
[0.36 , 0.4225, 0.61 , 0.9225, 1.36 ],
[0.64 , 0.7025, 0.89 , 1.2025, 1.64 ],
[1. , 1.0625, 1.25 , 1.5625, 2. ]]))

We can visualize a function of two variables on a rectangular grid using the plot_surface
matplotlib function (Figure 17.12):

fig = [Link](figsize=(6,6))
ax = [Link](111, projection='3d')
ax.plot_surface(X, Y, Z, cmap='binary')

Based on the built-in universal NumPy functions, you can write your own universal
functions that will work both with scalar data and with arrays passed to them as argu-
ments. Unfortunately, this will only be the case as long as no conditional expressions are
encountered in the function. Let’s consider an example of a function in “pure” Python that
returns rectangular pulses with unit amplitude and period T.

def imp1(t, T=2.):


ts = t % T
amp = 1. if ts<=T/2. else 0.
return amp

imp1(0.), imp1(1.5), imp1(10.4)

FIGURE 17.12 Visualization of a function of two variables on a rectangular grid.


Arrays and Images ◾ 389

For scalar argument values, everything is fne:

(1.0, 0.0, 1.0)

Passing an array function as the frst argument raises a ValueError exception. Te error
message reads: ‘Te truth value of an array with more than one element is ambiguous. Use
[Link] () or [Link] ()’. We want the equivalent of the “pure” Python conditional operator. Te
NumPy [Link] function solves this problem. Tree arguments are passed to it. Te frst
argument is an array containing boolean values, the second argument is an array whose
element is returned if the corresponding element of the frst element is True, the third
argument is an array whose elements are returned if the corresponding elements of the
frst array are False. Scalar values can be passed as the second and/or third argument. We’ll
use this to rewrite imp1 to work with arrays (Figure 17.13):

def imp2(t, T=2.):


ts = t % T
return [Link](ts<=T/2, 1., 0.)

t = [Link](-2, 5, 1000)
y = imp2(t)
[Link](t, y, 'k-', lw=3)
[Link]('t', fontsize=14)
[Link]('y(t)', fontsize=14)

Note that the imp2 function can be passed both arrays and scalar values. Te only thing
that needs to be borne in mind is that when passing a scalar value, the function returns an
array with a single element.

FIGURE 17.13 Graph of function imp2(t).


390 ◾ STEM Problems with Mathcad and Python

NumPy lacks tools that would allow us to get a black and white image of a raccoon in a
more or less decent form, but a search on the Internet almost immediately points to the PIL
– Python Imaging Library, whose main task is image processing. We could use only PIL
tools, but let’s do as we do with almost all scientifc and technical problems in the Python
ecosystem. We have a NumPy array with an image, we need to convert it to an PIL image
object, convert a color image to black and white. Tis transformation is called dithering
and is performed using the Floyd-Steinberg algorithm [6]. For this, there are ready-made
tools, you can fgure out how to use them in 10 minutes:

%matplotlib inline
import numpy as np
import [Link] as plt
from [Link] import face, ascent
from PIL import Image

# color image - NumPy array


fc = face()
# create PIL Image from NumPy array
im = [Link](fc)
# convert PIL image into black and white
fbw = [Link](mode='1',dither=[Link])
# create NumPy array from PIL Image
fbw = [Link](fbw)
# visualize black and white array
[Link](fbw, cmap='gray')
[Link], [Link]

Te last line of the example demonstrates that the transformed array contains 1,024 rows
and 768 columns and contains the Boolean values True and False:

((768, 1024), dtype('bool'))

Te transformed image is shown in Figure 17.14.


Comparing Figures 17.9 and 17.14 shows that a simple solution doesn’t always give an
acceptable result. To show that Figure 17.14 really consists of black and white pixels, render
a slice of the fw array with a raccoon nose (Figure 17.15):

ff = fbw[400:500, 550:650]
[Link](ff, cmap='gray');

It is clearly seen in this fgure that the high quality of converting a color image to black
and white (reducing the color resolution) is ensured by redistributing the density of black
and white pixels.
PIL provides tools to apply various efects to images. Let’s demonstrate this using the
flter function using the example of a black square drawn on a white background:
Arrays and Images   ◾    391

FIGURE 17.14 Converting a raccoon color image to black and white using the Floyd-Steinberg
algorithm.

FIGURE 17.15 Visualization of a slice of fbw array – raccoon nose.

from PIL import ImageFilter

def filter(flt=None):
BLACK, WHITE, n = 0, 255, 100
im = [Link]((n, n), dtype=np.uint8) * WHITE
im[n//3:2*n//3, n//3:2*n//3] = BLACK
392 ◾ STEM Problems with Mathcad and Python

if flt:
im = [Link](im)
filtered = [Link](flt)
[Link](figsize=(4, 4))
im = [Link](filtered)
[Link](im, cmap='gray')

filter()

Te PIL flter object is passed to the function. Te original array with n rows and columns
is flled with 255, which plays the role of white. A slice in the center of the white square
creates a black one.
In the event that a flter object is passed to the function, then the original NumPy array
is converted into a PIL image, and the flter passed to the function is applied to it. Next, the
image is converted to a NumPy array and rendered using matplotlib. If no flter is passed,
then the original black square is rendered on a white background (Figure 17.16).
Let’s demonstrate how PIL flters can transform images (Figures 17.17–17.19) using the
flter function calls.:

filter([Link])
filter(ImageFilter.SMOOTH_MORE)
filter(ImageFilter.FIND_EDGES)

FIGURE 17.16 Original black square on white background.


Arrays and Images ◾ 393

FIGURE 17.17 Applying the [Link] flter to the black square.

FIGURE 17.18 Applying the ImageFilter. SMOOTH_MORE to the black square.


394 ◾ STEM Problems with Mathcad and Python

FIGURE 17.19 Applying the ImageFilter. FIND_EDGES to the black square.

In this chapter, we have shown how the NumPy tools allow us, frstly, to work with
arrays as with scalar values, secondly, to improve the performance of solving computa-
tional problems in Python, thirdly, to associate arrays and slices of NumPy arrays with
images, and, in fourthly, to demonstrate how easy it is to use the Python ecosystem tools
to solve complex problems.

QUESTIONS AND TASKS FOR THE READER


1. Reproduce all the examples of a chapter in Jupyter Notebook or JupyterLab.
2. Write the raccoon-to-black-and-white conversion in pure Python and compare the
execution time with the solution provided in this chapter.
3. List the tools to improve the performance of solving computational problems in
Python.
4. How are NumPy arrays diferent from pure Python sequences?
5. How do I create a NumPy array from a Python list?
6. How to fnd out the amount of RAM occupied by a NumPy array.
7. How are NumPy arrays related to images? What types of array elements should you
use when working with images?
Arrays and Images ◾ 395

8. What are slices, and why are they used when working with NumPy arrays?
9. What is stacking? Give examples.
10. How to get a negative of a grayscale?

REFERENCES
1. W. McKinney. Python for Data Analysis (O’REILLY, Cambrige, 2015), ISBN 978-1-419-31979-
3, 482 p.
2. R. Johansson. Numerical Python. Scientifc Computing and Data. Science Applications with
Numpy, SciPy and Matplotlib. Second Edition. (APRESS, Urayasu-shi, Chiba, Japan, 2019),
ISBN 978-1-4842-4246-9, 709 p.
3. A.J. Gupta. Scientifc Python. Second Edition (Techno World, Kolcata, 2021). ISBN 978-81-
949567-6-1, 668 p.
4. Q. Kong, T. Siauw, A. M. Bayen. Python Programming and Numerical Methods. A Guide for
Engineers and Scientists (Academic Press, London, 2021), 462 p., ISBN: 978-0-12-819549-9
5. PEP 20 -- Te Zen of Python. URL:[Link]
6. B. W. Kolpatzik and C. A. Bouman. Optimized error difusion for image display, Journal of
Electronic Imaging 1(3), (1992). [Link]
Chapter 18

Three Circles Tied


with an Elastic Band
or New Pendulum

Komarov looks and sees the ball.


“What is it?” whispers Komarov.
And from the sky it rumbles: “This is a ball.”
“What ball?” whispers Komarov.
And from the sky it rumbles: “The ball is smooth-surfaced!”
Daniil Kharms “On Phenomena and Existence”

The following task has been “doing the rounds” of the Internet—Figure 18.1.
There are three circles with the same radius, r. We want to find the length of the rope
tying them together in the form of a pyramid.
The answer is pretty easy to find. To do this, draw line segments connecting the centers of
the circles to each other. You will get an equilateral triangle with sides 2r. Next, connect the
centers of the circles with the points where the rope leaves the circles. We see three rectan-
gles with sides r and 2r. The length of the rope L will be equal to the length of one circle (the
length of three circular arcs with an angle of 120°) plus six radii of the circles (three long
sides of the rectangles). The corresponding formula can be seen at the bottom of Figure 18.1.
The problem can be generalized to find the length of the rope connecting any number
of circles of any radius. If we leave three different circles, but “tie” them not with a rope,
but with a triangle, then we get two problems solved by the Italian mathematician Malfatti
([Link] “Triangles Malfatti” and “The
Malfatti Problem”.

DOI: 10.1201/9781003228356-19 397


398 ◾ STEM Problems with Mathcad and Python

FIGURE 18.1 Tree circles tied with rope.

FIGURE 18.2 Tree cylinders (end view), tied with an elastic band and laid on a table (the formula
for the length of the elastic band L and its elongation relative to that shown in Figure 18.1).

Te frst problem is to inscribe three circles in an arbitrary triangle such that each circle
touches the other two and two sides of the triangle. Te second problem requires three
circles to be inscribed in a triangle so that their total area is a maximum.
Let’s take three identical cylinders of mass m (three round pencils, for example, or three
aluminum cans with drinks—see Figure 18.10 below), and tighten them, not with a string,
but with a round (closed) elastic band. Something like this is pulled into a bun hair on the
head or banknotes in a pack. And then we put it all fat on the table—see Figure 18.2. What
will happen?
Te answer may also seem quite simple: the rubber band pulls the three cylinders into a
pyramid, as shown in Figure 18.1.
But elastic bands are diferent—with diferent stifnesses. Tis is the time to remember
the famous “school” Hooke’s law, which says that the stretching of the elastic is propor-
tional to the force applied to it. Te proportionality factor is the coefcient of elasticity k
(Hooke’s coefcient). Tere are no materials in nature that correspond completely to such
a linear law. However, for small tensions, we have certain linearity, which greatly simpli-
fes the calculations. Our elastic will elongate by less than 17% (see Figure 18.2 with the
number 1.163...), and we can apply Hooke’s linear law here.1 But with signifcant stretching,
the linearity will disappear: if the elastic is strongly stretched, then it will gradually
cease to lengthen, and then it will completely break. If we introduce nonlinearity into
1 Seventeen and seven are two beautiful prime numbers. If we consider the simplest pendulum (a load suspended on a
string), then the number 7 appears there. Convention dictates that when the angle of deviation of the pendulum from
the vertical is less than 7° the sine of the angle can be replaced by the angle itself, which greatly simplifes the solution of
the diferential equation. By the way, in the simplest pendulum, you can also replace a rigid rope with an elastic band.
Three Circles Tied with an Elastic Band ◾ 399

FIGURE 18.3 Raised central cylinder.

our calculation, then the problem becomes somewhat more complicated (an integral will
appear), but the nature of the answer will remain the same. Tis will be discussed at the
end of the chapter.
So, if the elastic band is elastic enough, then this can happen.
Te middle cylinder may be in the stable position shown in Figure 18.3, characterized
by the fact that the sum of the potential energies of the upper cylinder and the stretched
elastic band will be minimal (D’Alembert – Lagrange principle). We will prove this with
a simple physical and geometric calculation, taking into account the fact that the triangle
connecting the centers of the circles (see Figure 18.1) will no longer be equilateral, but isos-
celes with a base length of 2l and sides equal to 2r.
Figure 18.4 shows the PE function created in Mathcad with arguments h and k, return-
ing the potential energy of our mechanical system, consisting of three cylinders and elastic
bands tightening them. Tis energy is the sum of the potential energy of the raised middle
cylinder PED and the potential energy of the stretched elastic band PEB. Te elastic band is
only slightly stretched, by ΔL, so Hooke’s linear law can be used in the calculations. Te
formula for the potential energy of a stretched elastic band with the elasticity coefcient
k multiplied by half the square of the stretching of the elastic band, ΔL, repeats the for-
mula for kinetic energy, where the mass acts instead of the elasticity coefcient, and speed
instead of stretching. Tink of a slingshot that transfers the potential energy of a stretched
elastic band into the kinetic energy of a stone fying out of a slingshot.
But we digress! Let’s get back to our task!
Figure 18.5 shows a graph of the change in the potential energy of our mechanical sys-
tem with a potential well—with a local minimum of the sum of energies (point C). As the
reader might guess, the coefcient k (6.5 newtons per meter) was chosen so that this curve
has a local minimum, and the right end of the curve (point D) is slightly higher than the
local maximum (point B).
400 ◾ STEM Problems with Mathcad and Python

FIGURE 18.4 Te formula for the potential energy of three cylinders tied with an elastic band.

FIGURE 18.5 Graph of the change in the potential energy of three cylinders tied with an elastic
band (option 1).

Implementing Figures 18.4 and 18.5 in Python is quite simple:

%matplotlib inline
import numpy as np
import [Link] as plt
# Figure 18.4
def PE(h, k, m=1., r=1., g=9.81):
PE_D = m*g*(h - r)
l = [Link]((2*r)**2 - (h-r)**2)
L = 2*(l + [Link]*r +2*r)
ΔL = L - 2*r*(3 + [Link])
PE_B = k*ΔL**2/2
return PE_D + PE_B

When constructing Figure 18.5, in contrast to Mathcad, we look at several dependencies of


potential energy on h for k = 6., 6., 6.5, 7.0:
Three Circles Tied with an Elastic Band ◾ 401

# Figure 18.5
h = [Link](1, 2.732, 1000)
[Link](figsize=(6,6))
[Link](h, PE(h, 5.0), 'k:', lw=3, label=f'k=5.0')
[Link](h, PE(h, 6.0), 'k--', lw=3, label=f'k=6.0')
[Link](h, PE(h, 6.5), 'k-', lw=3, label=f'k=6.5')
[Link](h, PE(h, 7.0), 'k-.', lw=3, label=f'k=7.0')
[Link]('h', fontsize=14)
[Link]('PE(h, 6.5), ', fontsize=14)
[Link](loc='best');

So. Tree cylinders with a radius r of 1 m and a mass m of 1 kg2 are pulled together with an
elastic band with a stifness coefcient k equal to six and a half Newtons per meter and laid
out on a table (h = r, point A in Figure 18.5, see also Figure 18.2). Ten we slowly lif the mid-
dle cylinder (increase the value of h) and place it at the local maximum (point B). Here the
cylinder will be in a metastable stationary state. Te slightest external infuence (a light blow
on the table, for example) can return the cylinder to the table (point A), or turn it into a kind
of pendulum that will roll around a local minimum (point C). Te decay rate of such a pen-
dulum will depend on the friction forces, which can be neglected in our thought experiment.
We could also move the middle cylinder almost to the right edge of the curve (point D
in Figure 18.5) and release it. If we raise the cylinder above the local maximum point, then
the cylinder will “roll” over this maximum and fall on the table. If the cylinder is not raised
so high, then it will begin to behave like a pendulum—it will “roll from side to side” near
the local minimum.
But if the coefcient of elasticity k of the tightening band is reduced, then we will not get
a pendulum. Te middle cylinder, afer being lifed, will “roll” down onto the table along the
curve shown in Figure 18.7. Tere is also a metastable point on this curve; this is not a local
maximum, but an infection point, the coordinates of which are easy to fnd through the
numerical solution of a system of two equations with two unknowns (Figure 18.6—where
the frst and second derivatives of the potential energy function are set to zero). At this
point, the middle cylinder will be stationary, but “hitting the table” will cause it to fall down.
To solve the algebraic equation in Figure 18.6 using Python, we need to use the fsolve
function of the [Link] library:

# Figure 18.6
from [Link] import fsolve
def opt(x, Δh):
h, k = x
dPE_dh = (PE(h+Δh, k) - PE(h-Δh, k))/(2*Δh)
d2PE_dh2 = (PE(h+Δh, k)- 2*PE(h, k) + PE(h-Δh, k))/Δh**2

2 An old metrological anecdote immediately comes to mind. Exam dialogue. Teacher: What is horsepower? Student: - Tis
is the strength that a horse 1 m tall and weighing 1 kg develops. - But where did you see such a horse!? “You can’t see her.
She is kept in Paris, in the Chamber of Weights and Measures.
402 ◾ STEM Problems with Mathcad and Python

FIGURE 18.6 Calculating the infection point on a potential energy curve.

return dPE_dh, d2PE_dh2


h1, k1 = fsolve(opt, (2, 7), args=(0.0001,))
h1, k1
(2.2166173910224636, 5.447621665706348)

Naturally, we get a result close to that obtained in Mathcad (Figure 18.6):


Plotting Figure 18.7 in Python is easy:

# Figure 18.7
h = [Link](1, 2.8, 1000)
[Link](figsize=(6,6))
[Link](h, PE(h, k1), 'k-', lw=3, label=f'k={k1:7.4f}')
[Link]('h', fontsize=14)
[Link](f'PE(h, {k1:7.4f}), ', fontsize=14)
[Link](loc='best');

If the elastic band is sufciently strong (Figure 18.7), then the three cylinders lying on the
table will also be in a metastable state. But “a light blow” on the table will pull the cylinders
into the pyramid shown in Figure 18.1. In this case, the middle ball does not have to be at
the top. One of the extreme balls, and not the middle one, can begin to rise, and the whole
structure will roll over on its side.
It is easy to prove that at the ends of the curve shown in Figure 18.8 derivatives are equal
to zero.
Three Circles Tied with an Elastic Band ◾ 403

FIGURE 18.7 Graph of the change in the potential energy of three cylinders tied with an elastic
band (option 2).

FIGURE 18.8 Graph of the change in the potential energy of three cylinders tied with a strong
elastic band (option 3).

You can remove the “physics” from the problem, leaving only the “mathematics”, or
rather elementary functional analysis. To do this, the variables m, g and r must be made
dimensionless and assigned unit values3—see Figure 18.9. A fairly simple functional
dependence will be obtained, which can be analyzed using symbolic rather than numeri-
cal mathematics to fnd expressions for the minimum, maximum, and infection points.
And for starters, you can simply build a family of curves with abscissa h for diferent
values of k.

3 Assigning single values to the radius and mass does not raise questions (see also footnote 2). But here the unit for the
acceleration of free fall can be confusing. Let’s explain! Te physical fundamental principle of the meter is the length
of the pendulum, the oscillation period of which is equal to 2 seconds [2]. But you could set the meter like this. A meter
is the distance at which the acceleration due to gravity is 1 m divided by a second squared. By the way, in schools, to
facilitate calculations for physics problems, it is sometimes recommended to round g to 10. We can also in our transfor-
mation in Figure 18.8 assign a ten to the variable g, not a one. In the “tail” of the fnal expression, h – 1 will be replaced by
10h – 10, but this will not change the nature of the twists of the curves.
404 ◾ STEM Problems with Mathcad and Python

FIGURE 18.9 Simplifcation of the potential energy function with graphical analysis of a family
of curves.

Te graphs can show the isolines of the local maximum (the frst metastable point) and
the infection point (the second metastable point). As the value of k increases, the frst iso-
line will approach unity (the lef edge of the graph), and the second one, to the right edge
of the graph, will approach the maximum value of h, equal to the root of three plus one.
Te symbolic solution of the equation in Figure 18.9 in Python is done using the sympy
library:
Three Circles Tied with an Elastic Band ◾ 405

from sympy import init_printing, simplify, symbols, sqrt, pi


m, g, r, h, k = symbols('m g r h k')
PE_D = m * g *(h - r)
l = sqrt((2*r)**2 - (h-r)**2)
L = 2*(l + pi*r +2*r)
ΔL = L -2*r*(3+pi)
PE_B = k * ΔL**2/2
PE = PE_D + PE_B
init_printing()
simplify(PE)

Afer simplifying the symbolic expression, we get:

( )
2
gmh − gmr + 2k −r + 4r 2 − ( h − r )
2

Substituting single values for m, g, r:

PE_s = simplify([Link](m,1).subs(g, 1).subs(r,1))


PE_s

we get:

( )
2
4 − ( h −1) −1 −1
2
h + 2k

To plot the curves at the bottom of Figure 18.9, we convert symbolic expressions to numeri-
cal values:

from sympy import lambdify


PE_sl = lambdify((h, k), PE_s, 'scipy')
n = 1000
h = [Link](1, 2.8, n)
[Link](figsize=(6,6))
for k in (5, 4, 3, 2, 1, 0.5, 0):
[Link](h, PE_sl(h, k), lw=3, label=f'k={k}')
[Link]('h', fontsize=14)
[Link]('PE(h, k)', fontsize=14)
[Link](loc='best')
[Link](figsize=(6,6))
for k in (1, 0.9, 0.8, 0.7, 1, 0.6, 0.5, 0.4):
[Link](h, PE_sl(h, k), lw=3, label=f'k={k}')
[Link]('h', fontsize=14)
406 ◾ STEM Problems with Mathcad and Python

(a) (b) (c)

FIGURE 18.10 Photographs of three cans of energy drink, showing the three stable cases described
above of tightening the circles with an elastic band. (a) Tree elastic bands (see Figure 18.1). (b) Two
elastic bands (see Figure 18.3). (c) One elastic band (see Figure 18.2).

[Link]('PE(h, k)', fontsize=14)


[Link](loc='best')

Te problem described in the chapter is good in that it is not difcult to display it in a sim-
ple physical experiment—see Figure 18.10, which shows three photographs of aluminum
cans, tied with rubber bands—one, two and three.
If the cans, elastic bands and the surface of the table are well lubricated with oil, then
you could try to get the above-described pendulum (oscillator). At the same time, it would
be nice to make sure that the rubber bands are in some circular grooves of the cans and do
not come into contact with the table surface.
Half-joking remark. Our cans store not ordinary drinks, but the so-called energy drinks.
On the cans, you can see the inscription (advertising slogan) “Absolute Energy”. It can be
assumed that the frst can stores kinetic energy, the second can stores the potential energy
of the raised middle jar, and the third can stores the potential energy of the stretched rub-
ber band. Joking aside, when our pendulum oscillates, these energies will change from one
form to another, but their sum must remain constant, assuming there is no loss of energy
due to friction. Te constancy of the sum of energies is one of the criteria for the correct-
ness of the created mathematical model.
You could take more than three cylinders, pull them together with an elastic band and
see how they behave when put on the table.
And now let’s go up to the beginning of the chapter—to the epigram!
Our task can be translated from a plane into a volume: take not cylinders, but “smooth-
surface” balls (Figure 18.11) and cover them not with an elastic band, but with an elastic
flm. Let the flm be transparent and preferably completely invisible.
If the flm is sufciently rigid, the balls will line up in the pyramid shown in Figure 18.11
(see also Figure 18.1). If the flm is sufciently elastic, then the balls will fall on the table
(see Figure 18.2). It should be expected that for a certain intermediate elasticity of the flm,
this entire three-dimensional structure will behave like a pendulum. In this case, however,
it would be necessary to ensure that the lower balls lying on the table move apart in straight
Three Circles Tied with an Elastic Band ◾ 407

FIGURE 18.11 Ten balls in transparent flm.

lines in the right directions. For this, we would need to make sure that the lower balls roll
in some grooves made on the surface of the table.
In addition, it is possible to study a system with diferent radii of round cylinders and
spheres.
Te elasticity of the band and the flm is highly dependent on temperature. By heating
or cooling our cylinders and balls tied with elastic or flm, all the cases described above
could be obtained.
It is possible to compose a diferential equation, the solution of which will give peri-
odic functions of the change in the position of the center of the middle cylinder in time.
Without taking into account the forces of friction, this is quite simple to do. But what
would result if we account for friction?
We entrust this work to readers!
A discussion of this problem, which led to the idea of a new pendulum, can be viewed here:
[Link] We
express our gratitude to the participants in this discussion. Tere you can also view anima-
tions of the oscillation of our new pendulum (oscillator).

18.1 AFTERWORD ON NONLINEARITY


Figure 18.12 shows the ΔLnl function (and graph) that returns the elongation of an elastic
band as a function of the force applied to it, taking into account nonlinearity. Te so-
called logistic function is used ([Link] Rather,
408 ◾ STEM Problems with Mathcad and Python

FIGURE 18.12 Nonlinear Hooke’s law.

FIGURE 18.13 Function inverse to the nonlinear dependence of Hooke’s law.


only its right half—we can only stretch the elastic band, but we cannot compress it like a
spring. Also shown is the linear dependence of ΔLl of the elongation of the elastic band on
the applied force, which we used earlier. Such a dependence is embedded in the so-called
spring scales ([Link] where the weight of an object
suspended from such scales is judged by the tension of the spring. Te scale of such scales
should be uniform.
Figure 18.12 shows how you can create an inverse function Fnl that returns the force
applied to the elastic depending on its length. To do this in Mathcad, one can use the
symbolic solve math operator or the root numerical math function—see Figure 18.13. Te
function generated in this way is shown in the graph.
In Python, we take into account the nonlinearity a little diferently, frst plotting the
dependence of the force on the elongation:

# Figure 18.12
N, Fmax = 20, 20
k = 6.5
n = 1000
F = [Link](0, Fmax, n)
Three Circles Tied with an Elastic Band ◾ 409

ΔLnl = 5/(1+[Link](-0.5*F))-0.5 - 2
[Link](figsize=(8,6))
[Link](F, F/k, 'r-', lw=3, label='$\Delta L_l(F)$')
[Link](F, ΔLnl, 'b-', lw=3,
label=r'$\Delta_{nl}L(F)$')
[Link]()
[Link](loc='best')
[Link](r'$F$', fontsize=14)
[Link](r'$\Delta_lL(F), \ \Delta_{nl}L(F)$', fontsize=14);

We invert this nonlinear dependence not by solving an algebraic equation, as in Mathcad,


but by using spline interpolation (see Chapter 15):

# Figure 18.13
from [Link] import interp1d
ΔLnl_min, ΔLnl_max = [Link](ΔLnl), [Link](ΔLnl)
ΔL = [Link](ΔLnl_min, ΔLnl_max, n)
F_nl = interp1d(ΔLnl, F)
F_nl_appr = F_nl(ΔL)
[Link](ΔL, F_nl_appr, 'b-', lw=3);
[Link]()
[Link]('ΔL', fontsize=14)
[Link](r'$F_{nl}(ΔL)$', fontsize=14);

As a result, we get the F _ nl function, which allows us to calculate the force depending
on the elongation.
Figure 18.14 shows the potential energy function of three cylinders pulled together by
an elastic band with a nonlinear restoring force.
Te implementation of the calculations in Figure 18.14 is carried out using the PE(h)
function, and the calculation of the defnite integral using the quad function from the
[Link] library.

# Figure 18.14
from [Link] import quad
r = 1.
g =9.81
m = 0.2
def PE(h):
PE_D = m*g*h
l = [Link]((2*r)**2 - (h - r)**2)
L = 2*(l + [Link]*r + 2*r)
ΔL = L -2*r*(3 + [Link])
PE_B, err = quad(F_nl, 0, ΔL)
return PE_D + PE_B
410 ◾ STEM Problems with Mathcad and Python

FIGURE 18.14 Potential energy of three cylinders pulled together by an elastic band with a non-
linear restoring force.

h = [Link](r, ([Link](3) + 1)*r, n)


PE_ = [Link](n)
for i,hh in enumerate(h):
PE_[i] = PE(hh)
[Link](figsize=(8, 6))
[Link](h, PE_, 'b-', lw=3)
[Link]()
[Link]('h', fontsize=14)
[Link]('PE(h)', fontsize=14)
[Link](5, 6.2);

If there is a linear dependence under the integral, then it is easy to take such an integral
and obtain the simple formula we have already used with the coefcient of elasticity k and
with the elongation squared divided by two (see Figure 18.4).
Three Circles Tied with an Elastic Band ◾ 411

TASKS FOR READERS

1. Solve the problems described in this chapter (creating and solving the diferential
equation for the oscillation of the middle cylinder, more cylinders, etc.).
2. Te rope that tightens three circles (Figure 18.1) can be likened to the rails along
which the train rolls during its tests. But when the rope is separated from the circle,
the curvature of the rail of such a test “circle” will change abruptly from 0 (straight
section of the path) to the value 1/r (section of the path along the arc of a circle). Tis
is not good at this point in the path there will be a sideways force on the train. Replace
the circle with another line whose curvature changes smoothly from 0 to 1/r. Hint in
Chapter 2 “Oval and Ellipse”—see Figure 2.10.
3. Tree cylinders of radius r are connected together in the form of a pyramid (see
Figure 18.1) and ft tightly into a pipe with radius R. Te radius of the pipe begins to
increase. How will the position of the cylinders in the pipe change? Problem variant:
cylinders are connected with an elastic band of diferent elasticity.

FIGURE 18.15 Solution of the diferential equation for the oscillation of a new pendulum.

FIGURE 18.16 Oscillating curve of the new pendulum.


412 ◾ STEM Problems with Mathcad and Python

FIGURE 18.17 Change in the potential energy of a new pendulum during its oscillation from point
A to point B.

4. To reveal the process of compiling the diferential equation for the oscillation of
our new pendulum, shown in Figure 18.15, Figure 18.16 shows how the height of the
middle cylinder changes over time. Figure 18.17 shows the graph of changes in the
potential energy of the system of those cylinders and the elastic band around them.
Points A and B mark the ends of the interval of oscillation of the pendulum, where
the potential energy of the middle cylinder and the elastic band decreases and turns
into the kinetic energy of the movement of three cylinders.

Te curve in Figure 18.16 can be called the Ochkov-Vasileva sinusoid, and the pendu-
lum described in this chapter of the book is the Point pendulum. Why? Only the authors
of this book know this secret. On this riddle, we fnish it.
Index

absolute value 190, 192, 196–197 chaotic 270–271, 339


accuracy 29–30, 35, 55–56, 86, 94, 98, 121, 200, 204, chase 228–233, 236
209–211, 231, 252, 273 Chekhov, Anton 67–69
additional restriction 105–107, 113 circle 53, 55, 58–59, 66, 119, 122, 130–138, 139–147,
algebra, algebraic 6–7, 11, 27–28, 30, 43, 53, 67–71, 160–168, 201, 207, 230–232, 236, 244,
89, 94, 101, 115, 117, 119–120, 128, 131, 248–252, 253–262, 280, 350, 352, 355–356,
149–150, 249, 260, 263, 274, 293, 320, 363, 382, 397–399, 406–407, 411
401, 409 colormap 40, 43, 190, 192, 203–205
Anaconda distribution 30 comet 53, 83–89, 117–130, 134, 138, 148, 293
analogy 6, 11–13 complex array 364–365, 367, 389
analytic continuation 194–195, 199, 201, 204 complex plane 189, 194, 196, 201–202
analytic solution of algebraic equations in complex variable 189
Python 98 computational experiment 10, 19–20, 24
approximate, approximately 29, 68, 97–103, 115, 118, computational tools 3, 5–7, 10–14, 16–18
121, 135–138, 194–196, 207–209, 216, 226, concave pentagon 167
242, 254, 298, 300, 326–327 concave triangle 165, 167
Archimedean spiral 159–160, 165 conformal mapping 209, 212–213, 219, 221
array initialization 368–369 conjugate gradient 35–36, 46
array slice 363, 375–376, 378, 390–391, 394 constraints 8
arrow 29, 33–44, 83, 86, 117 convergence process 263–264, 267
arshin 67, 69, 75–76, 226 copy of array 379, 381
attractor 274–278 creative thinking 3
critical thinking 22
banknote 311–312, 398 curve fitting 195–196
battleships 212, 220 curve gallery 179–181, 187
beetle 134–137 curve generation 174–178, 182–183, 185
bifurcation diagram 270–274 curvilinear cell 190, 192
bisection 7, 300 Cython 362
black and white image 370, 379–380, 390–392
black box 6, 14, 15 decomposition 12–13, 24
boundary value 13, 96, 238, 291 dependence of water density on temperature
broadcasting 373, 376 297, 301
determinant 68, 70
cardioid 207–211 differential equations 5, 7, 13–14
Cassini 60–66, 134–135 digital twin 121, 234, 293–296, 312, 316
catenary 241, 244–249, 252 direct problems 7, 11
Cauchy problem 13, 238 distance learning 3
cell 333
cellular automaton 333–357 eccentricity 118–119, 135–136, 138
cellular automaton animation 333, 345, 352 educational problems 8, 11, 13
Celsius 299, 302, 307 elastic band 398–403, 406–412

413
414   ◾    Index

electricity 304, 313–315, 319 imaginary part 190–195, 202–205


ellipse 53–66, 84–89, 117–130, 134–138, 161, 411 infected 234–238
Engineer 1–25 infinity 60, 133–136, 265, 270, 382
equations 27–51, 53, 55–56, 60, 67–89, 91–102, initial situation 9
109–115, 117, 120–123, 128–131, 148–152, input, output parameters 7, 8, 11–12, 14–15
155, 158, 207, 226, 229–230, 238, 244–247, integer array 364–366, 371, 373, 375
250–252, 256–260, 263, 274–276, 308, 320, interpolation 120, 122, 129, 311, 316–323, 326,
322, 363, 401 328–330, 409
equation to determine the pressure 299–301 inverse problems 7, 8, 11, 19, 24
equipotentials 193, 196
error 28, 30–43, 48, 55–58, 73, 78–80, 87–89, 93, jit 361–362
101–103, 113, 118, 130, 161, 176–178, Julia set 276–287
193–197, 200, 208, 224, 236, 249–252, JupyterLab 356, 359, 394
304–305, 378, 389, 395 Jupyter Notebook 30, 40, 58, 64, 89, 95–96, 163, 178,
Euler’s formula 159–160, 165 203, 227, 256, 261, 291, 345–348
extrapolation 319, 321, 328 Jupyter Notebook interactive application 163–164,
345–351
Fahrenheit 307
Fermat 139–141, 147, 150 Kelvin 299, 302, 305–310
fiction 53, 67–89, 92, 94, 117, 148, 157, 226 kinetic energy 314, 399, 406, 412
1st, 2nd , 3rd order interpolation 326
float array 364, 367 lens 50, 136, 147–150, 153, 157
friction 313–319, 401, 406–407 Levenberg-Marquardt 34, 36, 38, 46
library 30, 40, 56, 64, 94, 99, 114, 160, 178, 190, 237,
Game of Life 347–348, 350, 352, 355, 357–358 263, 278, 301, 323, 334, 361, 363, 370, 382,
gears 182, 186 390, 401, 404, 409
“glue” the solution of the problem from the logarithmic scale 237–238
solutions of the subtasks 5, 12, 15–17, 24 logistics map 264–273
graphical, graphically 27, 31–33, 45, 92–98, 106,
111–115, 122, 129, 135, 140–144, 241, magic curves 172, 182–183, 185–186
252, 404 Malfatti 397
gray scale image 363, 370–372, 376, 379, 390, 392 Mandelbrot set 283–291
Maple 18
half-division 296, 300 Mathcad 16, 18, 20, 22, 28, 30
hard skills 22 Mathematica 18, 21
hare 139–147, 228–234, 239 mathematical systems 1, 13–14, 16–18, 20
harmony 53, 293 Mathematician 1–25
healthy 234–238 Matlab 16, 18, 20, 159–161
heart 33–44, 207 matplotlib 40–41, 56, 62, 64–65, 94–96, 103, 114,
heat capacity 297–298, 302–304 190, 194, 196, 201, 236–237, 265, 274,
Heaviside 383–385 278, 299, 334, 336, 338, 345–346, 388,
heptagon 253–254 390, 392, 400
higher education 2–3 matrix rank 69, 70–72, 74, 75, 77, 83, 86–88
Himmelblau function 44, 46, 48–50 maximize 45–46, 56, 125, 139
hippodrome 59–62, 64 Mephistopheles 11
histogram 88, 216, 219, 224, 226 merchant 67–81
Hooke’s law 398, 408 MCC 253–258
hybrid 36–37, 49 MIC 253–258
hydroelectric 311–315, 319 minimize 45–46, 55–58, 139–140, 147, 230, 246, 252,
hyperbola 59, 84, 89, 117, 119, 127, 134–137 301–302
model 9–10, 24
image filters 390–394 models and predictions 9
image slicing 376–377 Moliere’s philistine in the nobility 293
Index   ◾    415

Monte-Carlo 207–211, 220 Quasi-Newton 35–36, 46


Moore 333, 335, 345–346, 354–355, 357
Moore neighborhood 333, 335, 345–346, raccoon 370–371, 376–377, 379–380, 390–391, 394
354–355, 357 random 36, 54, 88–89, 207, 209, 216–218, 222–223,
multidimensional array 368–369, 374, 381 226, 228, 327–330, 333–344, 348, 350–357,
386–387
Nautilus 92–100, 103, 106–107, 109–112, 116 random filling 334
Neumann neighborhood 333, 345–346, 352, rank 69–77, 82–83, 86–89
355–356 Rankine 307, 313
Newton’s method 7, 263–264, 273–275 real part 190–195, 202–205
Nikuradze 316–317 rectangle mapping 189–205
non-conducting boundaries 193–194 reflection 161, 169, 172, 174–178
nonlinear, nonlinearity 30, 36, 68, 93, 95, 101, 111, reinventing the wheel 6, 7, 13, 16, 263
151, 259, 398, 407–410 Reynolds number 315–319
numba 361–362 root(s) 28–51, 62, 91–116, 125–128, 197, 241–244,
numerical, numerically 27–48, 55, 67, 86, 92, 96–99, 263–264, 273–276, 296–297, 300, 404, 408
106–134, 143, 149–150, 222, 229–230, rosettes 182–183
244–245, 249, 252, 270, 320–322, 363, 395, rotation 161, 169, 172, 174–178
401–405, 408
numerical integration 409 sazhen 226
Numpy 30, 39–41, 56, 62, 64–65, 69, 79, 95–96, scientific and technical problems 7
99–105, 113, 146, 159, 190–196, 201, Scilab 18
216–217, 221, 236–237, 260, 265–267, 274, scipy 30, 56, 69, 101–102, 111, 116, 146, 195, 263,
278, 299, 336, 345–346, 361–369, 372–374, 300–302, 323, 331, 345–346, 363, 370–372,
379–384, 387–395, 400 390, 395, 401, 405, 409
[Link] 69 scipy images 370–371, 390
[Link] 409
Octave 18 [Link] 69
optics, optical 66, 136, 141, 147–158 [Link] 331
oval 53–66, 134–135, 143, 411 [Link] 101–102, 401–402
[Link].minimize_scalar 146, 301–302
pandemic 3, 234 [Link] 101, 111
parabola 59, 84, 117, 119, 121, 127, 134–138, 151, 241, sick 258
243, 322, 325 SLAE 68, 70, 75–76, 82–86
parallel 55, 127, 136, 148–151, 154, 189, 221–224, SMath 18
230, 232, 236, 316 smoothing 318, 320, 323, 326, 328
parity rule 335, 345, 347–348, 351–356 soft skills 14, 22–23
pendulum 150, 398, 401, 403, 406–407, 411–412 sort, sorting 177, 221–228, 235, 385–386
PIL 390–392 spiral 159–160, 164–165
plot surface 388 spirograph 167–172
polynomial 37, 39–40, 93–94, 204, 321–323 spline 311, 316–331, 409
population 234, 264–265 stack array 381–382
portrait 33–38, 44–46, 49–51, 370 stages of problem solving 10, 15, 17
potential energy 246–247, 249–250, 314, 399–406, standard deviation 57–58, 327, 361, 386
410, 412 star and gears hybrids 186
practical problems 6, 7, 8, 11, 20, 22, 23 stars 184
problem conditions 4, 8–12, 17, 19, 24 statistical modelling 19
problem solving 1, 3, 10, 17, 21–23 STEAM 1, 3, 23
pseudoinverse 70–77 STEM 1, 3–4, 19, 23
pseudo-parallel computations 221, 224, 230, 236 streamlines 193, 196
pump 305–307, 313 string array 364, 367
Pushkin, Alexander 33, 36, 83, 157, 234 student 1–25
Python ecosystem 14–15, 18, 20–21, 263–264 submarine 92–100, 105–116, 212, 216, 218
416   ◾    Index

symbolic, symbolically 28–29, 33, 36, 39–43, 48, 86, universal functions 370, 382–389
92–95, 99–100, 107–111, 115–116, 131, 149, user-defined 31, 98, 109, 120, 126
244, 254, 403–408
symmetry 169, 175–178 vershok 226
sympy 28, 39, 94–95, 99, 403–405 virus 234, 238
syntactic sugar 221 visualization 5, 14, 17–18, 20–21, 243–244, 189, 202,
system(s) 27–51, 53–56, 60, 68–73, 78, 82–89, 92–97, 205, 266, 274–275, 280, 333–334, 345, 363,
101, 109–115, 117, 120–121, 128–131, 138, 388, 391
149–152, 157, 178, 221, 228, 234, 238, von Neumann 333, 335, 345–346, 352, 355–356
244–246, 250–252, 263–264, 291, 294, vortices 314, 316, 319
307–311, 320–322, 348, 351, 358, 363, 369,
379, 390, 394, 399–401, 407, 412 WaterSteamPro 293, 296, 298, 302, 308, 310
WaterSteamPro function description 330, 331
target situation 8–9 well-solvable problems (WSP) 5, 13–16, 18, 24
tasks and subtasks 5, 13–17, 22 wheel 143, 228, 241, 243–250, 253, 255, 259, 263,
3D surfaces 201–203 305–307, 314
Tolstoy 27, 59, 62, 64, 83, 117, 121, 243, 304 WinPython distribution 30
torus 305, 333–334, 347 wolf 139, 147, 228–234, 239
trajectory 83–89, 117, 121, 124, 130, 134–135, 139, WolframAlpha 31–32, 78–79, 106–107, 109
143, 158, 228, 232 Wolfram automaton 335–345
transformation 91, 93, 109, 115, 153, 189, 192–194,
201, 208, 228, 249, 265–266, 270, 279, 283, Zen of Python 7
315, 379, 390, 403 zero-order interpolation 323, 326–327, 329–330
trigonometry, trigonometric 27–28, 30–31, 152,
198, 384
tuple 30, 42–44, 56, 95, 101–102, 113–114, 161, 163,
168–169, 174–178, 183, 185–186, 192, 264,
274, 277, 300, 364, 368, 375, 386

You might also like