World history is rife with epic power struggles, world-conquering tyrants, and heroic underdogs. The history of web browsers isn’t very different. University pioneers wrote simple software that sparked an information revolution, and battle for browser superiority and internet users.
By mid-1995, popular culture had begun to notice the web, and Netscape Navigator was the de facto standard for web browsing at that time. An ex-colleague of Tim Berners-Lee called Mark Andreesen founded the Netscape Corporation, which built on the previous Mosaic browser to establish the first mass-market browser, the Netscape Navigator.
In August 1995 Netscape became a public company, fuelled by the success of the world wide web, and, to many minds ushered in the Dotcom boom. To that point of time, Microsoft had thought the future action would be in multi channel interactive cable television. However the success of Netscape caused it to release Internet Explorer 1.0 as part of the Microsoft Windows 95 Plus Pack in August 1995. Internet Explorer 2.0 was released three months later, and by then the race was on.
New versions of Netscape Navigator (later Netscape Communicator) and Internet Explorer were released at a rapid pace over the following few years. Features often took priority over bug fixes, and therefore the browser wars were a time of unstable browsers and lots of user headaches. Internet Explorer only began to approach par with its competition with version 3.0 (1996).
In 1997 Netscape still held 72% of the browser market. But in October 1997, Internet Explorer 4.0 was released and changed the tides of the browser wars. It was faster and it adopted the W3C's published specifications more faithfully than Netscape Navigator 4.0.
A lot was at stake for these two companies involved in the browser wars. A popular web browser could earn a lot of money: search engine companies would bid to be the default tool used in the web browser, and other companies with a web presence would bid to be listed in the default set of bookmarks which was preinstalled with the browser. Since a web browser is a powerful gateway to a great deal of information, the company which controlled this gateway could conceivably have a lot of influence over its users.
Microsoft had two strong advantages in the browser wars. One was simply an issue of resources: Netscape began with a nearly 90% market share and a good deal of public goodwill, but as a relatively small company deriving the great bulk of its income from what was essentially a single product (Navigator and its derivatives), it was financially vulnerable. Netscape's total revenue never exceeded the interest income generated by Microsoft's cash on hand.
The other, more important, advantage was that Microsoft Windows had a monopoly in the operating system marketplace that could be used to leverage IE to a dominant position. IE was bundled with every copy of Windows; therefore, even though early versions of IE were markedly inferior to Netscape's browser, Microsoft was still able to enlarge its market share. And IE remained free while the enormous revenues from Windows were used to fund its development and marketing, resulting in rapid improvements until it was so similar to Netscape feature-wise that users had no desire to download and install Netscape.
The effect of these actions were to "cut off Netscape's air supply," as stated by a Microsoft executive during the United States v. Microsoft case (which resulted in Microsoft being prosecuted for having used its monopoly status to manipulate the market). This, together with several bad business decisions on Netscape's part, led to Netscape's defeat by the end of 1998, after which the company was acquired by America Online for USD $4.2 billion. Internet Explorer became the new dominant browser, attaining a peak of about 96% of the web browser usage share during 2002, more than Netscape had at its peak.
Thus ended the pioneering era of web browsers, with the dominant software company dominating the market. Microsoft might have been a late entry, but to this day it has remained dominant in the browser market, challenged only recently by the excellent Mozilla browser.
What to write here?


This is a quick brutally simple welcome message that tells you that this is a microblog template.
View Bio »
Author Name
Let's talk about the weather and why thunderstorms are therapeutic.
Posted 10/13/2020
Lorem ipsum no facer prompta vim, movet ubique qui ei. Per no regione aliquid, ea mei nulla scribentur liberavisse. Vim cu tale ludus possit, discere suavitate nam ad. No verterem reprimique vix, phaedrum hendrerit an quo. Qui feugait apeirian ut, ne virtute numquam mandamus mea.
Read More »
My fantasies and thoughts about deep space.
My thoughts about environmental issues and clean energy.
My favorite moments from my camping adventures.
Privacy Policy | Sitemap


Variable
| Static Public Summary | ||
| public |
Contaier file for storing constats: action constants. |
|
| public |
|
|
| public |
AddMessage: * |
|
| public |
|
|
| public |
|
|
| public |
|
|
| public |
|
|
| public |
|
|
| public |
MessagesList: * |
|
| public |
Sidebar: * |
|
| public |
|
|
| public |
chat: * |
|
| public |
|
|
| public |
|
|
| public |
store: * |
|
| public |
userServices: {"login": *, "logout": *} |
Static Public
public ADD_MESSAGE: string source
import {ADD_MESSAGE} from 'chat-1/src/constants/ActionTypes.js'
Contaier file for storing constats: action constants.
public CHANGE_USERNAME: string source
import {CHANGE_USERNAME} from 'chat-1/src/constants/ActionTypes.js'
public LOGIN_FAILURE: string source
import {LOGIN_FAILURE} from 'chat-1/src/constants/ActionTypes.js'
public LOGIN_REQUEST: string source
import {LOGIN_REQUEST} from 'chat-1/src/constants/ActionTypes.js'
public LOGIN_SUCCESS: string source
import {LOGIN_SUCCESS} from 'chat-1/src/constants/ActionTypes.js'
public MESSAGE_RECEIVED: string source
import {MESSAGE_RECEIVED} from 'chat-1/src/constants/ActionTypes.js'
public connectedLoginPage: * source
import {connectedLoginPage} from 'chat-1/src/containers/Login.js'
public userServices: {"login": *, "logout": *} source
import {userServices} from 'chat-1/src/services/auth.js'


CIFAR-10 Example¶
Prerequisites for this tutorial are a good knowledge of Python and nuts-flow. Please read the nuts-flow tutorial if you haven’t. Some knowledge of Keras, and of course deep-learning, will be helpful.
Task¶
In this example we will implement a nuts-ml pipeline to classify CIFAR-10 images. CIFAR-10 is a classical benchmark problem in image recognition. Given are 10 categories (airplane, dog, ship, …) and the task is to classify small images of these objects accordingly.
The CIFAR-10 dataset consists of 60000 RGB images of size 32x32. There are 6000 images per class and the dataset is split into 50000 training images and 10000 test images. For more details see the Tech report.
In the following we will show how to use nuts-flow/ml and Keras to train a Convolutional Neural Network (CNN) on the CIFAR-10 data. For readability some code will be omitted (e.g. import statements) but the complete code and more examples can be found under nutsml/examples.
Network¶
The network architecture for the CNN is a slightly modified version of the Keras
CNN
example (Keras version 2.x) with the notable exception of the last line,
where the model is wrapped in a KerasNetwork
.
INPUT_SHAPE = (32, 32, 3)
NUM_CLASSES = 10
def create_network():
model = Sequential()
model.add(Convolution2D(32, (3, 3), padding='same',
input_shape=INPUT_SHAPE))
model.add(Activation('relu'))
model.add(Convolution2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(Convolution2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Convolution2D(64, (3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(NUM_CLASSES))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='adam', metrics=['accuracy'])
return KerasNetwork(model, 'weights_cifar10.hd5')
The wrapping allows us using the CNN as a nut
within a nuts-flow,
which simplifies training. The wrapper also takes a path to a weights file
for check-pointing. Weights are saved in the standard Keras format as
HDF5 file.
Note
So far only wrappers for Keras and Lasagne models are provided. However, any deep-learning library that accepts an iterable over mini-batches for training will work with nuts-ml.
Loading data¶
In many image processing applications the complete set of training images is too large to fit in memory and images are loaded in a streamed fashion. See read_images.py for an example that loads images sequentially.
CIFAR-10, however, is small benchmark data set and fits in memory. We therefore
take advantage of the function cifar10.load_data()
provided by Keras,
and load all images in memory but rearrange the data slightly
def load_samples():
from tensorflow.python.keras.datasets import cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
train_samples = list(zip(x_train, map(int, y_train)))
test_samples = list(zip(x_test, map(int, y_test)))
return train_samples, test_samples
Specifically, we convert class labels from floats to integers,
and zip inputs x
and outputs y
to create lists with training and test samples.
Sample are then tuples of format (image, label)
, where the image is a
Numpy array of shape (32,32,3)
, and the label is an integer between 0 and 9,
indicating the class. We can verify the type and shape of the samples
by running the following flow
(complete code here )
train_samples, test_samples = load_samples()
train_samples >> Take(3) >> PrintColType() >> Consume()
which takes the first three samples and prints for each sample the data type and content information for the sample columns
item 0: <tuple>
0: <ndarray> shape:32x32x3 dtype:uint8 range:0-255
1: <int> 6
item 1: <tuple>
0: <ndarray> shape:32x32x3 dtype:uint8 range:5-254
1: <int> 9
item 2: <tuple>
0: <ndarray> shape:32x32x3 dtype:uint8 range:20-255
1: <int> 9
Note
The standard formats for image data in nuts-ml are NumPy arrays
of shape (h,w,3)
for RGB images, (h,w)
for gray-scale images
and (h,w,4)
for RGBA image.
Not only can we inspect the type of the data but we can also have a look at the images themselves
train_samples, test_samples = load_samples()
train_samples >> Take(3) >> PrintType() >> ViewImage(0) >> Consume()
Training¶
We will introduce the code for the network training in pieces before showing the complete code later. First, let us create the network and load the sample data using the functions introduced above
network = create_network()
train_samples, test_samples = load_samples()
Having a network and samples we can now train the network (for one epoch) with the following nuts-flow
train_samples >> augment >> rerange >> Shuffle(100) \
>> build_batch >> network.train() >> Consume()
The flow augments the training images by random transformations, re-ranges pixel values to [0, 1], shuffles the samples, builds mini-batches, trains the network and consumes outputs of the training (losses, accuracies).
Consume
and Shuffle
are nuts from nuts-flow. Image augmentation,
re-ranging and batch-building are parts of nuts-ml that we describe
in detail in the next sections.
Augmentation¶
Deep learning requires large data sets and a common strategy to increase the amount of image data is to augment the data set with randomly perturbed copies, e.g. rotated or blurred. Here we want augment the CIFAR-10 data set by flipping images horizontally and changing the brightness
p = 0.1
augment = (AugmentImage(0)
.by('identical', 1.0)
.by('fliplr', p)
.by('brightness', p, [0.7, 1.3]))
The AugmentImage
nut takes as parameter the index of the image within the
sample (image, label)
, here position 0 and augmentations are specified
by invoking by(transformation, probability, *args)
.
We augment by passing the unchanged image ('identical'
) through with
probability 1.0 (all of them), flipping images horizontally for 10%
of the samples (p = 0.1
), and randomly changing the brightness
in range [0.7, 1.3]
, again with 10% probability p
. We could have
a look at the augmented images and their labels using the following flow
(complete code here )
train_samples, test_samples = load_samples()
train_samples >> augment >> ViewImageAnnotation(0, 1, pause=1) >> Consume()
In detail: for every sample processed by AugmentImage
, the image is
extracted from position 0 of the sample tuple and new samples with the same label
but with augmented images are outputted. For each input image the identical
output image is generated (identical
), and additional augmented samples
(fliplr
, brightness
) are created with 10% probability each, resulting
in 20% more training data.
Transformation¶
Images returned by load_samples()
are NumPy arrays with integers in range
[0, 255]
. The network, however, expects floating point numbers (float32
)
in range [0,1]
. We therefore transform images by reranging
rerange = TransformImage(0).by('rerange', 0, 255, 0, 1, 'float32')
where TransformImage
takes as parameter the index of the image within
the sample and transformation are defined by invoking by(transformation, *args)
.
Note
Transformation are chained, meaning that an input image is transformed by sequentially applying all transformations to the image, resulting in one output image. Consequently, the number of input and output images after transformation are the same. Augmentations, on the other hand, are applied independently and the number of input and output images can differ.
See TransformImage
in transformer.py
for a list of available transformations. Each transformation can also be used for
augmentation. Custom transformations can be added via register
>>> from nutsml import TransformImage, AugmentImage
>>> my_brightness = lambda image, c: image * c
>>> TransformImage.register('my_brightness', my_brightness)
>>> transform = TransformImage(0).by('my_brightness', 1.5)
>>> augment = AugmentImage(0).by('my_brightness', [0.7, 1.3])
While transformations take a specific parameter values, e.g. 1.5
for brightness,
augmentations take ranges, e.g. [0.7, 1.3]
, where parameter values are
uniformly sampled from.
 BuildBatch(batchsize)
is used to build these batches. The following example creates a batcher that
extracts images from column 0 of the samples and class labels from column 1.
Class labels are encode as one-hot vectors, while images within the batch
are represented as NumPy arrays with dtype float32
.
NUM_CLASSES = 10
BATCH_SIZE = 32
build_batch = (BuildBatch(BATCH_SIZE)
.input(0, 'image', 'float32')
.output(1, 'one_hot', 'uint8', NUM_CLASSES))
Having a batcher we can now build a complete pipeline that trains the network for one epoch
train_samples >> augment >> rerange >> build_batch >> network.train() >> Consume()
Note
Consume()
, Collect()
, Unzip()
or some other data sink is needed.
Without a consumer at the end of the pipeline no data is processed.
Usually it is a good idea to shuffle the data (especially after augmentation) to ensure that each mini-batch contains a nice distribution of different class examples. Complete shuffling is not feasible if the training images do not fit in memory but we can perform a partial shuffling, e.g. over 100 samples. Let’s also train for more than one epoch
EPOCHS = 20
for epoch in range(EPOCHS):
(train_samples >> augment >> rerange >> Shuffle(100) >> build_batch >>
network.train() >> Consume())
Training results¶
Instead of consuming (and throwing away) the outputs of the training we can collect and print the results (loss, accuracy)
for epoch in range(EPOCHS):
t_loss, t_acc = (train_samples >> augment >> rerange >> Shuffle(100) >>
build_batch >> network.train() >> Unzip())
print("train loss :", t_loss >> Mean())
print("train acc :", t_acc >> Mean())
network.train()
takes mini-batches as input and outputs loss and accuracy
per mini-batch as specified in create_network()
. Unzip()
transforms the
outputted sequence of (loss, accuracy)
tuples into a sequence of losses
t_loss
and a sequence of accuracies t_acc
.
Finally, we print the mean (over mini-batches) for training loss and accuracy.
Validation¶
The CIFAR-10 data set is divided into a training and a test set but does not come with a validation set per default. However, we can easily split the training set into a new training set and a validation set
train_samples, val_samples = train_samples >> SplitRandom(0.8)
The new training set will contain 80% of the original set and the validation set the remainder.
Note
SplitRandom()
can split into more than two sets and can take constraints
into account and SplitLeaveOneOut()
performs leave-one-out splits.
The performance of the network on the validation data can then be computed analogous
to the way the training results were computed. Important differences are
that we are using the validation data, calling network.validate()
instead of
network.train()
, do not perform augmentation and there is no need to shuffle the data
for epoch in range(EPOCHS):
v_loss, v_acc = val_samples >> rerange >> build_batch >> network.validate() >> Unzip()
print("val loss :", v_loss >> Mean())
print("val acc :", v_acc >> Mean())
Again, printed results are mean values over mini-batch losses and accuracies.
Evaluation¶
Validation accuracy averaged over mini-batches provides a reasonable estimate for the
prediction accuracy and is, for instance, useful for early stopping,
but is not an accurate measure of the true classification performance. Typically
we want to evaluate on an independent test set and average over samples, not mini-batches.
The code below calls network.evaluate()
to compute the categorical_accuracy
over all test samples
e_acc = test_samples >> rerange >> build_batch >> network.evaluate([categorical_accuracy])
print("evaluation acc :", e_acc)
In contrast to the training or validation accuracies computed by network.train()
or network.validate()
, network.evaluate()
returns a single number per metric and
no averaging is required.
Check-pointing¶
A common method to enable the continuation of an interrupted training or to implement
early-stopping is to save the network weights, either at regular intervals (e.g. at
each epoch) or when the validation accuracy reaches a new high.
Network weights can be easily be saved by invoking the save()
method
network.save()
where the path to the weights file was specified when wrapping the model via
KerasNetwork(model, weightsfile)
in create_network()
.
For early-stopping we want to save the weights depending on the validation loss
or accuracy. The following code shows how to compute the validation accuracy
and uses save_best()
to save the weights for the network with the highest
accuracy
v_acc = val_samples >> rerange >> build_batch >> network.validate() >> Get(1) >> Mean()
network.save_best(v_acc, isloss=False)
Note that the computation of the validation accuracy is slightly different than shown
before. Here we need only the accuracies but not the losses and therefore call Get(1)
to extract them. Since the output then contains only accuracies and not tuples
(loss, acc)
anymore, we can directly call Mean()
and don’t need to Unzip
.
If we want to save the network with the smallest loss instead, we can write
v_loss = val_samples >> rerange >> build_batch >> network.validate() >> Get(0) >> Mean()
network.save_best(v_loss, isloss=True)
Reading¶
The CIFAR-10 benchmark dataset is small enough to fit in memory. However, in many practical applications the image datasets are too large to be loaded in memory entirely and images need to be read sequentially from the file system. The following example shows how to read PNG images from a folder and to display them
show_image = ViewImage(0, pause=1, figsize=(2, 2), interpolation='spline36')
glob('images/*.png') >> ReadImage(None) >> show_image >> Consume()
ReadImage
takes a sequence of file paths as input, generated using glob
,
reads the image from the file system, and returns tuples of shape (image,)
,
where images are numpy arrays. We can then display the image with ViewImage
,
where 0
indicates the column in the input sample that contains the image
and pause=1
forces a pause of one second between images.
See cifar/read_images.py for a complete code example.
A common method to organize image data for network training on the file system is to store them in sub-folders named after the class labels, for instance
images\
0\
img123.jpg
img456.jpg
...
9\
img789.jpg
We can read these images with their corresponding class labels using the following code
ReadLabelDirs('images', '*.jpg') >> ReadImage(0) >> show_image >> Consume()
where ReadLabelDirs
returns tuples of the form (filepath, label)
.
See mnist/read_images.py for a complete example using the MNIST data.
Writing¶
Often we not only want to read image data but also write them, e.g. after transformation or augmentation. The following code writes the first 20 of the CIFAR-10 training images in PNG format to the file system
train_samples, _ = load_samples()
imagepath = 'images/img*.png'
train_samples >> Take(20) >> WriteImage(0, imagepath) >> Consume()
The filenames for the images are generated automatically by replacing the
*
in imagepath
by a running number. For instance, the code above
would create the following files
./images/img0.png
./images/img0.png
...
./images/img19.png
A more complex example that includes the class label of an image in its filename can be seen in cifar/write_images.py .
Prediction¶
After having trained and evaluated a network we usually want to apply it and predict labels for new images. Here an example
samples = glob('images/*.png') >> ReadImage(None)
pred_batch = BuildBatch(BATCH_SIZE).input(0, 'image', 'float32')
predictions = (samples >> rerange >> pred_batch >> network.predict() >>
Map(ArgMax()) >> Collect())
print(predictions)
As before we read images from the file system with ReadImage
, re-range
them and build a batch. Note that it would be easy to add a transformation
that resizes the new input images to the shape required by the network.
Note
For classification the batch needs to be created differently (without class labels) compared to training/evaluation, since class labels are not available - that is what we want to predict!
We call network.predict
to retrieve the prediction of the network for an
input image. The output is a softmax vector (see create_network()
) and
we use Map(ArgMax())
to get the class index. If you want the class index
together with the class probability Map(ArgMax(retvalue=True))
can be
called instead.
cifar/cnn_classify.py contains a more complex example that displays the image with the true and predicted class names.
Code¶
Here is the complete code (without imports) for the network training. The entire code can be found in cifar/cnn_train.py.
rerange = TransformImage(0).by('rerange', 0, 255, 0, 1, 'float32')
build_batch = (BuildBatch(BATCH_SIZE)
.input(0, 'image', 'float32')
.output(1, 'one_hot', 'uint8', NUM_CLASSES))
p = 0.1
augment = (AugmentImage(0)
.by('identical', 1.0)
.by('brightness', p, [0.7, 1.3])
.by('color', p, [0.7, 1.3])
.by('shear', p, [0, 0.1])
.by('fliplr', p)
.by('rotate', p, [-10, 10]))
plot_eval = PlotLines((0, 1), layout=(2, 1))
network = create_network()
train_samples, test_samples = load_samples()
train_samples, val_samples = train_samples >> SplitRandom(0.8)
for epoch in xrange(NUM_EPOCHS):
print('EPOCH:', epoch)
t_loss, t_acc = (train_samples >> PrintProgress(train_samples) >>
Pick(PICK) >> augment >> rerange >> Shuffle(100) >>
build_batch >> network.train() >> Unzip())
t_loss, t_acc = t_loss >> Mean(), t_acc >> Mean()
print("train loss : {:.6f}".format(t_loss))
print("train acc : {:.1f}".format(100 * t_acc))
v_loss, v_acc = (val_samples >> rerange >>
build_batch >> network.validate() >> Unzip())
v_loss, v_acc = v_loss >> Mean(), v_acc >> Mean()
print('val loss : {:.6f}'.format(v_loss))
print('val acc : {:.1f}'.format(100 * v_acc))
network.save_best(v_acc, isloss=False)
plot_eval((t_acc >> Mean(), v_acc))
print('testing...')
e_acc = (test_samples >> rerange >> build_batch >>
network.evaluate([categorical_accuracy]))
print('test acc : {:.1f}'.format(100 * e_acc))


Training
Unique Interdisciplinary Curriculum
The program will offer graduate courses in information
technology, emergency management, computer science, mathematics, environmental study, business,
geometric engineering and civil engineering from 10 graduate programs of 6 participating universities.
Students will be required to take at least one course outside their home program, and at least two core
courses of the ADERSIM program. Examples of core courses include: Advanced Disaster and
Emergency Management, Agent-Based Modeling and Simulation, Information Retrieval, Data Mining,
and WebGIS. These courses will allow trainees to develop a diverse range of knowledge and skills for
various disaster and emergency simulations.
Internship
All trainees will take part in at least one
internship of 4-6 months in one of the ADERSIM confirmed partners from private sectors (Cadillac-
Fairview, IBM, CriSys, Felix, Mircom, ESRI Canada, AbsoluteTrac etc.), government sectors (City of
Brampton, City of Markham, City of Toronto, Toronto Hydro, Hydro One, Public Health Ontario,
Greater Toronto Airport Authority, Toronto Transit Commission, etc.), or non-governmental
organizations (Red Cross, Saint-John Ambulance, Salvation Army, United Nations, etc.). Working
closely with collaborators from partner organizations, interns will be engaged in emergency simulation
needs assessments, development of disaster and emergency simulations and information management
and their implementation and testing in their internship organizations. The content of each internship
project needs to be approved by the ADERSIM Scientific and Academic Committee (STSC). Internship
placement with industry partners and simulation users will ensure that our research and technology
development are closely related to the end-user's need. Mitacs will provide Accelerate internships for
eligible ADERSIM candidates. Mitacs has committed $7,500 per internship, up to 6 Mitacs Accelerate
Internship units per year for eligible ADERSIM trainees. PhD graduates engaged with ADERSIM will be
encouraged to apply for placement in Mitacs Elevate, which will provide continuity for the trainees and
help their transition into the work force.
Inter-university Experiences
Field trips and summer schools will provide trainees with opportunities to examine disaster
risks and disaster and emergency management functions while gaining useful inter-university
experiences. Each trainee should participate in at least one of our professional field trips or a course in
another university. For example, York University has a formal agreement with the University of Geneva
and runs an annual field trip to volcanic islands of Italy. We will arrange field study courses and field
trips through University of Geneva's CERG Program, designed specifically for hands on and practical
disaster risk and emergency management. Students of other participating universities can take the
Disaster Risk Assessment course offered by the Disaster & Emergency Management Program at York
University, or the Post Disaster Recovery and Reconstruction course that is under development by York
University's Disaster & Emergency Management in collaboration with the University of Montreal and
the University of Canterbury (New Zealand). Also, in collaboration with our international partners,
particularly the University of Bremen (Germany), University of Calabria (Italy), University of Geneva
(Switzerland), University of Calabria (Italy), and Wuhan University (China), we will organize joint
summer schools. The summer schools will be intensive graduate level programs that will be led by
members of the program committee and distinguished experts. There will be different themes for summer
schools each year. Although the summer schools will be offered to the ADERSIM program trainees, they
will be open to other selected students and faculty members for recruitment and networking purposes.
We are considering a maximum of 30 trainees in each summer school. The objective is to keep
participants abreast of the latest developments in simulation methods, both from theoretical and
application aspects. Summer schools will be divided into two parts: part one will be designed to
introduce participants to simulation methods and an advanced part where the participants can study a
particular simulation method in depth.
Live Disaster & Emergency Simulations and Exercises
In
order for our trainees to better understand the importance of the use of simulations in disaster and
emergency management environment, and to better learn how emergencies are managed, they will be
required to take part in at least one live emergency exercise conducted at York University or emergency
exercises and simulations conducted by our partners (Centennial College's annual 'Mock Disaster' mass
casualty incident, City of Brampton, Red Cross, Cadillac-Fairview, Greater Toronto Airport Authority,
Toronto Transit Commission, etc.). ADERSIM trainees will also take part in live emergency exercises
conducted by our partner organizations, which will help them to test their simulations tools.
International Research Fellowship
ADERSIM trainees will be provided with student exchange
opportunities through our strong collaborations and formal student exchange agreements with University
College London, University of Edinburgh, University of Geneva, University of Calabria, University of
Bremen, University of Sao Paulo, Huazhong University of Science and Technology, Academia Sinica
(Taiwan), Kyoto University (Disaster Prevention Research Institute), Tongji University and Wuhan
University (China). Depending on the type of hazards, simulation technology, and expertise of our
international collaborators, trainees will be sent to them. We have secured 20 International Research
Internship awards from Mitacs ($5000 per internship) to support our formal student exchange.
Joint Supervision
A supervisory committee consisting of two academic co-applicants from different
disciplines and one representative from the end-users or industry partners (who are eligible to be
appointed to the respective graduate program as an adjunct faculty member) will be appointed for each
trainee. The trainees will undertake cutting-edge disaster and emergency information retrieval and
disaster simulation research projects under the supervisory committee. This will also allow us to rotate
students between different universities and partner companies and organizations.
Interdisciplinary Seminars
Regular
The program will organize regular monthly seminars and an annual boot-camp at coapplicant
universities in Canada to provide a highly interactive and interdisciplinary environment to
enrich the learning experience and to improve the trainee's communication and collaborative skills.
Research teams will present their projects, achievements, and challenges in monthly seminars. These
seminars will be broadcasted online to provide opportunities for distance trainees and collaborators to
participate. Boot-camps will cover different types of disaster and emergency information retrieval and
simulations topics. We will invite representatives from industry partners to actively participate in our
seminars and boot-camps by giving presentations and commenting on research projects.
International Conferences & Student Competition
Canada
hosts a number of annual professional conferences related to the ADERSIM training area (e.g., World
Disaster Management Conference, Annual Summit on Emergency and Disaster Planning for Colleges,
Universities, and k-12 Schools, Disaster Preparedness, International Conf. on Flood Management
(ICFM)). In collaboration with conference organizers, we will organize special sessions on disaster
information retrieval and simulations. Building on our existing student competition experiences
(Emergency Management Student Competition at York University, and I-Rec International Student
Competition organized by our co-applicant from the University of Montreal) we will run an annual
students disaster simulation competition.
ADERSIM Virtual Lab and Learning Management
System
Interdisciplinary disaster and emergency simulation teams must work closely, share information,
and collaborate with industry and end users to develop simulation tools that meet the needs of emergency
managers at different contexts. One of the most important aspects of learning and experience in the
ADERSIM Training Program is the opportunities that participants will have for collaboration and
interaction through a state-of-the-art Virtual Disaster Simulation Lab using Second Life and OpenSim
platforms integrated with a Moodle Learning Management System. These systems will provide access to
online disaster simulation modules, virtual disaster simulation labs, and opportunities to share
information and interact with other program participants in a regular basis. ADERSIM training program
is designed to promote and facilitate interdisciplinary learning, research, and experience for the next
generation of Highly Qualified Personnel (HQP), including active involvement with industry partners,
end users, and disaster impacted communities and organizations. Working with interdisciplinary
supervisory teams, advance intellectual and professional development activities, and significant
networking and experiential learning opportunities, ADERSIM will provide trainees with unique
opportunities to become the future leaders of disaster and emergency simulation industry and
applications.


|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.newdawn.slick.GameContainer
public abstract class GameContainer
A generic game container that handles the game loop, fps recording and managing the input system
| Field Summary | |
|---|---|
protected boolean |
alwaysRender
True if we should render when not focused |
protected boolean |
clearEachFrame
True if we should clear the screen each frame |
protected boolean |
forceExit
True if we should force exit |
protected int |
fps
The current count of FPS |
protected Game |
game
The game being managed |
protected static SGL |
GL
The renderer to use for all GL operations |
protected int |
height
The height of the display |
protected Input |
input
The input system to pass to the game |
protected long |
lastFPS
The last time the FPS recorded |
protected long |
lastFrame
The time the last frame was rendered |
protected Game |
lastGame
The last game started |
protected long |
maximumLogicInterval
The maximum logic update interval |
protected long |
minimumLogicInterval
The minimum logic update interval |
protected boolean |
paused
True if the game is paused |
protected int |
recordedFPS
The last recorded FPS |
protected boolean |
running
True if we're currently running the game loop |
protected int |
samples
The number of samples we'll attempt through hardware |
protected static org.lwjgl.opengl.Drawable |
SHARED_DRAWABLE
The shared drawable if any |
protected boolean |
smoothDeltas
Smoothed deltas requested |
protected static boolean |
stencil
True if we require stencil bits |
protected long |
storedDelta
The stored delta |
protected boolean |
supportsMultiSample
True if this context supports multisample |
protected int |
targetFPS
The FPS we want to lock to |
protected boolean |
vsync
True if vsync has been requested |
protected int |
width
The width of the display |
| Constructor Summary | |
|---|---|
protected |
GameContainer(Game game)
Create a new game container wrapping a given game |
| Method Summary | |
|---|---|
void |
destroy()
Called to clean up the program's memory. |
static void |
enableSharedContext()
Enable shared OpenGL context. |
static void |
enableStencil()
|
protected void |
enterOrtho()
Enter the orthographic mode |
protected void |
enterOrtho(int xsize,
int ysize)
Enter the orthographic mode |
void |
exit()
Cause the game to exit and shutdown cleanly |
boolean |
getAlwaysRender()
True if this container should render when it has focus |
float |
getAspectRatio()
Get the aspect ratio of the screen |
static int |
getBuildVersion()
Get the build number of slick |
Font |
getDefaultFont()
Get the default system font |
protected int |
getDelta()
Retrieve the time taken to render the last frame, i.e. |
int |
getFPS()
Get the current recorded FPS (frames per second) |
Graphics |
getGraphics()
Get the graphics context used by this container. |
int |
getHeight()
Get the height of the game canvas |
Input |
getInput()
Get the input system |
float |
getMusicVolume()
Retrieve the current default volume for music |
int |
getSamples()
The number of samples we're attempting to performing using hardware multisampling |
abstract int |
getScreenHeight()
Get the height of the standard screen resolution |
abstract int |
getScreenWidth()
Get the width of the standard screen resolution |
static org.lwjgl.opengl.Drawable |
getSharedContext()
Get the context shared by all containers |
float |
getSoundVolume()
Retrieve the current default volume for sound fx |
long |
getTime()
Get the accurate system time |
int |
getWidth()
Get the width of the game canvas |
abstract boolean |
hasFocus()
Check if the game currently has focus |
protected void |
initGL()
Initialise the GL context |
protected void |
initSystem()
Initialise the system components, OpenGL and OpenAL. |
boolean |
isFullscreen()
Check if the display is in fullscreen mode |
abstract boolean |
isMouseGrabbed()
Check if the mouse cursor is current grabbed. |
boolean |
isMusicOn()
Check if music is enabled |
boolean |
isPaused()
Check if the container is currently paused. |
boolean |
isShowingFPS()
Check if the FPS is currently showing |
boolean |
isSoundOn()
Check if sound effects are enabled |
boolean |
isUpdatingOnlyWhenVisible()
Check if this game is only updating when visible to the user (default = true) |
boolean |
isVSyncRequested()
True if vsync is requested |
protected void |
onResize()
Called when the GL context is resized. |
void |
pause()
Pause the game - i.e. |
void |
reinit()
Renitialise the game and the context in which it's being rendered |
void |
resume()
Resumt the game - i.e. |
boolean |
running()
True if the game is running |
void |
setAlwaysRender(boolean alwaysRender)
Indicate whether we want this container to render when it has focus |
void |
setAnimatedMouseCursor(java.lang.String ref,
int x,
int y,
int width,
int height,
int[] cursorDelays)
Get a cursor based on a image reference on the classpath. |
void |
setClearEachFrame(boolean clear)
Indicate if we should clear the screen at the beginning of each frame. |
void |
setDefaultFont(Font font)
Set the default font that will be intialised in the graphics held in this container |
abstract void |
setDefaultMouseCursor()
Set the default mouse cursor - i.e. |
void |
setForceExit(boolean forceExit)
Indicate if we should force exitting the VM at the end of the game (default = true) |
void |
setFullscreen(boolean fullscreen)
Indicate whether we want to be in fullscreen mode. |
abstract void |
setIcon(java.lang.String ref)
Set the icon to be displayed if possible in this type of container |
abstract void |
setIcons(java.lang.String[] refs)
Set the icons to be used for this application. |
void |
setMaximumLogicUpdateInterval(int interval)
Set the maximum amount of time in milliseconds that can passed into the update method. |
void |
setMinimumLogicUpdateInterval(int interval)
Set the minimum amount of time in milliseonds that has to pass before update() is called on the container game. |
abstract void |
setMouseCursor(org.lwjgl.input.Cursor cursor,
int hotSpotX,
int hotSpotY)
Set the mouse cursor to be displayed - this is a hardware cursor and hence shouldn't have any impact on FPS. |
abstract void |
setMouseCursor(ImageData data,
int hotSpotX,
int hotSpotY)
Set the mouse cursor to be displayed - this is a hardware cursor and hence shouldn't have any impact on FPS. |
abstract void |
setMouseCursor(Image image,
int hotSpotX,
int hotSpotY)
Set the mouse cursor based on the contents of the image. |
abstract void |
setMouseCursor(java.lang.String ref,
int hotSpotX,
int hotSpotY)
Set the mouse cursor to be displayed - this is a hardware cursor and hence shouldn't have any impact on FPS. |
abstract void |
setMouseGrabbed(boolean grabbed)
Indicate whether mouse cursor should be grabbed or not |
void |
setMultiSample(int samples)
Indicate whether we want to try to use fullscreen multisampling. |
void |
setMusicOn(boolean on)
Indicate whether music should be enabled |
void |
setMusicVolume(float volume)
Set the default volume for music |
void |
setPaused(boolean paused)
Indicates if the game should be paused, i.e. |
void |
setShowFPS(boolean show)
Indicate whether the container should show the FPS |
void |
setSmoothDeltas(boolean smoothDeltas)
Indicate if we want to smooth deltas. |
void |
setSoundOn(boolean on)
Indicate whether sound effects should be enabled |
void |
setSoundVolume(float volume)
Set the default volume for sound fx |
void |
setTargetFrameRate(int fps)
Set the target fps we're hoping to get |
void |
setUpdateOnlyWhenVisible(boolean updateOnlyWhenVisible)
Indicate if the display should update only when the game is visible (the default is true) |
void |
setVerbose(boolean verbose)
Inidcate we want verbose logging |
void |
setVSync(boolean vsync)
Indicate whether the display should be synced to the vertical refresh (stops tearing) |
void |
sleep(int milliseconds)
Sleep for a given period |
boolean |
supportsMultiSample()
Check if this hardware can support multi-sampling |
protected void |
updateAndRender(int delta)
Update and render the game |
protected void |
updateFPS()
Updated the FPS counter |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Field Detail |
|---|
protected static SGL GL
protected static org.lwjgl.opengl.Drawable SHARED_DRAWABLE
protected long lastFrame
protected long lastFPS
protected int recordedFPS
protected int fps
protected boolean running
protected int width
protected int height
protected Game game
protected Input input
protected int targetFPS
protected long minimumLogicInterval
protected long storedDelta
protected long maximumLogicInterval
protected Game lastGame
protected boolean clearEachFrame
protected boolean paused
protected boolean forceExit
protected boolean vsync
protected boolean smoothDeltas
protected int samples
protected boolean supportsMultiSample
protected boolean alwaysRender
protected static boolean stencil
| Constructor Detail |
|---|
protected GameContainer(Game game)
game
- The game to be wrapped| Method Detail |
|---|
public static void enableStencil()
public void destroy()
public void setDefaultFont(Font font)
font
- The font to use as defaultpublic void setMultiSample(int samples)
samples
- The number of samples to attempt (2 is safe)public boolean supportsMultiSample()
public int getSamples()
public void setForceExit(boolean forceExit)
forceExit
- True if we should force the VM exitpublic void setSmoothDeltas(boolean smoothDeltas)
smoothDeltas
- True if we should report smooth deltaspublic boolean isFullscreen()
public float getAspectRatio()
public void setFullscreen(boolean fullscreen) throws SlickException
fullscreen
- True if we want to be in fullscreen mode
SlickException
- Indicates we failed to change the display modepublic static void enableSharedContext() throws SlickException
SlickException
- Indicates a failure to create the shared drawablepublic static org.lwjgl.opengl.Drawable getSharedContext()
public void setClearEachFrame(boolean clear)
clear
- True if the the screen should be cleared each framepublic void reinit() throws SlickException
SlickException
- Indicates a failure rerun initialisation routinespublic void pause()
public void resume()
public boolean isPaused()
public void setPaused(boolean paused)
paused
- True if the game should be pausedpublic boolean getAlwaysRender()
public void setAlwaysRender(boolean alwaysRender)
alwaysRender
- True if this container should render when it has focuspublic static int getBuildVersion()
public Font getDefaultFont()
getDefaultFont
in interface GUIContext
public boolean isSoundOn()
public boolean isMusicOn()
public void setMusicOn(boolean on)
on
- True if music should be enabledpublic void setSoundOn(boolean on)
on
- True if sound effects should be enabledpublic float getMusicVolume()
public float getSoundVolume()
public void setSoundVolume(float volume)
volume
- the new default value for sound fx volumepublic void setMusicVolume(float volume)
volume
- the new default value for music volumepublic abstract int getScreenWidth()
getScreenWidth
in interface GUIContext
public abstract int getScreenHeight()
getScreenHeight
in interface GUIContext
public int getWidth()
getWidth
in interface GUIContext
public int getHeight()
getHeight
in interface GUIContext
public abstract void setIcon(java.lang.String ref) throws SlickException
ref
- The reference to the icon to be displayed
SlickException
- Indicates a failure to load the iconpublic abstract void setIcons(java.lang.String[] refs) throws SlickException
refs
- The reference to the icon to be displayed
SlickException
- Indicates a failure to load the iconpublic long getTime()
getTime
in interface GUIContext
public void sleep(int milliseconds)
milliseconds
- The period to sleep for in millisecondspublic abstract void setMouseCursor(java.lang.String ref, int hotSpotX, int hotSpotY) throws SlickException
setMouseCursor
in interface GUIContext
ref
- The location of the image to be loaded for the cursorhotSpotX
- The x coordinate of the hotspot within the cursor imagehotSpotY
- The y coordinate of the hotspot within the cursor image
SlickException
- Indicates a failure to load the cursor image or create the hardware cursorpublic abstract void setMouseCursor(ImageData data, int hotSpotX, int hotSpotY) throws SlickException
setMouseCursor
in interface GUIContext
data
- The image data from which the cursor can be construtedhotSpotX
- The x coordinate of the hotspot within the cursor imagehotSpotY
- The y coordinate of the hotspot within the cursor image
SlickException
- Indicates a failure to load the cursor image or create the hardware cursorpublic abstract void setMouseCursor(Image image, int hotSpotX, int hotSpotY) throws SlickException
image
- The image to use as the cursorhotSpotX
- The x coordinate of the hotspot within the cursor imagehotSpotY
- The y coordinate of the hotspot within the cursor image
SlickException
- Indicates a failure to load the cursor image or create the hardware cursorpublic abstract void setMouseCursor(org.lwjgl.input.Cursor cursor, int hotSpotX, int hotSpotY) throws SlickException
setMouseCursor
in interface GUIContext
cursor
- The cursor to usehotSpotX
- The x coordinate of the hotspot within the cursor imagehotSpotY
- The y coordinate of the hotspot within the cursor image
SlickException
- Indicates a failure to load the cursor image or create the hardware cursorpublic void setAnimatedMouseCursor(java.lang.String ref, int x, int y, int width, int height, int[] cursorDelays) throws SlickException
ref
- The reference to the image to be loadedx
- The x-coordinate of the cursor hotspot (left -> right)y
- The y-coordinate of the cursor hotspot (bottom -> top)width
- The x width of the cursorheight
- The y height of the cursorcursorDelays
- image delays between changing frames in animation
SlickException
- Indicates a failure to load the image or a failure to create the hardware cursorpublic abstract void setDefaultMouseCursor()
setDefaultMouseCursor
in interface GUIContext
public Input getInput()
getInput
in interface GUIContext
public int getFPS()
public abstract void setMouseGrabbed(boolean grabbed)
grabbed
- True if mouse cursor should be grabbedpublic abstract boolean isMouseGrabbed()
protected int getDelta()
protected void updateFPS()
public void setMinimumLogicUpdateInterval(int interval)
interval
- The minimum interval between logic updatespublic void setMaximumLogicUpdateInterval(int interval)
interval
- The maximum interval between logic updatesprotected void updateAndRender(int delta) throws SlickException
delta
- The change in time since last update and render
SlickException
- Indicates an internal fault to the game.public void setUpdateOnlyWhenVisible(boolean updateOnlyWhenVisible)
updateOnlyWhenVisible
- True if we should updated only when the display is visiblepublic boolean isUpdatingOnlyWhenVisible()
protected void onResize()
protected void initGL()
protected void initSystem() throws SlickException
SlickException
- Indicates a failure to create a native handlerprotected void enterOrtho()
public void setShowFPS(boolean show)
show
- True if the container should show the FPSpublic boolean isShowingFPS()
public void setTargetFrameRate(int fps)
fps
- The target fps we're hoping to getpublic void setVSync(boolean vsync)
vsync
- True if we want to sync to vertical refreshpublic boolean isVSyncRequested()
public boolean running()
public void setVerbose(boolean verbose)
verbose
- True if we want verbose logging (INFO and DEBUG)public void exit()
public abstract boolean hasFocus()
public Graphics getGraphics()
protected void enterOrtho(int xsize, int ysize)
xsize
- The size of the panel being usedysize
- The size of the panel being used
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


Two Wiznet 810 W5200 Ethernet modules for Ciseco OpenKontrolGateway
Costs £25 new: http://shop.ciseco.co.uk/openkontrol-gateway/
Happy to sell for £10 each or £15 for pair. Fully working, just excess to our needs. Will throw in a whole OKG unit for extra £5
£3.50 Worldwide Postage + packaging
Please email me glyn.hudson [AT] openenergymonitor.org if your interested
Re: SOLD - 2 x OpenKontrolGateway Wiznet 810 W5200 Etherent modules £10 (Retail £25)
These have now been sold


Generated by SCIgen, the completely reliable paper machine.
The complexity theory method to multicast algorithms is defined not only by the refinement of voice-over-IP, but also by the unproven need for scatter/gather I/O. after years of key research into replication, we verify the exploration of IPv7. Our focus in this work is not on whether the much-touted robust algorithm for the emulation of e-business by Martinez et al. [6] is NP-complete, but rather on introducing an autonomous tool for synthesizing multi-processors (Puff) [6].


The Puzzler is a VR game that is similar to Simon Says. Instead of following instructions from someone, you have to follow the pattern in which the spheres light up. The Puzzler is a great intro app for those with no VR experience, thisproject focuses on how to design VR environments in a manner that is understandable and pleasant. Designing and developing this gamegave me experience in creating environments effi ciently by taking advantage of axis of symmetry. I was also able to set interactive elements in the game, things like walking, clicking buttons with responsive sound were great things to learn as well.
The building of this app also taught me about the design process. The design approach I took was to figure out a persona or whom I wanted to build this app for and then going through sketches to havean idea of the end result. I concluded this by doing some basic user testing to make sure the interaction was clear and effi cient. I’ll describe each step in more detail next.
Statement of Purpose: The Puzzler is a simple and easy to use mobile VR app that engages new VR users to solve a puzzle similar to the Simon game in a challenging and fun way.
My user for this project is my husband. The user can help the designer understand what can be improved in the VR app. A seamless VR experience is such where you don’t have a feeling that you are in a different space, where things like motion sickness are minimized and your objects have a realistic dimension. Updating every time there is a change can be tedious but it definitely saves time and you can finish your project with more confidence.
In my sketches I tried to draw what I wanted in my VR app, having something on paper helped with how I wanted to start building.
For my first user test, I asked a user with very little VR experience the questions below to help judge if the scale of the building and objects in the scene felt appropriate.
I had to increase the size of the building so it did not feel like the user will hit their head entering the dungeon.
My second test was done after adding 2 billboard signs to start and restart the game and background sound
Following the user’s feedback, I adjusted the users point of view distance so that all orbs are visible by the user when they look forward.
Last user test was done after the VR app was completed.
Moved the player up so it would be further away from the floor
The VR app starts with the player outside of the dungeon. The game starts once the “Begin” button is clicked.
Game starts by entering the dungeon, there will be orbs floating thatwill light up in a certain order. The player must follow the correct sequence to win, if there is a mistake they will be notified with a sound. At this point another sequence will start and player gets more chances to complete the correct pattern. After winning, the player advances to exit the dugenon and a restart billboard is shown.
This VR app project was a great learning experience. It gave me a sense of what the design process should be and the importance of understanding your user and getting feedback.  Overall it gives you a sense of what to expect as a VR developer for end-to-end project.


Civil and Environmental Engineering Major
Computer Engineering Major
Electrical Engineering Major
German Minor
Aerospace Engineering Major
Mechanical Engineering Major
Chemical Engineering Major
Computer Science Major
Finance Major
Chinese Major


Our goal is to try and find you a charity that you may be interested in, and how you can help that cause.
If you would like to help the lives of many wildlife, click here for charities you can help.
Help people all around the world deal with health problems, education issues, and others.
Environmental charities work to preserve and protect the environment and to promote environmental research, conservation, and appreciation.


PyCon France 2023
It has been 4 years since I gave a keynote at PyCon France, they are welcome to be back with open arms!
Day 1 - Sprint
I took the first flight in the morning and arrived around 10 am, the orientation of the sprint has already started. All projects are giving presentations and many of them are trying to speak in both French and English. I appreciated that. After the presentation, we all break out into different rooms to work. But before that, I got some coffee - the organisers gave us light refreshments and coffee. Seems they know I need coffee to function!
@pyconfr sprint orientation, half of it is in French… I am not good enough at French to understand so I got a “I speak English” flag. Will get better next year! pic.twitter.com/6akFc0OyRw
— Cheuk Ting Ho (@cheukting_ho) February 16, 2023
However, as I still got work to do, after chatting with some friends and maintainers, I have to sit down in a corner to catch up on some work. But I managed to grab lunch with some folks that are sprinting and we sit outside to enjoy lunch and the nice weather - I do not miss London regarding the weather.
After lunch, I did a bit more work and then went to check in at the hotel. I took a nap as I woke up at 3 am to catch my flight. After my Zoom meeting later that day, I head out to meet up with my colleague and friends for drinks and dinner. It was fun.
Had a blast yesterday for a drink with the folks @pyconfr pic.twitter.com/ZDdrdIg78P
— Cheuk Ting Ho (@cheukting_ho) February 17, 2023
Day 2 - More sprinting
I tried to wake up early but when I arrived at the venue, it was already 10 am when I got there. But people are still chilling at the breakfast table, so I guess I was not late.
@pyconfr was so nice to give us light breakfast and bottomless coffee for the sprinters ❤ pic.twitter.com/ytRAKPQYTS
— Cheuk Ting Ho (@cheukting_ho) February 17, 2023
After that, I went back to the sprint rooms to work. But then I met Victor again! But he is busy helping the sprint with translating the official Python documentation to French. So he went there. I tried to finish as much work as I can then I headed to the city centre for lunch. This is my second time in Bordeaux but I have never seen the city in daylight! So I grab this chance to have lunch there and have a walk in the city.
Les esprits bouillonnent à la PyConFR ! pic.twitter.com/zyRfaDTbq6
— PyConFr (@pyconfr) February 16, 2023
In the evening, my colleague Sophia and I were having dinner together. It’s nice to hang out with your team once in a while.
Day 3 - Conference day 1
It’s a very sunny day! After arriving and bag check, the opening is starting. Although I do not understand a word, the room was full of energy and people are hyped about the start of the conference.
@pyconfr is starting 🤩 pic.twitter.com/zS0j9mfZL3
— Cheuk Ting Ho (@cheukting_ho) February 18, 2023
After the opening, I do not have too much time to hang around as I have to give my talk in another room. The unfortunate thing is that the presentation stream setup is not done properly yet and we have a 15 mins delay due to technical difficulties. (I should sing a song while they are setting it up)
.@cheukting_ho presenting Python memory profiling at @pyconfr 🙌 pic.twitter.com/AUzJX6orGO
— Sophia Yang (@sophiamyang) February 18, 2023
After my talk, I met a few friends outside and we chat with some organisers in France. The weather was so nice we went out to grab a gallette - a savoury crepe. I associate this food with PyCon France as in 2019 that’s what I had for lunch every day.
Will I have another galette today? @pyconfr pic.twitter.com/AB3nFcAByB
— Cheuk Ting Ho (@cheukting_ho) February 19, 2023
Then it’s Sophia’s talk, it’s about PyScript.
After lunch @pyconfr @sophiamyang is giving a talk about @pyscript_dev pic.twitter.com/g3czDVkQeP
— Cheuk Ting Ho (@cheukting_ho) February 18, 2023
After that, I went to Max’s talk - he is from the UK but he is trying very hard to speak French there.
By the time the wrap-up session of the day, I am already tired. So I went back to the hotel to lie down for a bit before the social event.
@europython announcement at @pyconfr #CfP and #FinAid open on 6th March - there are also speaker mentorship program available ❤ pic.twitter.com/OvTufRZVqm
— Cheuk Ting Ho (@cheukting_ho) February 18, 2023
I was a bit lost when I tried to find the place for the social event, and when I got there, it was already packed with people. I was told that the catering company workers are striking so that explained why the organisers were serving the food themselves.
Social event @pyconfr with nice wine and food - the organisers were serving the food themselves - thank you so much pic.twitter.com/UxlFUfbR03
— Cheuk Ting Ho (@cheukting_ho) February 19, 2023
The social event was great! I had many nice conversations with organisers from the Czech Republic and other local conference attendees. Only a few people do not speak French but at the end of the day, it does not matter, we all had a good time.
Day 4 - Conference day 2
In the morning it was the annual meeting of the L’Association Francophone Python so I do not need to attend (it will be in french anyway). So I aim to be at the venue at 10 am. I arrived a bit early and had a chat with Marine of Taipy and she was so nice to offer me some Canelés which is the local delicacy. I hope I will be able to grab some to bring home later.
Back to London from @pyconfr Managed to get some Canelés home ❤ the trip ended on a high note pic.twitter.com/tgRL1JWFTP
— Cheuk Ting Ho (@cheukting_ho) February 19, 2023
In the morning I gave my talk and also attend Raphaël’s talk about version control - the talk is in French so I was there to give moral support.
Maybe the only French talk I attend this year - talk by Raphaël @pyconfr pic.twitter.com/9jeMgkDmGi
— Cheuk Ting Ho (@cheukting_ho) February 19, 2023
Then I grab some lunch at the food truck with Autur, a board member of the EuroPython Society, we spent some time in the after talking about ideas for EuroPython. I also managed to interview some organisers of PyCon France.
Closing session - Did you had a good time @pyconfr? pic.twitter.com/kgSdkenlp1
— Cheuk Ting Ho (@cheukting_ho) February 19, 2023
The last day of the conference is shorter and we had a closing session at around 3 pm. Everyone seems to enjoy the conference. Congratulation and thank you to the organising team of PyCon France.
See some people that I met at PyCon France:


Documentation
Introduction
Azia Angular Admin is a responsive Angular 8 template that is based on the CSS framework Bootstrap 4 and it is built with Sass. Sass compiler makes it easier to code and customize. If you are unfamiliar with Bootstrap or Sass, visit their website and read through the documentation. All of Bootstrap components have been modified to fit the style of Azia Angular Admin and provide a consistent look throughout the template.
Before you start working with the template, we suggest you go through the pages that are bundled with the theme. Most of the template example pages contain quick tips on how to create or use a component which can be really helpful when you need to create something on the fly.
File Structure
Once you have download the package you will see the following folder structure inside the folder.
Installation
Set up the Development Environment
Install Node.js and npm if they are not already on your machine.
Angular CLI is a command line interface for the latest Angular. Install it before start with the Angular app.
If you have Angular CLI installed previously, update it to the latest Angular CLI. Remove the older version and re-install it.
Template Installation
Go to the project directory and install the Angular local project dependencies.
Run npm install
. This command install the dependencies in the local node_modules
folder.
By default, npm install
will install all modules listed as dependencies in package.json
.
The ng serve
command launches the server, watches your files, and rebuilds the app as you make changes to those files.
Using the --open
(or just -o
) option will automatically open your browser on http://localhost:4200/.
For more detailed information to install the Angular application, visit this official Angular documentation website.
Deployment
Deploy Angular app
For the simplest deployment, create a production build and copy the output directory to a web server.
1. Start with the production build:
2. Copy everything within the output folder (dist/) to a folder on the server.
3. Configure the server to redirect requests for missing files to index.html.
If you copy the files into a server sub-folder, append the build flag, --base-href
and set the <base href>
appropriately.
For example, if the index.html
is on the server at /my/app/index.html
, set the base href to <base href="/my/app/">
like this.
If you're serving the app out of a subfolder, edit a version of index.html to set the base href appropriately.
For example, if the URL to index.html
is www.mysite.com/my/app/index.html
, set the base href to:
Learn more about the role of <base href>
below.
You also can set the base href right in the ng build
command
For more detailed information, visit this official Angular documentation website.
Basic Structure
App Component
Header
Footer
Customer Support
If you face any issues while using Azia Angular Admin Template, please feel free to contact us via BootstrapDash support desk.
We will respond to you as quickly as we can.


A Fee for a given Plan.
| Attr plan: | ForeignKey(Plan) |
|---|---|
| Attr name: | CharField(max_length=100) |
| Attr group: | ForeignKey(FeeGroup) |
| Attr default_amount: | |
| DecimalField(default=0) |
add a fee to the given user, with description and amount. if amount is not passed, then it will use default_amount if it is greater than 0.
if 404 or 422 are returned, the default action is not to save the line item to the db, this can be overriden with the setting SPREEDLY_SAVE_ON_FAIL, but it is not recomended as who knows what will happen.
| Parameters: |
|
|---|---|
| Raises : | ValueError if the user is not subscribed to the plan or is subscribed to a different plan. |
| Raises : | Http404 if spreedly can’t find the plan, user, etc. |
| Raises : | HttpUnprocessableEntity if spreedly raised 422 for some reason. |
FeeGroup(name)
This is an instance of a fee
Subscription plan
Manager that handles syncing plans and finding enabled plans
Class that manages the details for a specific auth.User‘s subscription to a plan. Since a user can only have one subscription, this is sometimes treated as a user profile class.
Add a fee to the subscription
| Parameters: |
|
|---|---|
| Returns: | None |
| Raises : | Http404 if incorrect subscriber, HttpUnprocessableEntity for any other 422 error |
Allow a free Trial
| Returns: | Subscription |
|---|---|
| Raises : | Exception (of some kind) if bad juju |
| Raises : | NotImplementedError cause it isn’t implemented |
|---|
update a subscription with supplied data


A Universal Plotting Tool
A Universal Plotting Tool
Pick Data Source:
Online File
Upload Files
Staged Files
Online File
Online Data File:
Variable Name:
{{onlineFileVarDict[key]['longName']}}
name:
dim:
units:
OPeNDAP
Upload files
Select files to upload:
Drag and Drop Files Here
Files Progress
0%
Upload (button)
Variable Name:
{{uploadFileVarDict[key]['longName']}}
name:
dim:
units:
Staged Files
Model:
Variable:
{{varList[key][0]}}
name:
dim:
units:
Data Subsetting
longitude (deg):
pick a value
average over
form an axis
latitude (deg):
pick a value
average over
form an axis
pressure (hPa):
pick a value
average over
form an axis
Time (year-month-day):
pick a value
average over
form an axis
Use Full Range
{{this.timeDashV(this.timeSLim) + ' to ' + this.timeDashV(this.timeELim)}}
Display Options:
Ferret Level Type:
10 levels
10 levels, variance-based
10 levels, zero-centered
10 levels, histogram-based
interval=0.5
vmin=0, vmax=35, interval=1, open-ended
vmin=0, vmax=35, interval=1; outside values cropped
vmin=0, vmax=35, interval=1; within (25,28), interval=0.5
   Modify It:
Specify Colormap:
rainbow
centered
bright_centered
white_centered
grayscale
inverse_grayscale
red_blue_centered
topo
ocean_temp
yellow_orange_brown
brown_orange_yellow
warm_cmyk
terrestrial
Plot Title:
Analysis Purpose:
Generate Data
Download Data
Browser URL:
Refresh
Open a page with the browserUrl
Copy to clipboard
Data File URL:
{{data_url}}
Service Response Text:


node_editor.graphics.graphics_resizable_rect_item module¶
-
class
node_editor.graphics.graphics_resizable_rect_item.
QGraphicsResizableRectItem
(min_height, min_width, *args)¶ Bases:
PyQt5.QtWidgets.QGraphicsRectItem
-
initUI
()¶
-
initContent
()¶
-
initTitle
()¶
-
property
height
¶
-
property
width
¶
-
updateHandles
()¶
-
boundingRect
(self) → QRectF¶
-
handleAt
(point)¶
-
hoverMoveEvent
(self, QGraphicsSceneHoverEvent)¶
-
hoverLeaveEvent
(self, QGraphicsSceneHoverEvent)¶
-
mousePressEvent
(event: PyQt5.QtWidgets.QGraphicsSceneMouseEvent) → None¶ Executed when the mouse is pressed on the item.
-
mouseReleaseEvent
(event: PyQt5.QtWidgets.QGraphicsSceneMouseEvent) → None¶ Executed when the mouse is released from the item.
-
mouseMoveEvent
(event: PyQt5.QtWidgets.QGraphicsSceneMouseEvent) → None¶ Executed when the mouse is being moved over the item while being pressed.
-
resize
(pos)¶ Update rectangle and bounding rectangle
-
shape
()¶ Returns the shape of this item as a QPainterPath in local coordinates.
-
paint
(self, QPainter, QStyleOptionGraphicsItem, widget: QWidget = None)¶
-


hey,
you shouldnt be here.
you probably typed a url trying to look at my web files.
shame on you, don't let me catch you here again.
if you weren't spying on my files and ended up here by accident, my bad. sorry about that accusation.
suporte@mozg.com.br


CATALOG
WANT TO GRAB SOME FREE BASIC COURSES?
REGISTER NOW !!!
Here are some amazing courses which u should try!!!!
HTML 5 AND CSS FUNDAMENTALS FOR BEGINNERS
MACHINE LEARNING
CAREER DEVELOPMENT
C FOR BEGINNERS
PYTHON FOR BEGINNERS
JAVA
ARTIFICIAL INTELLIGENCE
DATA STRUCTURES AND ALGORITHMS
BASIC YOUTUBE COURSES


WITNESS LIST
Ways & Means Committee
September 26, 2016 - 10:00 AM
Chapter 313
On:
Craymer, Dale (Texas Taxpayers and Research Association)
Elliott, Verma (State Auditor's Office)
Lehman, Jennifer (Texas State Auditor's Office)
Rivero, Hector (Texas Chemical Council)
Registering, but not testifying:
On:
Hicks, Willie (State Auditor's Office)
Franchise Tax
On:
Currah, Tom (Comptroller)
Greener, Jerome (Americans for prosperity)
Kavanaugh, Kevin (Legislative Budget Board)
Marine Goods and Services
On:
Allison, Greg (Self; Bay area houston economic development)
Urbanic, Simon (Bay Area Houston EcOnomic Partnership)
Registering, but not testifying:
On:
Reynolds, Brad (Comptroller)
Reynolds, Brad (Comptroller)
Property Tax
On:
Esparza, Mike (Comptroller of Public Accounts)
Greener, Jerome (Americans for prosperity)
Kavanaugh, Kevin (Legislative Budget Board)
Kennedy, John (Texas Taxpayers and Research Association)
Mcgeady, John (Legislative Budget Board)
Mesick, Bill (Comptroller of Public Accounts)
Pulver, Wayne (Legislative Budget Board)
South, Brent (Texas Association of Appraisal Districts)
Revenue & Budget Overview
On:
Currah, Tom (Comptroller of Public Accounts)
Parks, Ursula (Legislative Budget Board)
1
WITNESS LIST
State Tax Litigation
On:
Currah, Tom (Comptroller)
2


Get the Lead Out, Pittsburgh is a city wide coalition of organizations committed to raising awareness and making preventative steps towards lead remediation.
READ MOREThe Pittsburgh Water & Sewer Authority has posted guidelines about water contaminant remediation.
READ MOREFollow the steps outlined by the Urban Redevelopment Authority of Pittsburgh to replace your service line.
READ MORE


Aston Martin V8 Vantage
Specs(V8 Vantage/600)
Price |
$275,283 / N/A |
Top Speed |
186mph(officially) record 191mph/ N/A |
Acceleration |
|
Engine |
|
0-30mph |
2.1sec / N/A |
Type |
Twin Supercharged V8 , 32valve Quad cam / same |
0-60mph |
4.6sec / 4.3sec? |
Displacement |
5.3L(5340cc) / same |
0-100 |
11.3(est.) / N/A |
Power |
550hp@6500rpm / 600hp@? |
1/4 mile |
13.2sec/?mhp / N/A |
Torque |
551 lbs-ft@4000rpm / 600lbs-ft@? (!!) |
Weight |
4,020 lbs / slightly heavier |
Handling |
|
Gas mileage |
14.5mpg |
Skidpad |
N/A |
City |
N/A |
600ft slalom |
N/A |
Highway |
N/A |
Powertrain |
Front engined, rear wheel drive, 6 speed manual / same |
(? = incomplete data or unverified info, N/A = info Not Available)
Beyond the specs:
Fully equipped with all the luxury expected of an Aston Martin, this fairly heavy car (2 tons is by no means light!) has amazing acceleration. For those who want to go very fast but still want luxury worthy of a king then this is the car for you, that's if of course if you can afford it. Simply put, this 550hp beast can in the right hands embarrass almost any musclecar driver who dares to test it, all while allowing its occupants to enjoy the leathery lap of luxury. Just remember that having good tire grip, a 2-ton vehicle with 551 lbs-ft of torque is not quite the easiest combination to handle.
~Oracle


LZ
Discrete Fourier Transform
This is just my understanding / intuitive explanation of what this algorithm means.
So, what's the objective here?
Digital signals in sounds usually come to us in the time-domain form. That is to say a linear array of values, each relating to a sample in time.
The fundamental question we are asking is this:
- "how do we make a frequency-domain representation of a signal?"
What we will see is that this question is really the same question as:
- "What sinusoids are present in a signal, and what is their amplitude and phase?"
A Roundabout Introduction
Joseph Fourier was a French mathematician who was doing his thing at the end of the 18th to the beginning of the 19th centuries. Two things that we will discuss carry his name: The Fourier Transforms and Fourier Series. A Fourier series is a representation of a signal as a sum of a series of sinusoids. The Fourier Transforms are, as far as we are concerned, algorithms for identifying which sinusoids are in that series. So it's essentially a the recipe of a signal, where the raw ingredients are sinusoids.
Sinusoids, circles and epicycles
Let's start by thinking of a sinusoid as an aspect of circular movement in relation to time. As we probably all learned in school at some stage, sine and cosine functions describe the ratios of various sides of a right-angle triangle as its angle \(\theta\) changes. You may have seen some sort of visual representation of this with a right-angle triangle in the unit circle, like this:
If we add a more circles to our system we can start to make more elaborate periodic signals, like so:
So we have this idea that given enough circles, you can make all sorts of complicated 2D patterns.
This idea was well understood way back into antiquity. Many scientists through history have been concerned with mapping out the movements of the stars. Since the idea that the earth was the center of the universe was generally accepted for a long time, many extremely elaborate models of circles within circles were dreamt up to explain the movements of the heavenly bodies. This method of circles with circles was called deferent and epicycle. Despite being wrong, this vision of the universe managed to give pretty accurate predictions, and was relied on for millennia until Copernicus came along with heliocentrism.
Remember the popular toy Spirograph? That was essentially based on the idea of epicycles. The image below shows the kind of beautiful mess that epicycles and geocentricism gave us:
In the words of Norwood Russell Hanson:
There is no bilaterally-symmetrical, nor eccentrically-periodic curve used in any branch of astrophysics or observational astronomy which could not be smoothly plotted as the resultant motion of a point turning within a constellation of epicycles, finite in number, revolving around a fixed deferent.
Rather than trying to work through any formal proof here, I think it's quite sufficient at this stage to just assume the following: Just like having enough circles can explain the movement of all the stars in the redundant geocentric model - given enough sinusoids, using destructive and constructive interference, we could make any signal we want.
We could demonstrate this by proving that we can make a single-sample impulse and then extrapolating that to show we could add those impulses together to make any series of samples. But I think that's a distraction here, and the end result is intuitive.
Amplitude and Phase
What we do need is a method to find out which sinusoids are in a given signal. Just the frequency of those sinusoids isn't enough information. We also need their amplitude and phase properties. You know what those are, right? Amplitude is how loud the sinusoid is, phase is its offset in time.
Here's a sinusoid with its amplitude being changed:
And here's one with its phase value being changed:
Phase is aurally a strange property because we don't really hear it in the direct sense we hear frequency or amplitude, however it can affect sounds differently in different situations from resultant destructive and constructive interference.
So, as we discussed above, with enough sinusoids with various frequency, amplitude and phase values can make any signal we like. But how to find out which frequencies, amplitudes and phase values we need?
Hold that thought. We're going to need to make sure some other mathematical dependencies are installed in your brain-sacks in order to solve this problem. If these concepts are all new to you, or you want more depth on these topics then further reading on them is definitely recommended, we'll barely scratch the surface here. Links at the bottom of the article
Imaginary and Complex Numbers
\[i = \sqrt{−1}\]
This number i, sometimes called j by engineers, is the unit of imaginary numbers. Mathematics was having a hard time reconciling the idea of square roots with negative numbers, because it makes no intuitive sense to to find a number that multiplies with itself to make a negative. The solution was to just give them a new name.
Imaginary numbers were first described as such by René Descartes, who was essentially taking the piss out of what he and many mathematicians saw as a bandage-job and not proper maths. However, as time passed it became clear that this solution opened up a whole bunch of interesting possibilities that so-called real numbers didn't offer.
Incidentally, if you think imaginary is a rubbish name for them, then you are not alone. Gauss suggested lateral numbers as a better name, which makes a lot of sense to me.
We can treat i in many of the same ways we would an algebraic variable, which is handy. So \[3\times 2i = 6i\] or \[\frac{10i}{2} = 5i\] and so on.
We can also use them alongside real numbers. The combination of imaginary and real numbers are what we call complex numbers. This is usually just written as an addition, for example \[10 + 5i\]. While these complex numbers don't really have a position on a normal 1 dimensional number line, we can position them in two dimensions. This is usually done with the x-axis as real and the y-axis as imaginary. Here's \(4 + 3i\) in the complex plane:
As with any position in a 2D space, we can use Cartesian coordinates, but we can also talk about it in polar coordinates, terms of a magnitude and angle.
Using basic trigonometry we can work out its polar coordinates from the Cartesian ones. We know that the magnitude, which is just the hypotenuse of a right-angle triangle, and therefore equal to \[\sqrt{real^2 + ima^2}\], and the angle is equal to \[\tan^{−1}({\frac{ima}{real}})\].
Eventually we'll use complex numbers to start talking about circular movements in the complex plane, and that will be very useful for figuring out what sinusoids are living in a signal. Before that let's boot up some other concepts we'll need.
Euler's Number
Usually known as simply e, Euler's number is a mathematical constant. It's a real, irrational number that's approximately equal to 2.71828. This number is important to us because it's intrinsically linked to continuous growth. We can imagine how we get to e through an analogy to compound interest.
Growth
This section seems pretty unrelated at first, but it's actually key to understanding the DFT. I should add that this bank loan analogy is just an analogy. I don't understand anything about finance or loans. Just go with it.
Imagine we take out a loan from the bank in January. It's only a small loan, just £1.00 in fact! However, we get a really bad interest rate for our loan: 100% per year. Now after a year how much do we owe the bank? Well, it depends on when they calculate the interest. If it's at the end of the year, for example:
- Then we owe them the original £1 + another £1 of interest. That's £2.
But what if they calculate it half-way through the year?
- /That'd be 50% in June and then 50% in January. So in June the debt becomes £1 + 50% of £1. So a total of £1.50. Then we get to January and we have £1.50 + 50% of £1.50, so a total of £2.25. That's a worse deal for us!/
OK, so how about 4 times a year?
- /That's £1 + £0.25 = £1.25 in March, then by June we're at £1.56 ish. September takes us to around £1.95. Now by the New Year we're at about £2.44./
We can see a pattern forming, the more we divide up the year, the more money we owe by the end of it. This value doesn't shoot up uncontrollably however, it converges around the value £2.71828… our old friend e.
So, e is the value that you get if you grow 1 continuously by 100% for exactly 1 unit of time.
We can use e as a base of an exponent to grow 1 by amounts other than 100%:
- as we've already seen, growing at 100% yields: \[e^1 \approx 2.71828\]
- Growing at 200%: \[e^2 \approx 7.368\]
- Growing at 300%: \[e^3 \approx 20.086\]
These are the values that you'd end up with if our initial interest rate was 200% or 300% respectively. So, going forward, whenever we see something in the format \(e^n\), we can think of it as 1 being grown for one unit of time an \(n\times 100\%\).
What about for longer than 1 unit of time? Well, we can break down n into a multiplication. What n really equals is \[rate \times duration\]. Why? Well growing something at 100% for 3 units of time is really just the same result as growing it at 300% for one unit of time.
What about if we don't want our initial loan to be £1?  Well we can just multiply the whole thing by the initial amount we want, so we end up with a sort of formula for continuous growth:
\[a \times e^{rd}\]
Where a equals our initial amount, r is the rate and d is the duration.
For example, if we had some gray goo that grows continuously at a rate 300%. If we start with 10 grams of gray goo on the beginning of Monday, by the end of Wednesday we'll have \[10 \times e^{3 \times 3} = 81030.8392758\], so about 81.03kg of gray goo!
How is all this gray goo stuff helping us with the Fourier Transforms?
This all seems pretty far away from our main agenda now, I know, but what we are going to see is that growth really translates into rotation when we start using e in the complex plane. That is going to help us make a tool for seeking out sinusoids in a signal.
Imaginary Growth is Anticlockwise Rotation
To turn growth into rotation, let's try growing 1 by i, so using our formula this is \(e^i\). If we put this into a calculator we'll get back something like: \(0.540302306 + 0.841470985 i\).
What happened there? We got a complex number, both components have a value between 0 and 1. Maybe you would have expected at least the real component to get bigger since we started with 1 and grew it. Things get a bit clearer if we think \(e^i\) in polar coordinates.
Remember the magnitude is \(\sqrt{real^2 + ima^2}\).
So that's \[\sqrt{0.540302306^2 + 0.841470985^2} ~= 1 \]
And recall the angle is equal to \[\tan^{−1}({\frac{ima}{real}})\] .
So \[\tan^{−1} \left( \frac{0.841470985}{0.540302306} \right ) = 57.29577951282339\]. Which doesn't seem too special until you convert it from degrees to radians. Then you'll see the answer comes to (allowing for some rounding error) 1.
So what's really happened is that we've grown our initial 1 but, instead of going further along the real axis, it has grown along the edge of a perimeter circle exactly one radian. We've rotated it by 1.
The upshot is we can use e to make circles. This is the basis of the complex sinusoid.
Complex sinusoid
The complex sinusoid is really just the sum of two sinusoids, one real and one imaginary. These two sinusoids are in phase quadrature, which is just a fancy way of saying exactly halfway between in phase and perfectly out of phase. This is also called sometimes called an orthogonal relationship, meaning they are at right-angles. This makes sense because their phase difference is 90 degrees.
The most obvious example of sinusoids in phase quadrature are the sine and cosine functions; sine is really just a cosine that's been shifted forward by 90 degrees.
Think about quadrature as when sinusoids of the same frequency are at the most unrelated they can possibly be. Which is to say, while in phase or close to it they match pretty well up, and while perfectly out of phase or close to it they are not far off being mirror images of each other. In quadrature they are as dissimilar as can be without becoming opposite.
We can use the rotational abilities of Euler's number to generate our complex sinusoid. As we saw above, we can use e to rotate a point in a circular arc. At any stage of rotation the position of that point can be described by Cartesian coordinates, which are just the two sides of a right-angle triangle.
Along the real axis we'll have a length (the adjacent side of a right-angle triangle) that will oscillate as a cosine function, and along the imaginary axis the length (which is same length as the opposite side of a right-angle triangle) will describe a sine function. This is how we use the magic of e to make a complex sinusoid:
\[e^{i\omega t} = \cos(\omega t) + i\sin(\omega t)\]
Where \(t\) is the time and \(\omega\) is frequency.
This is an alternative form of Euler's formula. This gives rise to one of the most beautiful mathematical identities out there, known as Euler's identity. It's a related but tangential topic which I encourage you to read about.
Taking the formula above, if we keep \(\omega = 1\) and increment through \(t\) in time, we the situation described by the animation below: The imaginary component is in blue and the real component is in green.
There is no magic to having a real and an imaginary component, it's just a convenience. We need two sinusoids in quadrature, as we will see this helps us get the phase information of the sinusoids inside a signal. Using a complex sinusoid helps us keep it all compact and tidy.
The Discrete Fourier Transform
We've got all the bits we need! We're going to just dive in:
OK, there's a bunch going on here, it'll take a bit of unpicking:
We need to know that \(x\) is the input signal and \(X\) is the output spectrum. \(N\) is the number of samples in our input signal. Notice the distinction between \(N\) and \(n\), which is really the time index of our input signal. Everyone else you've already met, or is defined in the equation. We'll go through with the colours:
- Frequency bin k in the output spectrum X equals…
- the sum, of…
- The nth sample of our input signal
- Multiplied by
- -i times a full circle's worth of radians of rotation times the k, which is the bin number, times...
- n the present sample number, over N, the number of samples in our input signal
Let's clarify things a bit. Frequency bins are essentially the frequencies that we will graph on our output spectrum. There are as many of them as there are samples in the input signal. They represent the sinusoids in the signal.
There are two variables in this that we are looping through: k and n. The k is the bin frequencies and the n is the time indices. Think of the n loop as being inside the k loop. For every new k we get the full range of n.
The sum goes from 0 to N-1 (so thats N many). From this we can see that for every frequency bin we are summing together N things. That's potentially a lot of summing, which is why the DFT can sometimes be slow. Inside that sum is our input signal multiplied by a complex sinusoid. The exponent of our complex sinusoid has a rate, which is \(2 \pi\) radians (ie. all the way round) times k, which is the frequency. The exponent also has a time, which is n samples out of a total of N.
Notice the sign of the exponent is negative, because we are rotating here clockwise rather than an anticlockwise as we have been before.
As we already know, the complex sinusoid is made up of a real cosine function and an imaginary sine function. So we could just as well write in ether of these forms:
So here's a broad-stroke description:
For every frequency we make a complex sinusoid of the given frequency and multiply that with our input signal. The sum of all the samples of the resulting multiplication will indicate the amount of that frequency present in the signal.
You may be asking yourself…
Why are we multiplying our input signal by sinusoids?
The complex sinusoid is different for each bin. It's frequency is set by k. This complex sinusoid hunts for a sinusoid that matches it in our input signal and, if it finds something, will give us back some numbers that we can then use to find the amplitude and phase of of that frequency.
Imagine we have a sinusoid A, which is at Nyquist frequency, 7 samples long:
If we summed all of these samples we'd get -1. The 1s mostly cancel out the -1s along the way, and if this was an even longer signal they'd continue to do so, no matter how many samples long this sinusoid was, the sum of all it's samples would never equal anything greater than 1 or less than -1.
Say we do a point-wise multiplication this by a sinusoid of a another sinusoid of a different frequency, for example ½ Nyquist frequency:
The sum of AB is now 0. The positives cancel out the negatives even after the multiplication.
However, what if we multiply A by a sinusoid with the same frequency?
Now the sum of AB = 7 because a negative times a negative is a positive. This in phase quality of A and B yields a larger number. The size of this number really tells us the amount of B in A, times the number of samples in total. If A and B were perfectly out of phase we'd get a -7, telling us that A is the exact opposite of B.
However, if it's not in phase or exactly out of phase then we are not going to get such a clear indication of its presence. That's why we need both components of the complex sinusoid. Let's see this by working through some examples:
Examples
We'll start with a signal to test. Here's a signal made from two sinusoids. We'll use the just the real part of the DFT to find out which sinusoids.
We'll call this input signal x.
It's 10 samples long (0 to 9). The DFT always uses the same number of bins as the length of the input signal. So our output spectrum will show 10 frequencies. So we're going to make 10 sinusoids and multiply our input signal above with them:
So k goes from 0 to 9. Our real sinusoids are as follows. Notice 2 things: Firstly, these cosines are not very smooth because of the low sample-rate. That's OK though. Secondly, once we get past a frequency of \[2 \pi \times 5\] the frequencies look like they are going back down. Once we pass Nyquist we enter into negative frequencies. These are just discarded if we are analyzing the real signal (ie. any sound signal) since they will give results symmetrical to the positive frequencies. With this first example we'll only look at the real component of our complex sinusoids.
In this case, for example you might see the results that are all zero apart from at frequencies 2 and 3 (and their respective negative frequencies 7 and 8). These are indeed the frequencies that x was made from. Here they both happened to be at 0 phase, so we can catch it all with just the real sinusoids.
But what happens if they don't start at the right time? We'll try another example and use both the real and imaginary components of our complex sinusoids.
We looked at calculating phase and magnitude before when we were talking about points in the complex plane. This is what we'll do with our real and imaginary components.
*What we need to do here is imagine the sums of our multiplications of the signal with our real and imaginary sinusoids as Cartesian coordinates, and we want to work out their polar coordinates - their magnitude and phase.*
Here's a new example: it is also 10 samples long, but we'll only bother with the frequencies up to Nyquist because of the symmetry explained above.
As we can see, the two sinusoids were matching the bin frequencies 1 and 4. At 1 it was in phase, at 4 it was one radian out of phase.
This is what the DFT does. It gives us a set of coordinates for each frequency, and from those we can work out the magnitude and phase. If you graphed the magnitude section, you'd get what you might recognise as a static frequency spectrum of that sound.
Some Properties of the DFT
The bigger the DFT, the more frequency detail
Since the number of frequency bins depends on the number of samples that are input, we can say that the longer the sample size, the more detail frequency we can get in our output spectrum.
The magnitude spectrum is symmetrical around the y-axis for any real signal
As we've seen, the DFT gives us magnitude and phase values for a set of frequencies. These frequencies are determined by the length of the input signal. However, in practice we are only using the first half of them because the second half become the negative frequencies and are symmetrical.
If a sinusoid in a signal doesn't exactly match a bin frequency, a peak will form at its closest bin frequency
We only saw what happens if the input signal is made of sinusoids that perfectly match one of the bin frequencies - what happens if there are sinusoids present that are not exactly one of those frequencies? Well, our input signal is inherently band-limited because it is discrete. So there simply can't exist any frequencies which are above Nyquist or below the frequency of a sinusoid that completes one oscillation across the entire length of N. Nonetheless we could have a frequency that is in between two of our bin frequencies (in fact, out in the wild most frequencies will be like that). In this case the DFT will give you a peak at the closest bin frequency and the rest of the sinusoids energy will be distributed around a bunch of other bins at a generally low level.
The magnitude is scaled by the number of samples in the input signal
Also, you may have noticed that the magnitude spectrum output is scaled by the number of samples in our input signal. To get the amplitude you'll have to divide it by N.
Where next?
As pointed out at the top of the page, we barely scratched the surface here. I hope, however, it is enough to solidify some of the basic concepts and provide an "a-ha" or two. Some key topics we've missed here include the benefits of zero-padding, zero-phase windowing, windows, and many more. I strongly recommend Julius Smith's website for a very in-depth read on all the main topics. It's an awful lot more academic than the approach in this article.
For a fun journey through the ideas surrounding imaginary numbers, this youtube series has great explanations and very watchable.
BetterExplained has a good article on Euler's formula. It's very clear and jargon-free.
As ever, if you read this all then thanks for humoring me and please let me know of any corrections or suggestions you have. I'm not formally trained in any of this stuff, I just learn it for fun and I hope that comes through.


LOTR gets second season before first even begins
The pre-production of the Lord of The Rings series is underway, and a second season of series has already been confirmed.
Deadline reported Amazon's studio head Jennifer Salke confirmed the news.
The 2017 rights deal for the global TV production of the J.R.R. Tolkien series included a multi-season and spinoff commitments, but Amazon Studios must green light each new season to go ahead.
The show will be produced in New Zealand and is set to be the most expensive TV show ever produced.
The timing of the deal means the hiatus between the first and second seasons will be shorter, and the break about filming the first two episodes will allow the writing team to produce the majority of the scripts for season two.
The approach is similar to how Peter Jackson filmed the LOTR movie trilogy, and the strategy allows for efficient filming. It could mean parts of season two are able to be shot during the first season's production.
It also caters for New Zealand's weather, with filming set to get underway in 2020 after winter.
J.D. Payne and and Patrick McKay are the show's executive producers and showrunners. The lead cast of the show is yet to be confirmed, however, Will Poulter, Markella Kavenagh and Joseph Mawle are reported to be starring in the series.


{% extends "base.html" %} {% block title %}Contact{% endblock %} {% block content %} {% load static %}
Alumni Needs enables you to harness the power of your alumni network. Whatever may be the need


Holds an auxiliary mshadow gpu stream that can be synced with a primary stream.
More...
#include <base.h>
|
| static void | StreamSync (mshadow::Stream< gpu > *s1, mshadow::Stream< gpu > *s2, cudaEvent_t event) |
| | Make future work enqueued to s2 wait on completion of current work enqueued to s1 . More...
|
| |
Holds an auxiliary mshadow gpu stream that can be synced with a primary stream.
| mxnet::GPUAuxStream::GPUAuxStream |
( |
mshadow::Stream< gpu > * |
primary_stream | ) |
|
|
inlineexplicit |
constructor.
- Parameters
-
| primary_stream | gpu stream that is synced with the created auxiliary stream. |
| mxnet::GPUAuxStream::~GPUAuxStream |
( |
| ) |
|
|
inline |
| mshadow::Stream<gpu>* mxnet::GPUAuxStream::GetStream |
( |
| ) |
|
|
inline |
Getter for created auxiliary stream.
| void mxnet::GPUAuxStream::PostAuxStreamUseSync |
( |
| ) |
|
|
inline |
Makes future primary stream work wait on the completion of existing aux stream work.
| void mxnet::GPUAuxStream::PreAuxStreamUseSync |
( |
| ) |
|
|
inline |
Makes future aux stream work wait on the completion of existing primary stream work.
| static void mxnet::GPUAuxStream::StreamSync |
( |
mshadow::Stream< gpu > * |
s1, |
|
|
mshadow::Stream< gpu > * |
s2, |
|
|
cudaEvent_t |
event |
|
) |
| |
|
inlinestatic |
Make future work enqueued to s2
wait on completion of current work enqueued to s1
.
- Parameters
-
| s1 | stream with work that must be completed before future s2 work can begin. |
| s2 | stream whose future work is made to wait on the completion of existing s1 work. |
| event | used to pass s1 state to s2. |
The documentation for this class was generated from the following file: