text:
Every Machine Learning (ML) product should reach its final stage: the deployment to production.

We all know that there is a lot of hype around the ML-based solutions (or with even more hype, the “AI-powered” solutions) and that everyone claims to have some fancy model in production. More than often, this is false1 and the development of the ML-based solution stops at the Jupiter Notebook where the scientists/researchers did their job.

Some lucky model, however, reaches the final stage - or because the management had a great plan (see video below), or because the model performed well and it passed all the QA steps.

>
We have a great plan: deploy everything to production right now!

Unfortunately, there isn’t a plethora of examples containing information on how to deploy a model to production and how to design the model environment for the production: all we can find is a bunch of articles on Medium that stops at the measurement of some metric on the validation set (some good person, at least, measures the performance on the test set).

In this article, I’m going to cover these points using TensorFlow 2 as the framework of choice and Go as the target language for the deployment - and training!

The Gopher (created by Takuya Ueda (@tenntenn). Licensed under the Creative Commons 3.0 Attributions license)
overlapping the Tensorflow Logo.

Note: the topic of deployment to production is broad and way more complex than what it’s presented in this article - in this article we can find the general guidelines for the design of the model, how to properly export and use a SavedModel, and how to deploy a model using Go - that’s fine for a small project, but it’s not representative of the real complexity of the whole MLOps pipeline (that not required, in any case, for the great majority of the ML projects - most of them, especially the project targeted for dedicated devices, can follow a simpler pipeline similar to the one presented in the article).

## Human Activity Recognition

Let’s start with the most important advice: do not use Machine Learning if the problem you’re trying to solve can be solved with a decent accuracy with some good heuristic - or even worse, if the problem is solvable with a deterministic algorithm (it’s crazy, but we have to stress this since everyone is now throwing machine learning to every problem, even when it’s completely useless).

In our case, the problem we want to solve is human activity recognition from sensor data. We want to use data coming from an accelerometer to predict the activity the user is currently performing.

We want to first train the model on some labeled data and afterward use the deployed model to do incremental learning. With incremental learning we intend the continuous update of the model parameters (on the deployed model!), using new (labeled) data.

We suppose the user is wearing a generic “device” equipped with an accelerometer. This device is also our target deployment platform. We also suppose that the target device is able to run a Go program since we decided to use Go as target language.

The accelerometer gives us the acceleration values along the 3-axis, and the device accompany the acceleration data with the timestamp. Formally we have the endless acquisition $$A = (a_1, a_2, \cdots,)$$ where $$a_i = (x_i, y_i, z_i, t_i)$$ is a tuple with acceleration $$(x_i, y_i, z_i) [\frac{m}{s^2}]$$ at instant $$t_i$$.

Luckily, there is a public domain dataset containing this kind of data we can use for running this simulation. The WISDM dataset introduced in the paper Activity Recognition using Cell Phone Accelerometers is our choice.

The (raw) dataset contains the following features:

• user: An unique identifier of the user doing the activity.
• activity: The label for the current row. We have six different categories: walking, jogging, upstairs, downstairs, sitting, and standing.
• timestamp: the time step $$t_i$$ in which the accelerometer acquired the data.
• (x, y, z): the acceleration values along the 3 axes (at the time step $$t_i$$).

The process of data acquisition has been documented and we have a nice YouTube video showing it:

The Smartlab has developed a new publicly available database of daily human activities that has been recorded using accelerometer and gyroscope data from a waist-mounted Android-OS smartphone (Samsung Galaxy S II). The six studied activities are: Walking, Walking Upstairs, Walking Downstairs, Sitting, Standing and Laying down.
In the video the red color is the X axis, green for Y and blue for Z.

Note: in the real scenario, starting from a public domain dataset it might be the correct choice if the domain of application is very very similar and the process of transfer learning / fine-tuning is thus applicable. Otherwise, if you have some raw data without labels and you don’t have any ready-to-use dataset, perhaps it is worth to annotate the raw data - it can save you a lot of time in the long run.

Looking at the dataset structure, we can see we have a CSV file (WISDM_ar_v1.1_raw.txt) that contains all the features previously described:

ID Activity Timestamp X Y Z
33 Jogging 49105962326000 -0.6946377 12.680544 0.50395286;
33 Jogging 49106062271000 5.012288 11.264028 0.95342433;
33 Jogging 49106112167000 4.903325 10.882658 -0.08172209;

As we can see, the final value contains a ; that should be removed. However, to make the processing more fun, instead of doing it in Python, we’ll do it using Go - as well as the training phase (!).

Note: The article contains the full training process (without metric measurement, model selection, and so on) in Go, just to show how it’s possible to export into a SavedModel very complex functions and how to design the tf.Module for this task. However, the correct training procedure (with dataset split, validation, metric measurement, model selection, and cross-validation) it’s the recommended path to follow and to do in Python.

## Model definition

There are tons of architecture that can solve this task pretty well: we have RNNs and bidirectional-RNNs that are the standard de-facto for time series classification. In this article we don’t focus that much on the architecture since it’s not the main topic - we’ll use an RNN just to have a small model and to train it easily. Perhaps a bidirectional-RNN would be better since the architecture takes into account the future data (w.r.t. the current timestep $$t_i$$).

We define this dummy model using the Keras Sequential API: the idea is to do not reset the state of the model until we change the activity - in this way we can train the RNN making it see the complete sequence of sensor data per activity and per user.

In order to be production-oriented - that in this context means to be ready to export the model itself - we define it inside a tf.Module. Placing the model inside a tf.Module is not required if we are interested in exporting only the model, because the Keras API supports it out of the box. However, since we are interested in exporting the training loop we want to put the model, the training step, and all the required dependencies for the training (and inference) inside a tf.Module.

import sys

import tensorflow as tf
import tensorflow.keras as k

class ActivityTracker(tf.Module):
def __init__(self):
super().__init__()

self.num_classes = 6  # activities in the training set
self.num_features = 3  # sensor (x,y,z)

# NOTE: we need a fixed batch size because the model has a state
self.batch_size = 32
self._model = k.Sequential(
[
k.layers.Input(
shape=(1, self.num_features),
batch_size=self.batch_size,
),
# Note the stateful=True
# we'll reset the states and the end of the per-user activity sensor data
k.layers.LSTM(64, stateful=True),
k.layers.Dense(self.num_classes),
]
)

The model, I repeat, is dummy - but I won’t be surprised if that simple model is able to solve the problem as well.

In the __init__ method, we also want to add all the stateful objects, because as explained in Analyzing tf.function to discover AutoGraph strengths and subtleties - part 1: Handling states breaking the function scope when we convert the eager code to its graph representation, every Python tf.Variable definition defines a new graph node, but we don’t want to create a new node every time we invoke a function

Note: We must design our production-oriented code in this way from the beginning, always thinking about the graph representation, otherwise we’ll find ourselves rewriting everything from scratch in a final rush when it’s time to deploy.

Moreover, we also want to add to the tf.Module all the objects we want to serialize together with the model. Thus, since we are interested in serializing the whole training loop, we add:

• The optimizer (self._optimizer)
• The loss function (self._loss)
• The training steps counter (self._global_step)
• A variable containing the last tracked activity - we use this variable to reset the model state when it’s the right time (self._last_tracked_activity)
• A handy StaticHashTable that maps the scalars $$[0, 6[$$ to the corresponding textual representation of the labels.
        self.mapping = tf.lookup.StaticHashTable(
tf.lookup.KeyValueTensorInitializer(
keys=tf.range(self.num_classes, dtype=tf.int32),
values=[
"Walking",
"Jogging",
"Upstairs",
"Downstairs",
"Sitting",
"Standing",
],
),
"Unknown",
)

self._global_step = tf.Variable(0, dtype=tf.int32, trainable=False)
self._optimizer = k.optimizers.SGD(learning_rate=1e-4)
# Sparse, so we can feed the scalar and get the one hot representation
# From logits so we can feed the unscaled (linear activation fn)
# directly to the loss
self._loss = k.losses.SparseCategoricalCrossentropy(from_logits=True)

self._last_tracked_activity = tf.Variable(-1, dtype=tf.int32, trainable=False)

All the stateful objects and utility attributes have been defined, we are now ready to define two graphs:

1. The training step: this graph is just a single training step.
2. The inference: this graph takes the input and returns a single prediction (the label resulting from the prediction over the whole input timesteps).

Before defining the graph, first a small digression about tf.function

## All in graph

As explained in part 1, part 2, and part 3 of the article Analyzing tf.function to discover AutoGraph strengths and subtleties and summarized in the talk Dissecting tf.function to discover AutoGraph strengths and subtleties we have to design our functions thinking about the graph representation, otherwise we will have a hard time to convert our code to its graph-convertible counterpart.

The second most important thing to remember (the first one is how to deal with functions that create a state) is that we have to use as many TensorFlow primitive operations as we can, instead of using the Python one. In fact, the Python code is executed during the first invocation of the function (with a certain input and type, as explained in the previously linked articles) and the function execution is traced while the tf.Graph get’s created.

Thus, when we define our train step graph and inference graph, we’ll use all the tf.* operation instead of the Python operations (e.g. tf.range instead of range, tf.assert instead of assert, …).

## Train step graph & SignagureDef

We want to design our learn function as a training step over a batch of data. We have to be sure that all the data in the batch is data coming from the same activity (thus they all have the same label), and we want to take care of the state of the training by changing the value of self._last_tracked_activity if the current batch is labeled as a new activity (respect to the previously seen batch), and resetting the RNN state.

The training step is pretty common so we won’t focus on it (the code is pretty clear), but the interesting part of the snippet below is the tf.function decoration with the input_signature specification, together with the return value (the loss) that’s a dict.

Defining the input_signature of a tf.function-decorated function is mandatory to correctly export the function as a graph in the SavedModel.

A SavedModel contains a complete TensorFlow program, including weights and computation. It does not require the original model building code to run, which makes it useful for sharing or deploying2

Without this specification, the SavedModel will contain only a section called “functions” that are not usable outside of a Python environment.

The input_signature parameter must define the input shape and type we require for the graph. Since this is a training step, we need a batch of data with shape $$(\text{None}, 1, 3)$$ since we want to feed this data to an RNN one observation at a time, where every observation is composed by the $$(x,y,z)$$ values of the sensor data.

The return value of this function is the loss value, wrapped in a dictionary. Wrapping it in a dictionary is not mandatory, but it’s recommended.

Defining the input_signature parameter of tf.function together with the usage of a dictionary to create a pair (key, value) for the return value, is the process of definition of the so-called SignatureDef.

A SignatureDef defines the signature of a computation supported in a TensorFlow graph. SignatureDefs aim to provide generic support to identify inputs and outputs of a function and can be specified when building a SavedModel.

More information about the SignatureDef are available in the TFX tutorial: SignatureDefs in SavedModel for TensorFlow Serving

    @tf.function(
input_signature=[
tf.TensorSpec(shape=(None, 1, 3), dtype=tf.float32),
tf.TensorSpec(shape=(None,), dtype=tf.int32),
]
)
def learn(self, sensor_data, labels):
# All the sensor data should be about the same activity
tf.assert_equal(labels, tf.zeros_like(labels) + labels[0])

# If the activity changes, we must reset the RNN state since the last update
# and the current update are not related.

if tf.not_equal(self._last_tracked_activity, labels[0]):
tf.print(
"Resetting states. Was: ",
self._last_tracked_activity,
" is ",
labels[0],
)
self._last_tracked_activity.assign(labels[0])
self._model.reset_states()

with tf.GradientTape() as tape:
loss = self._loss(labels, self._model(sensor_data))
tf.print(self._global_step, ": loss: ", loss)

return {"loss": loss}

The definition of the training loop in Python, with the creation of the tf.data.Dataset object, the proper validation, and model selection of the best model is left as an exercise to the reader :)

We will cover the training part directly in Go - but here’s a spoiler: it won’t be persistent on the disk, because the support Go side (and tfgo side) is not completed yet - that’s why I recommend doing the complete training in Python (want to contribute? continue reading the article, find the tfgo repository link and let’s talk there!).

## The inference graph

The inference graph SignatureDef definition follows the very same rules used for the train step graph - the only difference is in the input/output parameters of course. In this case, we want to return the majority class predicted for the set of activities in the batch.

In this function, we also use the mapping created in the __init__ to print the textual representation of the prediction.

    @tf.function(input_signature=[tf.TensorSpec(shape=(None, 1, 3), dtype=tf.float32)])
def predict(self, sensor_data):
predictions = self._model(sensor_data)
predicted = tf.cast(tf.argmax(predictions, axis=-1), tf.int32)
tf.print(self.mapping.lookup(predicted))
return {"predictions": predicted}

Note: printing in the graph is not recommended (although it’s very useful to understand what’s going on) because it’s a side effect that the target platform/language should handle and perhaps is not always easy to do it.

## Export everything as a SavedModel

After having defined everything inside a tf.Module and having correctly decorated the functions we want to export as graphs, all we need to do is to use the tf.saved_model.save function.

Since we are exporting a tf.Module we have to remember that the default behavior is to do not export the serving signature defs (that are handy entry points inside the SavedModel that tools like saved_model_cli and to Go bindings (and all the others) can use to load the correct graph from the SavedModel), and thus we have to explicit the signatures by ourselves.

Important: the process of graph creation is executed only after the function execution is traced, we have to run the functions with some dummy input (but with the correct shape and dtype).

def main() -> int:
at = ActivityTracker()

# Executing an invocation of every graph we want to export is mandatory
at.learn(
tf.zeros((at.batch_size, 1, 3), dtype=tf.float32),
tf.zeros((at.batch_size), dtype=tf.int32),
)
at.predict(tf.zeros((at.batch_size, 1, 3), dtype=tf.float32))

tf.saved_model.save(
at,
"at",
signatures={
"learn": at.learn,
"predict": at.predict,
},
)

return 0

if __name__ == "__main__":
sys.exit(main())

Saving the file as export.py and executing it with python export.py we end up with the at folder inside our current working directory that contains our SavedModel.

## SavedModel inspection

Before jumping in the Go code and defining the training loop and using the graphs we just defined, we have to analyze the SavedModel created to see:

• The exported tag (that’s by default one, the "serve" tag)
• The exported graphs
• The input/output tensor to use to feed the graph / get the results.

The tool to use is saved_model_cli that comes with the Python installation of TensorFlow.

saved_model_cli show --all --dir at

The CLI tool gives us this information:

signature_def['learn']:
The given SavedModel SignatureDef contains the following input(s):
inputs['labels'] tensor_info:
dtype: DT_INT32
shape: (-1)
name: learn_labels:0
inputs['sensor_data'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 1, 3)
name: learn_sensor_data:0
The given SavedModel SignatureDef contains the following output(s):
outputs['loss'] tensor_info:
dtype: DT_FLOAT
shape: ()
name: StatefulPartitionedCall_1:0
Method name is: tensorflow/serving/predict

signature_def['predict']:
The given SavedModel SignatureDef contains the following input(s):
inputs['sensor_data'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 1, 3)
name: predict_sensor_data:0
The given SavedModel SignatureDef contains the following output(s):
outputs['predictions'] tensor_info:
dtype: DT_INT32
shape: (-1, 1)
name: StatefulPartitionedCall_2:0
Method name is: tensorflow/serving/predict

We have our 2 SignatureDef defined previously, with the input name taken from the input parameters name, and the output is taken from the keys in the return dict we used (loss and predictions).

Note: we are interested in the name section of every input/output. This name is the name of the tf.Tensor that we have to use to feed the model (for the inputs) or for getting the result (for the output nodes). The :0 (or in general :<suffix>) is a progressive number that indicates how many outputs the operation (a tf.Operation is a node that produces 0 or more tf.Tensor) produces.

## The simulation of the real case scenario

In this article, we simulate the real scenario in which we suppose the user wears this device equipped with an accelerometer.

1. The user device gathers the data during an activity.
2. At the end of the activity, we perform an inference step and try to label the sensor data (Observations) received.
3. We ask the user if the predicted label is the correct one. If it’s not, we ask the user to choose the correct label.
4. With the data and the label, we perform a training step to adapt the model parameters to the user-generated data.

In this way, in the long run, the model will predict the correct label for the tracked activity, even if the user exhibits an unusual pattern in the observations (this might be the case of people with disabilities or athletes).

But first, we perform the training directly in Go :)

Note: as anticipated, the persistence of the trained model is not possible for now, thus it’s better to train the model in Python - in the article we’ll show, however, how it’s possible to train a model from Go (the persistence part needs your help!)

## Training and Inference in Go with tfgo

The setup of the Go environment and the installation of the TensorFlow’s C library goes beyond the scope of this article and it won’t get covered.

I just leave a link to the project I maintain, tfgo, that allows not to install the official TensorFlow Go package (because it’s not go-gettable, see #39307, #41808, #35133) and it gives to you, as a dependency automatically installed by go get, a working version of the tensorflow package together with all the features exposed by the tfgo package.

Just a small note, the fork that is automatically installed when go-getting tfgo is just a fork of the TensorFlow repository (branch r2.3) that contains all the compiled protobuf files needed to make go-gettable the package.

From the SavedModel inspection, we know everything we need to use the graphs we defined.

We begin with the various import we’ll use throughout the main package, and we start with the definition of the Observation struct that maps a row of the dataset to a Go type, and the of the batchSize constant (that should be as such because the RNN is stateful).

package main

import (
"encoding/csv"
tg "github.com/galeone/tfgo"
tf "github.com/tensorflow/tensorflow/tensorflow/go"
"io"
"log"
"math/rand"
"os"
"strconv"
"strings"
"time"
)

type Observation struct {
ID        int
Activity  string
Label     int32
Timestamp time.Time
X         float32
Y         float32
Z         float32
}

const batchSize int = 32

We can now start wrapping the model graphs using the *tfgo.Model functions. The predict function is pretty easy and it doesn’t require any explanation, just note that we extract with model.Op the operation names (followed by the suffix 0 in this case) from the graph, and we use these operations to get the Tensors to use for the model input/output.

// predict invokes the predict method of the model and returns the majority class
// predicted for the input batch.
//
// model: the *tg.Model to use
// sensorData: a tf.Tensor with shape (32, 1, 3)
func predict(model *tg.Model, sensorData *tf.Tensor) int32 {
predictions := model.Exec([]tf.Output{
model.Op("StatefulPartitionedCall_2", 0),
}, map[tf.Output]*tf.Tensor{
model.Op("predict_sensor_data", 0): sensorData,
})[0].Value().([][]int32)

for i := 0; i < len(predictions); i++ {
}

var maxVote int = -1
var topLabel int32 = 0
for label, vote := range votes {
if vote > maxVote {
maxVote = vote
topLabel = label
}
}
}

The predict function works on the raw *tf.Tensor, so we can define a utility function observationsToTensor and hide the raw *tf.Tensor with a new Predict function that works, instead, with a batch of observations.

func observationsToTensor(observations [batchSize]Observation) *tf.Tensor {

var sensorData [batchSize][1][3]float32
size := len(observations)
if size < batchSize {
log.Fatalf("Observations size %d < batch size %d", size, batchSize)
}

for i := 0; i < size; i++ {
sensorData[i][0] = [3]float32{observations[i].X, observations[i].Y, observations[i].Z}
}

var err error
var sensorTensor *tf.Tensor

if sensorTensor, err = tf.NewTensor(sensorData); err != nil {
log.Fatal(err)
}

return sensorTensor
}

func Predict(model *tg.Model, observations [batchSize]Observation) int32 {
sensorData := observationsToTensor(observations)
return predict(model, sensorData)
}

To Go code is really easy to read and understand, the only peculiarity is that we must always use the Go type that corresponds to the correct type expected by the graph, otherwise the *tg.Model.Exec call will panic. The panic is caused by the underlying TensorFlow C library that returns an error code and the model just forwards the error message to the caller.

The same reasoning must be applied in the opposite direction: the invocation of *tf.Tensor.Value() returns an interface{} type and we must access the underlying value doing the correct type assertion to avoid panics.

We can do the very same reasoning for the training graph. We have in our SavedModel a graph that’s a training step, and we can use it in the very same way we use the prediction graph.

// learn runs an optimization step on the model, using a batch of values
// coming from the same observed activity.
// NOTE: all the observations must have the same label in the same batch.
//
// model: the *tg.Model to use
// sensorData: a tf.Tensor with shape (32, 1, 3)
// labels: a tf.Tensor with shape (32)
func learn(model *tg.Model, sensorData *tf.Tensor, labels *tf.Tensor) float32 {
loss := model.Exec([]tf.Output{
model.Op("StatefulPartitionedCall_1", 0),
}, map[tf.Output]*tf.Tensor{
model.Op("learn_sensor_data", 0): sensorData,
model.Op("learn_labels", 0):      labels,
})[0]

return loss.Value().(float32)
}

func Learn(model *tg.Model, observations [batchSize]Observation) float32 {
var sensorData [batchSize][1][3]float32
var labels [batchSize]int32

for i := 0; i < batchSize; i++ {
sensorData[i][0] = [3]float32{observations[i].X, observations[i].Y, observations[i].Z}
labels[i] = observations[i].Label
}

var err error
var sensorTensor *tf.Tensor
var labelTensor *tf.Tensor

if sensorTensor, err = tf.NewTensor(sensorData); err != nil {
log.Fatal(err)
}
if labelTensor, err = tf.NewTensor(labels); err != nil {
log.Fatal(err)
}

return learn(model, sensorTensor, labelTensor)

}

We now have all we need to define the training function we use to run one epoch of training.

### Training loop definition in Go

Our goal is to parse every row of the training set (CSV), skip errors that ARE present in the dataset structure, and use the Observation to train the model.

We can start, thus, defining the NewObservation constructor that instantiates an *Observation from a []string and a map that contains the mapping ID -> textual label.

func NewObservation(record []string, mapping map[string]int32) (*Observation, error) {
var err error
var id int
if id, err = strconv.Atoi(record[0]); err != nil {
return nil, err
}

activity := strings.ToLower(record[1])

var sec int
if sec, err = strconv.Atoi(record[2]); err != nil {
return nil, err
}

var x, y, z float64

if x, err = strconv.ParseFloat(record[3], 32); err != nil {
return nil, err
}

if y, err = strconv.ParseFloat(record[4], 32); err != nil {
return nil, err
}

if z, err = strconv.ParseFloat(strings.TrimRight(record[5], ";"), 32); err != nil {
return nil, err
}

return &Observation{
ID:        id,
Activity:  activity,
Label:     mapping[activity],
Timestamp: time.Unix(int64(sec), 0),
X:         float32(x),
Y:         float32(y),
Z:         float32(z),
}, nil
}

The training loop can now be easily defined: we build the batch, run the training step, and assure that every value in the batch has the same label (and comes from the same user).

func train(model *tg.Model, datasetPath string, mapping map[string]int32) {
var err error
var filePtr *os.File

if filePtr, err = os.Open(datasetPath); err != nil {
log.Fatal(err)
}

defer func() {
if err := filePtr.Close(); err != nil {
log.Fatalf("close: %s", err)
}
}()

var record []string

var user int
var label int32

var observations [32]Observation

for {
if err == io.EOF {
break
}

if err != nil {
log.Fatal(err)
}

var o *Observation
if o, err = NewObservation(record, mapping); err != nil {
log.Printf("Skipping observation %v", record)
continue
}
// Set the user for the current set of observations
// The user and the label must be the same for all the training batch
if read == 1 {
user = o.ID
label = o.Label
}

if user != o.ID || label != o.Label {
if user != o.ID {
log.Printf("Changing user %d -> %d\n", user, o.ID)
}
if label != o.Label {
log.Printf("Changing label %d -> %d\n", label, o.Label)
}
user = o.ID
label = o.Label
}

if read == batchSize {
Learn(model, observations)
}
}
}

Here we go: we are ready to invoke our train function and use Go to train the model.

func main() {
mapping := map[string]int32{
"walking":    0,
"jogging":    1,
"upstairs":   2,
"downstairs": 3,
"sitting":    4,
"standing":   5,
}

var model tg.Model = *tg.LoadModel("at", []string{"serve"}, nil)

train(&model, "WISDM_ar_v1.1/WISDM_ar_v1.1_raw.txt", mapping)

Running the code written so far, we can see the training loop working, the internal states changing, and everything going as expected :)

I highlight again that this is just an example to show how to design a training loop with TensorFlow and Go - it lacks all the minimal features we need for correct training.

## Simulating the user interaction

The user interaction is just simulated and also the sensor data is randomly generated, however, in the following lines of code, we can see how easy it by using Go to receive the observations from a chan and do a prediction over this received data.

The prediction is sent back over a channel to be displayed to the user, and if the user accepts (or changes the label) the new training data is sent to a go-routine that invokes the Learn function with this new set of observations, to iteratively refine the model and customizing it on the user behavior.

	// With a trained model, we are ready to receive other observations
// and use them to train it during its lifetime.

observations := make(chan Observation, batchSize)
prediction := make(chan int32, 1)

go func() {
var obs [batchSize]Observation
for i := 0; i < batchSize; i++ {
obs[i] = <-observations
}

prediction <- Predict(&model, obs)
// requeue all the observations in the same channel
// in order to let other routines to use the same
// observations (for training with the predicted/adjusted label)
for i := 0; i < batchSize; i++ {
observations <- obs[i]
}

}()

done := make(chan bool, 1)
go func() {
// This is an example of a real case
// where the sensor is gathering some data
// and the user labels it (perhaps after our model suggestion that
// can be used as a hint for the user to set the label :) ).

// This function generates the data of the activity
// and sends a batch of this data in the observation channel.

// On the other side of the channel we have the model waiting
// for this data, that sends back a suggested label and waits for a
// user confirmation.

// Generate sensor data

var min, max float32 = 1, 10
rand.Seed(time.Now().UnixNano())

for i := 0; i < batchSize; i++ {
x := min + rand.Float32()*(max-min)
y := min + rand.Float32()*(max-min)
z := min + rand.Float32()*(max-min)

observations <- Observation{
Timestamp: time.Now(),
X:         x,
Y:         y,
Z:         z,
}
}

predictedLabel := <-prediction
log.Printf("predicted label: %d", predictedLabel)

// In the real case, the predicted label is asked for
// confirmation to the user and if the user accepts the suggestion
// the model is trained with the current set of the observations
// and the confirmed label (or the new label given by the user)

var obs [batchSize]Observation
for i := 0; i < batchSize; i++ {
obs[i] = <-observations
obs[i].Label = predictedLabel
}

Learn(&model, obs)
// Here we terminarte the application, but in the real scenario
// this is an endless loop with frequent checkpoints
// and model versioning.
done <- true
}()

<-done

}

The code contains some (I hope helpful) comments to understand how to organize the message exchange and the whole application in the real scenario.

The complete go code is available here: device.go.

## Conclusion

Designing code that can be exported as a SavedModel requires thinking about the graph representation - every production-oriented ML code should be designed with the graph in mind.

The SavedModel format contains a TensorFlow program: it’s not limited to the model inference, we can save everything that’s graph-convertible inside it. We have to take care of the SignatureDef and the peculiarities of tf.Module but this comes with the great advantage of being able to deploy this tf.Module everywhere.

Using tfgo it’s possible to have a working version of the official tensorflow go package, with a single go get, together with all the additional features of tfgo.

It’s possible to train a model in Go (although not recommended until we can save the status of a SavedModel) and in general, it’s really easy to use any graph defined inside a tf.Module if it has been correctly designed and exported.

The Go Philosophy of “Don’t communicate by sharing memory; share memory by communicating” fits well with the interactions that an ML model has with its deploy environment, especially if we are interested in incremental learning.

Disclaimer: The actual Python code executed in the article is not an RNN but I replaced the RNN with a Dense layer. Not for my choice but because TensorFlow has an open bug with the deployment of RNNs that should be addressed ASAP in my opinion (after all, this bug is preventing the deployment of stateful RNNs :S): #44428 - unfortunately the bug is still open and not addressed after 29 days (at the time of writing).

1. https://venturebeat.com/2019/07/19/why-do-87-of-data-science-projects-never-make-it-into-production/ “87% of data science projects never make it into production”

2. https://www.tensorflow.org/guide/saved_model


text:
## On the value of time…essence of time management

Time is Life.

Money lost can come back, but time lost can never come back. Time is more valuable than money. (Bertrand Russell).

## Mathematics versus Physics

The object of pure Physics is the unfolding of the laws of the intelligible world; the object of pure Mathematic that of unfolding the laws of human intelligence. — J. J. Sylvester.

In my opinion, for example, Boole’s Laws of (Human) Thought.

## An observation about Sir Isaac Newton

Newton’s patience was limitless. Truth, he said much later, was the offspring of silence and meditation. And, he said, I keep the subject constantly before me and wait till the first dawnings open slowly, by little and little into a full and clear light.

## Applications of Derivatives IITJEE Maths tutorial: practice problems part IV

Question 1.

If the point on $y = x \tan {\alpha} - \frac{ax^{2}}{2u^{2}\cos^{2}{\alpha}}$, where $\alpha>0$, where the tangent is parallel to $y=x$ has an ordinate $\frac{u^{2}}{4a}$, then what is the value of $\alpha$?

Question 2:

Prove that the segment of the tangent to the curve $y=c/x$, which is contained between the coordinate axes is bisected at the point of tangency.

Question 3:

Find all the tangents to the curve $y = \cos{(x+y)}$ for $-\pi \leq x \leq \pi$ that are parallel to the line $x+2y=0$.

Question 4:

Prove that the curves $y=f(x)$, where $f(x)>0$, and $y=f(x)\sin{x}$, where $f(x)$ is a differentiable function have common tangents at common points.

Question 5:

Find the condition that the lines $x \cos{\alpha} + y \sin{\alpha} = p$ may touch the curve $(\frac{x}{a})^{m} + (\frac{y}{b})^{m}=1$.

Question 6:

Find the equation of a straight line which is tangent to one point and normal to the point on the curve $y=8t^{3}-1$, and $x=4t^{2}+3$.

Question 7:

Three normals are drawn from the point $(c,0)$ to the curve $y^{2}=x$. Show that c must be greater than 1/2. One normal is always the x-axis. Find c for which the two other normals are perpendicular to each other.

Question 8:

If $p_{1}$ and $p_{2}$ are lengths of the perpendiculars from origin on the tangent and normal to the curve $x^{2/3} + y^{2/3}=a^{2/3}$ respectively, prove that $4p_{1}^{2} + p_{2}^{2}=a^{2}$.

Question 9:

Show that the curve $x=1-3t^{2}$, and $y=t-3t^{3}$ is symmetrical about x-axis and has no real points for $x>1$. If the tangent at the point t is inclined at an angle $\psi$ to OX, prove that $3t= \tan {\psi} +\sec {\psi}$. If the tangent at $P(-2,2)$ meets the curve again at Q, prove that the tangents at P and Q are at right angles.

Question 10:

Find the condition that the curves $ax^{2}+by^{2}=1$ and $a^{'}x^{2} + b^{'}y^{2}=1$ intersect orthogonality and hence show that the curves $\frac{x^{2}}{(a^{2}+b_{1})} + \frac{y^{2}}{(b^{2}+b_{1})} = 1$ and $\frac{x^{2}}{a^{2}+b_{2}} + \frac{y^{2}}{(b^{2}+b_{2})} =1$ also intersect orthogonally.

More later,

Nalin Pithwa.

## Applications of Derivatives: IITJEE Maths tutorial problem set: III

Slightly difficult questions, I hope, but will certainly re-inforce core concepts:

1. Prove that the segment of the tangent to the curve $y=c/x$ which is contained between the co-ordinate axes, is bisected at the point of tangency.
2. Find all tangents to the curve $y=\cos{(x+y)}$ for $-\pi \leq x \leq \pi$ that are parallel to the line $x+2y=0$.
3. Prove that the curves $y=f(x)$, where $f(x)>0$ and $y=f(x)\sin(x)$, where $f(x)$ is a differentiable function, have common tangents at common points.
4. Find the condition that the lines $x\cos{\alpha} + y \sin{\alpha}=p$ may touch the curve $(\frac{x}{a})^{m} + (\frac{y}{b})^{m}=1$.
5. If $p_{1}$ and $p_{2}$ are lengths of the perpendiculars from origin on the tangent and normal to the curve $x^{2/3} + y^{2/3}=a^{2/3}$ respectively, prove that $4p_{1}^{2}+p_{2}^{2}=a^{2}$.
6. Show that the curve $x=1-3t^{2}$, $y=t-3t^{3}$ is symmetrical about x-axis and has no real points for $x>1$. If the tangent at the point t is inclined at an angle $\psi$ to OX, prove that $3t = \tan{\psi} + \sec{\psi}$. If the tangent at $P(-2,2)$ meets the curve again at Q, prove that the tangents at P and Q are at right angles.
7. A tangent at a point $P_{1}$ other than $(0,0)$ on the curve $y=x^{3}$ meets the curve again at $P_{2}$. The tangent at $P_{2}$ meets the curve at $P_{3}$ and so on. Show that the abscissae of $P_{1}, P_{2}, \ldots, P_{n}$ form a GP. Also, find the ratio of area $\frac{\Delta P_{1}P_{2}P_{3}}{area \hspace{0.1in} P_{2}P_{3}P_{4}}$.
8. Show that the square roots of two successive natural numbers greater than $N^{2}$ differ by less than $\frac{1}{2N}$.
9. Show that the derivative of the function $f(x) = x \sin {(\frac{\pi}{x})}$, when $x>0$, and $f(x)=0$ when $x=0$ vanishes on an infinite set of points of the interval $(0,1)$.
10. Prove that $\frac{x}{(1+x)} < \log {(1+x)} < x$ for $x>0$.

More later, cheers,

Nalin Pithwa.

## Applications of Derivatives: Tutorial: IITJEE Maths: Part II

Another set of “easy to moderately difficult” questions:

1. The function $y = \frac{}x{1+x^{2}}$ decreases in the interval (a) $(-1,1)$ (b) $[1, \infty)$ (c) $(-\infty, -1]$ (d) $(-\infty, \infty)$. There are more than one correct choices. Which are those?
2. The function $f(x) = \arctan (x) - x$ decreases in the interval (a) $(1,\infty)$ (b) $(-1, \infty)$ (c) $(-\infty, -\infty)$ (d) $(0, \infty)$. There is more than one correct choice. Which are those?
3. For $x>1$, $y = \log(x)$ satisfies the inequality: (a) $x-1>y$ (b) $x^{2}-1>y$ (c) $y>x-1$ (d) $\frac{x-1}{x}. There is more than one correct choice. Which are those?
4. Suppose $f^{'}(x)$ exists for each x and $h(x) = f(x) - (f(x))^{2} + (f(x))^{3}$ for every real number x. Then, (a) h is increasing whenever f is increasing (b) h is increasing whenever f is decreasing (c) h is decreasing whenever f is decreasing (d) nothing can be said in general. Find the correct choice(s).
5. If $f(x)=3x^{2}+12x-1$, when $-1 \leq x \leq 2$, and $f(x)=37-x$, when $2. Then, (a) $f(x)$ is increasing on $[-1,2]$ (b) $f(x)$ is continuous on $[-1,3]$ (c) $f^{'}(2)$ doesn’t exist (d) $f(x)$ has the maximum value at $x=2$. Find all the correct choice(s).
6. In which interval does the function $y=\frac{x}{\log(x)}$ increase?
7. Which is the larger of the functions $\sin(x) + \tan(x)$ and $f(x)=2x$ in the interval $(0?
8. Find the set of all x for which $\log {(1+x)} \leq x$.
9. Let $f(x) = |x-1| + a$, if $x \leq 1$; and, $f(x)=2x+3$, if $x>1$. If $f(x)$ has local minimum at $x=1$, then $a \leq$ ?
10. There are exactly two distinct linear functions (find them), such that they map $[-1,1]$ and $[0,2]$.

more later, cheers,

Nalin Pithwa.

## Applications of Derivatives: Tutorial Set 1: IITJEE Mains Maths

“Easy” questions:

Question 1:

Find the slope of the tangent to the curve represented by the curve $x=t^{2}+3t-8$ and $y=2t^{2}-2t-5$ at the point $(2,-1)$.

Question 2:

Find the co-ordinates of the point P on the curve $y^{2}=2x^{3}$, the tangent at which is perpendicular to the line $4x-3y+2=0$.

Question 3:

Find the co-ordinates of the point $P(x,y)$ lying in the first quadrant on the ellipse $x^{2}/8 + y^{2}/18=1$ so that the area of the triangle formed by the tangent at P and the co-ordinate axes is the smallest.

Question 4:

The function $f(x) = \frac{\log (\pi+x)}{\log (e+x)}$, where $x \geq 0$ is

(a) increasing on $(-\infty, \infty)$

(b) decreasing on $[0, \infty)$

(c) increasing on $[0, \pi/e)$ and decreasing on $[\pi/e, \infty)$

(d) decreasing on $[0, \pi/e)$ and increasing on $[\pi/e, \infty)$.

Fill in the correct multiple choice. Only one of the choices is correct.

Question 5:

Find the length of a longest interval in which the function $3\sin(x) -4\sin^{3}(x)$ is increasing.

Question 6:

Let $f(x)=x e^{x(1-x)}$, then $f(x)$ is

(a) increasing on $[-1/2, 1]$

(b) decreasing on $\Re$

(c) increasing on $\Re$

(d) decreasing on $[-1/2, 1]$.

Fill in the correct choice above. Only one choice holds true.

Question 7:

Consider the following statements S and R:

S: Both $\sin(x)$ and $\cos (x)$ are decreasing functions in the interval $(\pi/2, \pi)$.

R: If a differentiable function decreases in the interval $(a,b)$, then its derivative also decreases in $(a,b)$.

Which of the following is true?

(i) Both S and R are wrong.

(ii) Both S and R are correct, but R is not the correct explanation for S.

(iii) S is correct and R is the correct explanation for S.

(iv) S is correct and R is wrong.

Indicate the correct choice. Only one choice is correct.

Question 8:

For which of the following functions on $[0,1]$, the Lagrange’s Mean Value theorem is not applicable:

(i) $f(x) = 1/2 -x$, when $x<1/2$; and $f(x) = (1/2-x)^{2}$, when $x \geq 1/2$.

(ii) $f(x) = \frac{\sin(x)}{x}$, when $x \neq 0$; and $f(x)=1$, when $x=0$.

(iii) $f(x)=x |x|$

(iv) $f(x)=|x|$.

Only one choice is correct. Which one?

Question 9:

How many real roots does the equation $e^{x-1}+x-2=0$ have?

Question 10:

What is the difference between the greatest and least values of the function $f(x) = \cos(x) + \frac{1}{2}\cos(2x) -\frac{1}{3}\cos(3x)$?

More later,

Nalin Pithwa.

## Applications of Derivatives: A Quick Review

Section I:

The Derivative as a Rate of Change

In case of a linear function $y=mx+c$, the graph is a straight line and the slope m measures the steepness of the line by giving the rate of climb of the line, the rate of change of y with respect to x.

As x changes from $x_{0}$ to $x_{1}$, y changes m times as much:

$y_{1}-y_{0}=m(x_{1}-x_{0})$

Thus, the slope $m=(y_{1}-y_{0})(x_{1}-x_{0})$ gives the change in y per unit change in x.

In more general case of differentiable function $y=f(x)$, the difference quotient

$\frac{f(x+h)-f(x)}{x+h-x} = \frac{f(x+h)-f(x)}{h}$, where $h \neq 0$

give the average rate of change of y (or f) with respect to x. The limit as h approaches zero is the derivative $dy/dx = f^{'}(x)$, which can be interpreted as the instantaneous rate of change of f with respect to x. Since, the graph is a curve, the rate of change of y can vary from point to point.

Velocity and Acceleration:

Suppose that an object is moving along a straight line and that, for each time t during a certain time interval, the object has location/position $x(t)$. Then, at time $t+h$ the position of the object is $x(t+h)$ and $x(t+h)-x(t)$ is the change in position that the object experienced during the time period t to $t+h$. The ratio

$\frac{x(t+h)-x(t)}{t+h-t} = \frac{x(t+h)-x(t)}{h}$

gives the average velocity of the object during this time period. If

$\lim_{h \rightarrow 0} \frac{x(t+h)-x(t)}{h}=x^{'}(t)$

exists, then $x^{'}(t)$ gives the instantaneous rate of change of position with respect to time. This rate of change of position is called the velocity of the object. If the velocity function is itself differentiable, then its rate of change with respect to time is called the acceleration; in symbols,

$a(t) = v^{'}(t) = x^{''}(t)$

The speed is by definition the absolute value of the velocity: speed at time t is $|v(t)|$

If the velocity and acceleration have the same sign, then the object is speeding up, but if the velocity and acceleration have opposite signs, then the object is slowing down.

A sudden change in acceleration is called a jerk. Jerk is the derivative of acceleration. If a body’s position at the time t is $x(t)$, the body’s jerk at time t is

$j = \frac{da}{dt} = \frac{d^{3}x}{dt^{3}}$

Differentials

Let $y = f(x)$ be a differentiable function. Let $h \neq 0$. The difference $f(x+h) - f(x)$ is called the increment of f from x to $x+h$, and is denoted by $\Delta f$.

$\Delta f = f(x+h) - f(x)$

The product $f^{'}(x)h$ is called the differential of f at x with increment h, and is denoted by $df$

$df = f^{'}(x)h$

The change in f from x to $x+h$ can be approximated by $f^{'}(x)h$:

$f(x+h) - f(x) = f^{'}(x)h$

Tangent and Normal

Let $y = f(x)$ be the equation of a curve, and let $P(x_{0}, y_{0})$ be a point on it. Let PT be the tangent, PN the normal and PM the perpendicular to the x-axis.

The slope of the tangent to the curve $y = f(x)$ at P is given by $(\frac{dy}{dx})_{(x_{0}, y_{0})}$

Thus, the equation of the tangent to the curve $y = f(x)$ at $(x_{0}, y_{0})$ is $y - y_{0} = (\frac{dy}{dx})_{(x_{0}, y_{0})}(x-x_{0})$

Since PM is perpendicular to PT, it follows that if $(\frac{dy}{dx})_{(x_{0}, y_{0})} \neq 0$, the slope of PN is

$- \frac{1}{(\frac{dy}{dx})_{(x_{0}, y_{0})}} = - (\frac{dx}{dy})_{(x_{0}, y_{0})}$

Hence, the equation of the normal to the curve $y = f(x)$ at $(x_{0}, y_{0})$ is

$y - y_{0} = - (\frac{dx}{dy})_{(x_{0}, y_{0})}(x-x_{0})$

The equation of the normal parallel to the x-axis is $y = y_{0}$, that is, when $(\frac{dy}{dx})_{(x_{0}, y_{0})} = 0$. The length of the tangent at $(x_{0}, y_{0})$ is PT, and it is equal to

$y_{0}\csc{\theta} = y_{0}\sqrt{1+\cot^{2}{\theta}} = y_{0}\sqrt{1+[(\frac{dx}{dy})_{(x_{0}, y_{0})}]^{2}}$

The length of the normal is PN and it is equal to $y_{0}\sec {\theta} = y_{0}\sqrt{1 + [(\frac{dy}{dx})_{(x_{0}, y_{0})}]^{2}}$

If the curve is represented by $x = f(t)$ and $y = g(t)$, that is, parametric equations in t, then

$\frac{dy}{dx} = \frac{g^{'}(t)}{f^{'}(t)}$ where $g^{'}(t)= \frac{dy}{dt}$ and $f^{'}(t) = \frac{dx}{dt}$. In this case, the equations of the tangent and the normal are given by

$y - g(t) = \frac{g^{'}(t)}{f^{'}(t)}[x - f(t)]$ and $[y-g(t)] g^{'}(t) + [x-f(t)]f^{'}(t) = 0$ respectively.

The Angle between Two Curves

The angle of intersection of two curves is defined as the angle between the two tangents at the point of intersection. Let $y = f(x)$ and $y=g(x)$ be two curves, and let $P(x_{0}, y_{0})$ be their point of intersection. Also, let $\psi$ and $\phi$ be the angles of inclination of the two tangents with the x-axis, and let $\theta$ be the angle between the two tangents. Then,

$\tan {\theta} = \frac{\tan{\phi}-\tan{\psi}}{1+\tan{\phi}\tan{\psi}} = \frac{g^{'}(x) - f^{'}(x)}{1+f^{'}(x)g^{'}(x)}$

Example 1:

Write down the equations of the tangent and the normal to the curve $y = x^{3} - 3x + 2$ at the point $(2,4)$.

Solution 1:

$\frac{dy}{dx} = 3x^{2}-3 \Longrightarrow \frac{dy}{dx}_{(2,4)} = 3.4 - 3 = 9$.

Hence, the equation of the tangent at $(2,4)$ is given by $y-4 = 9(x-2) \Longrightarrow 9x-y-14=0$ and the equation of the normal is $y - 4 = (-1/9)(x-2) \Longrightarrow x+9y -38=0$.

Rolle’s Theorem and Lagrange’s Theorem:

Rolle’s Theorem:

Let $f(x)$ be a function defined on a closed interval $[a,b]$ such that (i) f(x) is continuous on $[a,b]$, (ii) f(x) is derivable on $(a,b)$, and (iii) f(a) = f(b). Then, there exists a $c \in (a,b)$ such that $f^{'}(x)=0$.

For details, the very beautiful, lucid, accessible explanation in Wikipedia:

https://en.wikipedia.org/wiki/Rolle%27s_theorem

Lagrange’s theorem:

Let $f(x)$ be a function defined on a closed interval $[a,b]$ such that (i) $f(x)$ is continuous on $[a,b]$, and (ii) $f(x)$ is derivable on $(a,b)$. Then, there exists a $c \in [a,b]$ such that

$f^{'}(c) = \frac{f(b)-f(a)}{b-a}$

Example 2:

The function $f(x) = \log {\sin(x)}$ satisfies the conditions of Rolle’s theorem on the interval $[\frac{\pi}{6}, \frac{5\pi}{6}]$, as the logarithmic function and $\sin (x)$ are continuous and differentiable functions and $\log {\sin (\frac{5\pi}{6})} = \log {\sin (\pi - \frac{\pi}{6})} = \log{\sin{(\frac{\pi}{6})}}$.

The conclusion of Rolle’s theorem is given at $c=\frac{\pi}{2}$, for which $f^{'}(c) = \cot (c) = \cot (\pi/2) =0$.

Rolle’s theorem for polynomials:

If $\phi(x)$ is any polynomial, then between any pair of roots of $\phi(x)=0$ lies a root of $\phi^{'}(x)=0$.

Monotonicity:

A function $f(x)$ defined on a set D is said to be non-decreasing, increasing, non-increasing and decreasing respectively, if for any $x_{1}, x_{2} \in D$ and $x_{1} < x_{2}$, we have $f(x_{1}) \leq f(x_{2})$, $f(x_{1}) < f(x_{2})$, $f(x_{1}) \geq f(x_{2})$ and $f(x_{1}) > f(x_{2})$ respectively. The function $f(x)$ is said to be monotonic if it possesses any of these properties.

For example, $f(x) = e^{x}$ is an increasing function, and $f(x)=\frac{1}{x}$ is a decreasing function.

Testing monotonicity:

Let $f(x)$ be continuous on $[a,b]$ and differentiable on $(a,b)$. Then,

(i) for $f(x)$ to be non-decreasing (non-increasing) on $[a,b]$ it is necessary and sufficient that $f^{'}(x) \geq 0$ ($f^{'}(x) \leq 0$) for all $x \in (a,b)$.

(ii) for $f(x)$ to be increasing (decreasing) on $[a,b]$ it is sufficient that $f^{'}(x)>0$ ($f^{'}(x)<0$) for all $x \in (a,b)$.

(iii) If $f^{'}(x)=0$ for all x in $(a,b)$, then f is constant on $[a,b]$.

Example 3:

Determine the intervals of increase and decrease for the function $f(x)=x^{3}+2x-5$.

Solution 3:

We have $f^{'}(x) = 3x^{2}+2$, and for any value of x, $3x^{2}+2>0$. Hence, f is increasing on $(-\infty, -\infty)$. QED.

The following is a simple criterion for determining the sign of $f^{'}(x)$:

If $a,b \geq 0$, then $(x-a)(x-b)>0$ iff $x > \max (a,b)$ or $x < \min(a,b)$;

$(x-a)(x-b)<0$ if and only if $\min(a,b) < x < \max(a,b)$

Maxima and Minima:

A function has a local maximum at the point $x_{0}$ if the value of the function $f(x)$ at that point is greater than its values at all points other than $x_{0}$ of a certain interval containing the point $x_{0}$. In other words, a function $f(x)$ has a maximum at $x_{0}$ if it is possible to find an interval $(\alpha, \beta)$ containing $x_{0}$, that is, with $\alpha < x_{0} < \beta$, such that for all points different from $x_{0}$ in $(\alpha, \beta)$, we have $f(x) < f(x_{0})$.

A function $f(x)$ has a local minimum at $x_{0}$ if there exists an interval $(\alpha, \beta)$ containing $x_{0}$ such that $f(x) > f(x_{0})$ for $x \in (\alpha, \beta)$ and $x \neq x_{0}$.

One should not confuse the local maximum and local minimum of a function with its largest and smallest values over a given interval. The local maximum of a function is the largest value only in comparison to the values it has at all points sufficiently close to the point of local maximum. Similarly, the local minimum is the smallest value only in comparison to the values of the function at all points sufficiently close to the local minimum point.

The general term for the maximum and minimum of a function is extremum, or the extreme values of the function. A necessary condition for the existence of an extremum at the point $x_{0}$ of the function $f(x)$ is that $f^{'}(x_{0})=0$, or $f^{'}(x_{0})$ does not exist. The points at which $f^{'}(x)=0$ or $f^{'}(x)$ does not exist, are called critical points.

First Derivative Test:

(i) If $f^{'}(x)$ changes sign from positive to negative at $x_{0}$, that is, $f^{'}(x)>0$ for $x < x_{0}$ and $f^{'}(x)<0$ for $x > x_{0}$, then the function attains a local maximum at $x_{0}$.

(ii) If $f^{'}(x)$ changes sign from negative to positive at $x_{0}$, that is, $f^{'}(x)<0$ for $x, and $f^{'}(x)>0$ for $x > x_{0}$, then the function attains a local minimum at $x_{0}$.

(iii) If the derivative does not change sign in moving through the point $x_{0}$, there is no extremum at that point.

Second Derivative Test:

Let f be twice differentiable, and let c be a root of the equation $f^{'}(x)=0$. Then,

(i) c is a local maximum point if $f^{''}(c)<0$.

(ii) c is a local minimum point if $f^{''}(c)>0$.

However, if $f^{''}(c)=0$, then the following result is applicable. Let $f^{'}(c) = f^{''}(c) = \ldots = f^{n-1}(c)=0$ (where f^{r} denotes the rth derivative), but $f^{(n)}(c) \neq 0$.

(i) If n is even and $f^{(n)}(c)<0$, there is a local maximum at c, while if $f^{(n)}(c)>0$, there is a local minimum at c.

(ii) If n is odd, there is no extremum at the point c.

Greatest/Least Value (Absolute Maximum/Absolute Minimum):

Let f be a function with domain D. Then, f has a greatest value (or absolute maximum) at a point $c \in D$ if $f^(x) \leq f(c)$ for all x in D and a least value (or absolute minimum) at c, if $f(x) \geq f(c)$ for all x in D.

If f is continuous at every point of D, and $D=[a,b]$, a closed interval, the f assumes both a greatest value M and a least value m, that is, there are $x_{1}, x_{2} \in [a,b]$ such that $f(x_{1})=M$ and $f(x_{2})=m$, and $m \leq f(x) \leq M$ for every $x \in [a,b]$.

Example 4:

a) $y=x^{2}$, with domain $(-\infty, \infty)$. This has no greatest value; least value at $x=0$

b) $y=x^{2}$ with domain $[0,2]$. This has greatest value at $x=2$ and least value at $x=0$.

c) $y=x^{2}$ with domain $(0,2]$. This has greatest value at $x=2$ and no least value.

d) $y=x^{2}$ with domain $(0,2)$. This has no greatest value and no least value.

Some other remarks:

The greatest (least) value of continuous function $f(x)$ on the interval $[a,b]$ is attained either at the critical points or at the end points of the interval. To find the greatest (least) value of the function, we have to compute its values at all the critical points on the interval $(a,b)$, and the values $f(a), f(b)$ of the function at the end-points of the interval, and choose the greatest (least) out of the values so obtained.

We will continue with problems on applications of derivatives later,

Nalin Pithwa.

format: plain


text:
# Links in comments do not work if they contain space before dollar and also square brackets inside MathJax

The format [text](url) is the standard format for using links in the comments. And it works just fine even if the text contains MathJax.

Normally, adding spaces inside MathJax do not influence the end result. However, it seems that if inside the MathJax we have [...] then spaces can cause link not to be rendered correctly. (I have noticed this when there is space before the last dollar in the title of the link. But possible there are also some other situations.) I will also explicitly mention that I am aware of the fact that if [ or ] are used outside of MathJax, they have to be escaped.

To include some example: Both [Divisibility in $\mathbb{Z}[X]$](https://math.stackexchange.com/q/3179896) Divisibility in $$\mathbb{Z}[X]$$ and [Divisibility in $\mathbb{Z}[X]$](https://math.stackexchange.com/q/3179896) Divisibility in $$\mathbb{Z}[X]$$ both work correctly in a post, but in a comment the latter does not work. (See the comments below this post and also a screenshot showing how they are displayed at the moment.)

Even if this is not going to be fixed, at least I would like to know whether I can count on the fact that the comments that work correctly now will be rendered the same in the future. (Not too long ago there was change in the Stack Exchange software which caused many comments to be rendered rather differently than they looked at the time when they were posted. So I am basically asking for assurance that similar problem will not come up with comments with hyperlinks containing MathJax.)

EDIT: It's possible that this is related to this problem with MarkDown in comments: Trailing spaces on comment link format. (See also: Why is mini-markdown working in some of my comments, but broken in others? An answer there says: "you have extra leading or trailing spaces in some of them, which are no longer allowed. It's by design because of tricksters who wish to subvert the minimum character comment input.".)

• Test: [Divisibility in $\mathbb{Z}[X]$](https://math.stackexchange.com/q/3179896) works: Divisibility in $\mathbb{Z}[X]$. However: [Divisibility in $\mathbb{Z}[X]$](https://math.stackexchange.com/q/3179896) [Divisibility in $\mathbb{Z}[X]$](math.stackexchange.com/q/3179896). – Martin Sleziak Aug 22 '19 at 9:50
• Test without MathJax: Although these formats both work in a post, in comments we have to escape square brackets: [Divisibility in Z$X$](https://math.stackexchange.com/q/3179896) Divisibility in Z[X] and [Divisibility in Z[X]](https://math.stackexchange.com/q/3179896) [Divisibility in Z[X]](math.stackexchange.com/q/3179896). – Martin Sleziak Aug 22 '19 at 9:51
• Test what happens to links from the first comment if we add backslash: [Divisibility in $\mathbb{Z}$X$$](https://math.stackexchange.com/q/3179896) Divisibility in $\mathbb{Z}$X$$ and [Divisibility in $\mathbb{Z}$X$$](https://math.stackexchange.com/q/3179896) Divisibility in $\mathbb{Z}[X]$. – Martin Sleziak Aug 22 '19 at 9:52
• $$\text{Divisibility in }\mathbb{Z},\left [X\right ]$$ – user645636 Sep 15 '19 at 22:19
• ${\text{Divisibility in }\mathbb{Z},\left [X\right ]}$ second one in case my first didn't leave the space. – user645636 Sep 17 '19 at 12:54


text:
1. ## definite integrations

Integral of [sqrt(t)*ln t]dt from 1 to 4.
I tried to do substitution but I think I am doing it wrong

u = ln t
du/dt = 1/t
tdu = dt

the square root in the original problem is confusing me. can someone help?
thanks

2. Did you try, integration by parts?

3. Originally Posted by Krizalid
Did you try, integration by parts?
oh wow I forgot about that. thank you lol, i got the answer


text:
# Math Help - Infimum and supremum

1. ## Infimum and supremum

I dont understand the infimum and supremum. Could someone please explain these terms. I have the definitions and don't quite understand the full meaning. Maybe explain using an example such as proving the infimum and supremum on the interval (a,b). An example always helps.

2. I'll only try to give intuition for the supremum, and in $\mathbb R$. The infimum is pretty much the same deal

Imagine you have a set $X$ in $\mathbb R$. It is legitimate to ask whether this set has a maximum element or not, that is: is there an element $s$, belonging to $X$, such that $s\geq x$ for all other $x\in X$? This element may or may not exist.

Example 1: $[a,b]$, where $a has a maximum element: $b$.

Example 2: $]a,b[$, does not have a maximum element. You can get as close to $b$ as you wish, but there is no "end point".

Example 3: $]a,\infty[$ does not have a maximum element.

Now let's take a closer look at example 2. If we were to define a "generalized maximum" concept, it would be extremely tempting to say the "generalized maximum" of $]a,b[$ is $b$, since, as we've stated, we can get as close to $b$ as we wish... we're just... missing the point itself!

What property then, does $b$ have, that makes us want to choose it as the "generalized maximum"? And, since we want to generalize the notion of maximum, we want to define this new concept in such a way that $b$ is also a "generalized maximum" in example 1.

Instead of thinking of the intervals $[a,b]$ and $]a,b[$, we then think of the set of all upper bounds of $[a,b]$ and $]a,b$ respectively, and observe that, in both cases, $b$ is the minimum of the corresponding sets of upper bounds. We take that as a definition: we say that an element $b$ is a supremum of a set $X$ if $b$ is the least upper bound of $X$.

And of course, we may think of the supremum of $X$ as a value that is bigger than all elements of $X$, and is "infinitely" close to $X$. It may, or may not belong to $X$ itself. If it does belong, we are in the case of example 1: the set has a maximum. If it doesn't, we're in the case of example 2.

Finally observe that example 3 does not have a supremum either. There is no fixed value that is greater than all others of the interval.

Let me know if it was of any help ^^

4. Thank you that really helps!

5. Originally Posted by summerset353
I dont understand the infimum and supremum. Could someone please explain these terms. I have the definitions and don't quite understand the full meaning. Maybe explain using an example such as proving the infimum and supremum on the interval (a,b). An example always helps.
The official definition for the supremum is the following:

If S is a set such that $S\neq\emptyset$ and $S\ subset R$ then,

.................SupS = v iff..............

1) for all,x: if xεS ,then $x\leq v$

2) for all ε>0 there exists a yεS ,such that v-ε<y $\leq v$

The first condition tell us that v is an upper bound and the second that v is the least upper bound.

Now can you use the above fefinition and prove that Sup(a,b) = b??

The definition for infemum is similar


text:
## Explain Vibratory Plate Compactor Compaction Equipment

The vibratory plate compactor is mainly used for compaction of different type of soils in narrow and restricted areas where it is not possible or economical to use large compaction equipment. The different types of compaction equipment used in compaction project depend on the scope of work. It is used for compaction of coarse soils with 4 to 8% fines. Compaction with the help of vibrations and impact is most effective when the soil is in noncohesive nature.

##### Also Read: Explain Smooth Wheeled Roller Equipment

The vibratory plate compactor is power-engines, walk-behind equipment that imparts powerful vibratory compaction effort to loose materials, by transmitting vibration through the vibrating plate which generates power from the single rotor in vibration case. The size of the plate may vary from manufacturer to manufacturer. The weights of these compactors vary from 100 kg to 2 tonnes with plate areas between 0.16 sqmt to 1.6 sqmt. In the diesel or gasoline engine drive my eccentric weight at a high speed generates compaction force. If the plate is heavy, the more compaction forces are generated.

The upper part of the compactor is made up of a power source, belt cover, handle, water tank for sprinkling and guard hook which are fixed by engine base. The base of the engine is fixed on Vibrating plate by shock absorbing Rubber. The lower part of the compactor is made up of vibrating plate and vibrating unit has an eccentric rotary shaft built in. The shape of the plate also affects the compaction process. A curved plate can make turning easier than a square plate.

Courtesy - 123rf

While selecting and purchasing a plate compactor, make sure that you find a plate the suits the types of the job it will be used on and make sure that features and elements will allow you to get the best compaction and smoothest job possible.

There are three types of vibratory plate compactors:

#### 01. Single-Plate Compactor:

These types of compactors go in a forward direction only and work on high frequencies and comparatively low amplitude for compacting the thin layer of sand and gravel.

#### 02. Reversible Plate Compactor:

Reversible plate compactor can go in both forward and reverse direction. It is most suitable for granular soils and mixed soils.

#### 03. Heavy Duty or High-Performance Plate Compactors:

These type of compactors are applicable for semi-cohesive soils and on large amplitude. It is often used for sub-base or deeper depth of compaction.

### Characteristics Vibratory Plate Compactor:

01. Frequency range is usually 2500 to 6000 vpm.

02. Vibratory plate compactor can work at any temperature between 10 °C to 50 °C.

03. The depth of Compaction ranges from 13 cm to 30 cm depending on the size and capacity of the compactors and types of soil compacted.

04. Plate compactors are most suitable for the embankment, base and sub-base course, as well as asphalt course.

05. The more weight and size will deliver excellent compaction results and also gives high area output.

## Material Exhibition

Explore the world of materials.


text:
# Quantum phase transition with inhomogeneous driving in the Lechner-Hauke-Zoller model

@article{Hartmann2019QuantumPT,
title={Quantum phase transition with inhomogeneous driving in the Lechner-Hauke-Zoller model},
author={Andreas Hartmann and Wolfgang Lechner},
journal={Physical Review A},
year={2019}
}
• Published 27 June 2019
• Physics
• Physical Review A
We study the zero-temperature phase diagram of the LHZ model. An analytic expression for the free energy and critical coefficients for finite-size systems and in the thermodynamic limit are derived and numerically verified. With the aim to improve standard quantum annealing, we introduce an inhomogeneously driven transverse field with an additional time-dependent parameter that allows one to evade the first-order quantum phase transition and thus improve the efficiency of the ground state… Expand
8 Citations

#### Figures from this paper

Diabatic quantum annealing by counter-diabatic driving
• Physics
• 2020
We introduce a two-parameter approximate counter-diabatic term into the Hamiltonian of the transverse-field Ising model for quantum annealing to accelerate convergence to the solution, generalizingExpand
Minimal constraints in the parity formulation of optimization problems
• Physics, Mathematics
• New Journal of Physics
• 2021
As a means to solve optimization problems using quantum computers, the problem is typically recast into an Ising spin model whose ground-state is the solution of the optimization problem. AnExpand
Iterative classical superadiabatic algorithm for combinatorial optimization
This work considers a classical and superadiabatic version of an iterative quantum adiabatic algorithm to solve combinatorial optimization problems and finds that more than 90\% of such 64-bits hard instances can be resolved by a few iteration. Expand
Two-parameter counter-diabatic driving in quantum annealing
• Computer Science, Physics
• 2020
The authors introduce a two-parameter counter-diabatic protocol to enhance the performance of quantum annealing to solve generic combinatorial optimization problems.
Diversity measure for discrete optimization: Sampling rare solutions via algorithmic quantum annealing
Sampling a diverse set of high-quality solutions for hard optimization problems is of great practical relevance in many scientific disciplines and applications, such as artificial intelligence andExpand
High-accuracy Ising machine using Kerr-nonlinear parametric oscillators with local four-body interactions
• Physics
• 2020
A two-dimensional array of Kerr-nonlinear parametric oscillators (KPOs) with local four-body interactions is a promising candidate for realizing an Ising machine with all-to-all spin couplings, basedExpand
Inhomogeneity induced shortcut to adiabaticity in Ising chains with long-range interactions
• Physics
• 2020
Driving a homogeneous system across a quantum phase transition in a quench-time $\tau_Q$ generates excitations on wavelengths longer than the Kibble-Zurek (KZ) lengthExpand
Variational optimization of the quantum annealing schedule for the Lechner-Hauke-Zoller scheme
• Physics
• 2020
The annealing schedule is optimized for a parameter in the Lechner-Hauke-Zoller (LHZ) scheme for quantum annealing designed for the all-to-all-interacting Ising model representing genericExpand

#### References

SHOWING 1-10 OF 88 REFERENCES
Dynamics of an inhomogeneous quantum phase transition
• Physics
• 2009
We argue that in a second order quantum phase transition driven by an inhomogeneous quench density of quasiparticle excitations is suppressed when velocity at which a critical point propagates acrossExpand
Energy gaps in quantum first-order mean-field-like transitions: The problems that quantum annealing cannot solve
• Physics, Computer Science
• 2010
First-order quantum phase transitions in models where the mean-field treatment is exact are studied, and the exponentially fast closure of the energy gap with the system size at the transition is studied. Expand
Exponential Speedup of Quantum Annealing by Inhomogeneous Driving of the Transverse Field
• Physics
• 2018
We show, for quantum annealing, that a certain type of inhomogeneous driving of the transverse field erases first-order quantum phase transitions in the p-body interacting mean-field-type model withExpand
Inhomogeneous quasi-adiabatic driving of quantum critical dynamics in weakly disordered spin chains
• Physics
• 2016
We introduce an inhomogeneous protocol to drive a weakly disordered quantum spin chain quasi-adiabatically across a quantum phase transition and minimize the residual energy of the final state. TheExpand
Quantum annealing with antiferromagnetic fluctuations.
• Physics, Medicine
• Physical review. E, Statistical, nonlinear, and soft matter physics
• 2012
This work introduces antiferromagnetic quantum fluctuations into quantum annealing in addition to the conventional transverse-field term and finds that there exists a quantum path to reach the final ground state from the trivial initial state that avoids first-order transitions for intermediate values of p. Expand
Quantum annealing of the p -spin model under inhomogeneous transverse field driving
• Physics
• Physical Review A
• 2018
We solve the mean-field-like $p$-spin Ising model under a spatiotemporal inhomogeneous transverse field to study the effects of inhomogeneity on the performance of quantum annealing. We previouslyExpand
Energy Gap at First-Order Quantum Phase Transitions: An Anomalous Case
• Physics
• 2013
We show that the rate of closing of the energy gap between the ground state and the first excited state, as a function of system size, behaves in many qualitatively different ways at first-orderExpand
Quantum annealing in the transverse Ising model
• Physics
• 1998
We introduce quantum fluctuations into the simulated annealing process of optimization problems, aiming at faster convergence to the optimal state. Quantum fluctuations cause transitions betweenExpand
Rapid counter-diabatic sweeps in lattice gauge adiabatic quantum computing
• Physics
• New Journal of Physics
• 2019
We present a coherent counter-diabatic quantum protocol to prepare ground states in the lattice gauge mapping of all-to-all Ising models (LHZ) with considerably enhanced final ground state fidelityExpand
Zero-temperature quantum annealing bottlenecks in the spin-glass phase
• S. Knysh
• Physics, Medicine
• Nature communications
• 2016
Here it is shown how for large problems the complexity becomes dominated by O(log N) bottlenecks inside the spin-glass phase, where the gap scales as a stretched exponential. Expand


text:
A Mathematics Today column by Alan Champneys [2] describes a fascinating example that can be found in Wikipedia [4] and goes back to a paper by Rabinowitz [3]; see also [1]. Here is a bivariate polynomial $p(x,y)$:

tic
r2 = @(x,y) x.^2 + y.^2; xy = @(x,y) x.^2 - 3*y.^2;
p = @(x,y) r2(x,y).^4 - 45*r2(x,y).^3 - 41283*r2(x,y).^2 + ...
7950960*r2(x,y) + 16*xy(x,y).^3 + 48*r2(x,y).*xy(x,y).^2 + ...
x.*xy(x,y).*(16*r2(x,y).^2 - 5544*r2(x,y) + 266382) - 373248000;

The result is that the zero set of $p$ has constant width in the complex plane! -- like the British 50p coin. Let's verify this in Chebfun. Here's the domain, computed with the Chebfun2 roots command:

pc = chebfun2(p,[-11 11 -11 11]);
r = roots(pc);
copper = [.722 .451 .20];
fill(real(r),imag(r),copper)
axis(12*[-1 1 -1 1]), axis square, grid on

We compute its width measured in 5 different directions, and they agree to 5 digits, which is not bad considering the size of the coefficients.

disp('theta/pi     width')
for theta = pi*(0:4)/5;
a = exp(1i*theta);
width = max(real(a*r)) - min(real(a*r));
fprintf('%8.5f %12.8f\n',theta/pi,width)
end
theta/pi     width
0.00000  18.00727883
0.20000  18.00041631
0.40000  18.00052076
0.60000  18.00086199
0.80000  18.00028527

The exact result should be 18, as can be verified by setting $y=0$, in which case the polynomial reduces to

p = @(x) x^8 + 16*x^7 + 19*x^6 - 5544*x^5 - 41283*x^4 + 266382*x^3 + 7950960*x^2 - 373248000;

We confirm that this is zero at $x=-8$ and $x=10$:

p(-8)
p(10)
ans =
0
ans =
0

Just for fun let's compute the perimeter of the coin, presumably also accurate to about 5 digits:

perimeter = norm(diff(r),1)
perimeter =
57.179193996908275

time_for_this_example = toc
time_for_this_example =
3.371892000000000

[1] M. Bardet and T. Bayen, On the degree of the polynomial defining a planar algebraic curves of constant width, arXiv:1312.4358v1, 2013.

[2] A. Champneys, Westward Ho! Musing on mathematics and mechanics, Mathematics Today, April 2022, 56--59.

[3] S. Rabinowitz, A polynomial curve of constant width, Missouri Journal of Mathematical Sciences 9 (1997), 23--27.

[4] Wikipedia, "Curve of constant width".


text:
Translate locations in bibliography depending on document/babel language

I often write texts in German and Englisch and use JabRef to organize my references. Citing a lot of conference papers, it is often quite annoying to always change the language of the locations according to the document language. So I wondered whether I could provide a kind of dictionary to biblatex, so I don't have to adapt my database every time.

E.g. in the preamble I'd like to define:

Munich = München
Germany = Deutschland

in case the document or babel language is ngerman.

Can this be done?

MWE

\documentclass[ngerman]{article}

\usepackage[ngerman]{babel}

\begin{filecontents}{bla.bib}
@inproceedings{Orwell1984,
author  = "George Orwell",
title   = "1984",
year    = "1948",
booktitle = "Books about big brothers",
location = "Munich, Germany",
}
\end{filecontents}

\RequirePackage[backend=biber,style=ieee-alphabetic]{biblatex}

\begin{document}
\cite{Orwell1984}. \\
\printbibliography
\end{document}

You can use biblatex's bibstrings to translate certain phrases. The question is what would be a good interface. If you want to be able to combine arbitrary terms in one field, you'd have to do something like the following (which feels a bit clunky).

\documentclass[ngerman]{article}
\usepackage{babel}
\usepackage{csquotes}
\usepackage[backend=biber,style=ieee-alphabetic]{biblatex}

\NewBibliographyString{munich,germany}
\DefineBibliographyStrings{german}{
munich  = {München},
germany = {Deutschland},
}

\begin{filecontents}{\jobname.bib}
@inproceedings{Orwell1984,
author    = {George Orwell},
title     = {1984},
year      = {1948},
booktitle = {Books about big brothers},
location  = {\bibstring{munich}, \bibstring{germany}},
}
\end{filecontents}

\begin{document}
\autocite{Orwell1984}
\printbibliography
\end{document}

If you are OK with using only one string per field, you could make things a little nicer

\documentclass[ngerman]{article}
\usepackage{babel}
\usepackage{csquotes}
\usepackage[backend=biber,style=ieee-alphabetic]{biblatex}

\NewBibliographyString{de-munich}
\DefineBibliographyStrings{german}{
de-munich  = {München},
}
\DefineBibliographyStrings{english}{
de-munich  = {Munich, Germany},
}

\DeclareListFormat{location}{%
\usebibmacro{list:delim}{#1}%
\ifbibstring{#1}{\bibstring{#1}}{#1}\isdot
\usebibmacro{list:andothers}}

\begin{filecontents}{\jobname.bib}
@inproceedings{Orwell1984,
author    = {George Orwell},
title     = {1984},
year      = {1948},
booktitle = {Books about big brothers},
location  = {de-munich},
}
\end{filecontents}

\begin{document}
\autocite{Orwell1984}
\printbibliography
\end{document}

A more BibTeX-y solution uses @strings. You can define strings for each location in different .bib files (one for each language) and then select the .bib file for the language you need in your document.

\documentclass[ngerman]{article}
\usepackage{babel}
\usepackage{csquotes}
\usepackage[backend=biber,style=ieee-alphabetic]{biblatex}

\begin{filecontents}{locationstrings-german.bib}
@string{de:munich = "München"}
\end{filecontents}
\begin{filecontents}{locationstrings-english.bib}
@string{de:munich = "Munich, Germany"}
\end{filecontents}
% select the bib file for the language you want

\begin{filecontents}{\jobname.bib}
@inproceedings{Orwell1984,
author    = {George Orwell},
title     = {1984},
year      = {1948},
booktitle = {Books about big brothers},
location  = de:munich,
}
\end{filecontents}

\begin{document}
\autocite{Orwell1984}
\printbibliography
\end{document}

The still very experimental multiscript version of biblatex might also be of interest: https://github.com/plk/biblatex/issues/416

• Thank you! My aim is to leave the original .bib file unmodified.. So I wonder if maybe your first approach allows something like \DeclareFieldFormat{pubstate}{\ifbibstring{#1}{\bibstring{#1}}{#1}}, so I won't have to define with bibstring withtin the bib-file. However, I could't manage to pass the two comma-separated values to the command. Do you think it can be done? – thewaywewalk Sep 14 at 7:13
• @thewaywewalk In theory you could try and use etoolbox CSV list macros to loop over the field as a comma-separated list. But that removes spaces around commas, so you'd have to manually re-add them. Furthermore, I believe that there is a difference between printable text and 'keys'/bibstring names (bibstring names should ideally use ASCII only for maximum compatibility, while printable text can consist of everything). ... – moewe Sep 14 at 14:28
• ... I think you can't have your cake and eat it, too. Either go for fixed printable text in your .bib fields or for sane key markup (as shown in this or Ulrike's answer). Having both will get extremely messy at some point. – moewe Sep 14 at 14:29
\documentclass[ngerman]{article}

\usepackage[ngerman]{babel}

\begin{filecontents}{german-strings.bib}
@string{muenchen={München}}
@string{germany={Deutschland}}
\end{filecontents}

\begin{filecontents}[overwrite]{bla.bib}
@inproceedings{Orwell1984,
author  = "George Orwell",
title   = "1984",
year    = "1948",
booktitle = "Books about big brothers",
location = muenchen # ", " # germany
}
\end{filecontents}

\RequirePackage[backend=biber,style=ieee-alphabetic]{biblatex}


text:
# Ideal gas entropy

1. Apr 8, 2010

### mahdert

1. The problem statement, all variables and given/known data

what is the entropy of 1.0 litre of gasoues n2 at Ta=350 K and Pa=2.0 bar given that So = 191.61 J/(K gmol) at To = 298.15 K and Po = 1 bar?

2. Relevant equations
I think : S(at 350) - So = NC_p ln (Ta/To) - NR ln(Pa/po)

3. The attempt at a solution
My problem is, C_p is not given and can we use this formula if p is not constant.

2. Apr 8, 2010

### Mapes

1) Are you sure you don't know $c_P$ for an ideal gas?
2) To see if you can use this equation even if P is changing, how about starting from $dU=T\,dS-P\,dV$, isolating dS, and integrating?

3. Apr 8, 2010

### mahdert

C_p = 5/2 R;

I did the integration and I got the right answer. But the question remains, the specific heat capacity at constant pressure; C_p should be used at constant pressure. Here, the pressure is changing? A qualitative expalnation would suffice. Thanks

4. Apr 8, 2010

### Mapes

The pressure isn't changing; there's no process occurring. $c_P$ is just a variable.


text:
Dictionary Definition

candela n : the basic unit of luminous intensity adopted under the Systeme International d'Unites; equal to 1/60 of the luminous intensity per square centimeter of a black body radiating at the temperature of 2,046 degrees Kelvin [syn: candle, cd, standard candle]

User Contributed Dictionary

English

Noun

candela
1. In the International System of Units, the base unit of luminous intensity; the luminous intensity, in a given direction, of a source that emits monochromatic radiation of frequency 540 × 1012 hertz and that has a radiant intensity in that direction of 1/683 watt per steradian. Symbol: cd

candela
1. candela

Latin cande¯la

candela

Extensive Definition

The candela (, /-ˈdiːlə/, symbol: cd) is the SI base unit of luminous intensity; that is, power emitted by a light source in a particular direction, weighted by the luminosity function (a standardized model of the sensitivity of the human eye to different wavelengths, also known as the luminous efficiency function).

Definition

Like other SI base units, the candela has an operational definition—it is defined by a description of a physical process that will produce one candela of luminous intensity. Since the 16th General Conference on Weights and Measures (CGPM) in 1979, the candela has been defined as:
The candela is the luminous intensity, in a given direction, of a source that emits monochromatic radiation of frequency 540 hertz and that has a radiant intensity in that direction of 1/683 watt per steradian.
The definition describes how to produce a light source that (by definition) emits one candela. Such a source could then be used to calibrate instruments designed to measure luminous intensity, for example.
The candela is sometimes still called by the old name candle http://m-w.com/dictionary/candela, such as in foot-candle and the modern definition of candlepower.

Explanation

The frequency chosen is in the visible spectrum near green, corresponding to a wavelength of about 555 nanometers. The human eye is most sensitive to this frequency, when adapted for bright conditions. At other frequencies, more radiant intensity is required to achieve the same luminous intensity, according to the frequency response of the human eye. The luminous intensity for light of a particular wavelength \lambda is given by
I_v(\lambda)= 683.002\,\overline(\lambda) I(\lambda)
where I_v(\lambda) is the luminous intensity in candelas, I(\lambda) is the radiant intensity in W/sr and \overline(\lambda) is the standard luminosity function. If more than one wavelength is present (as is usually the case), one must sum or integrate over the spectrum of wavelengths present to get the total luminous intensity.
A common candle emits roughly 1 cd. A 100 W incandescent lightbulb emits about 120 cd.

Origin

Prior to 1948, there existed a variety of standards for luminous intensity in use in various countries. These were typically based on the brightness of the flame from a "standard candle" of defined composition, or the brightness of an incandescent filament of specific design. One of the best-known of these standards was the English standard: candlepower. One candlepower was the light produced by a pure spermaceti candle weighing one sixth of a pound and burning at a rate of 120 grains per hour.
It became clear that a better-defined unit was needed. The Commission internationale de l'éclairage (International Commission on Illumination) and the CIPM proposed a “new candle” based on the luminance of a Planck radiator (a black body) at the temperature of freezing platinum. The value of the new unit was chosen to make it similar to the earlier unit candlepower. The decision was promulgated by the CIPM in 1946: The value of the new candle is such that the brightness of the full radiator at the temperature of solidification of platinum is 60 new candles per square centimetre.
It was then ratified in 1948 by the 9th CGPM which adopted a new name for this unit, the candela. In 1967 the 13th CGPM removed the term "new candle" and gave an amended version of the candela definition, specifying the atmospheric pressure applied to the freezing platinum: The candela is the luminous intensity, in the perpendicular direction, of a surface of 1/600 000 square metre of a black body at the temperature of freezing platinum under a pressure of 101 325 newtons per square metre.
In 1979, because of the difficulties in realizing a Planck radiator at high temperatures and the new possibilities offered by radiometry, the 16th CGPM adopted the modern definition of the candela. The arbitrary (1/683) term was chosen so that the new definition would exactly match the old definition. Although the candela is now defined partly in terms of the watt, which is a derived SI unit of power, the candela remains a base unit of the SI system, by definition.http://www1.bipm.org/en/si/si_brochure/appendix2/photometric.html#history

SI photometric light units

Relationship between luminous intensity and luminous flux

If a source emits a known intensity (in candelas) in a well-defined cone, the total luminous flux in lumens can be calculated by taking the number of candelas, and dividing it by the number in the table below that corresponds to the "radiation angle" of the lamp (the full vertex angle of the emission cone). See MR16 for emission angles of some common lamps. Theory Formulas Online converter
• Example: A lamp that emits 590 cd with a radiation angle of 40°: 590/2.64 = approximately 223 lumens.
If the source emits light uniformly in all directions, the flux can be found by multiplying the intensity by 4π: a uniform 1 candela source emits 12.6 lumens.

References

candela in Arabic: شمعة (وحدة قياس)
candela in Bengali: ক্যান্ডেলা
candela in Bosnian: Kandela
candela in Breton: Candela
candela in Bulgarian: Кандела
candela in Catalan: Candela
candela in Czech: Kandela
candela in Danish: Candela
candela in German: Candela
candela in Estonian: Kandela
candela in Spanish: Candela
candela in Esperanto: Kandelo (mezurunuo)
candela in Basque: Kandela
candela in Persian: کاندلا
candela in French: Candela
candela in Korean: 칸델라
candela in Hindi: कैण्डेला
candela in Croatian: Kandela
candela in Indonesian: Candela
candela in Icelandic: Kandela
candela in Italian: Candela (unità di misura)
candela in Hebrew: קנדלה
candela in Latvian: Kandela
candela in Lithuanian: Kandela
candela in Hungarian: Kandela
candela in Malay (macrolanguage): Kandela
candela in Dutch: Candela (eenheid)
candela in Japanese: カンデラ
candela in Norwegian: Candela
candela in Norwegian Nynorsk: Candela
candela in Polish: Kandela
candela in Portuguese: Candela
candela in Romanian: Candelă
candela in Russian: Кандела
candela in Simple English: Candela
candela in Slovak: Kandela
candela in Slovenian: Kandela
candela in Serbian: Кандела
candela in Finnish: Kandela
candela in Swedish: Candela
candela in Ukrainian: Кандела
candela in Urdu: کنڈیلا
candela in Chinese: 坎德拉


text:
# Common Emitter Amp - modelled vs actual outputs

Joined Dec 15, 2020
1
Hi All

So I modelled a simple CE amp in LTSpice (asc file attached) which indicated a gain in the input signal of about 4.5x.

I then breadboarded the exact same circuit (with an A50k pot on the output) and put a tone generator through it and only managed to achieve about 1.5x gain. Also tried a number of other transistors (PN100, BC549...) with the same result.

Note the transistor has a measured hfe of 354 (from a DMM with a transistor port), but the model in LTSpice is an unmodified BC547B (hfe about 295).

Is this discrepancy between modelled and real-world response normal? what can I do to push the signal amplification higher?

I've also attached my spreadsheet calculating the resistor requirements for biasing and capacitor selection - being very new to electronics, I'd be keen for some QA.

I'd be using these for audio circuitry - primarily guitar pedals, so input frequencies are likely to be between 30Hz-5kHz to allow for harmonics.

#### Attachments

• 77 KB Views: 18
• 1.6 KB Views: 32

#### Audioguru again

Joined Oct 21, 2019
2,374
This circuit's input impedance is much too low for a guitar pickup. Usually the pickup feeds 1M or more.
The low input impedance of this circuit will kill the level and high frequencies from the pickup.
When fed from a low impedance signal, the gain is increased with a bypass capacitor parallel to the emitter resistor.

#### Attachments

• 44.7 KB Views: 61

#### LvW

Joined Jun 13, 2013
1,160
I then breadboarded the exact same circuit (with an A50k pot on the output) and put a tone generator through it and only managed to achieve about 1.5x gain. Also tried a number of other transistors (PN100, BC549...) with the same result.

Note the transistor has a measured hfe of 354 (from a DMM with a transistor port), but the model in LTSpice is an unmodified BC547B (hfe about 295).
Is this discrepancy between modelled and real-world response normal? what can I do to push the signal amplification higher?
Please note that it is not the hfe value which determines the voltage gain.
It is the transconductance gm at a given operational point (dc current Ic) which is responsible for the gain.
(The BJT acts as a current source - driven by the voltage Vbe).
A higher hfe value (for a fixed operational point) allows a larger input resistance of the stage - that´s all!

#### ericgibbs

Joined Jan 29, 2010
11,577
hi Tim,
This LTS sim demonstrates the point in Post #3 regarding the effect of BF on the circuit Gain.
The BF values are shown on the diagram.

E

#### Attachments

• 36.8 KB Views: 43

#### LvW

Joined Jun 13, 2013
1,160
hi Tim,
This LTS sim demonstrates the point in Post #3 regarding the effect of BF on the circuit Gain.
The BF values are shown on the diagram.
Question: Is it really the BF value which influences the circuit gain?

I dont think so - because in both cases the DC quiescent point (operational point) is not the same (same resistor values are used in both circuits).
So - you are comparing two transistor stages with different quiescent collector currents Ic (different transconductance gm).

For my opinion, a fair comparison of two different transistors in a circuit should be done for equal DC operational conditions only.

#### LvW

Joined Jun 13, 2013
1,160
Question: Is it really the BF value which influences the circuit gain?

I dont think so - because in both cases the DC quiescent point (operational point) is not the same (same resistor values are used in both circuits).
So - you are comparing two transistor stages with different quiescent collector currents Ic (different transconductance gm).

For my opinion, a fair comparison of two different transistors in a circuit should be done for equal DC operational conditions only. For equal operating points, both transistors (both hfe (BF) values) will have the same voltage gain.

#### Audioguru again

Joined Oct 21, 2019
2,374
How did you get a voltage gain of only 1.5 times? Mine shows a voltage gain of 4.5 times when biased with lots of current and a voltage gain a little less at 4.125V when biased with minimum current without any clipping.

Notice that on my simulations I show the DC output to show if the collector current is high or is low, and how far from clipping is the output.

#### Attachments

• 43.9 KB Views: 26

#### ericgibbs

Joined Jan 29, 2010
11,577
hi agu,

I just copied the TS's circuit as posted, no changes.
Used a BC547B_ from my standard.bjt and increased the BF to 350 for the right hand circuit on that sim.
The left side BC547 is the regular LTS transistor.

I would be interested if you can identify any differences.

E

BTW: Please post your asc file and I will give a run.

Update:
Clip from TS's opening post.
So I modelled a simple CE amp in LTSpice (asc file attached) which indicated a gain in the input signal of about 4.5x.

I then breadboarded the exact same circuit (with an A50k pot on the output) and put a tone generator through it and only managed to achieve about 1.5x gain. Also tried a number of other transistors (PN100, BC549...) with the same result.

#### Attachments

• 3.1 KB Views: 3

#### Ylli

Joined Nov 13, 2015
999
(with an A50k pot on the output)
Are you sure that is a 50K pot? What load is on the output of the pot? Gain falls to about 1.5 with a 240 ohm load.

#### Audioguru again

Joined Oct 21, 2019
2,374
Hi Eric,
When a transistor is close to cutoff then its voltage gain is reduced, the top of the waveform appears squashed.

#### ericgibbs

Joined Jan 29, 2010
11,577
hi agu,
Using the TS's original circuit.

The transistor in the LTS sim is not close to cut off, there is a 2V overhead voltage between Vc and Ve on the low Vout swing.

Also no distortion on the sine wave output, created a Vref sine wave source,[ see image] it overlays exactly the transistor Vout.

I suspect it could be a problem in LTS or the modelling.

E

#### Attachments

• 46.6 KB Views: 7

#### Audioguru again

Joined Oct 21, 2019
2,374
hi agu,
Using the TS's original circuit.
The transistor in the LTS sim is not close to cut off, there is a 2V overhead voltage between Vc and Ve on the low Vout swing.
Also no distortion on the sine wave output, created a Vref sine wave source,[ see image] it overlays exactly the transistor Vout.
I suspect it could be a problem in LTS or the modelling.
E
Hi Eric,
Tim wanted more gain so I added an emitter resistor bypass capacitor to cause the gain to be 120 times (with lots of distortion).

#### Attachments

• 63.5 KB Views: 10


text:
Rails is notorious for introducing breaking changes. Almost 2 years ago the Rails team decided to combine and deprecate rails db:structure:{dump,load} tasks into rails db:schema:{dump,load}. This was part of the “May of WTFs” strategy aimed to reduce many WTFs that happen when we use Rails. One of the WTFs chosen was to reduce the duplication of schema dump functions.

In Rails, there are separate tasks for db:schema:{dump,load} and db:structure:{dump,load}. The schema function dumps/loads the database into a Ruby format, while the structure function dumps it in a SQL format. It was decided to combine these into a single set of tasks and load either the schema or structure based on config.active_record.schema_format.

It seemed like a good idea at the time, however, it seems like there was solid reasoning to have separate tasks to load/dump different formats. As pointed out by @jeremy on Github,

• Apps, engines, CI flows, etc that invoke db:schema:dump to get a schema.rb file (say, for distribution) may now get a structure.sql file instead.
• And workflows that produce an additional structure.sql dump (say, for fast Docker database boot-up) will no longer be possible.

This was because the load/dump structure could only be changed by a Rails config, instead of something that’s outside the system.

### Before

When Rails deprecated db:structure:{dump,load} tasks this is what was followed:

• To generate a db/schema.rb file, set config.active_record.schema_format to :ruby before running rails db:schema:dump.
• To generate a db/structure.sql file, set config.active_record.schema_format to :sql before running rails db:schema:dump.

### After

Now it’s easier than ever after this PR:

• To generate a db/schema.rb file, set ENV["SCHEMA_FORMAT"] to :ruby before running rails db:schema:dump.
• To generate a db/structure.sql file, set ENV["SCHEMA_FORMAT"] to :sql before running rails db:schema:dump.


text:
# Find a solution for differential equations

1. Jan 23, 2014

### ip88

I have to solve the following differential equation (that I found in an article):

$\frac{1}{r^{5}}\partial_{r}(r^{5}\partial_{r}h(r)) -E\frac{h(r)}{r^{2}} = - \frac{C}{r^{5}}\delta(r-r_{0})$

where E and C are two constants.

The authors of the article first find a solution of the previous equation when $r≠r_{0}$ and the result is:

$h(r)=Ar^{c_{\pm}}$ where $c_{\pm} = -2 \pm \sqrt{E+4}$

Then they have to find the value of the constant A. In order to reach this aim they say that I have to integrate the differential equation and the result should be:

$\frac{C}{2\sqrt{E+4}}\times$ $\frac{1}{r_{0}^{4}}(\frac{r}{r_{0}})^{c_{+}}$ if r ≤ r_{0}

and

$\frac{C}{2\sqrt{E+4}}\times$ $\frac{1}{r^{4}}(\frac{r_{0}}{r})^{c_{+}}$ if r ≥ r_{0}

However I'm not able to recover this result. The point is that when I insert the solution of the homogeneous equation and I integrate the left side of the equation is always equal to zero. Probably I did not understand correctly what is the procedure that I have to follow in order to find the solution to the inhomogeneous equation (once I have the solution of the homogeneous equation), but I do not know how to reach this aim.

2. Jan 23, 2014

### vanhees71

The general solution for $r \neq r_0$ is
$$h(r)=A_1 r^{c_+}+A_2 r^{c_-},$$
where the constants $A_1$ and $A_2$ can be different for $r<r_0$ and $r>r_0$ in such a way that you get the $\delta$-distribution singularity. Since it's a 2nd-order equation you can demand that $h$ is continuous at $r_0$. This gives you one constraint for your four unknowns. You get a 2nd constraint by integrating the differential equation over an infinitesimal interval containing $r_0$ in its interior, leading to a condition for the appropriate jump in $h'(r)$.

Further you need some more conditions to fix the function completely. These should be given from the application treated with this function (Green's function for some physical problem?).

3. Jan 23, 2014

### the_wolfman

Hi ip88,

To expand upon what vanhees71 said.

After solving the homgenous equation you have two different solutions

$h_< = Ar^{c_+} + B r^c{_-}$
and
$h_> = L r^{c_+} + M r^{c_-}$

The solution $h_<$ is only valid for $r < r_0$ and $h_>$ is only valid for $r > r_0$.

The goal is then to find the constants $A,B,L, M$. There are 4 unknowns, and we need 4 equations. Two equations come from the boundary conditions of the ODE. A third equation is obtained by requiring $h_< =h_>$ at $r_0$.

To get a forth equation we integrate the differential equation from $r_0 -\epsilon$ to $r_0 +\epsilon$ and then take the limit that $\epsilon \rightarrow 0$. This last step is where all the magic happen and it gives you a "jump condition".

To see how this works lets take the integral: (I've also multiplied the equation by r^5)
$\int_{r_0-\epsilon}^{r_0+\epsilon} dr \left(\partial_r (r^5 \partial_r h) - Er^3h=-C\delta(r-r0) \right)$

The integral of the first term is:
$\left. r^5 \partial_r h \right|_{r_0-\epsilon}^{r_0+\epsilon}$
and in the limit that $\epsilon \rightarrow 0$ we get $r_0^5 \left(h'_>-h'_< \right)\left. \right|_{r_0}$. The primes are the derivatives in r.

The integral of the second term goes to zero in the limit that $\epsilon \rightarrow 0$.

Finally the integral of the third term is -C

Putting this together gives the jump condition
$r_0^5 \left(h'_>-h'_< \right)\left. \right|_{r_0} =-C$

4. Jan 23, 2014

### ip88

Thank you very much for the explanation


text:
# NEED HELP WITH ANGULAR SPEED?

• NEED HELP WITH ANGULAR SPEED?

1.) A wheel turns through 4 revolutions while being accelerated from rest at 20rpm/s. a)find the final angular speed b) find the time it takes to turn 4 ...
Positive: 73 %
$\omega$ is the angular frequency or angular speed and this measured in radians per second. ... Physics Help: Physics Tutor: Angular Speed. Angular Speed ...
Positive: 70 %

### More resources

I need help with part b. assume that, at a certain. angular speed W2, the radius R becomes twice L. find W2. R (w) =0.132m. Show transcribed image text An ...
Positive: 73 %
An object is traveling around a circle with a radius of 10 cm. If in 20s a central angle of 1/3 radians is swept out, what is the linear speed of the object?
Positive: 68 %
Hi, Tire(wheel) on a car travelling 60 km/hr has a diameter of 45.0cm. What is the angular speed?? So we use w=theta / time. But how do you find radians in ...