0.6 Release¶
Release 0.6.1¶
Statsmodels 0.6.1 is a bugfix release. All users are encouraged to upgrade to 0.6.1.
See the list of fixed issues for specific backported fixes.
Release 0.6.0¶
Statsmodels 0.6.0 is another large release. It is the result of the work of 37 authors over the last year and includes over 1500 commits. It contains many new features, improvements, and bug fixes detailed below.
See the list of fixed issues for specific closed issues.
The following major new features appear in this version.
Generalized Estimating Equations¶
Generalized Estimating Equations (GEE) provide an approach to handling dependent data in a regression analysis. Dependent data arise commonly in practice, such as in a longitudinal study where repeated observations are collected on subjects. GEE can be viewed as an extension of the generalized linear modeling (GLM) framework to the dependent data setting. The familiar GLM families such as the Gaussian, Poisson, and logistic families can be used to accommodate dependent variables with various distributions.
Here is an example of GEE Poisson regression in a data set with four count-type repeated measures per subject, and three explanatory covariates.
import numpy as np
import statsmodels.api as sm
import statsmodels.formula.api as smf
data = sm.datasets.get_rdataset("epil", "MASS").data
md = smf.gee("y ~ age + trt + base", "subject", data,
cov_struct=sm.cov_struct.Independence(),
family=sm.families.Poisson())
mdf = md.fit()
print mdf.summary()
The dependence structure in a GEE is treated as a nuisance parameter and is modeled in terms of a “working dependence structure”. The statsmodels GEE implementation currently includes five working dependence structures (independent, exchangeable, autoregressive, nested, and a global odds ratio for working with categorical data). Since the GEE estimates are not maximum likelihood estimates, alternative approaches to some common inference procedures have been developed. The statsmodels GEE implementation currently provides standard errors, Wald tests, score tests for arbitrary parameter contrasts, and estimates and tests for marginal effects. Several forms of standard errors are provided, including robust standard errors that are approximately correct even if the working dependence structure is misspecified.
Seasonality Plots¶
Adding functionality to look at seasonality in plots. Two new functions are sm.graphics.tsa.month_plot
and sm.graphics.tsa.quarter_plot
. Another function sm.graphics.tsa.seasonal_plot
is available for power users.
import statsmodels.api as sm
import pandas as pd
dta = sm.datasets.elnino.load_pandas().data
dta['YEAR'] = dta.YEAR.astype(int).astype(str)
dta = dta.set_index('YEAR').T.unstack()
dates = map(lambda x : pd.datetools.parse('1 '+' '.join(x)),
dta.index.values)
dta.index = pd.DatetimeIndex(dates, freq='M')
fig = sm.tsa.graphics.month_plot(dta)
Seasonal Decomposition¶
We added a naive seasonal decomposition tool in the same vein as R’s decompose
. This function can be found as sm.tsa.seasonal_decompose
.
import statsmodels.api as sm
dta = sm.datasets.co2.load_pandas().data
# deal with missing values. see issue
dta.co2.interpolate(inplace=True)
res = sm.tsa.seasonal_decompose(dta.co2)
res.plot()
(Source code, png, hires.png, pdf)
Addition of Linear Mixed Effects Models (MixedLM)
Linear Mixed Effects Models¶
Linear Mixed Effects models are used for regression analyses involving dependent data. Such data arise when working with longitudinal and other study designs in which multiple observations are made on each subject. Two specific mixed effects models are “random intercepts models”, where all responses in a single group are additively shifted by a value that is specific to the group, and “random slopes models”, where the values follow a mean trajectory that is linear in observed covariates, with both the slopes and intercept being specific to the group. The Statsmodels MixedLM implementation allows arbitrary random effects design matrices to be specified for the groups, so these and other types of random effects models can all be fit.
Here is an example of fitting a random intercepts model to data from a longitudinal study:
import statsmodels.api as sm
import statsmodels.formula.api as smf
data = sm.datasets.get_rdataset('dietox', 'geepack', cache=True).data
md = smf.mixedlm("Weight ~ Time", data, groups=data["Pig"])
mdf = md.fit()
print mdf.summary()
The Statsmodels LME framework currently supports post-estimation inference via Wald tests and confidence intervals on the coefficients, profile likelihood analysis, likelihood ratio testing, and AIC. Some limitations of the current implementation are that it does not support structure more complex on the residual errors (they are always homoscedastic), and it does not support crossed random effects. We hope to implement these features for the next release.
Wrapping X-12-ARIMA/X-13-ARIMA¶
It is now possible to call out to X-12-ARIMA or X-13ARIMA-SEATS from statsmodels. These libraries must be installed separately.
import statsmodels.api as sm
dta = sm.datasets.co2.load_pandas().data
dta.co2.interpolate(inplace=True)
dta = dta.resample('M').last()
res = sm.tsa.x13_arima_select_order(dta.co2)
print(res.order, res.sorder)
results = sm.tsa.x13_arima_analysis(dta.co2)
fig = results.plot()
fig.set_size_inches(12, 5)
fig.tight_layout()
Other important new features¶
- The AR(I)MA models now have a
plot_predict
method to plot forecasts and confidence intervals. - The Kalman filter Cython code underlying AR(I)MA estimation has been substantially optimized. You can expect speed-ups of one to two orders of magnitude.
- Added
sm.tsa.arma_order_select_ic
. A convenience function to quickly get the information criteria for use in tentative order selection of ARMA processes. - Plotting functions for timeseries is now imported under the
sm.tsa.graphics
namespace in addition tosm.graphics.tsa
. - New distributions.ExpandedNormal class implements the Edgeworth expansion for weakly non-normal distributions.
- New datasets: Added new datasets for examples.
sm.datasets.co2
is a univariate time-series dataset of weekly co2 readings. It exhibits a trend and seasonality and has missing values. - Added robust skewness and kurtosis estimators in
sm.stats.stattools.robust_skewness
andsm.stats.stattools.robust_kurtosis
, respectively. An alternative robust measure of skewness has been added insm.stats.stattools.medcouple
. - New functions added to correlation tools: corr_nearest_factor finds the closest factor-structured correlation matrix to a given square matrix in the Frobenius norm; corr_thresholded efficiently constructs a hard-thresholded correlation matrix using sparse matrix operations.
- New dot_plot in graphics: A dotplot is a way to visualize a small dataset in a way that immediately conveys the identity of every point in the plot. Dotplots are commonly seen in meta-analyses, where they are known as “forest plots”, but can be used in many other settings as well. Most tables that appear in research papers can be represented graphically as a dotplot.
- Statsmodels has added custom warnings to
statsmodels.tools.sm_exceptions
. By default all of these warnings will be raised whenever appropriate. Usewarnings.simplefilter
to turn them off, if desired. - Allow control over the namespace used to evaluate formulas with patsy via the
eval_env
keyword argument. See the Namespaces documentation for more information.
Major Bugs fixed¶
Backwards incompatible changes and deprecations¶
- RegressionResults.norm_resid is now a readonly property, rather than a function.
- The function
statsmodels.tsa.filters.arfilter
has been removed. This did not compute a recursive AR filter but was instead a convolution filter. Two new functions have been added with clearer namessm.tsa.filters.recursive_filter
andsm.tsa.filters.convolution_filter
.
Development summary and credits¶
The previous version (0.5.0) was released August 14, 2014. Since then we have closed a total of 528 issues, 276 pull requests, and 252 regular issues. Refer to the detailed list for more information.
This release is a result of the work of the following 37 authors who contributed a total of 1531 commits. If for any reason we have failed to list your name in the below, please contact us:
A blurb about the number of changes and the contributors list.
- Alex Griffing <argriffi-at-ncsu.edu>
- Alex Parij <paris.alex-at-gmail.com>
- Ana Martinez Pardo <anamartinezpardo-at-gmail.com>
- Andrew Clegg <andrewclegg-at-users.noreply.github.com>
- Ben Duffield <bduffield-at-palantir.com>
- Chad Fulton <chad-at-chadfulton.com>
- Chris Kerr <cjk34-at-cam.ac.uk>
- Eric Chiang <eric.chiang.m-at-gmail.com>
- Evgeni Burovski <evgeni-at-burovski.me>
- gliptak <gliptak-at-gmail.com>
- Hans-Martin von Gaudecker <hmgaudecker-at-uni-bonn.de>
- Jan Schulz <jasc-at-gmx.net>
- jfoo <jcjf1983-at-gmail.com>
- Joe Hand <joe.a.hand-at-gmail.com>
- Josef Perktold <josef.pktd-at-gmail.com>
- jsphon <jonathanhon-at-hotmail.com>
- Justin Grana <jg3705a-at-student.american.edu>
- Kerby Shedden <kshedden-at-umich.edu>
- Kevin Sheppard <kevin.sheppard-at-economics.ox.ac.uk>
- Kyle Beauchamp <kyleabeauchamp-at-gmail.com>
- Lars Buitinck <l.buitinck-at-esciencecenter.nl>
- Max Linke <max_linke-at-gmx.de>
- Miroslav Batchkarov <mbatchkarov-at-gmail.com>
- m <mngu2382-at-gmail.com>
- Padarn Wilson <padarn-at-gmail.com>
- Paul Hobson <pmhobson-at-gmail.com>
- Pietro Battiston <me-at-pietrobattiston.it>
- Radim Řehůřek <radimrehurek-at-seznam.cz>
- Ralf Gommers <ralf.gommers-at-googlemail.com>
- Richard T. Guy <richardtguy84-at-gmail.com>
- Roy Hyunjin Han <rhh-at-crosscompute.com>
- Skipper Seabold <jsseabold-at-gmail.com>
- Tom Augspurger <thomas-augspurger-at-uiowa.edu>
- Trent Hauck <trent.hauck-at-gmail.com>
- Valentin Haenel <valentin.haenel-at-gmx.de>
- Vincent Arel-Bundock <varel-at-umich.edu>
- Yaroslav Halchenko <debian-at-onerussian.com>
Note
Obtained by running git log v0.5.0..HEAD --format='* %aN <%aE>' | sed 's/@/\-at\-/' | sed 's/<>//' | sort -u
.


PC
4
Read
address
Instruction
[31-0]
Instruction
memory
Add
Instruction [31-26]
Instruction [25-21]
Instruction [20-16]
Instruction [15-11]
Instruction [15-0]
16
32
Instruction [5-0]
0
M
u
x
1
Control
RegDst
Brach
MemRead
MemtoReg
ALUOp
MemWrite
ALUSrc
RegWrite
Read
register 1
Read
data 1
Read
register 2
Read
data 2
Write
register
Write
data
Registers
Sign-
extend
s
ALU
control
0
M
u
x
1
Zero
ALU
ALU
result
Shift
left 2
Add
ALU
result
Address
Read
data
Write
data
Data
memory
0
M
u
x
1
Jump
1
M
u
x
0


{% load staticfiles %}
A graph or chart or diagram is a diagrammatical illustration of a set of data. If the graph is uploaded as an image file, it can be placed within articles just like any other image. Graphs must be accurate and convey information efficiently. They should be viewable at different computer screen resolutions. Ideally, graphs will also be aesthetically pleasing. Please note that "graph", "chart" and "diagram" are ambiguous terms, sometimes used interchangeably.


Forms Editor
Default Editor
Super simple wysiwyg editor on Bootstrap
This is an simple editable area.
- Select a text to reveal the toolbar.
- Edit rich document on-the-fly, so elastic!
End of simple area
Inline Editor
Air-mode give an interface without the Toolbar. To reveal popover Toolbar, select a text where you want to modify. Simply turn on airMode
and just focus on text.
This is an air-mode editable area.
- Select a text to reveal the toolbar.
- Edit rich document on-the-fly, so elastic!
End of air-mode area


THE JUSTICE
SEE OTHERS
THE JUSTICE ACCOUNT
LOGIN
Run
and Win
your
shoes
twice
a
year!
Register
Run Daily
Win Shoes
Register Your Account!
Lets start today
First Name
Last Name
User Email
*
User Password
*
I agree that my submitted data is being collected and stored.
Get 24/7 HELP NOW:
410800555
Available Sizes
244 mm /US 8/ EUR 391/3 248 mm /US 81/2/EUR 40 252 mm /US 9/EUR 401/2 257 mm /US 91/2/EUR 411/3 261 mm /US 10/2/EUR 42 265 mm /US 101/2/EUR 421/2
269 mm /US 11/ EUR 431/3 274 mm /US 111/2/EUR 432/3 278 mm /US 12/EUR 441/2 282 mm /US 121/2/EUR 45 286 mm /US 13/EUR 452/3 291 mm /US 131/2/EUR 461/3
5
to follow!
Step 1- Register your account!
Step 2- Run Weekly for 4 KM and take pictures,videos and upload to the account.
Step 3- Eat Healthy Food(Vegetables,Fruits) and upload pictures to your account.
Step 4- After 6 to 7 Weeks, your account will be examined by the team and we will send you on email regarding how you can get your shoes,
Step 5- Pay the shipping(€4.99) and get your shoes
If you eat fruit,vegetables once a week and walk 4Km or gothen you can get the
sports shoes for free
GET IN TOUCH
4 Goldfield Rd. Honolulu, HI 96815
585654578989
thejusticemail@gmail.com


Upfront deduction of 9% CST stops November 26 – Ken Ashigbey
The Ghana Chamber of Telecommunications has announced that effective Tuesday, November 26, 2019, Telecommunications Operators will cease upfront deductions of the 9% Communication Service Tax (CST) charge and apply the tax through a tariff adjustment on their products and services.
This follows the Chamber’s agreement with the government to apply the 9% CST as a price increase instead of as an upfront deduction on recharge.
The Chamber say the reconfiguration of their systems to accommodate the commercial and technical requirements is due to be completed by the 26 November 2019.
“This will offer customers a smooth transition and better experience,” a statement signed by Mr Kenneth Ashigbey, CEO of the Ghana Chamber of Telecommunications said.
The statement added that telecommunication operators will notify their customers on the completion of the exercise and provide transparency on the adjusted tariffs of their products and services as well as offer information to subscribers post usage of these services.
It is recalled that the Communications Ministry ordered Mobile Network Operators (MNOs) to stop passing on the 9% CST to subscribers.
In a letter addressed to the National Communications Authority (NCA), the Communications Ministry stated that the CST should be treated the same way VAT, NHIL, GETFUND levy and all other taxes and levies imposed on entities doing business in Ghana are treated.
The CST, which has been increased from 6% to 9%, has been applied to any recharge purchase by subscribers.


Beach restoration efforts see success
by ETB SivapriyanRavi Kumar, 33, was left disappointed during a trip to the famed Town Beach in Puducherry in March 2018. The beach didn’t quite meet his expectations. Coastal erosion had led to the retreat of the shoreline.
However, on his recent trip, he could spend more time on the beach as it was restored to its past glory. An artificial reef structure made of steel caisson with rock bottom has been immersed on the northern side. The reef will reduce wave activity which will prevent erosion along the coastline. “Now I can walk on the beach. Last year, there were only rocks and less sand,” Ravi Kumar told DH.
READ: Rising waves threaten our coasts, govt does little
‘Mumbai sinking’ is not just an alarm
Islanders are fighting a losing battle
As part of the restoration efforts, beach nourishment that involves dumping of sand on the beach was carried out with the sand dredged from the other side of the harbour.
As of now, more than Rs 40 crore has been spent on the project and a minimum of about 3 lakh cubic metres of sand should be dredged every year from the harbour to replenish Town Beach.
The problem of beach erosion began after the construction of the Puducherry port, which lies dormant now, in 1986 and due to various human interventions such as the construction of structures along the coast.
Over the years, more than 10 km of the coast was lost to erosion and with the use of new technology as suggested by scientists of National Institute of Ocean Technology (NIOT), Chennai a stretch of about 400 metres has been regained. Experts say that lakhs of tonnes of sand get accumulated on one side of the harbour due to which the coast on the other side of the harbour is getting eroded.
“We have a long way to go and hope we will be able to concentrate on other beaches close to Puducherry. Measures like immersing a reef is expensive, but things will worsen if we don’t act now,” Probir Banerjee, president of PondyCAN, told DH. PondyCAN has worked with the Puducherry government, NIOT and other organisations for the beach restoration project.
The government officials, in the beginning, were in denial about the causes of coastal erosion and kept constructing sea walls and groins to prevent beach erosion.
Aurofilio Schiavina, a coastal environment expert who co-founded PondyCan, said coastal erosion takes place when a harbour is constructed on a sandy coast.
“The sand was getting eroded to the north of the harbour and instead of using sand, rocks were being placed to mitigate the erosion. However, it didn’t solve the problem. Artificial reef along with beach nourishment is an excellent solution but it has to be regularly maintained,” Schiavina said.
He also said beach nourishment project is the only way to save the coastline. However, people living in near-by coastal villages that are part of Tamil Nadu complain that the Puducherry project has aggravated coastal erosion in their area.


If-else statement
- load in the Orange dataset
- Create a new, empty variable
- Write an if else statement that classifies trees based on their circumference: <= 65.5 – small >65.5 & <= 161.5 – medium >161.5 large
- Do the same with ifelse() in one step.
## Orange
##
## 3 Variables 35 Observations
## --------------------------------------------------------------------------------
## Tree
## n missing distinct
## 35 0 5
##
## lowest : 3 1 5 2 4, highest: 3 1 5 2 4
##
## Value 3 1 5 2 4
## Frequency 7 7 7 7 7
## Proportion 0.2 0.2 0.2 0.2 0.2
## --------------------------------------------------------------------------------
## age
## n missing distinct Info Mean Gmd
## 35 0 7 0.98 922.1 566
##
## lowest : 118<PHONE_NUMBER> 1231, highest: 664 1004 1231 1372 1582
##
## Value 118<PHONE_NUMBER> 1231 1372 1582
## Frequency 5 5 5 5 5 5 5
## Proportion 0.143 0.143 0.143 0.143 0.143 0.143 0.143
## --------------------------------------------------------------------------------
## circumference
## n missing distinct Info Mean Gmd .05 .10
## 35 0 30 0.999 115.9 66.97 30.0 32.4
## .25 .50 .75 .90 .95
## 65.5 115.0 161.5 193.4 204.8
##
## lowest : 30 32 33 49 51, highest: 177 179 203 209 214
## --------------------------------------------------------------------------------
Orange$cc <- NA
#Orange$tree <- "something else"
for (i in 1:nrow(Orange)){
print(i)
if (Orange$circumference[i] <= 65.5){
Orange$cc[i] <- "small"
} else if (Orange$circumference[i]>65.5 & Orange$circumference<=161.5){
Orange$cc[i] <- "medium"
} else {
Orange$cc[i] <- "large"
}
}
## [1] 1
## [1] 2
## [1] 3
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 4
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 5
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 6
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 7
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 8
## [1] 9
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 10
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 11
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 12
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 13
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 14
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 15
## [1] 16
## [1] 17
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 18
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 19
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 20
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 21
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 22
## [1] 23
## [1] 24
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 25
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 26
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 27
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 28
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 29
## [1] 30
## [1] 31
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 32
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 33
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 34
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
## [1] 35
## Warning in if (Orange$circumference[i] > 65.5 & Orange$circumference <= : the
## condition has length > 1 and only the first element will be used
Orange$cc <- ifelse(Orange$circumference<=65.5, "small",
ifelse(Orange$circumference<=161.5, "medium", "large"))
For, while loop
- for each tree (1 to 5), print the ages.
- for each tree, print the age, in which they were small.
- load esoph dataset.
- Using for loop(s), summarize ncontrols by agegp and alcgp, skipping the category alcgp==“120+” & agegp==“25-34”.
- Using a for loop simulate the flip a coin twenty times, keeping track of the individual outcomes (1 = heads, 0 = tails) in a vector that you preallocte.
- Use a while loop to investigate the number of terms required before the product 1234… reaches above 10 million
- Use a nested for loop (a for loop inside a for loop) that produces the following matrix, preallocate the matrix with NA values.
Orange[Orange$Tree==1,"age"]
## [1] 118<PHONE_NUMBER> 1231 1372 1582
for (i in 1:5){
cat("Tree: ", i, " Ages: ", paste0(Orange[Orange$Tree==i,"age"], collapse = ", "), "\n")
}
## Tree: 1 Ages: 118, 484, 664, 1004, 1231, 1372, 1582
## Tree: 2 Ages: 118, 484, 664, 1004, 1231, 1372, 1582
## Tree: 3 Ages: 118, 484, 664, 1004, 1231, 1372, 1582
## Tree: 4 Ages: 118, 484, 664, 1004, 1231, 1372, 1582
## Tree: 5 Ages: 118, 484, 664, 1004, 1231, 1372, 1582
for (i in 1:5){
cat("Tree: ", i, " was small at age: ", paste0(Orange[Orange$Tree==i & Orange$cc=="small","age"], collapse = ", "), "\n")
}
## Tree: 1 was small at age: 118, 484
## Tree: 2 was small at age: 118
## Tree: 3 was small at age: 118, 484
## Tree: 4 was small at age: 118, 484
## Tree: 5 was small at age: 118, 484
# 0 1 2 3 4
# 1 0 1 2 3
# 2 1 0 1 2
# 3 2 1 0 1
# 4 3 2 1 0
data("esoph")
for (agegrp in levels(esoph$agegp)){
print(sum(esoph$ncontrols[esoph$agegp==agegrp]))
}
## [1] 116
## [1] 199
## [1] 213
## [1] 242
## [1] 161
## [1] 44
for (agegrp in levels(esoph$agegp)){
for (alcgrp in levels(esoph$alcgp)){
#print(agegrp)
#print(alcgrp)
cat("Age group: ", agegrp, ", alcohol consumption group: ", alcgrp, " number of controls: ", sum(esoph$ncontrols[esoph$alcgp==alcgrp & esoph$agegp==agegrp]), "\n")
}
}
## Age group: 25-34 , alcohol consumption group: 0-39g/day number of controls: 61
## Age group: 25-34 , alcohol consumption group: 40-79 number of controls: 45
## Age group: 25-34 , alcohol consumption group: 80-119 number of controls: 5
## Age group: 25-34 , alcohol consumption group: 120+ number of controls: 5
## Age group: 35-44 , alcohol consumption group: 0-39g/day number of controls: 89
## Age group: 35-44 , alcohol consumption group: 40-79 number of controls: 80
## Age group: 35-44 , alcohol consumption group: 80-119 number of controls: 20
## Age group: 35-44 , alcohol consumption group: 120+ number of controls: 10
## Age group: 45-54 , alcohol consumption group: 0-39g/day number of controls: 78
## Age group: 45-54 , alcohol consumption group: 40-79 number of controls: 81
## Age group: 45-54 , alcohol consumption group: 80-119 number of controls: 39
## Age group: 45-54 , alcohol consumption group: 120+ number of controls: 15
## Age group: 55-64 , alcohol consumption group: 0-39g/day number of controls: 89
## Age group: 55-64 , alcohol consumption group: 40-79 number of controls: 84
## Age group: 55-64 , alcohol consumption group: 80-119 number of controls: 43
## Age group: 55-64 , alcohol consumption group: 120+ number of controls: 26
## Age group: 65-74 , alcohol consumption group: 0-39g/day number of controls: 71
## Age group: 65-74 , alcohol consumption group: 40-79 number of controls: 53
## Age group: 65-74 , alcohol consumption group: 80-119 number of controls: 29
## Age group: 65-74 , alcohol consumption group: 120+ number of controls: 8
## Age group: 75+ , alcohol consumption group: 0-39g/day number of controls: 27
## Age group: 75+ , alcohol consumption group: 40-79 number of controls: 12
## Age group: 75+ , alcohol consumption group: 80-119 number of controls: 2
## Age group: 75+ , alcohol consumption group: 120+ number of controls: 3
for (agegrp in levels(esoph$agegp)){
for (alcgrp in levels(esoph$alcgp)){
if (agegrp=="25-34" & alcgrp=="120+"){
#next
} else {
cat("Age group: ", agegrp, ", alcohol consumption group: ", alcgrp, " number of controls: ", sum(esoph$ncontrols[esoph$alcgp==alcgrp & esoph$agegp==agegrp]), "\n")}
}
}
## Age group: 25-34 , alcohol consumption group: 0-39g/day number of controls: 61
## Age group: 25-34 , alcohol consumption group: 40-79 number of controls: 45
## Age group: 25-34 , alcohol consumption group: 80-119 number of controls: 5
## Age group: 35-44 , alcohol consumption group: 0-39g/day number of controls: 89
## Age group: 35-44 , alcohol consumption group: 40-79 number of controls: 80
## Age group: 35-44 , alcohol consumption group: 80-119 number of controls: 20
## Age group: 35-44 , alcohol consumption group: 120+ number of controls: 10
## Age group: 45-54 , alcohol consumption group: 0-39g/day number of controls: 78
## Age group: 45-54 , alcohol consumption group: 40-79 number of controls: 81
## Age group: 45-54 , alcohol consumption group: 80-119 number of controls: 39
## Age group: 45-54 , alcohol consumption group: 120+ number of controls: 15
## Age group: 55-64 , alcohol consumption group: 0-39g/day number of controls: 89
## Age group: 55-64 , alcohol consumption group: 40-79 number of controls: 84
## Age group: 55-64 , alcohol consumption group: 80-119 number of controls: 43
## Age group: 55-64 , alcohol consumption group: 120+ number of controls: 26
## Age group: 65-74 , alcohol consumption group: 0-39g/day number of controls: 71
## Age group: 65-74 , alcohol consumption group: 40-79 number of controls: 53
## Age group: 65-74 , alcohol consumption group: 80-119 number of controls: 29
## Age group: 65-74 , alcohol consumption group: 120+ number of controls: 8
## Age group: 75+ , alcohol consumption group: 0-39g/day number of controls: 27
## Age group: 75+ , alcohol consumption group: 40-79 number of controls: 12
## Age group: 75+ , alcohol consumption group: 80-119 number of controls: 2
## Age group: 75+ , alcohol consumption group: 120+ number of controls: 3
apply, lapply, etc…
- define the following dataset:
dataset1 <- cbind(observationA = 16:8, observationB = c(20:19, 6:12))
- Calculate row and column means with apply
- Use apply to multiply the whole table by 3.
#two ways
multiply <- function(x, number){
x <- x*number
x
}
res <- apply(dataset1,2, multiply, number=3)
res <- apply(dataset1,2, function(x) x*3)
- create a list with 3 list elements. Print the length of each element.
lll <- list(list(1,3,5,6,1), list(5,2,1), list(6,2,5,7,3,1,9))
## [[1]]
## [1] 5
##
## [[2]]
## [1] 3
##
## [[3]]
## [1] 7


play
pause
stop
repeat
repeat off
mute
unmute
max volume
Update Required
To play the media you will need to either update your browser to a recent version or update your
Flash plugin
.


Teachers Upload - Attendance
Teacher ID
{% for id in teacherId %}
{{id}}
{% endfor %}
Select Class
{% for class in classroom %}
{{class}}
{% endfor %}
Select subject
Upload


President leaves Accra for a three-nation visit
Accra, Nov. 17, GNA - President Nana Addo Dankwa Akufo-Addo Sunday left Ghana for an eight-day trip that will take him to the United Arab Emirates, Germany and the United Kingdom.
The President will first be in Abu Dhabi for an official visit at the invitation of Sheikh Mohammed bin Zayed Al Nahyan, Crown Prince of Abu Dhabi and Deputy Supreme Commander of the UAE Armed Forces.
He will on Monday, November 18, 2019, hold bilateral talks with the Crown Prince, with the aim of renewing and deepening the ties of co-operation and friendship between the two countries.
President Akufo-Addo would thence move to Germany, where, at the invitation of the German leader, Chancellor Angela Merkel, participate in the summit of the G20 Compact with African countries, of which Ghana is a member.
The meeting will be held on Tuesday, November 19, 2019, after which he will then travel to the United Kingdom for a private visit.
The President was accompanied by the Minister for Foreign Affairs, Shirley Ayorkor Botchwey, and officials of the Presidency and the Foreign Ministry.
He will return to Ghana on Tuesday, November 26, 2019.
Vice President Mahamudu Bawumia will act while he is away.
GNA


|
| | CSubSC (const string &name, const map< string, string > attributes) |
| | constructor inherited from More...
|
| |
| virtual CParent * | getParent () const |
| | inherited method to get parent of an element More...
|
| |
| virtual void | addParent (CParent *) |
| | Inherited parent setter. More...
|
| |
| virtual void | printNode (WINDOW *p, int indent, map< int, CParent * > &elements) |
| | Prints element. More...
|
| |
| virtual string | printOutElement () const |
| | Creating output for the ofstream. More...
|
| |
| virtual void | printOut (ostream &os) const |
| | Fills ofstream with whole xml file. More...
|
| |
| | CParent (const string &name, const map< string, string > attributes) |
| | Constructor of CParent class. More...
|
| |
|
virtual | ~CParent () |
| | CParent destructor.
|
| |
| void | addContent (const char content) |
| | Method to add Content to element. More...
|
| |
| void | addContent (const string &content) |
| | Overloaded addContent function. More...
|
| |
| bool | sameName (const string &name) const |
| | Name testing method. More...
|
| |
| void | addSub (CParent *) |
| | Child insert. More...
|
| |
| string & | getName () |
| | Name getter. More...
|
| |
| void | changeVisibility () |
| | Visibility switcher. More...
|
| |
| void | update (const string &name, map< string, string > attributes, const string &content) |
| | Update of element. More...
|
| |
| virtual void | print (WINDOW *p, int indent) const |
| | Prints element to the ncurses window. More...
|
| |
| void | deleteNode () |
| | Node deletion. More...
|
| |
| virtual void | printFiltered (WINDOW *p, string element, vector< pair< string, string > > attributes, map< int, CParent * > &elements, int indent) |
| | Prints filtered elements. More...
|
| |
|
| void | printAttr (WINDOW *p, int curY, int curX, int indent) const |
| | Prints all attributes of element to given ncurses window. More...
|
| |
| void | printContent (WINDOW *p, int indent) const |
| | Prints content to ncurses window. More...
|
| |
| void | printEnd (WINDOW *p, int indent) const |
| | Prints closing tag of an element to ncurses window. More...
|
| |
| string | printOutEnd () const |
| | Creating output for ofstream. More...
|
| |
| string | printOutAttr () const |
| | Creating output for the ofstream. More...
|
| |
|
string | m_name |
| | name of an element
|
| |
|
map< string, string > | m_attribute |
| | map of all element attributes
|
| |
|
string | m_content |
| | element content
|
| |
|
vector< CParent * > | m_childs |
| | vector of all subelement
|
| |
|
bool | hidden |
| | parameter representing visibility of an element
|
| |
Class for all sub elements which are self-closing.


Preparation time
over 2 hours
Cooking time
1 to 2 hours
Serves
Serves 6
For the meatloaf, place the egg and milk into a large bowl and mix together.
Add the cubes of bread and leave to stand for 15 minutes.
Mash the milk and egg-soaked bread with a fork.
Add the mustard, thyme, nutmeg, basil, onion, celery and bacon lardons, season with salt and freshly ground black pepper and mix well.
Add the beef and pork mince and the Worcestershire sauce. Mix well to combine thoroughly.
Cover with cling film and place into the fridge to chill (overnight if possible, but for at least two hours).
Preheat the oven to 180C/360F/Gas 4.
Transfer the meatloaf mixture into a 30cm x 11cm/12in x 4in loaf tin.
Top with the streaky bacon slices to cover.
Transfer to the oven and bake for 55 minutes, or until completely cooked through.
Remove from the oven and leave the meatloaf to stand for 5-6 minutes before slicing.
For the mashed potato, mash the freshly cooked potatoes. Place into a pan over a low heat and mix in the butter. Season, to taste, with salt and freshly ground black pepper.
To serve, slice the meat loaf. Place a slice onto each plate with a dollop of mashed potato alongside. Pour over some gravy and enjoy.


Account: Username123
Link One
Link Two
Link Three
Link Four
Subnav One
Subnav Two
Subnav Three
Region Selector


Provides tools for estimating composition and configuration parameters from a categorical (binary) landscape map (grid) and then simulates a selected number of statistically similar landscapes. Class-focused pattern metrics are computed for each simulated map to produce empirical distributions against which statistical comparisons can be made. The code permits the analysis of single maps or pairs of maps.
| Version: | 1.7.1 |
| Depends: | R (≥ 2.14), SDMTools |
| Published: | 2016-10-28 |
| Author: | Tarmo K. Remmel, (Marie-Josee Fortin, Ferenc Csillag, Sandor Kabos) |
| Maintainer: | Tarmo K. Remmel <remmelt at yorku.ca> |
| License: | GPL (≥ 3) |
| NeedsCompilation: | no |
| CRAN checks: | PatternClass results |
| Reference manual: | PatternClass.pdf |
| Package source: | PatternClass_1.7.1.tar.gz |
| Windows binaries: | r-devel: PatternClass_1.7.1.zip, r-release: PatternClass_1.7.1.zip, r-oldrel: PatternClass_1.7.1.zip |
| OS X binaries: | r-release: PatternClass_1.7.1.tgz, r-oldrel: PatternClass_1.7.1.tgz |
| Old sources: | PatternClass archive |
Please use the canonical form https://CRAN.R-project.org/package=PatternClass to link to this page.


The Entrepreneur as American Hero
Walter
E. Williams1
Let=s start off with a brief discussion of the sources of income. That=s important because some of the rhetoric one hears gives the impression that income is somehow distributed - there=s a dealer of dollars. Thus, one might think that the reason some people have more income than others is that the dollar dealer is a racist, a sexist, or a multi-nationalist who deals out dollars unfairly. Or, alternatively, the reason that some people are richer than others is because they got to the pile of money first and took an unfair share. In either case, justice requires that government take the ill-gotten gains of the few and restore them to their rightful owners - in other word redistribute the income. While no one actually describes the sources of income this way, the logic of some arguments about the sources of income implies such a vision.
In a free society, income is earned through pleasing and serving one's fellow man.  In turn your give me dollars. We can think of dollars as certificates of performance. With these certificates of performance in hand, I go to my grocer and ask him to give me a pound of steak and a six-pack of beer that my fellow man produced. In effect the grocer says, AYou=re making a claim on something your fellow man produced. You=re asking him to serve you but did you serve him?@ I say, AYes I did.@ The grocer responds, AProve it!@ That=s when I show him my certificates of performance, namely the money my fellow man paid me to mow his lawn.
Contrast the morality of having to serve one=s fellow man as a condition of being served by him with the alternative. Government can say to me, "Williams, you don=t have to serve your fellow man in order to have a claim on what he produces. As long as you=re loyal to us, we will take what your fellow man produces and give it to you."
Obviously, some people are more effective at serving and pleasing their fellow man than others and thus earn a greater number of certificates of performance (higher income) and hence have greater claims on what their fellow man produces. Take Luciano Pavarotti. Why is his income much higher than mine.  You will plunk down $75 to hear him sing an aria from "La Boheme" but how much would you be willing to pay to hear me do the same? Those who would call Pavarotti=s income unfair and would have government to take part of it to give to others are essentially saying, AWe disagree with the decisions of millions upon millions of people acting voluntarily that resulted in Pavarotti=s higher income. We are going to use the coercive powers of government to cancel out the full effect of those decisions through income redistribution." I might add that income redistribution is simply a legal version of what a thief does, namely take the rightful property of one person for the benefit of another. The primary distinction between his behavior and that of congress is legality.
For the most part, in a free society, people who are wealthy have become so through effectively serving their fellow man. Cyrus McCormick=s reaping machine, Thomas Watson, the founder of IBM, Lloyd Conoverk, in the employ of Pfizer Company who created the antibiotic tetracycline a life-saving antibiotic are just a few of the exceptional contributors. While these people and their companies became extremely wealthy, society benefitted far more from their contribution than they did in terms of the value of healthier lives not to mention the millions and possibly billions of lives saved.
Propaganda and stubborn ignorance has it that the advances of capitalism benefits only the rich. But the evidence, as I=ve already pointed out refutes that. Let's look at more. The rich have always been able to afford entertainment but it was the development and marketing of radio and television that made entertainment accessible to the common man. The rich have never had the drudgery of washing and ironing clothing, beating out carpets or waxing floors. It was the development and mass production of washing machines, wash and wear clothing, vacuum cleaners and no-wax floors that spared the common man of this drudgery. At one time, only the rich could afford automobiles, telephones and computers. Now all but a tiny percentage of Americans enjoy these goods.
Today, as it has always been, the direct impetus for technological innovation and progress has been the entrepreneurial search for profits and the competitive economy. In the appendix, there=s a copy of a table taken from a paper written by Stephen Moore and Julian L. Simon A25 Wonderful Trends of the 20th Century.@ I=ll cite a few of their comparison statistics for the beginning of the 20th century versus its end: life expectancy rose from 47 years of age to 77 years. Deaths from infectious disease fell from 700 per 100,000 of the population to 50. Agricultural workers fell from 35 percent of the workforce to 2.5 percent. Auto ownership rose from one percent of the population to 91 percent. Patents granted rose from 25,000 a year to 150,000 a year. Controlling for inflation household assets rose from $6 trillion in 1945 to $41 trillion in 1998.
Let=s consider another factor that is nearly completely ignored. The output and wealth generated through free enterprise contributes to a more civilized society and civilized relationships. For most of mankind's existence, he has had to spend most of his time simply eking out a living. In pre-industrial society, and in many places today, the most optimistic scenario for the ordinary citizen was to be able to eke out enough to meet his physical needs for another day.
With the rise of capitalism and the concomitant rise in human productivity that yielded seemingly ceaseless economic progress, it was no longer necessary for mankind to spend his entire day simply providing for minimum physical needs. People were able to satisfy their physical needs with less and less time. This made it possible for people to have the time resources to develop spiritually and culturally. In other words, the rise of capitalism enabled the gradual extension of civilization to greater and greater numbers of people. More of them have time available to read and become educated in the liberal arts and gain more knowledge about the world around them. Greater wealth permits them to attend the arts, afford recreation, and contemplate more fulfilling and interesting life activities and do other culturally enriching activities that were formerly within the purview of only the rich.
How was all this achieved? In a market system, enterprise profits are performance-related, namely finding out what human wants are not being met and finding ways to meet them. In reference to the motivations of the entrepreneur, Adam Smith says, A. . .By directing that industry in such a manner as its produce may be of the greatest value, he intends only his own gain, and he is in this, as in many other cases, led by an invisible hand to promote an end which was no part of his intention.@
That might very well describe an entrepreneur like Thomas Watson Sr. founder of International Business Machines (IBM). Many of technological gains and previously unimaginable human progress are the direct results of having methods of handling large amounts of data accurately and rapidly. From the 1930s onward, IBM was at the forefront in the development of machinery to do this. The huge benefits we enjoy and the human progress that has been made as a result of IBM=s pioneering work was no part of the intention of Thomas Watson or his successors. They were in it for their gain - profits.
Profit has almost become a dirty word so let me spend a few minutes talking about the magnitude of profits and the role that profits play in a free market economy.
First, the magnitude of profits. Roughly six cents of each dollar companies take in represent after‑tax profits. By far, wages are the largest part of that dollar representing about 60 cents. As percentages of 2002 national income, after-tax profits represented about 5 percent and wages about 71 percent.
Let=s talk about what might be called normal profit and later about the more emotional windfall profits, what some have labeled obscene profits. Normal profit is the opportunity cost of using entrepreneurial abilities in the production of a good. It=s what the entrepreneur could have earned in his next best alternative, say, another business venture. Just as wages, rent, and interest must be paid in order to employ the services of labor, land and capital, normal profits must be paid to employ entrepreneurial services, the resource that makes decisions, innovates and takes risk.
Whether an entrepreneur makes a profit depends essentially on two things. The first is whether he is producing a good that consumers value and are willing to pay for and the second is whether he=s using the scarce resources of society in the most efficient manner to produce the good.
Let=s look at an example of the role of profits play in providing incentives to produce what the consumer wants. Remember 1985 when Coca Cola introduced the "new" Coke? Pepsi Cola president Roger Enrico called it "the Edsel of the 80's," representing one of the greatest marketing debacles of the 1980's. Who made Coca Cola Company bring back the old Coke? Was it congress, the courts, the president, or other government officials who were acting in the interests of soda-drinking Americans? No way. It was the specter of negative profits (losses) that convinced Coca Cola to bring back the old Coke. Thus, one role of profits is to discover what consumers want and if producers make mistakes, correct them.
Profits also force producers to employ resources
wisely. If producers waste inputs their
production costs will be higher. In
order to cover their cost, they must charge prices higher than what consumers
are willing to pay. After a while the
company will make unsustainable losses (negative profits) and go out of
business. As a result the company=s resources will become available to
someone else who=ll put
them to wiser use. This process is
short-circuited if government offers bailouts in the forms of guaranteed loans,
subsidies or restrictions on competitive products from abroad such as tariffs
and import quotas. Government Ahelp@
enables failing companies to continue squandering resources.2
Windfall profits are profits above and beyond those needed to keep an entrepreneur producing a good or service but they serve a vital social function. They serve as a signal that there are unmet human wants. One of the best examples of the role of windfall profits are those that arise in the wake of a disaster and are often condemned as price gouging. In the wake of a disaster, such as a hurricane, there is an immediate change in scarcity conditions and that=s reflected in higher prices for goods and services. Say a family of four sees their home damaged or destroyed. At before-disaster prices, they might decide to rent two adjoining hotel rooms. However, when they arrive at the hotel and see that room prices have doubled, they might easily decide to tough it out in a single room.  Thus, higher prices give people incentive to economize on scarce resources.
In the wake of
What caused these market participants to do what was in the social interest, namely, sacrifice or postpone alternative uses for plywood? The answer reveals perhaps the most wonderful feature of this process: rising prices and opportunities for higher profits encouraged people to do voluntarily what was in the social interest: help their fellow man recover from a disaster.
At this juncture let me say a few words about the modern push for corporate social responsibility. Do corporations have a social responsibility? Yes, and Nobel Laureate Professor Milton Friedman put it best in 1970 when he said that in a free society Athere is one and only one social responsibility of business - to use its resources and engage in activities designed to increase its profits so long as it stays within the rules of the game, which is to say, engages in open and free competition without deception or fraud.@
It is only people, not businesses, who have responsibilities. A CEO is an employee, an employee of shareholders and customers. The failure of the corporate executive community to recognize this, and engage in activities unrelated to the pursuit of profits, means national wealth will be lower, product prices will be higher and the return on investment lower.
How about the
Here's Williams' law: whenever the profit incentive is
missing, the probability that people's wants can be safely ignored is the
greatest. It's not just the post office
and schools but delivery of police services and garbage collection as
well. If a poll were taken asking people
what services they are most satisfied with and those they are most dissatisfied
with, for-profit organizations (supermarkets, computer companies and video
stores) would dominate the first list while non-profit organizations (schools,
post office and offices of motor vehicle registration) would dominate the
latter list. In a free economy, the
pursuit of profits and serving people are one and the same. No one argues that the free enterprise system
is perfect but it=s the
closest we=ll come
to perfect here on Earth.
Appendix
Table 1
25 Wonderful Trends of the 20th Century
|
Trend |
1900-1920a |
1995-1998b |
|
Life
expectancy (years) |
47 |
77 |
|
Infant
mortality (deaths per 1,000 live births) |
100 |
7 |
|
Deaths
from infectious diseases (per 100,000 population) |
700 |
50 |
|
Heart
disease (age-adjusted deaths per 100,000 population) |
307
(1950) |
126 |
|
Per
capita GDP (1998 dollars) |
$4,800 |
$31,500 |
|
Manufacturing
wage (1998 dollars) |
$3.40 |
$12.50 |
|
Household
assets (trillions of 1998 dollars) |
$6
(1945) |
$41 |
|
Poverty
rate (percent of |
40 |
13 |
|
Length
of workweek (hours) |
50 |
35 |
|
Agricultural
workers (percent of workforce) |
35 |
2.5 |
|
TV
ownership (percent of |
0 |
98 |
|
Homeownership
(percent of |
46 |
66 |
|
Electrification
(percent of |
8 |
99 |
|
Telephone
calls (annual per capita calls) |
40 |
2,300 |
|
Cars
for transportation (percent of |
1 |
91 |
|
Patents
granted |
25,000 |
150,000 |
|
High
school completion (percent of adults) |
22 |
88 |
|
Accidental
deaths (per 100,000 population) |
88 |
34 |
|
Wheat
price (per bushel in hours of work) |
4.1 |
0.2 |
|
Bachelor=s degrees awarded to women
(percent of degrees) |
34 |
55 |
|
Black
income (annual per capita, 1997 dollars) |
$1,200 |
$12,400 |
|
Resident
U.S. population (millions) |
76 |
265 |
|
Air
pollution (lead, micrograms per 100 cubic meters of air) |
135
(1977) |
4 |
|
Computer
speed (millions of instructions per second) |
0.02
(1976) |
700 |
|
Computer
ownership (percent of |
1
(1980) |
44 |
bValues are for latest year for which data are available.
Source: AThe Greatest Century That Ever Was: 25 Miraculous Trends of the Past 100 Years@ by Stephen Moore and Julian Simon. Policy Analysis No. 364 (Washington, D.C.: Cato Institute, December 15, 1999)
2A business going bankrupt doesnt mean that its
productive resources will vanish into thin air. It means someone else will own
them.


Tactly is created to help people who unintentionally become self-destructed online to have a better experience in communication. With a positively engagement and more rational conversation, people will be able to build a plausible credibility and relationships online.
TRY TACTLY NOW!How Tactly will help you.
Moderate conversations and remain rationality.
Self-check for politeness and avoid inappropriate terms.
build a better online relationships and credibility.
Help us improve Tactly.
Get the latest release and updates. Share your comments or feedbacks with us for improving the online engagement and self-censorship.
SIGN UP HERE!It is true that Tactly needs more improvements. Please email us if you have the same ideals and would like to get involved.
COME JOHN US!


{{ define "main" }}
Updated inventory for Premium Room from 19-Oct-17 to 31-Oct-17
Updated Food & Beverages and Fitness Spa
Updated Property Highlights


Our Goals for 2016
Goals are what motivate us to stay on track and to acomplish things that we really want to do. Some of these goals may not be attainted, but if everyone can see them it might motivate us to do more.
- Build 11 Client Websites
- Build 4 Client Apps
- Launch 2 apps under our name
- Create 3 Web apps
Having a scheduale is very important. Here is our expected timeline:
| January | February | March | April | May | June | July | August | September | October | November | December |
|---|---|---|---|---|---|---|---|---|---|---|---|
This is a very ambitious scheduale, but we hope we can can make it. We will update this post as we complete objectives. Happy 2016 🎉


Tolerably earnestly middleton extremely distrusts she boy now not. Add and offered prepare how cordial two promise. Greatly who affixed suppose but enquire compact prepare all put. Added forth chief trees but rooms think may. Wicket do manner others seemed enable rather in. Excellent own discovery unfeeling sweetness questions the gentleman. Chapter shyness matters mr parlors if mention thought. Increasing impression interested expression he my at. Respect invited request charmed me warrant to. Expect no pretty as do though so genius afraid cousin. Girl when of ye snug poor draw. Mistake totally of in chiefly. Justice visitor him entered for. Continue delicate as unlocked entirely mr relation diverted in. Known not end fully being style house. An whom down kept lain name so at easy. Ignorant branched humanity led now marianne too strongly entrance. Rose to shew bore no ye of paid rent form. Old design are dinner better nearer silent excuse. She which are maids boy sense her shade. Considered reasonable we affronting on expression in. So cordial anxious mr delight. Shot his has must wish from sell nay. Remark fat set why are sudden depend change entire wanted. Performed remainder attending led fat residence far. Acceptance middletons me if discretion boisterous travelling an. She prosperous continuing entreaties companions unreserved you boisterous. Middleton sportsmen sir now cordially ask additions for. You ten occasional saw everything but conviction. Daughter returned quitting few are day advanced branched. Do enjoyment defective objection or we if favourite. At wonder afford so danger cannot former seeing. Power visit charm money add heard new other put. Attended no indulged marriage is to judgment offering landlord.  Son read such next see the rest two. Was use extent old entire sussex. Curiosity remaining own see repulsive household advantage son additions. Supposing exquisite daughters eagerness why repulsive for. Praise turned it lovers be warmly by. Little do it eldest former be if. Two assure edward whence the was. Who worthy yet ten boy denote wonder. Weeks views her sight old tears sorry. Additions can suspected its concealed put furnished. Met the why particular devonshire decisively considered partiality. Certain it waiting no entered is. Passed her indeed uneasy shy polite appear denied. Oh less girl no walk. At he spot with five of view. Are own design entire former get should. Advantages boisterous day excellence boy. Out between our two waiting wishing. Pursuit he he garrets greater towards amiable so placing. Nothing off how norland delight. Abode shy shade she hours forth its use. Up whole of fancy ye quiet do. Justice fortune no to is if winding morning forming. Fat son how smiling mrs natural expense anxious friends. Boy scale enjoy ask abode fanny being son. As material in learning subjects so improved feelings. Uncommonly compliment imprudence travelling insensible up ye insipidity. To up painted delight winding as brandon. Gay regret eat looked warmth easily far should now. Prospect at me wandered on extended wondered thoughts appetite to. Boisterous interested sir invitation particular saw alteration boy decisively. Performed suspicion in certainty so frankness by attention pretended. Newspaper or in tolerably education enjoyment. Extremity excellent certainty discourse sincerity no he so resembled. Joy house worse arise total boy but. Elderly up chicken do at feeling is. Like seen drew no make fond at on rent. Behaviour extremely her explained situation yet september gentleman are who. Is thought or pointed hearing he. He went such dare good mr fact. The small own seven saved man age no offer. Suspicion did mrs nor furniture smallness. Scale whole downs often leave not eat. An expression reasonably cultivated indulgence mr he surrounded instrument. Gentleman eat and consisted are pronounce distrusts.


Blog
Nov. 17, 2020
Do you see the Body of Christ returning to their first love?
Do you see an increase of repentance by the Body of Christ?
What spiritual differences do you see happening with the Body of Christ during this COVID time?
Comment Box is loading comments...


Welcome to Pat's Salmon Cookies: Sales Data
Add New City
City Name
Minimum Customer
Maximum Customer
Average
Add City
Home Page


{{extend "layout.html"}} {{if request.function == "index":}}
{{=T('The "query" is a condition like "db.table1.field1==\'value\'". Something like "db.table1.field1 == db.table2.field2" results in a SQL JOIN.')}}
{{=T("Use (...)&(...) for AND, (...)|(...) for OR, and ~(...) for NOT to build more complex queries.")}}
{{=T('"update" is an optional expression like "field1=\'newvalue\'". You cannot update or delete the results of a JOIN')}}


The reset
defines a reset button which resets all form
values to its initial values.
Tip: Avoid reset buttons in your forms! It is frustrating for users if they click them by mistake.
Example:
An HTML form with a reset input field:
<form action="/action_page.php">
Enter your email:
<input type="email" id="email" name="email">

Enter a PIN:
<input type="text" id="pin" name="pin" maxlength="4">

<input type="reset" value="Reset">
<input type="submit" value="Submit">
</form>
Click on the reset button to reset the form.


Bora UI Automation
Students
Sign Up
Login
Sign Up
Create your Bora student account
Name:
Male
Female
Select a course:
Select a course
Selenium Automation
Front End Development with Angular
Java Spring Full Stack Development
Password:
Confirm Password:
I'm not a robot


--- layout: page title: About header-img: "img/about-bg.png" ---
I am currently studying web application programming through FlatIron.


{{paragraph}}
{{job.employer}}
{{job.title}}
{{job.dates}}
{{item}}
Search
{{education.college.name}}
{{education.college.dates}}
{{education.college.degree}}
{{education.college.major}}
{{nanodegree.school + nanodegree.title}}
{{nanodegree.dates}}
{{item}}
{{endorsement.statement}}
{{endorsement.endorser}}
Udacity project review feedback
{{feedback}}
Email: {{bio.contacts.email}}
Mobile: {{bio.contacts.mobile}}
Location: {{bio.contacts.location}}
GitHub
LinkedIn


Data Scientist - San Francisco, CA
Founded in 2015, Honor is now one of the fastest-growing, non-medical home care companies in the U.S. Why? Because we realized that by combining our amazing technology and operations with the local, personal touch of our partner agencies, we could make real progress in transforming this fast-growing, $30BN industry. This unique approach is powering our huge growth - we have cutting-edge machine learning, a beautiful, well-designed app, and industry-leading design, paired with a strong sales, marketing, and support engine.
Our mission and ambitions are huge. We're looking for people who believe, as we do, that modernizing home care for our parents—and yours—is one of the most important problems we can solve. Honor is a well-funded, strongly backed company with experienced leaders who have a proven track record of building large businesses and solving extraordinarily difficult challenges. Join us!
We're looking for a data scientist to join our team. You'll develop predictive models and algorithms to improve our operations platform and help us provide a better service to our clients. We're looking for a generalist who's excited to jump into new problems and write production-quality code. Are you a fit?
In this role, you will:
Help people across the company interpret complex data correctly.
Collaborate with a diverse team across engineering, care operations, product management, sales and marketing, and more.
Research operational and logistical problems.
Design, implement, and evaluate descriptive and predictive models.
Integrate machine learning into user-facing applications.
The ideal candidate will have:
Excellent communication skills with both technical and non-technical peers.
Excellent mathematical and statistical fundamentals, including a degree in a quantitative field (such as Computer Science, Mathematics, Statistics, Economics, Physics).
Working knowledge of Python or comparable programming language.
3+ years of industry experience.
Experience with numerical software packages such as NumPy, scikit-learn, or Keras.
Honor is an equal opportunity employer. All qualified applicants will receive consideration for employment without regard to race, color, religion, sex (including pregnancy), national origin, age, disability, genetic information, political affiliation or belief.


Theodore Norvell (C) 1999-2001
Parsing expressions by recursive descent poses two classic problems
The classic solution to the first problem does not solve the second. I will present the classic solution, a well known alternative known as the "Shunting Yard Algorithm", and a less well known one that I have called "Precedence Climbing".
Consider the following example grammar, G,
E --> E "+" E | E "-" E | "-" E | E "*" E | E "/" E | E "^" E | "(" E ")" | v
in which v is a terminal representing identifiers and/or constants.
We want to build a parser that will
Each input in the language will have a single AST based on the following precedence and associativity rules:
For example the first three rules tell us that
a ^ b * c ^ d + e ^ f / g ^ (h + i)
parses to the tree
+( *( ^(a,b), ^(c,d) ), /( ^(e,f), ^(g,+(h,i)) ) )
while the last rule tells us that
a - b - c
parses to -(-(a,b),c) rather than -(a,-(b,c)), whereas
a ^ b ^ c
parses to ^(a, ^(b,c)) rather than ^(^(a,b), c).
The precedence of unary - over ^ tells us that
- a ^ - b
parses to -( ^( a, -(b) ) ). Some programming language designers choose to put unary operators at the highest level of precedence. I took a different choice here because having some binary operators with higher precedence than some unary operators makes the parsing problem just a bit more challenging.
Aside: I am assuming that the desired output of the parser is an abstract syntax tree (AST). The same considerations arise if the output is to be some other form such as reverse-polish notation (RPN), calls to an analyzer and code generator (for one-pass compilers), or a numerical result (as in a calculator). All the algorithms I present are easily modified for these forms of output.
The idea of recursive-descent parsing is to transform each nonterminal of a grammar into a subroutine that will recognize exactly that nonterminal in the input.
Left recursive grammars, such as G, are unsuitable because a left-recursive production leads to an infinite recursion in the recursive-descent parser. While the parser may be partially correct, it may not terminate.
We can transform G to a non-left-recursive grammar G1 as follows:
E --> P {B P} P --> v | "(" E ")" | U P B --> "+" | "-" | "*" | "/" | "^" U --> "-"
The braces "{" and "}" represent zero or more repetitions of what is inside of them. Thus you can think of E as having an infinity of alternatives:
E --> P | P B P | P B P B P | ... ad infinitum
The language described by this grammar is the same as that of grammar G: L(G1) = L(G).
Not only is left recursion eliminated, but the G1 is unambiguous and each choice can be made by looking at the next token in the input.
Aside: Technically, G1 is an example of what is called an LL(1) grammar. I don't want to make this essay more technical than it needs to be, so I'm not going to stop and go into what that means. End of Aside.
Let's look at a recursive descent recognizer based on this grammar. I call this algorithm a recognizer because all it does is to recognize whether the input is in the language of the grammar or not. That is it does not produce an abstract syntax tree, or any other form of output that represents the contents of the input.
I'll assume that the following subroutines exist:
Using these, let's construct a subroutine "Expect", which I will use throughout this essay
expect( tok ) is if next = tok consume else error
We will now write a subroutine called "Erecognizer". If it does not call "error", then the input was an expression according to the above grammars. If it does call "error", then the input contained a syntax error, e.g. unmatched parentheses, a missing operator or operand, etc.
Erecognizer is E() expect( end )
E is P while next is a binary operator consume P
P is if next is a v consume else if next = "(" consume E expect( ")" ) else if next is a unary operator consume P else error
Notice how the structure of the recognition algorithm mirrors the structure of the grammar. This is the essence of recursive descent parsing.
The difference between a recognizer and a parser is that a parser produces some kind of output that reflects the structure of the input. Next we will look at a way to modify the above recognition algorithm to be a parsing algorithm. It will build an AST, according to the precedence and associativity rules, using a method known as the "shunting yard" algorithm.
The idea of the shunting yard algorithm is to keep operators on a stack until we are sure we have parsed both their operands. The operands are kept on a second stack. The shunting yard algorithm can be used to directly evaluate expressions as they are parsed (it is commonly used in electronic calculators for this task), to create a reverse Polish notation translation of an infix expression, or to create an abstract syntax tree. I'll create an abstract syntax tree, so my operand stacks will contain trees.
The key to the algorithm is to keep the operators on the operator stack ordered by precedence (lowest at bottom and highest at top), at least in the absence of parentheses. Before pushing an operator onto the operator stack, all higher precedence operators are cleared from the stack. Clearing an operator consists of removing the operator from the operator stack and its operand(s) from the operand stack, making a new tree, and pushing that tree onto the operand stack. At the end of an expression the remaining operators are put into trees with their operands and that is that.
The following table illustrates the process for an input of x*y+z. Stacks are written with their tops to the left. The sentinel value acts as an operator of lowest precedence.
| Remaining input | Operand Stack | Operator Stack | Next Action | |
| x * y + z end | sentinel | Push x on to the operand stack | ||
| * y + z end | x | sentinel | Compare the precedence of * with the precedence of the sentinel | |
| * y + z end | x | sentinel | It's higher, so push * on to the operator stack | |
| y + z end | x | binary(*) sentinel | Push y on to the operand stack | |
| + z end | y x | binary(*) sentinel | Compare the precedence of + with the precedence of * | |
| + z end | y x | binary(*) sentinel | It's lower, so make a tree from *, y, and x | |
| + z end | *(x,y) | sentinel | Compare the precedence of + with the precedence of the sentinel | |
| + z end | *(x,y) | sentinel | It's higher, so push + on to the operand stack | |
| z end | *(x,y) | binary(+) sentinel | Push z on to the operator stack | |
| end | z *(x,y) | binary(+) sentinel | Make a tree from +, z, and *(x,y) | |
| end | +( *(x,y), z ) | sentinel |
Compare this to parsing x + y * z.
| Remaining input | Operand Stack | Operator Stack | Next Action | |
| x + y * z end | sentinel | Push x on to the operand stack | ||
| + y * z end | x | sentinel | Compare the precedence of + with the precedence of the sentinel | |
| + y * z end | x | sentinel | It's higher, so push + on to the operator stack | |
| y * z end | x | binary(+) sentinel | Push y on to the operand stack | |
| * z end | y x | binary(+) sentinel | Compare the precedence of * with the precedence of +. | |
| * z end | y x | binary(+) sentinel | It's higher so, push * on to the operand stack | |
| z end | y x | binary(*) binary(+) sentinel | Push z on to the operand stack | |
| end | z y x | binary(*) binary(+) sentinel | Make a tree from *, y, and z | |
| end | *(y, z) x | binary(+) sentinel | Make a tree from +, x, and *(y,z) | |
| end | +( x, *(y, z) ) | sentinel |
In addition to "next", "consume". "end", "error", and "expect", which are explained in the previous section, I will assume that the following subroutines and constants exist:
In the algorithm that follows I compare operators and the sentinel with a > sign. This comparison is defined as follows:
Now we define the following subroutines:
Aside: I hope the pseudo-code notation is fairly clear. I'll just comment that I'm assuming that parameters are passed by reference, so only 2 stacks are created throughout the execution of EParser.
Eparser is var operators : Stack of Operator := empty var operands : Stack of Tree := empty push( operators, sentinel ) E( operators, operands ) expect( end ) return top( operands )
E( operators, operands ) is P( operators, operands ) while next is a binary operator pushOperator( binary(next), operators, operands ) consume P( operators, operands ) while top(operators) not= sentinel popOperator( operators, operands )
P( operators, operands ) is if next is a v push( operands, mkLeaf( v ) ) consume else if next = "(" consume push( operators, sentinel ) E( operators, operands ) expect( ")" ) pop( operators ) else if next is a unary operator pushOperator( unary(next), operators, operands ) consume P( operators, operands ) else error
popOperator( operators, operands ) is if top(operators) is binary const t1 := pop( operands ) const t0 := pop( operands ) push( operands, mkNode( pop(operators), t0, t1 ) ) else push( operands, mkNode( pop(operators), pop(operands) ) )
pushOperator( op, operators, operands ) is while top(operators) > op popOperator( operators, operands ) push( op, operators )
The classic solution to recursive-descent parsing of expressions is to create a new nonterminal for each level of precedence as follows. G2:
E --> T {( "+" | "-" ) T} T --> F {( "*" | "/" ) F} F --> P ["^" F] P --> v | "(" E ")" | "-" T
(The brackets [ and ] enclose an optional part of the production. As before, the braces { and } enclose parts of the productions that may be repeated 0 or more times, and | separates alternatives. The unquoted parentheses ( and ) serve only to group elements in a production.)
Grammar G2 describes the same language as the previous two grammars: L(G2) = L(G1) = L(G)
The grammar is ambiguous; for example, -x*y has two parse trees. The ambiguity is resolved by staying in each loop (in the productions for E and T) as long as possible and by taking the option if possible (in the production for F). With that policy in place, all choices can be made by looking only at the next token of input.
Note that the left-associative and the right-associative operators are treated differently; left-associative operators are consumed in a loop, while right-associative operators are handled with right-recursive productions. This is to make the tree building a bit easier.
Here is an example of parsing a*b - c^d - e*f
Each contour line shows what is recognized by each invocation of E, T, or F. For instance we can see that the top level call to E makes invokes T three times; these three invocations of T respectively recognize a*b, c^d, and e*f. Not shown are the calls to P, of which there is one for each variable.
We can transform this grammar to a parser written in pseudo code.
Eparser is var t : Tree t := E expect( end ) return t
E is var t : Tree t := T while next = "+" or next = "-" const op := binary(next) consume const t1 := T t := mkNode( op, t, t1 ) return t
T is var t : Tree t := F while next = "*" or next = "/" const op := binary(next) consume const t1 := F t := mkNode( op, t, t1 ) return t
F is var t : Tree t := P if next = "^" consume const t1 := F return mkNode( binary("^"), t, t1) else return t
P is var t : Tree if next is a v t := mkLeaf( next ) consume return t else if next = "(" consume t := E expect( ")" ) return t else if next = "-" consume t := F return mkNode( unary("-"), t) else error
It may be worthwhile to trace this algorithm on a few example inputs.
Although this is the classic solution, it has a few drawbacks:
When there are a large number of precedence levels, as in the C and C++ languages, the first two disadvantages become problematic. In Pascal the number of precedence levels was deliberately kept small because —I suspect— its designer, Niklaus Wirth, was aware of the shortcomings of this method when the number of precedence levels is large.
The size problem can be overcome by creating one subroutine that is parameterized by precedence level rather than writing a separate routine for each level. But the speed problem remains. Note that the number of calls to parse an expression consisting of a single identifier is proportional to the number of levels of precedence.
A method that solves all the listed problems of the classic solution, while being simpler than the shunting-yard algorithm is what I call "precedence climbing". (Note however that we will climb down the precedence levels.)
Consider the input sequence
a ^ b * c + d + e
The E subroutine of the classic solution will deal with this by three calls to T, and by consuming the 2 "+"s, building a tree
+(+(result of first call, result of second call), result of third call)
We say that this loop directly consumes the two "+" operators.
The precedence climbing algorithm has a similar loop, but it always directly consumes the first binary operator, then it consumes the next binary operator that is of lower precedence, then the next operator that is of lower precedence than that. When it consumes a left-associative operator, the same loop will also consume the next operator of equal precedence. Let me rewrite the example with operators written at different heights according to their precedence:
+ + * ^ a b c d e
One loop can consume all 4 operators, creating the tree
+(+(*(^(result of first call, result of second call) result of 3rd call), result of 4th call), result of 5th call)
Each operator is assigned a precedence number. To make things more interesting lets add a few more binary operators and use the following precedence tables:
|
|
We use the following grammar G3 in which nonterminal Exp is parameterized by a precedence level. The idea is that Exp(p) recognizes expressions which contain no binary operators (other than in parentheses) with precedence less than p
E --> Exp(0) Exp(p) --> P {B Exp(q)} P --> U Exp(q) | "(" E ")" | v B --> "+" | "-" | "*" |"/" | "^" | "||" | "&&" | "=" U --> "-"
The loop implied by the braces, { and }, in the production for Exp(p) presents a problem: when should the loop be exited? This choice is resolved as follows:
In the productions for Exp(p) and P, the recursive use of Exp is parameterized, by a value q. So there is a second choice to resolve: how is q chosen? The value of q is chosen according to the previous operator:
Consider what will happen in parsing the expression, a * b - c * d - e * f = g * h - i * j - k * l. To make things clearer, I'll present this expression 2 dimensionally to show the precedences of the operators:
2 = 3 - - - - 5 * * * * * * a b c d e f g h i j k l 0 0 0 0
The call to Exp(0) will consume exactly the operators indicated by a 0 underneath. The sub-expressions: a, b, c*d, e*f, and g*h-i*k-k*l will be parsed by calls to P and Exp(6), Exp(4), Exp(4) and Exp(3) respectively. The whole parse is illustrated by
In this picture, each call to Exp is indicated by a dashed contour. The number immediately inside the contour indicates the value of the p parameter. Not shown are the calls to P, of which there is one for each variable, in this example.
What about right-associative operators? Consider an expression
a^b^c
Because of the different way right-associative operators are treated, Exp(0) will only consume the first ^, as the second will be gobbled up by a recursive call to Exp(6).
A recursive-descent parser based on this method looks like this:
Eparser is var t : Tree t := Exp( 0 ) expect( end ) return t
Exp( p ) is var t : Tree t := P while next is a binary operator and prec(binary(next)) >= p const op := binary(next) consume const q := case associativity(op) of Right: prec( op ) Left: 1+prec( op ) const t1 := Exp( q ) t := mkNode( op, t, t1) return t
P is if next is a unary operator const op := unary(next) consume q := prec( op ) const t := Exp( q ) return mkNode( op, t ) else if next = "(" consume const t := Exp( 0 ) expect ")" return t else if next is a v const t := mkLeaf( next ) consume return t else error
I've used precedence climbing in a JavaCC parser for a subset of C++. I've also used it in a parser based on monadic parsing written in Haskell. I'd be happy to mail either grammar to anyone who is interested.
Michael Bruce-Lockhart has implemented a table driven version of the precedence climbing algorithm. Download it here parser.js and parserTest.htm.
I'm not sure who invented what I am calling the classic algorithm. (Anyone know?) Certainly it was made popular by Niklaus Wirth who used it in various compilers, notably for Pascal. I learned it from one of Wirth's books.
The Shunting Yard Algorithm was invented by Edsger Dijkstra around 1960 in connection with one of the first Algol compilers. It is described in a Mathematisch Centrum report (starting around page 21). I think I first saw a version of it described in an ad for the TI-58/59 calculators, two of the earlier calculators to handle precedence.
I first saw what I've called the precedence climbing method described by Keith Clarke in a posting to comp.compilers in 1992. It is closely related to the Top Down Operator Precedence method proposed by Vaughn Pratt in 1972.
Thanks to Colas Schretter for pointing out an error in the precedence climbing algorithm and suggesting a correction.


For the grand finale of the course, students will use Python/Numpy to implement the Laplacian mesh representation, which is a differential operator on the surface of the mesh which approximates the Laplacian of functions on the surface of the mesh. The Laplacian is something like the second derivative along the surface of a function at every point of the mesh, as discussed in class. This representation can be used for a diverse array of tasks in nonrigid geometry processing, such as nonrigid shape editing ("Laplacian mesh editing"), surface function interpolation, compression/denoising, and texture mapping ("uv unwrapping"), to name a few. Students will have an opportunity to implement all of the above operations in this assignment, and this should lead to a rich art contest.
As usual, groups of 1-2 have to earn 100 points, and groups of 3 have to earn 120 points. There will be an intermediate deadline at 11:59PM on Monday 4/18, which is to finish Laplacian Mesh Editing and Cotangent Weights. There will be a 15 point penalty for missing this deadline. The final deadline for the assignment will be on Wednesday 4/27 at 11:59PM.
Click here to download the code for this assignment
You will be filling in code in the file LaplacianMesh.py, and you will be testing it with a GUI in a file named LapGUI.py. This code runs on a library I made for dealing with meshes in Python called S3DGLPy (the same library that was used to load and sample meshes for the point cloud classification assignment). All of the code you write will be operating on a Python object of type PolyMesh. For this assignment, here's what you need to be aware of:
All of the vertices are stored in an array mesh.vertices. Each vertex has a field vertex.ID which stores its position in the list. So for instance, mesh.vertices[10].ID is 10
Each vertex has a function vertex.getVertexNeighbors() which returns a Python array of the 1-ring neighbors of this vertex, not necessarily in any order
The geometry for all of the vertices is stored in an N x 3 numpy array mesh.VPos, which is parallel to the array mesh.vertices. This is the array that you should multiply on the left by the laplacian matrix to get the delta coordinates, and it's also the array you should update after you solve the least squares Laplacian mesh system. Note that points are each along rows now instead of columns in the ordinary convention
If two vertices share a neighbor, then passing the corresponding two vertex objects to the function getEdgeInCommon(v1, v2) returns a MeshEdge object representing their edge, or None if they don't share an edge.
Each MeshEdge object has two fields f1 and f2 representing the faces on either edge of that edge. Each face is an object of type MeshFace. If the edge is along the boundary, then one or the other will be None. To check to see if f1 is None, for example, the syntax in Python is
if edge.f1:
print "f1 is not null"
if not edge.f1:
print "f1 is null"
Each MeshFace object has a function face.getVertices() which returns the vertex objects of that face, not necessarily in any particular order
You can check to see if two objects are equal in python with ==
When multiplying an ordinary matrix by a sparse matrix, the return type is numpy.matrix instead of numpy.array for some reason. So be sure to case the results as a numpy.array, which is what the rest of the code is expecting. For instance, if you have the Laplacian matrix in a sparse matrix L, then a multiplication by the vertices should be written as
Note: These laplacian matrices are known to be extremely ill-conditioned, so be sure to fix multiple anchor points where you don't want the surface to move
Fill in the functions getLaplacianMatrixUmbrella(mesh, anchorsIdx) and solveLaplacianMesh(mesh, anchors, anchorsIdx)
Set up the Laplacian matrix using umbrella weights and anchors as discussed in class, and solve the system in the least squares sense. You can assume that all anchors have a weight of 1. First, show that you can reconstruct the mesh by fixing one anchor, and then show that the system gives rise to stretching when you fix multiple anchors. To test this, go to the MeshLaplacian menu and click "Select Vertices." Hold SHIFT+Click to select an anchor point, and then hold CTRL + Click to drag that anchor somewhere else. The endpoint of the anchor you are currently selecting is drawn in red, and the endpoint of previously selected anchors is drwan in blue. The image below shows an example:
Then, when you are done, click MeshLaplacian->Solve With Constraints
Hints:
If I, J, and V are parallel numpy arrays that hold the rows, columns, and values of nonzero elements, respectively, and the matrix is of size M x N, then the following code makes this into a scipy sparse matrix:
L = sparse.coo_matrix((V, (I, J)), shape=(M, N)).tocsr()
If you have a system of equations Ax = b and A is a sparse matrix, then you can solve it by calling sparse least squares
x = scipy.sparse.linalg.lsqr(A, b)[0]
(and actually you can just write lsqr because I imported it in the starter code)
This system of equations is known to have very poor conditioning. Because of this, you should fix several anchors all over the mesh where you want it to stay stationary, in addition to the ones you want to move, to see the best results
Fill in the function getLaplacianMatrixCotangent(mesh, anchorsIdx)
Fill in the laplacian matrix with cotangent weights. That is, fill in the matrix so that
\[ L_{ij} = -\frac{1}{2} (\cot(\beta_{ij}) + \cot(\alpha_{ij})) \]
and
\[ L_{ii} = -\sum_{j = 1, j \neq i}^N L_{ij} \]
as shown in the figure below:
You can assume that this is a triangle mesh so that there is exactly one vertex across a face from an edge. Then, change your solveLaplacianMesh() function so that it uses cotangent weights instead of umbrella weights, and highlight the difference on at least one mesh in your README.
Hints:
The cotangent is cosine over sine. Recall that
\[ \vec{u} \cdot \vec{v} = ||\vec{u}|| || \vec{v} || \cos(\theta) \]
and
\[ ||\vec{u} \times \vec{v}|| = ||\vec{u}|| || \vec{v} || \sin(\theta)\]
See if you can use this fact to help you to get the cotangent (be sure to make use of the command np.cross)
Cotangent weights aren't a cure-all, especially when there are a lot of obtuse triangles (since the weights will be negative in that case). So if you see bad results on a particular mesh, don't despair...switch back to umbrella. They should at least improve the results on the homer mesh, though, as shown in class, and they should perform better for smoothing/sharpening below
Fill in the function smoothColors(mesh, colors, colorsIdx)
Given a function on the surface of a mesh specified at a few indices, you can do smooth blending of that function across the surface by specifying the function values as anchors in the Laplacian system, and setting the delta coordinates to be zero everywhere. Setting them to zero is like saying the function should minimize the second derivative everywhere, hence the smoothness of the interpolation. You can use this to "color" the entire mesh with very few clicks. In the code, an array called colors is passed along with the RGB values at the indices colorsIdx, and you need to fill in the rest of the colors by doing this function smoothing/completion for each color channel. Below shows an example:
You select the colors in the GUI by going to the menu MeshColoring->Select Color Vertices. Hold down SHIFT + Left Click to select vertices you want to color, just as you did for the Laplacian mesh editor. And then choose their color by holding down CTRL + Left click and clicking on a color in the lower left in the color chooser that's popped up:
when you've chosen the colors you want, click MeshColoring->Interpolate Colors to test your code
Hints:
The code for this should be incredibly similar to the code you wrote to do laplacian mesh editing. You just have to change the delta coordinates to be zero, and the functions on the surface are color channels instead of vertex coordinates (but they can all just be thought of as functions)
Fill in the functions doLaplacianSmooth(mesh) and doLaplacianSharpen(mesh). You can test these by clicking MeshLaplacian->Laplacian Smooth/Sharpen (no anchors needed)
You can use your Laplacian matrix to make simple, efficient surface sharpening and smoothing procedures, which can be shown to work like high and lowpass filters, respectively, by examining their effect on the mesh spectrum. Let L be the square laplacian matrix, and let LN be the laplacian matrix with each row divided by the sum of the weights of that vertex (so e.g. for umbrella each row should be divided by the degree), so that the diagonal part is all 1s. For the umbrella weights, for example, this normalization gives the vector from the centroid of the neighboring vertices to the vertex. Then to smooth the mesh, apply
\[ V' = V - L_N V \]
and to sharpen the mesh, apply
\[ V' = V + L_N V \]
Fill in the function makeMinimalSurface(mesh, anchors, anchorsIdx). You can test this by placing anchors and clicking MeshLaplacian->Minimal Surface
A minimal surface is a surface which has a mean curvature of zero, and which equivalently minimizes local surface area. To simulate one, use your original Laplacian matrix (either umbrella or cotangent weights for the purposes of this assignment), but set all delta coordinates to zero. Then, add anchors at particular positions to "anchor" this minimal surface in space with constraints, and apply the least squares laplacian mesh editing. You can think of the anchors as positions along a wire, and the surface as a soap bubble that forms inside of the wires. Click here to see some crazy examples.
NOTE: For this task, it will work better if instead of having anchors at the bottom, you overwrite the corresponding rows of the upper square laplacian matrix with the anchor rows, and you should do this. So for instance, if you want to anchor a point at index 100 with the position (a, b, c), then row 100 of L should contain all zeros except for a 1 at column 100, and row 100 of the "delta coordinates" should be (a, b, c). The rows corresponding to non-anchor vertices should still be as before, representing the Laplacian at that vertex. Below is an example of the result I got when anchoring the 8 corners of the high resolution cube mesh that way:
Fill in the function getLaplacianSpectrum(mesh, K)
As explained in class, the eigenvectors of the Laplacian matrix are analagous to a Fourier modes of functions along the surface of the mesh. To view the different "modes" of the surface, write code which computes them. To test your code, click MeshLaplacian->GetSpectrum. This code will save SPECTRUM_K modes to a series of .off files "spectrumX.off", where X ranges from 0 to SPECTRUM_K-1. SPECTRUM_K is a constant which is defined at the top of the GUI (default 20), which you can change. You can view the different modes by loading them into the GUI or by looking at them in meshlab
In your readme, explain what you're seeing as you transition from eigenvectors which have small eigenvalues to those which have larger ones.
As explained in this Stackoverflow post, to get the K smallest eigenvectors/eigenvalues of a sparse, symmetric matrix A, you should use the command
As shown in class, you can do something analagous to a lowpass Fourier filtering by projecting functions onto the lower eigenvectors of the Laplacian matrix of a surface. Let UK be a matrix with the first K eigenvectors in the columns of the matrix, and let V be a matrix with the x coordinates of all of the vertices along the first column, the y coordinates along the second column, and the z coordinates along the third column. Then you can project the coordinates of the geometry onto them with
\[ V' = U_K U_K^T V \]
Show that you can denoise homernoise.off with this technique. Also show a screenshot on at least one other mesh (lowpassing with very few frequencies looks quite interesting, as shown in class). You can vary the number of eigenvectors you choose by editing the variable LOWPASS_K at the top of the GUI file. Its default value is 20, which is quite low (it takes up to 500 for homer to start looking reasonable, for example, as shown in class)
where \phik is the kth eigenvector and \lambdak is the associated eigenvalue of the laplacian matrix. Given an initial set of point locations "initialVertices," apply "heatValue" amount of heat to them at the beginning of time, and return the amount of heat on all the vertices at time t according to the above equation.
To test this, click on MeshLaplacian->Do Heat Flow Simulation. This will output a bunch of files called heatX.png, where X ranges from 0 to 89 (so you can use this to make a 90 frame vide). To change the number of eigenvectors/eigenvalues used in the computation, feel free to change the variable HEAT_K at the top of the GUI. The more you use, the better the approximation will be for the initial heat distribution (though it won't matter so much after the first few frames since heat dissipates exponentially quickly). Below is an example of selecting the initial conditions as heat on the tips of Homer's 8 fingers
Selecting Initial Heat Vertices
Heat Flow Animation
Hints:
The eigenvalues and eigenvectors passed along are precomputed using your code in getLaplacianSpectrum to save computation running the heat simulation
As shown in class and described in this paper, a multiscale descriptor of curvature can be computed by looking at how much heat stays at each vertex after a certain amount of time has elapsed, with the following equation:
The larger the t, the more the curvature estimate is "regularized" (smoothed out). You can change the variables HKS_K and HKS_T, to change the number of eigenvectors used in the estimate and the time, respectively. Below shows a screenshot of two different times used on the homer mesh
t = 20
t = 500
Notice how for a smaller t, the curvature on the original fingers is resolvable, whiel in the smoothed version the whole hand contributes to one large curved region all merged together.
You can use Laplacian mesh editing to parameterize a surface with two coordinates. In other words, you can flatten the surface to the plane. To do this, use the Laplacian mesh anchor selector to select four vertices that go in counter-clockwise order around two triangles which share an edge, as shown in the picture below:
Then, build your laplacian matrix, ignoring the edge that connects the two triangles (effectively removing the two triangle faces from the mesh). Then, set all of the delta coordinates to zero, but put anchors of the four points at (0, 0, 0), (0, 1, 0), (1, 1, 0), and (1, 0, 0). You will want to overwrite rows in the upper square matrix instead of putting the anchors at the bottom, as you did in the minimal surfaces task, and you will also want to use umbrella weights instead of cotangent weights as explained in my undergraduate writeup. When you do all of this and solve the system, the points will try to be the average of their neighbors, and this will have the effect of flattening everything inside of the unit square in the XY plane. Below shows two views of doing this on the homer mesh:
You can test your code out by clicking MeshLaplacian->Do Flattening
Now that you have a way to flatten the mesh to the plane, you can wrap a texture around it by taking the x coordinate of each point to be the length along the image you want to wrap around and the y coordinate to be the height along the image. This is called UV mapping. Return an N x 2 matrix with the u coordinates of each point along the first column and the v coordinates of each point along the second column. When you test your code by clicking MeshLaplacian->Compute UV Coordinates, the GUI will automatically render a texture on your mesh using the UV coordinates you have. The texture will be whatever you put in the image texture.png (by default, a checkerboard).
Hints:
You're basically just reusing your code from above but returning the texture coordinates separately instead of updating the geometry. Just make sure all of your texture coordinates are actually in the unit square
You know the drill by now. 5 points for a submission, 20 points for the winner. The winner's points may be applied towards extra credit, while everyone else's scores are capped at 100%.