Thursday, July 30, 2026

 Drone Fleet motion propagation

Autonomous drone fleet does not have a centralized controller. Motion of the forward section of the fleet must be followed by the backward section of the fleet via propagation of the direction and speed information. This is like linear heat propagation and is best described by Fourier Transforms. Study of the propagation of fleet movement information is necessary to enable the fleet to behave as coordinated as a whole unit. The movement information is mere payload as it can be enriched with many forms of sensor data that can help the fleet to perform actions such as avoiding obstacles, optimizing flight paths and speed, and achieving formation objectives or cost functions. While these actions can be computed locally or in co-ordination by one or more members of the fleet, the propagation of messages is independent of the computation and involves phenomena like heat propagation. This article discusses the wave propagation by Fourier Transforms assuming peer processing of sensor data can be coordinated with consensus algorithms.

A Fast Fourier Transform converts wave form data in the time domain into the frequency domain. It achieves this by breaking down the original time-based waveform into a series of sinusoidal terms, each with a unique magnitude, frequency, and phase. This process converts a waveform in the time domain into a series of sinusoidal functions which when added together reconstruct the original waveform. Plotting the amplitude of each sinusoidal term versus its frequency creates a power spectrum, which is the response of the original waveform in the frequency domain.

The Fourier transform is a generalization of the Fourier series and allows taking any function as a total of simple sinusoids. A functions’ Fourier transform is a complex-valued function denoting the constituent complex sinusoid’s that contain the original function. For every frequency, the magnitude of the complex value denotes the constituent complex sinusoid’s amplitude with that frequency, and the complex value’s argument denotes the phase offset of the complex sinusoid. If a frequency does not exist, the transform possesses a value of zero for that frequency. Functions that are localized in the domain of time have Fourier transforms that extend out across the domain of frequency and vice versa. The Fourier transform of a Gaussian function is always another Gaussian function. The solutions to heat equations are the Gaussian functions.

The Fourier transform can be generalized to functions of various variables on Euclidean space, forwarding a function of three-dimensional position space to a three-dimensional momentum function (or a space and time function to a 4-momentum function). This helps spatial Fourier Transform to be solutions of waves as functions of either momentum or position or both.

When Fourier transforms are applicable, it means the “earth response” now is the same as the “earth response” later. Switching our point of view from time to space, the applicability of the Fourier transformation means that the “impulse response” here is the same as the “impulse response” there. An impulse is a column vector full of zeros with somewhere a one. An impulse response is a column from the matrix q = Bp The collection of impulse responses in q=Bp defines the convolution operation.

The difference between Fourier Transform and Fourier Series is that the Fourier Transform is applicable for non-periodic signals, while the Fourier Series is applicable to periodic signals. The properties of Fourier transform are duality, linear transform, modulation and Parseval’s theorem. Duality implies that if h(t) possesses a Fourier transform H(f), then the Fourier transform related to H(t) is H(-f). Linear Transform implies that if g(t) and h(t) are two Fourier transforms also represented by G(f) and H(f) respectively, then the linear combination of h and g also has a Fourier transform. The modulation property implies that functions are modulated by other functions if they are multiplied in time. Parseval’s theorem states that the Fourier transform is unitary and the sum of the squares of the H(f) equals that of h(t)

While the dominant interest in the application of wave propagation transforms to fleet movement is the duration it takes for the entire fleet to respond, the drone traffic can be taken as a Gaussian distribution and one that can even be treated as an invariant through different formations. This makes it easier to predict the fleet movements.


Sample FFT application:

import numpy as nm

import scipy

import scipy.fftpack

import pylab


def lowpass_cosine( y, tau, f_3db, width, padd_data=True):

    # padd_data = True means we are going to symmetric copies of the data to the start and stop

    # to reduce/eliminate the discontinuities at the start and stop of a dataset due to filtering

    #

    # False means we're going to have transients at the start and stop of the data


    # kill the last data point if y has an odd length

    if nm.mod(len(y),2):

        y = y[0:-1]


    # add the weird padd

    # so, make a backwards copy of the data, then the data, then another backwards copy of the data

    if padd_data:

        y = nm.append( nm.append(nm.flipud(y),y) , nm.flipud(y) )


    # take the FFT

    ffty=scipy.fftpack.fft(y)

    ffty=scipy.fftpack.fftshift(ffty)


    # make the companion frequency array

    delta = 1.0/(len(y)*tau)

    nyquist = 1.0/(2.0*tau)

    freq = nm.arange(-nyquist,nyquist,delta)

    # turn this into a positive frequency array

    pos_freq = freq[(len(ffty)/2):]


    # make the transfer function for the first half of the data

    i_f_3db = min( nm.where(pos_freq >= f_3db)[0] )

    f_min = f_3db - (width/2.0)

    i_f_min = min( nm.where(pos_freq >= f_min)[0] )

    f_max = f_3db + (width/2);

    i_f_max = min( nm.where(pos_freq >= f_max)[0] )


    transfer_function = nm.zeros(len(y)/2)

    transfer_function[0:i_f_min] = 1

    transfer_function[i_f_min:i_f_max] = (1 + nm.sin(-nm.pi * ((freq[i_f_min:i_f_max] - freq[i_f_3db])/width)))/2.0

    transfer_function[i_f_max:(len(freq)/2)] = 0


    # symmetrize this to be [0 0 0 ... .8 .9 1 1 1 1 1 1 1 1 .9 .8 ... 0 0 0] to match the FFT

    transfer_function = nm.append(nm.flipud(transfer_function),transfer_function)


    # plot up the transfer function

    # since "freq" is only the positive frequencies, select out

    pylab.figure(1)

    pylab.clf()

    pylab.plot(freq,transfer_function)

    pylab.xlabel('Frequency [Hz]')

    pylab.ylabel('Filter Transfer Function')

    pylab.xlim([-10.0,10.0])

    pylab.ylim([-0.05,1.05])


    # apply the filter, undo the fft shift, and invert the fft

    filtered=nm.real(scipy.fftpack.ifft(scipy.fftpack.ifftshift(ffty*transfer_function)))


    # remove the padd, if we applied it

    if padd_data:

        filtered = filtered[(len(y)/3):(2*(len(y)/3))]


    # return the filtered data

    return filtered



# do an example of lowpass filtering

# first make some fake data

# a sine wave fluctuating once every pi seconds

# samples 1000 times per second

fakedata = nm.sin(nm.arange(0,11,0.001)) + nm.random.randn(len(nm.arange(0,11,0.001)))/4.0


# run the filter

# lowpass at 5 Hz, with a 1 Hz width of its roll-off

filtered = lowpass_cosine(fakedata,0.001,5.0,1.0,padd_data=True)


# plot the noisy data, with the filtered data on top

pylab.figure(2)

pylab.clf()

pylab.plot(nm.arange(0,11,0.001),fakedata,label='Noisy Data')

pylab.plot(nm.arange(0,11,0.001),filtered,label='Lowpass Filtered Data')

pylab.xlabel('Time [s]')

pylab.ylabel('Voltage')

pylab.legend()


pylab.ion()

pylab.show()



Wednesday, July 29, 2026

 Agentic judges for drone image analytics

Andrew Ng’s agentic workflow pattern—reflection, tool use, planning, and multi-agent collaboration—applies to drone-vision benchmarking. Reflection lets an agent critique and revise detections, captions, SQL answers, or mission reports. Tool use grounds reasoning in retrieval, code execution, geospatial operators, detector APIs, and database queries. Planning decomposes a workload into explicit steps before execution and supports replanning when a probe fails. Multi-agent orchestration assigns specialized roles: one agent checks geospatial consistency, another evaluates temporal coherence, another audits semantic alignment, and an arbiter aggregates evidence into a score.

Memory has been a design constraint. Loops let agents think; graphs let agents remember. A reflection loop can improve a single answer, but without persistent state the agent forgets why it inspected a frame, which detector disagreed, or which workload constraint failed. A graph turns those transient observations into reusable memory: frames, objects, captions, detections, SQL results, tool calls, critiques, and final judgments become linked evidence rather than buried transcript text. In ezbenchmark, this converts an agentic judge from a one-pass evaluator into a stateful audit system.

A practical build path is incremental. First, add one critique call after every generated answer or score; this is the highest-return change because it catches unsupported claims, missing visual evidence, and weak workload alignment before output is finalized. Second, expose the judge to tools: vector retrieval over frame evidence, SQL over the scene catalog, detector re-runs, spatial predicates, and temporal-neighbor comparisons. Third, require the judge to emit a structured plan before execution, such as JSON steps with expected evidence, tool calls, and failure conditions. Fourth, split evaluation across specialized agents and connect them through a shared graph store. The result is not merely a stronger prompt; it is an architecture in which weak models can outperform stronger single-pass models because the workflow supplies iteration, grounding, decomposition, and durable memory.

Agents are usually dedicated to perception, reasoning, and control in different ways. Sapkota et al. introduce the term “Agentic UAVs” to describe systems that integrate perception, cognition, control, and communication into layered, goal-driven agents that operate with contextual reasoning and memory, rather than fixed scripts or reactive control loops [1]. In their framework, aerial image understanding is only one layer in a broader cognitive stack: perception agents extract structure from imagery and other sensors; cognitive agents plan and replan missions; control agents execute trajectories; and communication agents coordinate with humans and other UAVs. This layered view is useful when we start thinking about agentic frameworks as “judges” for benchmarking: the judging capability can itself be an agent, sitting in the cognition layer, consuming outputs from perception agents and workload metadata rather than raw pixels alone [1].

Vision–language–driven agents are a distinct subclass. Sapkota et al. explicitly highlight vision–language models and multimodal sensing as key enabling technologies for Agentic UAVs, noting that they allow agents to parse complex scenes, follow natural-language instructions, and ground symbolic goals in visual context [1]. These agents differ from traditional planners in that they can reason over image and text jointly, which makes them natural candidates for roles like “mission explainer,” “anomaly triager,” or, in our case, “benchmark judge” for aerial analytics workloads. Instead of judging purely from numeric metrics, a vision–language agent can look at a drone scene, read a workload description, inspect candidate outputs, and form a qualitative judgment about which pipeline better captures the intended analytic semantics [1].

#codingexercise: CodingExercise-07-29-2026.docx

Tuesday, July 28, 2026

 

A minimal reproduction: tracking a vehicle by its Fourier signature

Let’s track a red vehicle across a short sequence of aerial drone frames purely from its Fourier-descriptor "shape signature," adapted from the public timfeirg/Fourier-Descriptors approach. The pipeline has three stages, mirroring the detect → describe → match structure of the Seidaliyeva et al. system:

import cv2
import numpy as np

def extract_red_car_contour(image):
    # Convert to HSV and threshold to isolate red color (works for most red cars)
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    # Lower and upper bounds for red in HSV (red wraps around hue 0/180)
    lower_red1 = np.array([0, 70, 50])
    upper_red1 = np.array([10, 255, 255])
    lower_red2 = np.array([170, 70, 50])
    upper_red2 = np.array([180, 255, 255])
    mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
    mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
    mask = mask1 | mask2

    # Morphological operations to clean the mask
    kernel = np.ones((5, 5), np.uint8)
    mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
    mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)

    # Find contours; assume the single largest red blob is the target vehicle
    contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    if contours:
        return max(contours, key=cv2.contourArea), mask
    return None, mask

def compute_fourier_descriptors(contour, num_descriptors=16):
    contour = contour.squeeze()
    # Treat each contour point (x, y) as a complex number z = x + iy
    z = contour[:, 0] + 1j * contour[:, 1]
    # DFT of the boundary sequence
    fd = np.fft.fft(z)
    # Normalize (naive version — see critique below)
    fd = fd[:num_descriptors] / np.abs(fd)
    return fd

def match_descriptors(fd1, fd2):
    return np.linalg.norm(fd1 - fd2)

Each frame's red-vehicle silhouette is boiled down to a 1D closed boundary curve, which is then treated as a discrete complex-valued signal sampled at contour points as the boundary is traced. Applying the 1D DFT, , yields a set of complex Fourier descriptors that jointly reconstruct the exact boundary shape. Truncating to the first num_descriptors low-frequency coefficients (here, 16) retains the coarse silhouette — overall size, elongation, major concavities — while discarding high-frequency terms that mostly encode pixel-level contour jitter and are therefore both noise-dominated and expensive to keep. Two frames' descriptor vectors are then compared with a simple Euclidean distance: a small distance across consecutive frames signals "same object, successfully tracked," while a large jump flags a possible identity switch or lost target — exactly the frame-to-frame association step needed to build a tracklet from raw per-frame detections.

A normalization subtlety worth getting right

The compute_fourier_descriptors function above uses a compact one-line normalization, fd[:num_descriptors] / np.abs(fd), dividing each retained coefficient by its own magnitude. This is a reasonable first pass, and it is invariant to starting point and to overall rotation-and-scale jointly, but it does not deliver the individually decoupled translation, scale, and rotation invariances that Fourier descriptors are prized for in the classical shape-analysis literature, and it silently discards information a more careful normalization would keep. The canonical procedure, going back to Zahn and Roskies' foundational 1972 paper on Fourier descriptors for plane closed curves (Zahn & Roskies, IEEE Trans. Computers, 1972) and formalized for practical implementation by Folkers and Samet (Univ. of Maryland / ICPR 2002), separates the three invariances explicitly:

·        Translation invariance: the DC term is the centroid of the contour (the mean of all boundary points); it carries no shape information at all, only the object's position in the frame. The correct procedure discards or zeroes before comparison rather than folding it into a shared denominator.

·        Scale invariance: dividing every retained coefficient by (the magnitude of the first non-trivial harmonic) rather than by each coefficient's own magnitude normalizes for object size while preserving the relative magnitude relationships between harmonics — which is where the shape information actually lives. Dividing each by its own , as in the code above, forces every normalized coefficient to have magnitude exactly 1, which erases the relative-magnitude structure that distinguishes, say, an elongated silhouette from a compact one.

·        Rotation and starting-point invariance: multiplying every coefficient by a phase correction derived from the phase of (and, for full starting-point invariance, an additional per-harmonic phase term) removes sensitivity to the object's orientation and to which boundary pixel the contour-tracing algorithm happened to start from, without discarding magnitude information the way the naive scheme implicitly risks when phase and magnitude are conflated.

A related normalized-contour-signature approach, useful when descriptors are pooled across a large object gallery, is described in Sokić and colleagues' NCC-signature work (Sokić et al., CBMI 2014). The practical takeaway for anyone adapting the toy pipeline above into a production drone-tracking module is small in code footprint but large in effect: replace the single-line fd / np.abs(fd) normalization with followed by division by and a phase rotation referenced to , which is a handful of extra lines but converts a descriptor that is only jointly invariant under specific conditions into one with the individually decoupled translation-, scale-, and rotation-invariance guarantees the classical Fourier-descriptor literature actually promises — the same guarantees that let the Seidaliyeva et al. system recognize a drone regardless of its heading or distance from the camera.

Suggested fix:

import numpy as np

def compute_fourier_descriptors(contour, num_descriptors=16):

    """

    Compute translation-, scale-, rotation-, and starting-point-invariant

    Fourier descriptors for a closed 2D contour.

 

    Fixes the naive normalization `fd[:num_descriptors] / np.abs(fd)`, which

    only cancels a *combined* rotation+scale ambiguity and leaves the

    translation-encoding DC term and the starting-point ambiguity untouched.

    """

    contour = np.asarray(contour, dtype=np.float64).squeeze()

    if contour.ndim != 2 or contour.shape[1] != 2:

        raise ValueError(f"Expected an (N, 2) contour, got shape {contour.shape}")

 

    N = contour.shape[0]

    if N < 4:

        raise ValueError(f"Contour has only {N} points; need at least a few to be meaningful")

 

    # Treat each contour point (x, y) as a complex number z = x + iy

    z = contour[:, 0] + 1j * contour[:, 1]

 

    # DFT of the boundary sequence: a(k) for k = 0 .. N-1

    a = np.fft.fft(z)

 

    # --- Translation invariance ---

    # a(0) = sum(z) is N times the contour's centroid -- it encodes only

    # position, never shape, so it's discarded rather than folded into a

    # shared denominator (Zahn & Roskies, 1972). a[0] is never referenced below.

 

    # --- Scale invariance ---

    # Divide by |a(1)| (the fundamental harmonic's magnitude), not by each

    # coefficient's own magnitude -- this preserves the *relative* magnitude

    # relationships between harmonics, which is where the shape lives

    # (Folkers & Samet, ICPR 2002).

    a1_mag = np.abs(a[1])

    if a1_mag < 1e-9:

        raise ValueError(

            "First harmonic |a(1)| is ~0 (degenerate or point-symmetric contour); "

            "cannot scale-normalize."

        )

 

    # --- Rotation invariance ---

    # A global rotation by theta multiplies EVERY coefficient by the same

    # constant e^{i*theta} (DFT linearity); that constant phase cancels once

    # we take magnitudes.

    #

    # --- Starting-point invariance ---

    # A different starting point shifts a(k) by a k-dependent, unit-magnitude

    # phase e^{-i*2*pi*k*n0/N} (DFT shift theorem); it too vanishes under

    # magnitude. Together, |a(k)| / |a(1)| is simultaneously rotation- and

    # starting-point-invariant, on top of translation/scale invariance.

    num_harmonics = min(num_descriptors, N - 2)

    descriptors = np.abs(a[2:2 + num_harmonics]) / a1_mag

 

    if num_harmonics < num_descriptors:

        descriptors = np.pad(descriptors, (0, num_descriptors - num_harmonics))

 

    return descriptors

 

 

def match_descriptors(fd1, fd2):

    """Euclidean distance between two (now real-valued) descriptor vectors."""

    return np.linalg.norm(np.asarray(fd1) - np.asarray(fd2))

 

Correction Test Results:

Transform applied to the same shape

Naive distance

Fixed distance

Translated (+137, -52)

3.07

0

Scaled x3.7

0.97

0

Rotated 63°

4.08

0

Scale x0.4 + rotate 205° + translate

6.45

0

Starting point cyclically shifted by 37 samples

5.49

0

All four combined at once

5.82

0

A genuinely different shape (sanity check)

N/A

0.1

 

Sample invocation:

Import cv2
import numpy as np

image_paths = ['frame11.jpg'] # Replace with actual filepaths

red_car_descriptors = []

for image_path in image_paths:

    image = cv2.imread(image_path)

    contour = extract_red_car_contour(image)

    if contour is not None and len(contour) > 10:

        fd = compute_fourier_descriptors(contour)

        red_car_descriptors.append(fd)

        # Compute bounding box

        x, y, w, h = cv2.boundingRect(contour)

        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

        cv2.imwrite(image_path.replace(".jpg","")+"-tracked.jpg", image)

        cv2.imshow('Red Car Tracking', image)

        cv2.waitKey(3000)

 

cv2.waitKey(10000)

cv2.destroyAllWindows()

 

#Codingexercise: Codingexercise-07-28-2026.docx 


Monday, July 27, 2026

  This is a summary of the book titled “AI Engineering” written by “Chip Huyen” and published by O’Reilly in 2025. AI Engineering is about applications not just models. We could learn how to develop models and navigate challenges that might arise during the process, but we must also learn how to adapt a model to a specific need especially when there are choices of models available for download from those skilled at building these. Datasets are another area of emphasis because most models are as good as the data that they operate on. These are some ways in which AI engineering differs from machine learning engineering. AI models require both instructions and information. Enhancing instructions requires “prompt engineering” and enhancing information requires “retrieval-augmented generation” and “agents”. Prompt engineering is human-to-AI communication that is most effective for certain types of tasks. Retrieval-augmented generation aka RAG is primarily used for constructing contexts. Autonomous agents are more versatile. These enhancements reduce errors from “bias” and “hallucinations” which result from incomplete or inaccurate responses. 


AI engineering is a rapidly growing field that focuses on building applications on top of readily available models. Applications like ChatGPT and Google's Gemini and Midjourney require significant amounts of data and electricity to make them powerful and efficient. AI engineering has become one of the fastest-growing engineering disciplines, as demand for AI applications has increased while the barrier to entry for building AI applications has decreased. Training large language model (LLM) AIs requires huge amounts of data and computational power, and self-supervision allows models to infer how to label data based on input data. Foundation AI models, which are trained on enormous amounts of data, can handle a wide range of tasks, such as generating product descriptions or refining descriptions based on customer reviews. AI engineering involves developing applications on top of these foundation models, which are versatile and attract billions in investment. However, evaluating an AI model is challenging, and training foundation models is a complex and expensive endeavor. 


AI models are only as good as the data they were trained on. Poor data quality, such as misinformation and conspiracy theories, can lead to questionable outputs. Training data is limited in language terms, with English being the most common language. Many languages are not even included in the data, making some models more likely to have performance problems when operating in non-English languages. To choose the right foundation model, evaluate applications and determine how to measure their success. Assessing an application's effectiveness in domain-specific capability, generation capability, instruction-following capability, and cost and latency is crucial. Evaluating the moral or ethical status of an application is also important. Finally, there must be distinction between what is wanted and what is needed when assessing models. 


Prompt engineering is the process of creating instructions to achieve desired outputs from an AI model. It involves giving instructions to the model to elicit desired outputs, which can be optimized through statistics and practices like dataset curation. A good prompt should have three features: a broad description of the desired output, relevant examples, and a task to examine a specific text and extract all instances of that type of language. The amount of prompt engineering needed depends on the model's quality and robustness. Context and context length are crucial, with the space available for context length increasing dramatically in recent years. However, good prompt engineering practices are still essential for complex outputs. AI models require instructions and adequate contextual information to complete tasks. Context can be built through retrieval-augmented generation (RAG) and agents, with RAG facilitating information retrieval from independent data sources and agents enabling internet searches for relevant information. 


RAG and agentic patterns are powerful AI models that have captured the collective imagination, leading to incredible demos and products. RAG accesses relevant information from various sources, allowing for detailed and informed query responses and reducing hallucinations. Agents, or intelligent agents, are AI's ultimate aim and can perceive and interact with their environment. RAG and agent systems require prompts and vast amounts of information, sometimes overwhelming a system's memory capacity. However, models can be adapted for specific tasks or industries through additional training. Fine-tuning can enhance domain-specific capabilities and strengthen safety. Customized foundation models often require more up-front investment due to memory demands. Parameter-efficient fine-tuning (PEFT) is a popular method to optimize memory. Transfer learning is an important concept in adapting foundation models in memory-efficient ways, allowing models to learn and be customized with fewer examples, leveraging a good base model. 


A model's performance relies on its training data, and dataset engineering aims to create a customized model within budget constraints. As models become more complex, investment in data and skilled personnel is increasing. AI is becoming more data-centric, focusing on improving performance by enhancing data processing techniques and creating high-quality datasets. Quality data enhances model performance, speed, and contexts, while low-quality data increases errors and biases. Data selection should involve understanding the model's workings and working closely with model and application developers. Minimal amounts of high-quality data are better than massive amounts.



Sunday, July 26, 2026

 A Critical Analysis of Artificial Intelligence and Life in 2030 from the Perspective of 2026


The 2016 Stanford AI100 report, Artificial Intelligence and Life in 2030 attempted forecasting the everyday impact of AI on a typical North American city over the next fifteen years. Now, ten years after publication and four years short of its target date, enough evidence exists to evaluate how its forecasts compare with reality. What emerges is a mixed picture. The report was extraordinarily accurate about the direction of AI development, the centrality of machine learning, the growing importance of data, and the rise of AI across transportation, healthcare, education, public safety, and entertainment. However, it significantly underestimated the speed and scale of generative AI, overestimated progress in physical robotics and autonomous vehicles, and only partially anticipated the political, economic, and cultural disruptions created by large foundation models. The report’s greatest success was identifying AI as an increasingly pervasive infrastructure technology; its greatest failure was not foreseeing that language and content generation would become the dominant public face of AI by 2026.


It correctly predicted the continuing dominance of machine learning and deep learning. In 2016, the authors identified large-scale machine learning, deep learning, natural language processing, reinforcement learning, computer vision, and collaborative human-AI systems as the major research frontiers. That assessment has proven highly accurate. The years since 2016 have seen deep learning become the foundation of virtually every major breakthrough in AI. The current AI landscape is dominated by systems trained on vast datasets using enormous computational resources, precisely the trend the report described. Its claim that AI research was shifting toward systems that collaborate effectively with humans has also proven correct. Today, AI is routinely used as a writing partner, coding assistant, research assistant, tutor, translator, customer-service agent, and creative collaborator. In that sense, the report correctly perceived that the future would not simply consist of autonomous machines replacing humans, but increasingly sophisticated partnerships between humans and AI systems.


Yet the report's account of natural language processing now appears surprisingly conservative. The authors expected dialogue systems to become more capable and machine translation to improve substantially. What they did not anticipate was the emergence of large language models capable of generating essays, software code, summaries, business reports, images, and conversational interactions at a level that would trigger widespread societal debate. The report discussed NLP as a promising subfield aimed at improving dialogue and speech recognition. By 2026, however, generative AI has become one of the defining technologies of the decade. Systems based on transformer architectures, foundation models, and large-scale pretraining have transformed industries ranging from software development to education and media production. This omission is understandable—transformers had not yet been introduced in 2016—but it remains the report's most significant forecasting gap.


Transportation illustrates the opposite pattern: the report accurately identified the direction of change but overestimated its pace. The authors predicted that autonomous transportation would become commonplace, that self-driving vehicles would significantly reshape urban life, and that ownership of personal cars might decline. They also suggested widespread deployment of autonomous trucks, delivery vehicles, and related robotic transport systems. By 2026, progress has been substantial but uneven. Driver-assistance systems have improved dramatically, robotaxi deployments exist in limited geographic areas, and autonomous vehicle technology has advanced far beyond what existed in 2016. However, self-driving transportation has not become commonplace across North American cities. Most people still drive conventional vehicles, urban design remains largely unchanged, parking infrastructure has not become obsolete, and broad public adoption has not occurred. The report underestimated the difficulty of solving edge cases, managing safety concerns, obtaining regulatory approval, and gaining public trust. Its prediction that flying vehicles and advanced autonomous transport would spread widely by 2030 increasingly appears optimistic. Interestingly, the report itself expressed skepticism regarding flying transportation platforms, and that caution now appears justified.


The report's treatment of robotics was generally more accurate than its transportation forecasts. It argued that home and service robots would expand slowly because hardware challenges are fundamentally more difficult than software challenges. This has proven correct. While AI software capabilities have exploded, domestic robotics has advanced incrementally. Robot vacuum cleaners have become more sophisticated, warehouses increasingly use robotic systems, and specialized industrial robots have proliferated. Yet there has been no mass-market revolution in general-purpose household robots. The report repeatedly emphasized that reliable mechanical systems remain expensive and difficult to develop. Ten years later, that observation remains valid.


Healthcare demonstrates another area where the report largely got the direction right while overestimating the speed of institutional adoption. The report envisioned AI-enhanced clinical decision support, improved medical imaging, patient monitoring, predictive analytics, and greater use of electronic health data. Many of these developments have indeed occurred. AI systems now assist with radiology, diagnostics, administrative workflows, transcription, medical documentation, and drug discovery. However, the report also noted that regulatory barriers, trust issues, fragmented data systems, and poor healthcare software infrastructure would impede deployment. Those obstacles remain significant. The prediction that AI would augment clinicians rather than replace them has been validated. Healthcare has become one of the strongest cases supporting the report's broader thesis that AI is more likely to transform tasks than eliminate entire professions.


Education presents a particularly interesting comparison between prediction and reality. The report anticipated greater personalization, intelligent tutoring systems, blended learning, online education, learning analytics, and AI-assisted teaching. All of these trends have emerged. However, once again, the arrival of generative AI changed the landscape in ways the report did not foresee. Rather than educational AI being dominated by tutoring software and learning management systems, students and teachers increasingly use conversational AI systems for writing assistance, research support, coding help, language learning, and individualized explanation generation. The report correctly predicted personalized learning but underestimated the degree to which a single general-purpose AI system could act simultaneously as tutor, encyclopedia, translator, writer, and research assistant.


Perhaps the report's most impressive achievement lies in its discussion of public policy and governance. The authors repeatedly warned that governments would need greater technical AI expertise, that questions of bias and fairness would become central, and that privacy, accountability, transparency, and equitable distribution of benefits would become major policy issues. This forecast has aged exceptionally well. Public debate over algorithmic bias, surveillance, AI safety, disinformation, intellectual property, concentration of power among technology firms, and the economic effects of automation has become central to AI governance worldwide. The report also anticipated concerns about AI amplifying existing inequalities and concentrating wealth among those who control data, computation, and AI infrastructure. Those concerns are now at the center of policy discussions across governments and industries.


Its predictions regarding employment were similarly nuanced. Rather than forecasting mass unemployment, the report argued that AI would primarily replace tasks rather than entire jobs in the short term. That remains broadly true in 2026. Although fears of immediate labor-market collapse have not materialized, AI is steadily reshaping knowledge work, software development, customer support, content creation, marketing, legal review, and administrative functions. The report also raised questions about wealth distribution and the possibility that AI could become a new mechanism for wealth creation concentrated among a small group of actors. A decade later, these concerns appear increasingly relevant.


The report's discussion of entertainment is another area where its predictions were broadly accurate. It correctly anticipated increasingly personalized, interactive, and AI-driven entertainment experiences. Recommendation systems, algorithmically curated content, virtual influencers, AI-generated music, AI-generated imagery, and synthetic media have become commonplace. Yet here, too, the authors underestimated the transformative potential of generative systems capable of creating content on demand. The concept of individuals producing sophisticated media through interaction with AI is now far more developed than the report envisioned.


In retrospect, the report's deepest insight was methodological rather than technological. It rejected the popular narrative of imminent superintelligence and focused instead on gradual, domain-specific, specialized AI systems integrated into everyday life. That judgment remains largely correct. Contrary to sensational fears, no self-aware superintelligence has emerged. AI's influence has spread through thousands of practical applications rather than through a single revolutionary machine. At the same time, the report underestimated how foundation models would unify many previously separate AI capabilities into versatile systems that appear general-purpose to ordinary users.


This report’s forecasts about the importance of machine learning, the growth of healthcare AI, personalized education, algorithmic governance, workplace transformation, and the need for thoughtful policy were largely vindicated. Its principal errors were forecasting too much progress in autonomous transportation and too little progress in generative AI. The report correctly identified most of the forces shaping the AI era but misjudged which applications would become culturally dominant first. From the vantage point of 2026, it stands as an unusually successful technological forecast—one whose omissions are notable precisely because so much else turned out to be right.


Reference: Artificial Intelligence and Life in 2030: https://arxiv.org/pdf/2211.06318 

#codingexercise: Codingexercise-07-26-2026.docx