Math in school has been mostly learning by repetition, like how one trains ML models with supervised learning. Students are given bulk loads of problems and answers to solve until the problems themselves become familiar. That worked up to certain point. In fact, the math of my college freshmen year in Singapore was manageable since most questions were not so different from my high school math.
But can the subject be anything other than homework exercises just to get over with. Someone said that learning math is like learning a new language. To learn a language, one pickup the grammar and the vocabulary, word by word until the whole sentence starts to make sense. The vocabulary of math is the strange notations and symbols that can be daunting to look at. And mathematical materials are not always accessible to untrained eyes since math authors can have assumption of how much readers know. And it is not really their fault since after hundreds of years of development, mathematics has huge body of knowledge.
Also if like a new language, once understood, math can open up insights, meanings and other sort of pleasures. Something enjoyable. I remembered years ago when long English text started to become comprehensible. A new world of views, books, novels followed. So if that same realization can also be experienced with math, I want to give it another try. And who knows if I can become a cool dad once my kid reach school age. I can tell them one thing or two about mathematics that their teachers may not.
So far, I started with the book Programmer introduction to mathematics. The author covers a large breadth of topics with suggested keywords to look up even further. That was too many to take in. Since my purpose was to have an appreciation of math, not to know a lot of math, I needed to narrow it down to a smaller area. I ‘m trying another book Linear algebra done right (suggested by this quora post) and working through the first chapter on vector space.
The book does not start with the familiar cartesian planes and vectors as arrows in a 2D space, though it did mentioned that. Instead, vector spaces are developed by defining the notion of vector spaces as a set of objects (which can be lists as of Euclidean spaces, functions or objects like \(J(\infty)\)) and their addition and scalar multiplication that satsify certain properties like having additive identity, communtativity and associativity of addition…. With this approach, vector spaces are manipulatable. We can define a new vector space over an existing one by defining appropriate addition and scalar multiplication. And we can also have subspaces (a subset of a vector space which is also a vector space).
In a mathematician’s lament, the author argues that, math problems is hard creative work, which should be approached slowly and contemplatively. Thus, there need not be a goal to reach nor an immediate return on the effort. But given that we often push art aside for things more consequential in our day-to-day, that sounds challenging to keep up. Let see how long I can keep this personal project going.
]]>Like in Never Let Me Go, those children become donors and completes. Or in Klara and the Sun, child owners soon grow up and change, leaving robot servants behind. As these stories progress, we may hope for twists and turns that would resolve the tension and avoid sad endings. Yet none came, the tension defuses toward that inevitable. Just that instead of sadness or resentment, it is a sense of gentle acceptance. Kathy receives her first donation notice. And Klara finds herself in the junkyard. And life goes on.
]]>The months of pregnancy and hormonal changes signal the transition into motherhood for mothers, both physically and psychologically. Fathers don’t go through all that. Changes are external. More household chores when wifey was not well. Regular hospital visits for checkups. Getting the house ready. Is it any different from another busy period.
And then the baby will come. And fathers become fathers. No wonder why Ross were shocked by the realization. We weren’t prepared, there was no head-ups in our body to know that our roles in life are changing. And now the role includes responsibility for another human being.
Unprepared and overwhelmed, yes. But no problem. A slow start does not matter that much in such a long race. Father will learn to be father.
]]>>>> a = [None] * 4
>>> a
[None, None, None, None]
Then what about creating a 2D 4x4 array, should it be this:
>>> a = [[None] * 4] * 4
The answer is no. Doing that gives you an array where each row has the same underlying memory.
>>> a[0][1] = 1
>>> a
[[None, 1, None, None], [None, 1, None, None], [None, 1, None, None], [None, 1, None, None]]
Then what is the proper way to initialize a 2D array with each element an independent memory location:
>>> b = [[None] * 4 for i in range(0, 4)]
>>> b[0][1] = 1
>>> b
[[None, 1, None, None], [None, None, None, None], [None, None, None, None], [None, None, None, None]]
>>>
Voila!
]]>But solving an optimization problem is not as simple as plugging the data into the library. The process can be fasten if is assisted with domain knowledge to further prune the search space and to break symmetry. E.g observing the ditribution of warehouses and customers can lead to additional constraints like a customer is unlikely to be assigned to a warehouse that is too far away.

On the other hand, LS starts with a complete configuration which may not be valid. From there, making edits to get closer to a valid solution.
Given the initial solution configuration, make greedy changes to it in order to reach a more optimal state. Being greedy means making decision that optimizes for a local metric that may lead to an lower overall objective value. The local metric is something quick to compute. For example, in the traveling saleman problem (TSP), instead of asking which k edges we can swap to make the total distance decrease, we can look for which are the two longest edges. Now swapping k longest edges does not guarantee a lower overal objective value, but it is easier to calculate.
Sometimes, a greedy optimizer can get stuck jumping back and forth between states. Because deterministic edge selection like the one mentioned above can get into a local optimal state. If an intermidiate state between local and global optimum has a lower objective value, the greedy heuristic will not consider it. We can introduce some randomness or rely on meta-heuristics to address that.
It is fairly straightforward to make edge selection more random. For example, randomly choose an edge to swap with the longest edge. Or simply select 2 random edges. But simply picking random edges can be time consuming. Meta-heuristic methods can help escaping local optima more efficiently.
Meta heuristics approaches like Tabu Search and Simulated Annealing do not only consider the current solution state to make decision. They keep track of the search process to avoid duplicate moves or when to move away from local optima.
When the search space is large even pruning it with constraints does not really help.
]]>Instead of naiively trying out all combinations, CP works by picking a domain value for a decision variable one by one, and at each step, remove unsatisfying branches (prunning) and choose next assignments effectively (searching). When an assignment leads to an infeasible outcome, it backtrack on previous assignments and try next ones.
CP model the problem by definings a set of decision variables (e.g colors[i] a node i in graph coloring), each with its own domain of possible values. Contraints are the conditions these variables need to satisfy. i.e if a node’s color should be different from ones’ that are connected to it:
for u, v in edges:
model.Add(colors[node_u] != colors[node_v])
So if colors[0] is assigned to color 0, 0 is removed from the value domains of nodes that are connected to colors[0], which saves CPU time on infeasible combinations. The earlier in the assignment process a value is removed, the more (exponential) downstream choices are saved.
Besides basic constraints that are required to satisfy the problem goal, other non-primary constraints are often added to help removing unlikely or symmetrical choices faster. Symmetrical choices are changes in variable assignments that are relatively identical. In the case of graph coloring, given connected colors[0] and colors[1], color assignment of 0-1 and 1-0 are the same as actual color values does not matter as much as whether they differ. So to avoid iterating over symmetrical choices, additional constraints can be imposed to further reduce combinations that need to be explored. For example:
# Break the symmetry of colors by ordering them
for i in range(num_nodes):
model.Add(colors[i] <= (i + 1))
Other constraints can be inferred from domain knowledge of the problem. Given N nodes in the graph, the baseline solution is to given each of them a different color, right. Still, the variable domain can be reduced further based on the fact that if a node in the graph has max degree of M, then we won’t need more than M + 1 different colors to color the graph. The smaller the domain, the less combinations to explore.
colors = [model.NewIntVarFromDomain(cp_model.Domain.FromValues(range(max_degree)), f'node{i}') for i in range(num_nodes)]
At each assignment step, after pruning if there are still more choices, CP model needs to pick a not-yet assigned variable and assign to it a value from the possible domain. A few techniques can help.
model.AddDecisionStrategy(colors, cp_model.CHOOSE_FIRST, cp_model.SELECT_MIN_VALUE)
i has a domain of [1,3, 4] possible colors. Each assignment is a possible color that the CP model can assign to variable colors[i]. The model can choose wich branch to explore first by coming up with an optimistic estimation of the cost of each branch and try out the lower cost first.(Example code uses Google OR tool)
]]>Think about the time when you need to re-use a component in multiple screens to accomplish something. For example, to ask the user if she really wants to do something, a popup modal is often deployed across screens. One way to do that is to create a shared ConfirmModal component, and embed it wherever it is needed.
<ConfirmModal open={openConfirmModal}
message={"Are you sure you want to delete X?"}
onAccept={positiveAction}
onCancel={() => setOpenConfirmModal(false)}/>
function dangerousAction() {
setOpenConfirmModal(true);
}
That’s a first step towards DRY. Yet we can take one step further. Notice that, the host component does not need to manage the open/close state of the ConfirmModal. Rather, encapsulate the intent as a single function, and only return to the host page what it cares about.
function dangerousAction() {
const confirm = await confirm('Are you sure you want to delete X?');
if (confirm) {
//... continue with dangerousAction
}
}
Frontend application is stateful. UI components are tied to a set of flags to know if users have clicked on a checkbox or selected another tab. Some state flags are variables that get updated by interrupts (events) triggered by network callback, an interval timer. It’s important to choose a minimum set of flags that reflect your application state. Avoid having state variables that are derivative of another.
This is bad
{
user: User;
isLoggedIn: boolean;
}
isLoggedIn is redundant as its value can be inferred from user. Having it creates responsibility to update variables when needed.
Modern frameworks like Reactjs has built-in constructs to watch for changes in state variable. For example, when users select a new shipping address, another flow should be triggered to update delivery fee. I often see code along the line below, which works most of the time, except for when it does not, it leads to hard to find bug. Object comparison is not exactly the best way to check for changes. And if for some reason, user state data got refetched, the handler would be triggered again.
const selectAddress = () => {
// this function get called somewhere
// ....
setShippingInfo(newAddr);
}
useEffect(() => {
updateCurrentCartShippingFee(shippingInfo);
}, [shippingInfo])
To me, it’s way better to make the flow obvious
const selectAddress = () => {
// ... do something
setShippingInfo(newAddr);
updateCurrentCartShippingFee(newAddr);
}
Developing for UI is often developing with multiple quick iterations. Ideally, one would visualize the UI arrangement in his head and churn out css for as long as possible before having to look at the actual changes. In practice, the frequency of going back and forth between the code editor and the UI is high. Bret Victor, in his talk on inventing on principle, stressed the importance of having an immediate feedback loop when creating. I think it’s especially important for UI development. Maybe it’s part of the reason for web technologies’ presence in areas it’s not initially meant for like desktop & mobile app development. The web’s instant reload is faster to iterate than other frameworks like say Qt.
So, if your development project takes long to refresh UI, view it as a critical problem. Take a look at alternative build tools, or split stable parts of the code into sub-packages that don’t need to be rebuilt everytime.
Often, one component needs to communicate its change to others outside of its hierarchy. Two patterns to go about it:
Website speed is important so it’s better to be frugal on how much scripts get downloaded to the browser. More often than not, someone may add a library which is either bloated or not tree-shake friendly. When people notice the unusual bundle size, it can be a few MRs away from the causing one. Then it would be really hard to filter through past changes. In my experience, having checks that automatically fail pipeline when certain metrics degrade is really helpful.
Despite its popularity, I think React is more suitable for a small team of 2-3 developers than for larger project. It has many ways of doing things for users to decide, and a lot could go wrong if someone is new to the framework. For example, consider useEffect and its dependency array.
const fetchProductData = useHelper();
useEffect(() => {
// ...
fetchProductData();
}, [fetchProductData]);
Linter often suggests adding fetchProductData to the dependency array. But if fetchProductData is not wrapped by an useCallback, it risks pushingg CPU to 99% usage. For the unsuspectful, it’s hard to notice until suffering the pain a few times.
For larger team, I would suggest going with other more opinionated frameworks, say Angular (I have not tried the framework though).
]]>A new kind of virus, which wreaked havoc in Wuhan China since Lunar New Year, has spread out more than two hundred countries in the world. In mere months, more than a million people have suffered from it, tens of thousands died. To divert the trajectory of doom, governments around the world are enforcing social distancing. To save lives, lives must be turned upside down. Schools and businesses are closed, leaving kids at home and their parents with them. In France, people are getting fined or even imprisoned for wandering on the street, further pushing the line of what are acceptable. Leaders and doctors were faced with uncomfortable trade-offs. Pushing businesses into indebtedness and brankruptcy to prevent further deaths. Stories of Italian doctors weeping after pulling ventilators away from old patients to save younger ones circulated social networks. Triaging patients to direct care and resources to those that are most likely to be saved, and would have the longest time to live. This generally accepted utilitarian approach would have appalled many at another time, since it involves weighing lives on an impersonal scale. And it would be getting even more uncomfortable as the death toll decreases and economic damage mounts. People will start asking whether it’s worth the loss.
Among things that are turned upside down by the virus is, with irony, Vietnameses’ predisposition towards the West. Before long, many men and women from this country have strived for opportunities to work abroad and to migrate. European rich cities hold such allure that some accepted the risk of illegal trafficking to get there. But ever since the pandemic threatened to overwhelm medical systems in many European countries, there has been a reverted flow of people scrambling to repatriate. Before international flight route closure, thousands of Vietnamese arrived in Hanoi and HCM city each day. Home sweet home. The splendor of Paris streets was overshadowed by the danger of getting infected without treatment. The reversal does not just stop there. For many westerners, Southeast Asia destinations have always been attractive due to their welcoming locals. Foreigners were often regarded with keen interest as they were not only pleasantly different but also a highly valued revenue source. But since Europe has the virus pretty much out of control, the locals have shied away from anyone who looks caucasian. It was sad to hear stories of foreigners turned away by hotels. Hopefully, this temporary reversal of attitude won’t do too much damage to local tourism.
For many of us, fortunate enough to avoid infection and lay-off, last few weeks were mostly about dealing with confinement. Staying inside is not necessary a burden. Some people, me among them, prefer occasional solitude and appreciate being away from crowds. Yet, there seem to be a limit to it all. My friend, a dance instructor, once said that she felt like something was crumbling inside even though her work was going well despite the lockdown. Evolution has not changed our deeply wired need to be in pack and to be outside. Maybe there is some merit in the way state media portraying stay-at-home citizens as warriors in the war against Covid-19. We don’t fight against the virus, but rather against our visceral urge to go out when the day is nice and fair, which is harder than it sounds. Individualism and personalities have been valued in this age of Youtube celebs and influencers. Yet, never before has standing in line been this appreciated. Unfortunate souls, who had contracted the virus and had their itinerary laid bare for all to see, would attract scorn from the esteemed public for what could have been normal needs, e.g attending a wedding, visiting a clinic. Impersonal time indeed. An upside is that one can start on books that one has always wanted to read, chat up friends, or try on new hobby. My mom has found this a great opportunity to bake since everyone is around more often. When the legs laze, the mouth works.
So far the experience has been like hitting the brake when you are on highway. Activities come to a grinding halt. Everyday around the globe, someone somewhere lost her loved one. Death is an addition to the ever increasing number of casualties. For some, the prolonged calamity means suspended plans, unfulfilled promises. For others, it means shutting down businesses, letting employees go. The impact on society and on individuals will be long lasting. A silver lining of this circumstance is that people are brought closer together. Parents spending more times with their kids. Food giveaway booths are set up to help the poor. Let’s hope that better day will come.
]]>The pandemic makes people ill but measures in place to stop it is what are disrupting daily lives. One may pin his hope on the seasonality of the disease. As the weather gets warmer, the pandemic may eventually subside, giving the world’s economy a break. Yet, even if that’s the case, the virus may inflict far more damage in its wake than financial losses during temporary shutdowns. The short acute shock from the pandemic can lead to systematic failure of the market if borrowing has reached an unsustainable level. Right before the outbreak, the world has enjoyed almost 11 consecutive years of economic expansion. Yet a year before that, I remember reading forboding The Economist’s articles anticipating a coming recession, given the cyclicity of the world economy. Despite anticipation of market crash, macroeconomic indicators had been better than ever. Inflation had been well-behaved and unemployment in the U.S had been at record low. The problem with that is, investors and consumers could have come to feel a false sense of security, believing that good time would last forever, and thus increase debt-powered spendings. Loans are often collaterized with marked-to-market assets, and companies estimate their ability to service the loans based on good time profit. An unexpected event like covid-19 is all it needs to temporarily shrink firms’ profit, creates a shortage of cash which, making loans unservicable for companies. A few panicking investors sell their stocks, depressing assets’ prices. Depreciating collaterals force banks to sell, thus, further depress prices, creating a self-reinforcing downward sprial.
This is what is happening in stock market now. Two weeks ago, when news of patient no. 17 surfaced, investors anticipated worsening pandemic situation and started to sell off their shares. As assets’ prices went down hill, investors who had used borrowed money to buy stocks were forced to liquidate their positions. And not to mention investors who would jump in the action to avoid further loss. That was the opposite of economics 101, lower prices in the asset market did not trigger an increase in demand. Rather, demand dried up as a result of lower prices. This brought me some personal pain as I watched VNDirect’s dashboard covered in red. And market decline has not shown any sign of stop. Though, a choice to buy stocks now should be less risky than before covid-19 outbreak when the risk was not visible.
One lesson is that, had one looked at only inflation or unemployment rate, one would not have thought that the economy is doing very well. However, its ability to withstand occasional shocks is questionable. George Cooper suggested in his book Origin of financial crises that rather than traditional macroeconomic indicators, central banks should look at debt level and the cost of borrowing to guage the health of the economy.
Hanoi’s streets are still filled with motobikes and cars, as busy as ever. The usually inefficent system of reckless scooter drivers turn out to be pretty resilient in stressful time. Would this pandemic happen 10 years later, after Hanoi has managed to ban scooters, people would have a much harder time going around. Not everybody could afford a car and crowded public buses could be virus hot beds. Though public transportation is nice, the city would do better by encouraging bicycle riding as an active mode of going around. In time of stress, being able to travel at will can be very helpful.
Companies, including mine, are tinkering with work-from-home policies. Though VTV aired a section praising businesses moving to remote-working direction, I think it is by no mean a smooth transition for Vietnamese businesses. Working from home requires a certain level of trust in employees in order to work. I feel that that trust level is not really high and there are reasons for that. But I do hope that, when the pandemic subsides, firms do not write off working from home unworkable. Rather they should see it as necessary, build permanent policies and train their employees to work remotely on a more regular basis. Trust takes time.

The week right after when the patient no.17 was hospitalized, fear gripped the whole nation and my trip to Én cave was due. I got cold feet and wanted to postpone it but it was too late for rescheduling, and went ahead with the plan I did. Streets of Phong Nha was empty, and I was the only one staying in that twenty-plus room guest house. Suddenly, anyone could be a potential virus carrier, but forgetting that fact for a moment, then the trip was really enjoyable. Weather was nice, and one has all the space to himself, food was good. Nothing to complain about.
]]>