TECNO Camon 12 Air Review: Far Better Than I Thought
by George KamauThe TECNO Camon 12 Air was recently launched and I’ve been using for a couple of weeks now as my daily driver. The TECNO Camon 12 Air is the cheaper and better-designed smartphone in the TECNO Camon 12 series. The TECNO Camon 12 Air is the only device in this price range that features a punch-hole display. It’s not as feature-rich as the rest of the TECNO Camon 12 devices but still managed to impress me more than I expected.
Design
The TECNO Camon 12 Air comes in a beautiful and reflective colour gradient back where the triple ai-powered cameras and a fingerprint sensor are located. The phone is also light as a feather and makes for a good phone for those who hate bulky phones.
The phone’s back boasts triple camera setup vertically aligned on the top left corner. Next to the cameras is a quad-LED flash.
There’s a 6.55″ 720p display that features a punch-hole selfie camera with decent viewing angles but under direct sunlight makes it hard to read articles. The Dot-in display gives users of the TECNO Camon 12 Air a full-screen experience when browsing the web, consuming media or lazily going through your social media feeds.
The front of the TECNO Camon 12 Air has minimal side bezels. However, there’s a relatively large chin.
Performance
The TECNO Camon 12 Air comes with 3GB of RAM, 32GB of onboard storage and runs on Android 9 Pie with HiOS version 5.5.2. You’ll also get a MediaTek Helio P22 processor powers the phone. The performance is not class-leading but for the TECNO Camon 12 handles basic stuff well.
The phone also performs decently for some graphics-heavy tasks but you’ll occasionally have the stutter. Overall, the performance is surprisingly good and multitasking was no issue on this phone courtesy of the relatively fast processor and 3 gigs of RAM.
HiOS offers a few useful customisations options when it’s not annoying you with intermittent ads such as the Smart Panel and Fonts app. You’ll have to uninstall some of the preinstalled bloatware that comes with the phone.
Gaming on the TECNO Camon 12 is possible only at low settings. If you go with high settings, you’ll notice frame rates drop for games like Asphalt 9. If you’re a casual gamer, then this phone is for you.
The 4000mAh battery will push the TECNO Camon 12 Air through to the next day if you’re a light user but if you heavily tax your phone, you’ll still get a full day performance but you’ll have to juice it up before you go to sleep.

You can trust the TECNO Camon 12 Air with its relatively superb performance considering the price category it exists in.
Cameras
The TECNO Camon 12 Air spots a 16MP, 5MP and 2MP lens for the rear cameras and an 8MP selfie shooter. In well-lit scenes, the cameras areversatile and will give you decent shots. You have modes such as beauty, Bokeh, Portrait, AR Shot, Panorama, Wide Selfie and Video to play around with. Here are some samples and as always, click to expand.
Selfies
Portrait
Beauty Mode
Regular Shots
Bokeh shots
Low light
Being AI-powered gives the cameras an upper hand in scene recognition and optimising them to take better shots.
In low lit scenes, the cameras give an average performance and low image quality.
The macro camera works well and you ‘ll not be disappointed.
Generally, you won’t go wrong with the cameras on the TECNO Camon 12 Air especially in well-lit scenarios.
Should you buy it?
You’d think that the TECNO Camon 12 Air is underpowered since it lacks some of the features of its bigger siblings but that’s not the case. The phone impressed me in my hands-on review and still did after the honeymoon period.
The TECNO Camon 12 Air makes it easy to recommend to people as it’s not only the most interesting phone because of its modern-looking design in this fiercely contested price segment but also brings with it capable cameras, trustworthy performance and decent battery life – all at a budget.
The TECNO Camon 12 Air is available online and in TECNO retail stores and you can buy it for Ksh 13,499.


assigned
by None at 2022-12-12 16:39:48.closed
by None at 2022-12-12 12:41:37.Import profile updated per #298 ; awaiting creation in prod (see https://github.com/PrincetonUniversityLibrary/alma-config/issues/340)
labeled
by None at 2022-12-12 12:43:27.closed
by None at 2022-12-12 12:47:02.labeled
by None at 2022-12-12 12:48:21.referenced
by None at 2022-12-12 20:14:19.referenced
by Christina Chortaria at 2022-12-12 13:14:10.merged
by Christina Chortaria at 2022-12-12 13:14:10.closed
by Christina Chortaria at 2022-12-12 13:14:10.head_ref_deleted
by Christina Chortaria at 2022-12-12 13:14:11.Digital Science has indicated that accessing the CIFS/Samba share is not preferred or possible for this approach. Instead, two possible solutions are proposed: - RDSS uploads the HR feed report from the CIFS share to the Digital Science FTP endpoint - Google Sheets be updated and shared with Digital Science
I am going to proceed with trying both solutions, and then proceeding with informing OIT and Digital Science of the best possible solution from what I can best determine.
labeled
by Eliot Jordan at 2022-12-12 16:28:16.referenced
by Trey Pendragon at 2022-12-12 17:56:20.merged
by Trey Pendragon at 2022-12-12 17:56:20.closed
by Trey Pendragon at 2022-12-12 17:56:20.head_ref_deleted
by Trey Pendragon at 2022-12-12 17:56:21.Ran PrunePreservationObjectsJob
on all resources with multiple objects. There are no redundant preservation objects in Figgy now, but until #5584 and #5585 are merged, we'll have to periodically clean these up.
We think there might be a small race condition left over, but don't expect to hit it. We'll deploy #5584 and check to see if we're still getting duplicates.
The race condition is "a PreserveResourceJob starts, gets past the lock token check, and someone edits while it's actively being preserved, then that second queued PreserveResourceJob starts"
referenced
by Eliot Jordan at 2022-12-12 18:03:14.merged
by Eliot Jordan at 2022-12-12 18:03:14.closed
by Eliot Jordan at 2022-12-12 18:03:14.head_ref_deleted
by Eliot Jordan at 2022-12-12 18:03:15.deployed
by None at 2022-12-12 16:27:20.head_ref_force_pushed
by Eliot Jordan at 2022-12-12 18:02:30.labeled
by Eliot Jordan at 2022-12-12 18:11:06.assigned
by Eliot Jordan at 2022-12-12 18:49:04.assigned
by Eliot Jordan at 2022-12-12 20:32:31.head_ref_force_pushed
by Eliot Jordan at 2022-12-12 21:38:29.renamed
by Max Kadel at 2022-12-12 21:47:25.assigned
by Jane Sandberg at 2022-12-12 16:34:59.assigned
by Robert-Anthony Lee-Faison at 2022-12-12 16:35:12.deployed
by None at 2022-12-12 16:39:42.referenced
by Jane Sandberg at 2022-12-12 16:42:04.merged
by Jane Sandberg at 2022-12-12 16:42:04.closed
by Jane Sandberg at 2022-12-12 16:42:04.head_ref_deleted
by Jane Sandberg at 2022-12-12 16:42:05.labeled
by None at 2022-12-12 16:42:31.labeled
by None at 2022-12-12 16:42:31.deployed
by None at 2022-12-12 18:32:57.referenced
by Jane Sandberg at 2022-12-12 18:34:18.merged
by Jane Sandberg at 2022-12-12 18:34:18.closed
by Jane Sandberg at 2022-12-12 18:34:18.head_ref_deleted
by Jane Sandberg at 2022-12-12 18:34:19.@leefaisonr @sandbergja rubocop failed circleci
mentioned
by Jane Sandberg at 2022-12-13 00:00:51.subscribed
by Jane Sandberg at 2022-12-13 00:00:51.mentioned
by Robert-Anthony Lee-Faison at 2022-12-13 00:00:51.subscribed
by Robert-Anthony Lee-Faison at 2022-12-13 00:00:51.labeled
by Christina Chortaria at 2022-12-12 13:54:30.labeled
by Christina Chortaria at 2022-12-12 13:54:30.assigned
by Christina Chortaria at 2022-12-12 16:31:51.Both link and requests look good on catalog-qa.
assigned
by Max Kadel at 2022-12-12 16:56:17.assigned
by Christina Chortaria at 2022-12-12 16:56:49.assigned
by Kevin Reiss at 2022-12-12 16:56:49.assigned
by Robert-Anthony Lee-Faison at 2022-12-12 16:56:49.assigned
by None at 2022-12-12 16:56:50.assigned
by None at 2022-12-12 16:56:50.assigned
by Jane Sandberg at 2022-12-12 16:57:06.closed
by Max Kadel at 2022-12-12 16:58:30.There are now three events:
https://www.google.com/books/
)https://library.princeton.edu/resolve
)https://na05.alma.exlibrisgroup.com/view/uresolver/01PRI_INST
)closed
by Jane Sandberg at 2022-12-12 18:27:44.moved_columns_in_project
by Jane Sandberg at 2022-12-12 18:27:45.Coverage remained the same at 94.499% when pulling b00621364aa23d33fb6acaf561a289a179d33d5b on 3284-request-button-fixes into a7994535832251bf252977ccf4fe83c4ad7fa29f on main.
@kevinreiss updated the initial ticket with three more examples and he also describes some of the scenarios that could be tested https://github.com/pulibrary/orangelight/issues/3284.
ready_for_review
by None at 2022-12-12 14:19:55.mentioned
by Kevin Reiss at 2022-12-12 15:58:03.subscribed
by Kevin Reiss at 2022-12-12 15:58:03.deployed
by None at 2022-12-12 19:36:07.referenced
by Christina Chortaria at 2022-12-12 19:46:46.merged
by Christina Chortaria at 2022-12-12 19:46:46.closed
by Christina Chortaria at 2022-12-12 19:46:46.head_ref_deleted
by Christina Chortaria at 2022-12-12 19:46:47.closed
by Christina Chortaria at 2022-12-12 19:46:47.referenced
by Bess Sadler at 2022-12-12 13:25:31.merged
by Bess Sadler at 2022-12-12 13:25:31.closed
by Bess Sadler at 2022-12-12 13:25:31.head_ref_deleted
by Bess Sadler at 2022-12-12 13:25:32.referenced
by Bess Sadler at 2022-12-12 13:26:09.merged
by Bess Sadler at 2022-12-12 13:26:09.closed
by Bess Sadler at 2022-12-12 13:26:10.head_ref_deleted
by Bess Sadler at 2022-12-12 13:26:10.closed
by Bess Sadler at 2022-12-12 13:26:11.referenced
by Bess Sadler at 2022-12-12 13:27:26.merged
by Bess Sadler at 2022-12-12 13:27:26.closed
by Bess Sadler at 2022-12-12 13:27:26.head_ref_deleted
by Bess Sadler at 2022-12-12 13:27:27.closed
by Bess Sadler at 2022-12-12 13:27:28.assigned
by Hector Correa at 2022-12-12 14:42:22.assigned
by Hector Correa at 2022-12-12 14:42:48.Agreed, this was implemented in PR: https://github.com/pulibrary/pdc_describe/pull/654
closed
by Hector Correa at 2022-12-12 15:20:16.@mccalluc This is elegant easy-to-read code, which goes a long way toward solving a tricky problem. Well done! I've approved but I'm not going to merge in case others want to weigh in.
mentioned
by Chuck McCallum at 2022-12-12 13:23:57.subscribed
by Chuck McCallum at 2022-12-12 13:23:57.review_dismissed
by Chuck McCallum at 2022-12-12 14:39:54.referenced
by Chuck McCallum at 2022-12-12 15:23:27.merged
by Chuck McCallum at 2022-12-12 15:23:27.closed
by Chuck McCallum at 2022-12-12 15:23:27.head_ref_deleted
by Chuck McCallum at 2022-12-12 15:23:28.While we were cleaning out staging we utilized production to test our new rake tasks in #707.
We deleted all Works( datasets) and data from S3.
Changing over the DOI to production can be accomplished by modifying this file: https://github.com/pulibrary/princeton_ansible/blob/main/group_vars/pdc_describe/production.yml#L41-L50
We are going to wait until a round of test migration has occurred before making this change.
labeled
by None at 2022-12-12 18:40:47.I am sorry, I will look to port these proposed changes into https://github.com/pulibrary/pdc_describe/pull/692
convert_to_draft
by James R. Griffin III at 2022-12-12 13:33:38.assigned
by James R. Griffin III at 2022-12-12 15:05:14.head_ref_force_pushed
by James R. Griffin III at 2022-12-12 18:18:09.ready_for_review
by James R. Griffin III at 2022-12-12 18:19:03.head_ref_force_pushed
by James R. Griffin III at 2022-12-12 18:23:25.review_requested
by James R. Griffin III at 2022-12-12 19:07:23.assigned
by None at 2022-12-12 20:17:52.assigned
by Hannah H at 2022-12-12 21:15:59.unassigned
by Hannah H at 2022-12-12 21:40:38.ready_for_review
by Chuck McCallum at 2022-12-12 21:51:11.assigned
by Chuck McCallum at 2022-12-12 22:02:13.@bess This is the code that we ran during our meeting. It worked correctly.
head_ref_force_pushed
by None at 2022-12-12 14:29:35.convert_to_draft
by None at 2022-12-12 14:36:43.head_ref_force_pushed
by None at 2022-12-12 14:48:08.deployed
by None at 2022-12-12 14:56:31.deployed
by None at 2022-12-12 16:16:12.ready_for_review
by None at 2022-12-12 18:14:00.mentioned
by Bess Sadler at 2022-12-12 18:14:43.subscribed
by Bess Sadler at 2022-12-12 18:14:43.renamed
by None at 2022-12-12 18:32:05.referenced
by Bess Sadler at 2022-12-12 22:54:57.merged
by Bess Sadler at 2022-12-12 22:54:57.closed
by Bess Sadler at 2022-12-12 22:54:57.head_ref_deleted
by Bess Sadler at 2022-12-12 22:54:58.referenced
by None at 2022-12-12 14:19:51.assigned
by None at 2022-12-12 14:20:04.referenced
by None at 2022-12-12 14:29:35.referenced
by None at 2022-12-12 14:48:07.closed
by Bess Sadler at 2022-12-12 22:54:58.referenced
by Bess Sadler at 2022-12-12 22:54:58.referenced
by None at 2022-12-12 14:48:08.closed
by Bess Sadler at 2022-12-12 22:54:58.closed
by Bess Sadler at 2022-12-12 22:54:59.renamed
by Chuck McCallum at 2022-12-12 16:24:30.review_dismissed
by Chuck McCallum at 2022-12-12 21:11:43.@mccalluc I moved the JS to its own file and add it to the manifest.
mentioned
by Hannah H at 2022-12-12 16:45:22.subscribed
by Hannah H at 2022-12-12 16:45:22.head_ref_force_pushed
by Hector Correa at 2022-12-12 17:46:43.head_ref_force_pushed
by Hector Correa at 2022-12-12 17:49:22.mentioned
by Chuck McCallum at 2022-12-12 20:09:54.subscribed
by Chuck McCallum at 2022-12-12 20:09:54.review_requested
by Hector Correa at 2022-12-12 20:11:31.head_ref_force_pushed
by Hector Correa at 2022-12-12 20:41:41.referenced
by Bess Sadler at 2022-12-12 23:02:24.merged
by Bess Sadler at 2022-12-12 23:02:24.closed
by Bess Sadler at 2022-12-12 23:02:24.head_ref_deleted
by Bess Sadler at 2022-12-12 23:02:25.closed
by Bess Sadler at 2022-12-12 23:02:25.head_ref_force_pushed
by Hector Correa at 2022-12-12 21:02:15.assigned
by Tyler Wade at 2022-12-12 21:42:07.labeled
by Kevin Reiss at 2022-12-12 14:45:07.assigned
by Kevin Reiss at 2022-12-12 14:45:07.referenced
by Robert-Anthony Lee-Faison at 2022-12-12 15:23:08.merged
by Robert-Anthony Lee-Faison at 2022-12-12 15:23:08.closed
by Robert-Anthony Lee-Faison at 2022-12-12 15:23:08.head_ref_deleted
by Robert-Anthony Lee-Faison at 2022-12-12 15:23:09.referenced
by Vickie Karasic at 2022-12-12 15:29:48.merged
by Vickie Karasic at 2022-12-12 15:29:48.closed
by Vickie Karasic at 2022-12-12 15:29:48.head_ref_deleted
by Vickie Karasic at 2022-12-12 15:29:49.review_requested
by Max Kadel at 2022-12-12 15:39:17.referenced
by Christina Chortaria at 2022-12-12 15:43:05.merged
by Christina Chortaria at 2022-12-12 15:43:05.closed
by Christina Chortaria at 2022-12-12 15:43:05.head_ref_deleted
by Christina Chortaria at 2022-12-12 15:43:06.closed
by Francis Kayiwa at 2022-12-12 18:05:26.Small PR for minor fqrn updates to 'zookeeper' role.
heya @leefaisonr thanks! this needs to be ansible.builtin.service
review_requested
by Robert-Anthony Lee-Faison at 2022-12-12 16:49:11.mentioned
by Robert-Anthony Lee-Faison at 2022-12-12 17:07:42.subscribed
by Robert-Anthony Lee-Faison at 2022-12-12 17:07:42.referenced
by Francis Kayiwa at 2022-12-12 20:26:26.merged
by Francis Kayiwa at 2022-12-12 20:26:26.closed
by Francis Kayiwa at 2022-12-12 20:26:26.head_ref_deleted
by Francis Kayiwa at 2022-12-12 20:26:27.review_requested
by Francis Kayiwa at 2022-12-12 20:26:42.referenced
by Francis Kayiwa at 2022-12-12 20:33:28.merged
by Francis Kayiwa at 2022-12-12 20:33:28.closed
by Francis Kayiwa at 2022-12-12 20:33:28.head_ref_deleted
by Francis Kayiwa at 2022-12-12 20:33:29.head_ref_force_pushed
by Jane Sandberg at 2022-12-12 22:51:44.referenced
by Christina Chortaria at 2022-12-12 23:56:39.merged
by Christina Chortaria at 2022-12-12 23:56:39.closed
by Christina Chortaria at 2022-12-12 23:56:39.head_ref_deleted
by Christina Chortaria at 2022-12-12 23:56:40.referenced
by Eliot Jordan at 2022-12-12 18:05:38.merged
by Eliot Jordan at 2022-12-12 18:05:38.closed
by Eliot Jordan at 2022-12-12 18:05:39.head_ref_deleted
by Eliot Jordan at 2022-12-12 18:05:39.@dependabot rebase
mentioned
by Dependabot at 2022-12-12 18:05:57.head_ref_force_pushed
by None at 2022-12-12 18:07:27.referenced
by Eliot Jordan at 2022-12-12 18:13:05.merged
by Eliot Jordan at 2022-12-12 18:13:05.closed
by Eliot Jordan at 2022-12-12 18:13:06.head_ref_deleted
by Eliot Jordan at 2022-12-12 18:13:07.assigned
by Jane Sandberg at 2022-12-12 18:38:37.renamed
by Jane Sandberg at 2022-12-12 22:37:04.deployed
by None at 2022-12-12 23:04:08.deployed
by None at 2022-12-12 23:17:13.labeled
by None at 2022-12-13 00:29:21.labeled
by None at 2022-12-13 00:29:21.


--- layout: post status: publish published: true title: One improvement - HP BL495c G5 is supported by VMware & HP author: display_name: iguy login: iguy email<EMAIL_ADDRESS>url: '' author_login: iguy author_email<EMAIL_ADDRESS>wordpress_id: 39 wordpress_url: http://itsjustanotherlayer.com/?p=39 date: !binary |- MjAwOC0xMS0xNyAwMzozNDozNSAtMDYwMA== date_gmt: !binary |- MjAwOC0xMS0xNyAwMzozNDozNSAtMDYwMA== categories: - Uncategorized tags: [] comments: [] ---
In a previous blog I had stated some concerns about HP BL495c G5's "Virtualization Blade". VMware ESX 3.5 Update 3 came out and now both HP and VMware are supporting it. Woot.


Reports methods with result type Unit
that do not have parameter clauses.
Methods with a result type of Unit
are only executed for their
side effects
and, by the convention, methods with side effects have at least one (empty) parameter clause.
The quick-fix adds an empty parameter clause.
Example:
def test: Unit = ()
After the quick-fix is applied:
def test(): Unit = ()


Year
: 2012
Road Surface Condition
all
dry
wet/snow
Light Condition
all
darkness
daylight
Weather Condition
all
fine
rain/snow/fog


Regularized Linear Regression and Bias v.s. Variance
January 24, 2018
Python machine learning matplotlibThis post covers the fifth exercise from Andrew Ng’s Machine Learning Course on Coursera.
Regularized Linear Regression and Bias v.s. Variance
Introduction
Regularized linear regression will be implemented and it will be used to study models with different bias-variance properties.
Regularized Linear Regression
Regularized linear regression will be implemented to predict the amount of water flowing out of a dam using the change of water level in a reservoir. Several diagnostics of debugging learning algorithms and the effects of bias v.s. variance will be examined.
Visualizing the Dataset
The loaded data with the loadmat
function from scipy
library contain historical records on the change in the water level, $x$
, and the amount of water flowing out of the dam, $y$
. A scatter plot of $y$
against $x$
is shown in Figure 1.
This dataset is divided into three parts:
- A training set that the model will learn on:
$X$
,$y$
- A cross validation set for determining the regularization parameter:
$Xval$
,$yval$
- A test set for evaluating performance. These are “unseen” examples which the model will not see during training:
$Xtest$
,$ytest$
First, linear regression will be modelled and it will be used to fit a straight line to the data and plot learning curves. Following that, a polynomial regression will be modelled to find a better fit to the data.
import numpy as np
from scipy.io import loadmat
import matplotlib.pyplot as plt
%matplotlib inline
data = loadmat('ex5data1.mat')
for k in data:
print(k)
__header__
__version__
__globals__
X
y
Xtest
ytest
Xval
yval
X = data['X']
y = data['y']
Xval = data['Xval']
yval = data['yval']
Xtest = data['Xtest']
ytest = data['ytest']
print("Shapes of X{} and y{}".format(X.shape, y.shape))
print("Shapes of Xval{} and yval{}".format(Xval.shape, yval.shape))
print("Shapes of Xtest{} and ytest{}".format(Xtest.shape, ytest.shape))
plt.figure(figsize=(8, 6))
plt.xlabel('Change in water level (x)')
plt.ylabel('Water flowing out of the dam (y)')
plt.title('Figure 1: Data')
plt.plot(X, y, 'rx')
Shapes of X(12, 1) and y(12, 1)
Shapes of Xval(21, 1) and yval(21, 1)
Shapes of Xtest(21, 1) and ytest(21, 1)
[<matplotlib.lines.Line2D at 0x180f16fcf8>]
Regularized Linear Regression Cost Function
The regularized linear regression has the following cost function:
$$J(\theta)=\frac{1}{2m}\left( \sum_{i=1}^{m}\left(h_\theta\left(x^{(i)}\right)-y^{(i)}\right)^2\right)+\frac{\lambda}{2m}\left( \sum_{j=1}^{n}\theta_j^2\right)$$
where $\lambda$
is a regularization parameter which controls the degree of regularization (thus, help preventing overfitting). The regularization term puts a penalty on the overal cost $J$
. As the magnitudes of the model parameters $\theta_j$
increase, the penalty increases as well. Note that the $\theta_0$
term should never be regularized. Running the cost function with theta initialized at $[1, 1]$
the output will be about $303.993$
.
Regularized Linear Regression Gradient
Correspondingly, the partial derivative of regularized linear regression’s cost for $\theta_j$
is defined as
$$\frac{\partial{J(\theta)}}{\partial{\theta_0}} = \frac{1}{m} \sum_{i=1}^{m}\left( h_\theta\left(x^{(i)}\right)-y^{(i)}\right)x_j^{(i)} \quad \text{for} \quad j=0$$
$$\frac{\partial{J(\theta)}}{\partial{\theta_j}} = \left(\frac{1}{m} \sum_{i=1}^{m}\left( h_\theta\left(x^{(i)}\right)-y^{(i)}\right)x_j^{(i)}\right)+\frac{\lambda}{m}\theta_j \quad \text{for} \quad j\geq1$$
Running the gradient function using theta initialized at $[1, 1]$
the gradient will be $[-15.30, 598.250]$
.
# Insert the 1's column.
X_with_1s = np.insert(X, 0, 1, axis=1)
Xval_with_1s = np.insert(Xval, 0, 1, axis=1)
# Create a function to compute cost and gradient.
def linearRegCostFunction(X, y, theta, lambda_coef):
"""
Computes cost and gradient for regularized
linear regression with multiple variables.
Args:
X: array (m, number of features+1)
y: array (m, 1)
theta: array (number of features+1, 1)
lambda_coef: float
Returns:
J: float
grad: vector array
"""
# Get the number of training examples, m.
m = len(X)
# Ensure theta shape(number of features+1, 1).
theta = theta.reshape(-1, y.shape[1])
#############################################################
###################### Cost Computation #####################
#############################################################
# Compute the cost.
unreg_term = (1 / (2 * m)) * np.sum(np.square(np.dot(X, theta) - y))
# Note that we should not regularize the theta_0 term!
reg_term = (lambda_coef / (2 * m)) * np.sum(np.square(theta[1:len(theta)]))
cost = unreg_term + reg_term
#############################################################
#################### Gradient Computation ###################
#############################################################
# Initialize grad.
grad = np.zeros(theta.shape)
# Compute gradient for j >= 1.
grad = (1 / m) * np.dot(X.T, np.dot(X, theta) - y) + (lambda_coef / m ) * theta
# Compute gradient for j = 0,
# and replace the gradient of theta_0 in grad.
unreg_grad = (1 / m) * np.dot(X.T, np.dot(X, theta) - y)
grad[0] = unreg_grad[0]
return (cost, grad.flatten())
# Initialize theta at [1, 1].
theta = np.array([[1], [1]])
# Run the cost function with theta [1, 1] and lambda_coef = 1.
(cost, grad) = linearRegCostFunction(X_with_1s, y, theta, 1)
print('Cost and Gradient at theta = [1, 1]:', (cost, grad))
Cost and Gradient at theta = [1, 1]:<PHONE_NUMBER>2026429, array([ -15.30301567,<PHONE_NUMBER>7]))
Fitting Linear Regression
Once the cost function and gradient are working correctly, the optimal values of $\theta$ in trainLinearReg
should be computed. This training function uses the minimize
function from scipy
to optimize the cost function.
In this part, the regularization parameter $\lambda$ is set to zero. Because the current implementation of linear regression is trying to fit a 2-dimensional $\theta$
, regularization will not be incredibly helpful for a $\theta$
of such low dimension. Later, polynomial regression with regularization will be used.
from scipy.optimize import minimize
def trainLinearReg(X, y, lambda_coef):
"""
Trains linear regression using the dataset (X, y)
and regularization parameter lambda_coef.
Returns the trained parameters theta.
Args:
X: array (m, number of features+1)
y: array (m, 1)
lambda_coef: float
Returns:
theta: array (number of features+1, )
"""
# Initialize Theta.
initial_theta = np.zeros((X.shape[1], 1))
# Create "short hand" for the cost function to be minimized.
def costFunction(theta):
return linearRegCostFunction(X, y, theta, lambda_coef)
# Now, costFunction is a function that takes in only one argument.
results = minimize(fun=costFunction,
x0=initial_theta,
method='CG',
jac=True,
options={'maxiter':200})
theta = results.x
return theta
# Train linear regression with lambda_coef = 0.
theta = trainLinearReg(X_with_1s, y, 0)
theta
array([ 13.08790351, 0.36777923])
- Note: Plotting the best fit line, results in the Figure 2 image. The best fit line depicts that the model is not a good fit to the data because the data has a non-linear pattern. While visualizing the best fit as shown is one possible way to debug the learning algorithm, it is not always easy to visualize the data and model. Next, a function will be implemented to generate learning curves that can help to debug the learning algorithm even if it is not easy to visualize the data.
plt.figure(figsize=(8, 6))
plt.xlabel('Change in water level (x)')
plt.ylabel('Water flowing out of the dam (y)')
plt.title('Figure 2: Linear Fit')
plt.plot(X, y, 'rx')
plt.plot(X, np.dot(np.insert(X, 0, 1, axis=1), theta), '--')
[<matplotlib.lines.Line2D at 0x1817fbc390>]
Bias-Variance
An important concept in machine learning is the bias-variance tradeoff. Models with high bias are not complex enough for the data and tend to underfit, while models with high variance overfit to the training data.
Next, training and test errors will be plotted on a learning curve to diagnose bias-variance problems.
Learning Curves
Learning curves which are useful in debugging learning algorithms will be generated. A learning curve plots training and cross validation error as a function of training set size. The code in learningCurve
will return a vector of errors for the training set and cross validation set.
To plot the learning curve, a training and cross validation set error for different training set sizes is required. To obtain different training set sizes, different subsets of the original training set $X$
should be used. Specifically, for a training set size of $i$
, the first $i$
examples (i.e., $X(1:i,:)$
and $y(1:i)$
) should be used.
The trainLinearReg
function can be used to find the $\theta$
parameters. Note that the $\lambda$
is passed as a parameter to the learningCurve
function. After learning the $\theta$
parameters, the error on the training and cross validation sets will be computed. The training error for a dataset is defined as
$$J_{train}(\theta)=\frac{1}{2m}\left( \sum_{i=1}^{m}\left(h_\theta\left(x^{(i)}\right)-y^{(i)}\right)^2\right)$$
In particular, note that the training error does not include the regularization term. One way to compute the training error is to use the existing cost function and set $\lambda$
to $0$
only when using it to compute the training error and cross validation error. When the training set error is going to be computed, it must be computed on the training subset (i.e., $X(1:n,:)$
and $y(1:n)$
) (instead of the entire training set). However, for the cross validation error, it is computed over the entire cross validation set. The computed errors will be stored in the vectors error_train
and error_val
. The learning curves will be printed and the errors against the number of training examples will be plotted (Figure 3).
# Create a function that generates the errors.
def learningCurve(X, y, Xval, yval, lambda_coef):
"""
Generates the train and cross validation set errors needed
to plot a learning curve. In particular, it returns two
vectors of the same length - error_train and error_val.
Then, error_train(i) contains the training error for
i examples (and similarly for error_val(i)).
Note:
We should evaluate the training error on the first
i training examples (i.e., X(1:i, :) and y(1:i)), but
for the cross-validation error, we should instead
evaluate on the entire cross validation set (Xval, yval).
Args:
X: array (m, number of features+1)
y: array (m, 1)
Xval: array (s, number of features+1)
yval: array (s, 1)
lambda_coef: float
Returns:
error_train: array (m, 1)
error_val: array (m, 1)
"""
# Get the number of training examples, m.
m = len(X)
# Initialize train and cross validation set errors.
error_train = np.zeros((m, 1))
error_val = np.zeros((m, 1))
for i in range(1, m+1):
# Train with different subsets of the training
# set X to obtain the theta parameters.
theta = trainLinearReg(X[:i], y[:i], lambda_coef)
# Compute train/cross validation errors, storing
# the result in error_train and error_val.
# Note that to compute the errors, we should call
# the function with the lambda_coef set to 0.
error_train[i-1] = linearRegCostFunction(X[:i], y[:i], theta, 0)[0]
error_val[i-1] = linearRegCostFunction(Xval, yval, theta, 0)[0]
return error_train, error_val
In Figure 3, it is clear that both the train error and cross validation error are high when the number of training examples is increased. This reflects a high bias problem in the model. The linear regression model is too simple and is unable to fit the dataset well. Next, a polynomial regression will be implemented to fit a better model for this dataset.
m = len(X)
# Get the errors with lambda_coef set to 0.
error_train, error_val = learningCurve(X_with_1s, y,
Xval_with_1s, yval, 0)
print('# Training Examples\tTrain Error\tCross Validation Error\n')
for i in range(m):
print('{}\t\t\t{:f}\t{:f}\n'.format(i+1, float(error_train[i]), float(error_val[i])))
plt.figure(figsize=(8, 6))
plt.xlabel('Number of training examples')
plt.ylabel('Error')
plt.title('Figure 3: Linear regression learning curve')
plt.plot(range(1,m+1), error_train, 'b', label='Train')
plt.plot(range(1,m+1), error_val, 'g', label='Cross Validation')
plt.legend()
# Training Examples Train Error Cross Validation Error
1 0.000000 205.121096
2 0.000000 110.300366
3 3.286595 45.010232
4 2.842678 48.368911
5 13.154049 35.865141
6 19.443963 33.829957
7 20.098522 31.970987
8 18.172859 30.862446
9 22.609405 31.135998
10 23.261462 28.936207
11 24.317250 29.551432
12 22.373906 29.433818
<matplotlib.legend.Legend at 0x181801cd30>
Polynomial regression
The problem with the linear model was that it was too simple for the data and resulted in underfitting (high bias). Next, this problem will be addressed by adding more features. For use polynomial regression, the hypothesis has the form:
$$h_{\theta}(x)=\theta_0+\theta_1*\left(\text{waterLevel}\right)+\theta_2*\left(\text{waterLevel}\right)^2+\cdots+\theta_p*\left(\text{waterLevel}\right)^p$$
$$h_{\theta}(x)=\theta_0+\theta_1x_1+\theta_2x_2+\cdots+\theta_px_p$$
Notice that by defining $x_1=\left(\text{waterLevel}\right)$
, $x_2=\left(\text{waterLevel}\right)^2$
,…, $x_p=\left(\text{waterLevel}\right)^p$
, a linear regression model is obtained where the features are the various powers of the original value $\left(\text{waterLevel}\right)$
.
The code in polyFeatures
adds more features using the higher powers of the existing feature $x$
in the dataset. This function maps the original training set $X$
of size $(m, 1)$
into its higher powers. Specifically, when a training set $X$
of size $(m, 1)$
is passed into the function, the function returns a $(m, p)$
matrix X_poly
, where column 1 holds the original values of $X$
, column 2 holds the values of $X^2$
, column 3 holds the values of $X^3$
, and so on. Note that there is no need to account for the zero-eth power in this function.
# Create a function that maps the original X into its higher powers.
def polyFeatures(X, p):
"""
Takes a data set X and maps each example into its polynomial
features, where X_poly(i, :) = [X(i) X(i).^2 X(i).^3 ... X(i).^p]
Args:
X: array (m, 1)
p: int > 1
Returns:
X_poly: array (m, p)
"""
# Initialize X_poly.
X_poly = X
# Iterate over the polynomial power.
for i in range(1, p):
# Add the i-th power column in X.
X_poly = np.column_stack((X_poly, np.power(X, i+1)))
return X_poly
Learning Polynomial Regression
After adding more features with polyFeatures
, a polynomial regression model will be trained using the linear regression cost function.
Note that even though there are polynomial terms in the feature vector, the solution is still a linear regression optimization problem. The polynomial terms have been simply turned into features that they can be used for linear regression. The same cost function and gradient are going to be applied.
A polynomial degree of $8$
will be used. It turns out that running the training directly on the projected data, will not work well as the features would be badly scaled (e.g., an example with $x = 40$
will now have a feature $x_8=40^8=6.5\text{x}10^{12}$
). Therefore, feature normalization should be applied.
Before learning the parameters $\theta$
for the polynomial regression, featureNormalize
will be implemented, which will normalize the features of the training set, storing the mu
and sigma
parameters separately.
After learning the parameters $\theta$
, the following two plots (Figure 4, 5) were generated for polynomial regression with $\lambda=0$
.
From Figure 4, it can be seen that the polynomial fit is able to follow the datapoints very well - thus, obtaining a low training error. However, the polynomial fit is very complex. This is an indicator that the polynomial regression model is overfitting the training data and will not generalize well.
To better understand the problems with the unregularized $\left(\lambda=0\right)$
model, it can be seen that the learning curve (Figure 5) shows the same effect where the low training error is low, but the cross validation error is high. There is a gap between the training and cross validation errors, indicating a high variance problem.
# Create a function that normalizes the features of X.
def featureNormalize(X):
"""
Returns a normalized version of X where the mean value
of each feature is 0 and the standard deviation is 1.
Args:
X: array (m, number of features)
Returns:
X: array (m, number of features)
"""
mu = np.mean(X, axis=0)
X_norm = X - mu
sigma = np.std(X_norm, axis=0)
X_norm = X_norm / sigma
return X_norm, mu, sigma
p = 8
# Map X onto Polynomial Features and Normalize.
X_poly = polyFeatures(X, p)
X_poly, mu, sigma = featureNormalize(X_poly) # Normalize
X_poly = np.insert(X_poly, 0, 1, axis=1) # Add Ones
# Map X_poly_test and normalize (using mu and sigma).
X_poly_test = polyFeatures(Xtest, p)
X_poly_test = X_poly_test - mu
X_poly_test = X_poly_test / sigma
X_poly_test = np.insert(X_poly_test, 0, 1, axis=1) # Add Ones
# # Map X_poly_val and normalize (using mu and sigma).
X_poly_val = polyFeatures(Xval, p)
X_poly_val = X_poly_val - mu
X_poly_val = X_poly_val / sigma
X_poly_val = np.insert(X_poly_val, 0, 1, axis=1) # Add Ones
print('Normalized Training Example 1:')
print(X_poly[1, :])
# Create a function to plot a polynomial regression fit.
def plotFit(min_x, max_x, mu, sigma, theta, p):
"""
Plots the learned polynomial fit with power p
and feature normalization (mu, sigma).
Also works with linear regression.
Args:
X: array (m, number of features)
Returns:
X: array (m, number of features)
"""
# We plot a range slightly bigger than the min and max
# values to get an idea of how the fit will vary outside
# the range of the data points.
x = np.array(np.arange(min_x - 15, max_x + 25, 0.05))
# Map the X values.
X_poly = polyFeatures(x, p)
X_poly = X_poly - mu
X_poly = X_poly / sigma
# Add ones.
X_poly = np.insert(X_poly, 0, 1, axis=1)
# Plot
plt.plot(x, np.dot(X_poly, theta), '--')
# Train linear regression with lambda_coef = 0.
theta = trainLinearReg(X_poly, y, 0)
plt.figure(figsize=(8, 6))
plt.xlabel('Change in water level (x)')
plt.ylabel('Water flowing out of the dam (y)')
plt.title('Figure 4: Polynomial fit, $\lambda$ = 0')
plt.plot(X, y, 'rx')
plotFit(min(X), max(X), mu, sigma, theta, p)
# Get the errors with lambda_coef set to 0.
error_train, error_val = learningCurve(X_poly, y,
X_poly_val, yval, 0)
plt.figure(figsize=(8, 6))
plt.xlabel('Number of training examples')
plt.ylabel('Error')
plt.title('Figure 5: Polynomial learning curve, $\lambda$ = 0')
plt.plot(range(1,m+1), error_train, 'b', label='Train')
plt.plot(range(1,m+1), error_val, 'g', label='Cross Validation')
plt.legend()
Normalized Training Example 1:
[ 1. -0.8389201 0.0013142 -0.25896174 -0.34156482 0.09754927
-0.45519664 0.26677343 -0.46887381]
<matplotlib.legend.Legend at 0x181825c588>
One way to combat the overfitting (high-variance) problem is to add regularization to the model. Next, different $\lambda$
parameters will be tested to see how regularization can lead to a better model.
Adjusting the Regularization Parameter
In this section, it will be observed how the regularization parameter affects the bias-variance of regularized polynomial regression. The $\lambda$
parameter will be modified and the values $1, 100$
will be tested. For each of these values, a polynomial fit to the data and a learning curve will be generated.
For $\lambda=1$
, we see a polynomial fit that follows the data trend well (Figure 6) and a learning curve (Figure 7) showing that both the cross validation and training error converge to a relatively low value. This shows that the $\lambda=1$
regularized polynomial regression model does not have the high-bias or high-variance problems. In effect, it achieves a good trade-off between bias and variance.
For $\lambda=100$
, the polynomial fit (Figure 8) does not follow the data well. In this case, there is too much regularization and the model is unable to fit the training data.
p = 8
# Train linear regression with lambda_coef = 1.
theta = trainLinearReg(X_poly, y, 1)
plt.figure(figsize=(8, 6))
plt.xlabel('Change in water level (x)')
plt.ylabel('Water flowing out of the dam (y)')
plt.title('Figure 6: Polynomial fit, $\lambda$ = 1')
plt.plot(X, y, 'rx')
plotFit(min(X), max(X), mu, sigma, theta, p)
# Get the errors with lambda_coef set to 1.
error_train, error_val = learningCurve(X_poly, y,
X_poly_val, yval, 1)
plt.figure(figsize=(8, 6))
plt.xlabel('Number of training examples')
plt.ylabel('Error')
plt.title('Figure 7: Polynomial learning curve, $\lambda$ = 1')
plt.plot(range(1,m+1), error_train, 'b', label='Train')
plt.plot(range(1,m+1), error_val, 'g', label='Cross Validation')
plt.legend()
# Train linear regression with lambda_coef = 100.
theta = trainLinearReg(X_poly, y, 100)
plt.figure(figsize=(8, 6))
plt.xlabel('Change in water level (x)')
plt.ylabel('Water flowing out of the dam (y)')
plt.title('Figure 8: Polynomial fit, $\lambda$ = 100')
plt.plot(X, y, 'rx')
plotFit(min(X), max(X), mu, sigma, theta, p)
# Get the errors with lambda_coef set to 100.
error_train, error_val = learningCurve(X_poly, y,
X_poly_val, yval, 100)
plt.figure(figsize=(8, 6))
plt.xlabel('Number of training examples')
plt.ylabel('Error')
plt.title('Figure 9: Polynomial learning curve, $\lambda$ = 100')
plt.plot(range(1,m+1), error_train, 'b', label='Train')
plt.plot(range(1,m+1), error_val, 'g', label='Cross Validation')
plt.legend()
<matplotlib.legend.Legend at 0x1819ab8160>
Selecting $\lambda$ Using a Cross Validation Set
From the previous parts, it is observed that the value of $\lambda$
can significantly affect the results of regularized polynomial regression on the training and cross validation set. In particular, a model without regularization $\left(\lambda=0\right)$
fits the training set well, but does not generalize. Conversely, a model with too much regularization $\left(\lambda=100\right)$
does not fit the training set and testing set well. A good choice of $\lambda$ $\left(\text{e.g., }\lambda=0\right)$
can provide a good fit to the data.
In this section, an automated method to select the $\lambda$
parameter will be implemented. Concretely, a cross validation set will be used to evaluate how good each $\lambda$
value is. After selecting the best $\lambda$
value using the cross validation set, then the model can be evaluated on the test set to estimate how well the model will perform on actual unseen data.
Specifically, the code in validationCurve
uses the trainLinearReg
function to train the model using different values of $\lambda$
and computes the training error and cross validation error. Various values of $\lambda$
in the following range: $\left\{0, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, 3, 10\right\}$
will be tried.
Plotting the learning curves v.s. $\lambda$
(Figure 10) allows to select which $\lambda$
parameter to use. It can be seen that the best value of $\lambda$
is around $3$
. Due to randomness in the training and validation splits of the dataset, the cross validation error can sometimes be lower than the training error.
# Create a function to train the model with various values of lambda_coef.
def validationCurve(X, y, Xval, yval):
"""
Generates the train and validation errors needed to plot a validation
curve that can be used to select lambda.
Args:
X: array (m, number of features+1)
y: array (m, 1)
Xval: array (s, number of features+1)
yval: array (s, 1)
Returns:
lambda_vec: array (10,)
error_train: array (10, 1)
error_val: array (10, 1)
"""
# Create a list of 10 selected values of lambda_coef.
lambda_vec = np.array([0, 0.001, 0.003, 0.01, 0.03, 0.1, 0.3, 1, 3, 10])
# Initialize the errors.
error_train = np.zeros((len(lambda_vec), 1))
error_val = np.zeros((len(lambda_vec), 1))
# Loop over lambda_vec.
for i in range(len(lambda_vec)):
lambda_coef = lambda_vec[i]
# Train the model with current lambda_coef.
theta = trainLinearReg(X, y, lambda_coef)
# Get the errors with lambda_coef set to 0!!!
error_train[i] = linearRegCostFunction(X, y, theta, 0)[0]
error_val[i] = linearRegCostFunction(Xval, yval, theta, 0)[0]
return lambda_vec, error_train, error_val
lambda_vec, error_train, error_val = validationCurve(X_poly, y, X_poly_val, yval)
plt.figure(figsize=(8, 6))
plt.xlabel('$\lambda$')
plt.ylabel('Error')
plt.title('Figure 10: Selecting $\lambda$ using a cross validation set')
plt.plot(lambda_vec, error_train, 'b', label='Train')
plt.plot(lambda_vec, error_val, 'g', label='Cross Validation')
plt.legend()
print('lambda\tTrain Error\tValidation Error\n')
for i in range(len(lambda_vec)):
print('{}\t{}\t{}\n'.format(lambda_vec[i], error_train[i], error_val[i]))
lambda Train Error Validation Error
0.0 [ 0.03680561] [ 33.25962406]
0.001 [ 0.10821881] [ 9.44291069]
0.003 [ 0.16672837] [ 15.92955179]
0.01 [ 0.21816115] [ 17.17742104]
0.03 [ 0.27513924] [ 13.21785925]
0.1 [ 0.43867918] [ 7.92648401]
0.3 [ 0.86816725] [ 4.76079564]
1.0 [ 1.95869484] [ 4.26335866]
3.0 [ 4.52510481] [ 3.83217638]
10.0 [ 14.82580826] [ 8.88972473]
Computing Test Set Error
Previously, the cross validation error for various values of the regularization parameter $\lambda$
was computed. However, to get a better indication of the model’s performance in the real world, it is important to evaluate the “final”
model on a test set that was not used in any part of training (that is, it was neither used to select the $\lambda$
parameters, nor to learn the model parameters $\theta$
).
Now, the test error will be computed using the best value of $\lambda=3$
that was found previously.
# Train the model with the best value of lambda_coef.
theta = trainLinearReg(X_poly, y, 3)
# Get the test error with lambda_coef set to 0!!!
error_test = linearRegCostFunction(X_poly_test, ytest, theta, 0)[0]
print("Test error for the best lambda: {0:.4f}".format(error_test))
Test error for the best lambda: 3.5720
Plotting Learning Curves with Randomly Selected Examples
In practice, especially for small training sets, when plotting learning curves to debug an algorithm, it is often helpful to average across multiple sets of randomly selected examples to determine the training error and cross validation error.
Concretely, to determine the training error and cross validation error for $i$
examples, first $i$
examples from the training set and $i$
examples from the cross validation set should be randomly selected. Then the parameters $\theta$
will be learnt using the randomly chosen training set and will be evaluated on the randomly chosen training set and cross validation set. The above steps should then be repeated multiple times (say 50) and the averaged error should be used to determine the training error and cross validation error for $i$
examples.


Zorkas.com
Purpose: Zorkas are small fetish figures that are made from wine corks. The purpose of Zorkas.com is to
provide an online storefront while providing a medium to spread the myth
and create a sense of collector community around these unique up-cycled fetish dolls.
Target Audience Stats and Persona
- Name: Shawn Eileen Pat
- Age: 40-70 yrs old
- Sex: Female/male
- Location: USA
- Income: 35,000K-60,000K
- Education: Some College
- Job Title: Working parent/retired
- Marital Status: married/divorced/single
- Children: 2+
- Archetype: Collector
- Attributes: Creative, Social
|
Persona: Shawn is happy-go-lucky and enjoys the small funky things in life
Her mantra is, "Love the things that are tragically beautiful and beautifully tragic."
In here eyes form always out weighs the value of function. Because of this here home and
personal spaces are always decorated with small meaningful items. At the root of it she
just loves collecting. In here efforts to acquire new items she relies on the hands-on approach
and frequents garage/yard sales, flea markets, and knick-knack shops. Because she often does not
know what she is looking for she prefers a general browsing approach and the social reward
of face to face contact. After all friends where just strangers at one time.
Technology in Shawn's life: Although she is an avid email user, she rarely uses the internet for
other purposes due to how impersonal and voyeuristic it makes her feel. She only has a flip-phone
and an old I-Mac single unit computer.
Challenge: Create a super 'simple' website that allows users to interact with the Zorka myth and narrative
while agitating the desire to collect, share, and create stories as unique as each Zorka.


JSON Object containing file name as key and the letter as value
There was an error trying to parse the JSON:
Custom HTML, the content of the element with the class "letter" will be set to the letter.
Style for the button.
Name of the resulting zipfile
Scale Property for html2canvas (when the text is blurry you can try higher values to see if you can read it better)
If you want to generate multiple sizes, you can add a string here which is appended to the file name. (So you don't have to change the JSON everytime)
Generate Images
JSON Object containing file name as key and applied CSS classes as a value
There was an error trying to parse the JSON:
The HTML of the Mouse, the classes are applied to the top most
Style
Name of the resulting zipfile
Scale Property for html2canvas (when the text is blurry you can try higher values to see if you can read it better)
If you want to generate multiple sizes, you can add a string here which is appended to the file name. (So you don't have to change the JSON everytime)
Generate Images
View the GitHub repository
Star
Issue


- First item
- Second item
- Third item
- Nested First item
- Nested Second item
- Forth item
- Fifth item
- First item
- Second item
- Third item
- Nested First item
- Nested Second item
- Forth item
- Fifth item
- First item
- Second item
- Nested First item
- Neted Second iteom
- Third item
- forth item
- Fifth item


{# This template receives the following context: reset_link - the link that should be fetched (GET) to reset reset_token - this token is part of reset link - but can be used to construct arbitrary URLs for redirecting. user - the entire user model object security - the Flask-Security configuration #}


Chapter 2 TOV Equation
- TOV equation means Tolman-Oppenheimer-Volkoff equation.
2.1 Build Equation
For static, non-rotating and spherical symmetric star, metric is given as \[ds^2 = -e^{2\Phi(r)}dt^2 + e^{2\Lambda(r)} dr^2 + r^2 d\Omega^2\]
For isolated star, the metric must reduce to the Schwarzschild metric at outside of the star \[ds^2 = -\left(1 - \frac{2M}{r}\right) dt^2 + \frac{1}{1 - \frac{2M}{r}} dr^2 + r^2 d\Omega^2\]
At interior of the star, let define new metric function for convenience \[e^{-2\Lambda(r)} = 1 - \frac{2m(r)}{r}\]
The quantuty \(m(r)\) can be interpreted as the mass interior to radius \(r\).
Now, consider perfect fluid matter: \[T_{\mu\nu} = (\rho + P)u_\mu u_\nu + Pg_{\mu\nu}, ~u = e^{-\Phi}\frac{\partial}{\partial t}\]
Rewrite this to index-free notation: \[T = \rho^{2\Phi} dt^2 + \frac{P}{1 - \frac{2m(r)}{r}}dr^2 + Pr^2 d\Omega^2\]
Solve Einstein equation with this metric & EM tensor then, \[\begin{align} \frac{dm(r)}{dr} &= 4\pi r^2 \rho \\ \frac{d\Phi(r)}{dr} &= \frac{m(r) + 4\pi r^3 P}{r^2 \left(1 - \frac{2m(r)}{r}\right)} \end{align}\]
From energy conservation, we can get one more equation: \[\nabla_\mu {T^\mu}_\nu = 0 \Rightarrow (\rho + P) \frac{d\Phi}{dr} + \frac{dP}{dr} = 0\]
These three fundamental equations are called Tolman-Oppenheimer-Volkoff Equations
| Tolman-Oppenheimer-Volkoff equation |
| \[\begin{aligned} \frac{dm}{dr} &= 4\pi r^2 \rho \\ \frac{d\Phi}{dr} &= \frac{ m + 4\pi r^3 P}{r^2 (1 - \frac{2m}{r})} \\ \frac{dP}{dr} &= - \frac{(\rho + P)(m + 4\pi r^3 P)}{r^2 (1 - \frac{2m}{r})} \end{aligned}\] |
Now, use polytropic equation of state.
| Polytropic Equation of State |
| \[P = K \rho_0^\Gamma\]
\(P\): pressure \(K\): polytropic gas constant \(\rho_0\): rest mass density. for neutron star, \(\rho_0 = m_u n_B\) \(m_u\): nucleon mass with atomic mass unit \(n_B\): baryonic number density \(\rho = \rho_0(1 + \epsilon)\): total mass energy density \(\epsilon\): internal energy density per unit mass \(\Gamma \equiv 1 + \frac{1}{n}\) \(n\): polytropic index |
Thermodynamics process of neutron star is isentropic process. It means \(S, N\) are conserved and only \(V\) changes. First define densities as belows. \[s = \frac{S}{V},~ n = \frac{N}{V},~ \rho = \frac{U}{V}\] Since \(dS = dN = 0\), we can get next relations. \[\frac{ds}{s} = \frac{dn}{n} = - \frac{dV}{V}\] Now, denote 1st law of thermodynamics. \[dU = -PdV + TdS + \mu dN = -PdV\] Rewrite this in terms of \(\rho\), then we can get next relation. \[\frac{d\rho}{\rho + P} = - \frac{dV}{V}\] By above two relations, next equation is naturally given. \[\left(\rho + P\right) = n \frac{\partial \rho}{\partial n}\] Since, \(\rho = \rho_0 (1+\epsilon),~ \rho_0 = m_u n\), \[\frac{\partial \rho}{\partial n} = \frac{\rho}{n} + \frac{\partial}{\partial n}\left(\frac{\rho}{n}\right) \cdot n\] Then finally we can obtain next equation. \[\therefore \, P = n^2 \frac{\partial}{\partial n} \left(\frac{\rho}{n}\right)\]
Let substitute \(P\) from polytropic EoS, then \[\rho = \rho_0 + \frac{P}{\Gamma-1}\]
| Total Running Terms |
| \[\begin{aligned}
\frac{dm}{dr} &= 4\pi r^2 \rho \\
\frac{d\Phi}{dr} &= \frac{ m + 4\pi r^3 P}{r^2 (1 - \frac{2m}{r})} \\
\frac{dP}{dr} &= - \frac{(\rho + P)(m + 4\pi r^3 P)}{r^2 (1 - \frac{2m}{r})} \\
\frac{dN_B}{dr} &= \frac{4\pi r^2 n_B}{\sqrt{1 - \frac{2m}{r}}}
\end{aligned}\]
where \[\begin{gathered} \rho_0 = \left(\frac{P}{K}\right)^{\frac{1}{\Gamma}} \\ \rho = \rho_0 + \frac{P}{\Gamma - 1} \\ n_B = \frac{1}{m_u} \left(\frac{P}{K}\right)^{\frac{1}{\Gamma}} \end{gathered}\] |
| Boundary Conditions |
| \[\begin{aligned} m(0) &= 0\\ \Phi(0) &= 0\\ \rho_0(0) &= \rho_c \\ P(0) &= P_c = K\rho_c^{\Gamma}\\ n_B(0) &= n_c = \frac{1}{m_u} \rho_c \\ P(R) &= 0 \\ \Phi(R) &= \frac{1}{2}\ln \left(1 - \frac{2GM}{R}\right) \end{aligned}\] |
2.2 Code implementation
Below codes are examples in peroxide
- Rust numeric library.
2.2.1 Declare global constants
pub const K: f64 = 100.;
pub const GAMMA: usize = 2;
pub const GAMMAF: f64 = 2.;
pub const RHO0C: f64 = 1.28e-3;
2.2.2 Write total running term
Dual
means dual number structure \((x, dx)\)
pub fn tov_rhs(r: Dual, rs: Vec<Dual>) -> Vec<Dual> {
let m_old = rs[0];
let _phi_old = rs[1];
let p_old = rs[2];
let rho_0 = (p_old / K).powf(1. / GAMMAF);
let rho_old = rho_0 + p_old / (GAMMAF - 1f64);
let dm = 4f64 * PI * r.pow(2) * rho_old;
let dphi = if r.value() != 0f64 {
(m_old + 4f64 * PI * r.pow(3) * p_old)
/ (r.pow(2) * (1f64 - 2f64 * m_old / r))
} else {
dual(0, 0)
};
let dp = if r.value() != 0f64 {
- (rho_old + p_old) * (m_old + 4f64 * PI * r.pow(3) * p_old)
/ (r.pow(2) * (1f64 - 2f64 * m_old / r))
} else {
dual(0, 0)
};
vec![dm, dphi, dp]
}
2.2.3 Solve with GL4 & save result
pub fn main() {
let p_c = K*RHO0C.powf(GAMMAF);
let init_val = c!(0, 0, p_c);
let mut records = solve_with_condition(
tov_rhs,
init_val,
(0f64, 16f64),
1e-3,
GL4(1e-15),
|xs| xs[2] >= 0f64
);
records.print();
records.write_with_header(
"example_data/tov_gl4.csv",
vec!["r", "m", "phi", "p"]
).expect("Can't write file");
}


Single Row Element
Description
The single row element is a shortcut for a table with one row.
Commonly used by CSS anti-purists to get simple layouts to work in cross-browser scenarious. See http://giveupandusetables.com/ for more information.
Commonly used by CSS anti-purists to get simple layouts to work in cross-browser scenarious. See http://giveupandusetables.com/ for more information.
Attributes
cells
One or more tablecell elements.
Set the table cells to be rendered within this row.
See Also


Chapter Three: The Great American Game
Dear Diary,
Grandfather's creaky as his front porch, loads his shotgun beneath the awning, spittoon restless for rain, carpenter's chair against the whistling air. Rocking, back and forth, rocking snap shot picture - worth it, just like the movies
This is a song by Levi The Poet
She said that he loved baseball, and James Earl Jones; said that he's got god talking inside of his thoughts while he's rounding those bases on his way back home
"If you build it, they will come"
If you build it, they will come (and baby listens to what the Lord say). But I've been getting pretty worn, building for nearly a decade
In a perfect world we shouldn’t have been allowed to lose sight of what it means to love wholly. I’ve got a Polaroid hanging on my wall that a friend took of me and my angel. I remember the day like it’s something I can touch, but it’s stuck in the square between the borders of the film, and I can run my fingers over our faces, but I can’t get back to the places we were
You’ve got a pain deep in your bones, son.
"You’ve got a pain deep in your bones, son. It compels you forward like you’re tied to a slave master’s cruel hand, and it's the same pain that drives that oppressor’s heart of stone, so you’ve grown to love the man. You keep pouring yourself out, again and again, into legible lines through a crooked pen." Yeah, it’s painful, but it’s familiar – so habit breeds comfort, and I don’t know what I’d do without him
You can listen to this song on YouTube
So in the early morning, when you’ve fallen asleep in our home, I drift back into the memories that I’ve claimed as my own, and wonder if tonight will be a night I’ll hang on my wall like I did before we stopped taking photos, out of the habit of being comfortable with not trying at all
In a perfect world, we’ll have albums labeled Seasons, with chapter headings, and we’ll staple them to the cork-board that hangs at the foot of the bed. There’s longevity in a memory spilt out in pen, and if a picture is worth a thousand words then I’ve written down every one of them
I work hard, scarred, toil through that soil for the youth I see in my friends, but these journals are moments in time, snapshots of our lives, and in retrospect, age is an overexposed photo that the memories can't mend
Buy the album on BandCamp
Lorem ipsum dolor sit amet consectetur adipisicing elit. Molestiae totam quia vel eveniet porro, rem ducimus quam incidunt, dicta laborum quod earum tempore natus placeat neque aspernatur pariatur iusto quos.
I know my sweet seductress, and her name is Depression. I wrote best beneath that demon’s destructive oppression
In those Polaroids, she drove the ink into the canvas like a slave beneath his master’s cruel hand, and I hated that whip but always wondered what I’d do without it, so I grew to love the man
Oh, I wept for change!  I’ve got an ache in my chest for every season I miss and it gets worse when the snow starts to fall. There are butterflies alive in that couple’s eyes a few years since forgotten by all, and sometimes, if the phone starts to ring, I can still hear their wings when you call
But I begged for movement and I got what I asked for, and I can picture the answer like it came yesterday. And in the land of the gods, I think that things are timeless, but we are still prone to decay
You know I still lift up hope of certain smiles in those photos for us when I pray
"Idle hands build nothing that you can call your own"
Time is a cruel lover, and she breaks her house apart at its bones. You know comfort is no good reason for standing still, and idle hands build nothing that you can call your own.
— Levi The Poet