pymatgen.analysis.chemenv.utils.graph_utils module¶
-
class
MultiGraphCycle
(nodes, edge_indices, validate=True, ordered=None)[source]¶ Bases:
monty.json.MSONable
Class used to describe a cycle in a multigraph.
nodes are the nodes of the cycle and edge_indices are the indices of the edges in the cycle. The nth index in edge_indices corresponds to the edge index between the nth node in nodes and the (n+1)th node in nodes with the exception of the last one being the edge index between the last node in nodes and the first node in nodes
- Example: A cycle
nodes: 1 - 3 - 4 - 0 - 2 - (1) edge_indices: 0 . 1 . 0 . 2 . 0 . (0)
-
order
(raise_on_fail=True)[source]¶ Orders the SimpleGraphCycle.
The ordering is performed such that the first node is the “lowest” one and the second node is the lowest one of the two neighbor nodes of the first node. If raise_on_fail is set to True a RuntimeError will be raised if the ordering fails.
- Parameters
raise_on_fail – If set to True, will raise a RuntimeError if the ordering fails.
- Returns
None
-
class
SimpleGraphCycle
(nodes, validate=True, ordered=None)[source]¶ Bases:
monty.json.MSONable
Class used to describe a cycle in a simple graph (graph without multiple edges).
Note that the convention used here is the networkx convention for which simple graphs allow to have self-loops in a simple graph. No simple graph cycle with two nodes is possible in a simple graph. The graph will not be validated if validate is set to False. By default, the “ordered” parameter is None, in which case the SimpleGraphCycle will be ordered. If the user explicitly sets ordered to False, the SimpleGraphCycle will not be ordered.
-
classmethod
from_dict
(d, validate=False)[source]¶ - Parameters
d – Dict representation.
- Returns
MSONable class.
-
classmethod
from_edges
(edges, edges_are_ordered=True)[source]¶ Constructs SimpleGraphCycle from a list edges.
By default, the edges list is supposed to be ordered as it will be much faster to construct the cycle. If edges_are_ordered is set to False, the code will automatically try to find the corresponding edge order in the list.
-
order
(raise_on_fail=True)[source]¶ Orders the SimpleGraphCycle.
The ordering is performed such that the first node is the “lowest” one and the second node is the lowest one of the two neighbor nodes of the first node. If raise_on_fail is set to True a RuntimeError will be raised if the ordering fails.
- Parameters
raise_on_fail – If set to True, will raise a RuntimeError if the ordering fails.
- Returns
None
-
classmethod


Posted on January 19, 2016
Taking care of your skin can feel like a chore because you may not know what products to use, how to use them, in what order to use them and what works best for your individual skin type and issues. But it really doesn't have to be that difficult. Knowing what products work together, how they benefit your skin and the order to use them is very important when choosing the best skincare routine for you. The information below is a guideline you can follow to select products based on what works best for you and your specific skin concerns.
Tips for Putting Together a Skincare Regimen
If you want your skin to look its best, you have to give it the best possible care. A daily regimen will provide your skin with the essentials that it needs to remain healthy and youthful-looking. It is important that you put together the right regimen for your specific needs. Following these tips will help you select the right products and help to ensure the success of your regimen.
If you have multiple skincare concerns, you may need to add one or more treatments to your daily routine. You may only need to add one targeted treatment product to your routine, or you might need to alternate its use with other products. With a more advanced routine, some experimentation is needed to discover which method and frequency of application works best for your individual skincare type. Customize your regimen with products for your concerns. If you're not currently using a skincare regimen, I challenge you to take care of your skin. Consistency is key!
Cleansing is one of the most important steps in a daily routine, as it removes impurities that can irritate your skin and interfere with other skincare products. If a cleanser does what it should, it will pull impurities out of your skin, open up pores and clean the dead skin, dirt and bacteria away from your face. If it's a cheap wash, it will just push the junk around your skin instead of cleaning it off. Did you know that bubbles and foam are bad when it comes to cleansers? They destroy skin's delicate lipid barrier and ruin its natural moisture process. Oily skin will become oilier and dry skin will become drier.
Toner is a skincare product that has often been overlooked, but can do wonders when it comes to improving the appearance of your skin. Skin toners have come a long way. When you keep your skin appropriately pH-balanced with an alcohol-free toner, it is less likely to become too oily or too dry. The benefits to consistently using a toner in your daily routine are they shrink pores, give your skin pH balance, protect it, prepare your skin to better absorb anti-aging serums and moisturizers and help prevent ingrown hairs.
One of the main reasons why alcohol-free toners are recommended is because they help remove excess makeup, oil and other impurities left behind by your cleanser. Once all of the excess impurities are removed, the toner helps any serum or moisturizer you use better absorb into your skin. For best results, and depending on the sensitivity of your skin, a toner should be used at least once a day and up to twice a day, after cleansing and before moisturizing.
I'm still always surprised when people tell me they didn't know that the majority of how our skin ages (90% to be exact) comes from the amount of sun exposure we take in and how often we use proper sun protection. To know if a sunscreen or sunblock helps ward off skin cancer, look for the term "broad spectrum" on the label. This means the product offers protection against both UVA and UVB rays. Make sure to use a broad spectrum sunscreen or sunblock with at least an SPF of 15, an SPF of 20-30 is ideal.
Moisturizing is such an important step in your skincare routine. Normal, dry, oily and combination skin all require hydration, so every skincare regimen should contain a moisturizer. The key is to select a product developed with your skin type in mind. Moisturizers for complexions that are oily or prone to breakouts should be more light weight. Dry skin will benefit from thicker creams, while light weight creams/lotions best serve combination and normal skin. The best time to apply your lotion or cream is after you've dried off after your shower/bath or within 3 minutes after washing your face and applying toner. Seal in the moisture that's already been absorbed into your skin.
Try to keep lips soft, not dry and chapped, by applying a moisturizing lip serum to visibly smooth lip texture and combat dryness. Also, you should use an eye cream daily. The skin around your eyes is the thinnest on your body. So, wrinkles will appear there first. Yet so many people think they can skimp on using eye cream or use their facial moisturizer as an eye cream.
The first signs of aging are not wrinkles and crow's feet, but dull skin.  Exfoliating the old, dead outermost cells is the quickest, easiest way to make skin look smoother and more vibrant from head to toe. However, never scrub your face too hard with an exfoliator or use it too often. Over-exfoliation can strip away your lipid barrier, making skin more susceptible to irritation and bacterial infection.
When it comes to anti-aging products and treatments, look for ingredients such as peptides, hyaluronic acid, Vitamin C, Vitamin E, retinol and alpha-hydroxy acids. Even though many women don't begin to develop noticeable signs of aging until their late 30s and early 40s, the damage that causes fine lines and wrinkles starts occurring way before that. By adding anti-aging skincare products to your routine, you can decrease the chances of those fine lines and wrinkles showing up prematurely.
Micro-needling:After the age of 30, our collagen production slows down by 1% each year. The good news is that you can still get the most out of your skincare regimen by adding the AMP MD roller system to it. The AMP MD roller has little needles that "injure" skin and help build back collagen loss. When done daily or 3-5 times a week at home, your skin responds to the contact of the micro-needle tips, improving tone, texture and firmness. Used in conjunction with retinol and peptides, the result is firmer skin. Micro-needling is also great for acne scarring, pitting of the skin and post-surgical procedures to diminish scar tissue marks.
Macro Exfoliator:An advanced exfoliation skincare tool to consider that can give you microdermabrasion-like results at home is the Macro Exfoliator.  It features DOC-SMART technology to vary the degree and duration of exfoliation based on facial areas such as cheeks, nose, chin, forehead, outer eye area, neck and decolletage. Once a week for 5 minutes is all it takes to do your own microdermabrasion facial in the comfort of your own home.
Acne is a common skin condition that happens when oil and dead skin cells clog your pores. It can be caused by many things: heredity, hormones, stress and oil production. Make sure to practice good skincare techniques, improve your diet and get your acne under control ASAP. Use products targeted at oily or acne-prone skin and look for moisturizers, sunblocks and makeup that are non-comedogenic and don't block your pores. Over-the-counter spot creams and gels with ingredients such as benzoyl peroxide or salicylic acid are extremely effective for clearing acne.
However, there are some instances when over-the-counter products just aren't working. That's when it is best to see a dermatologist first in order to keep acne scarring to a minimum. Then once the dermatologist helps get your acne under control, regularly using a regimen such as UNBLEMISH will help keep acne under control.
Exposure to the sun and environment can leave you with dull-looking skin premature aging, including brown spots, dullness, discoloration, melasma, age spots and fine lines. Look for products with ingredients such as Vitamin C, alpha-hydroxy acid, kojic acid, salicylic acid, licorice, retinol and antioxidants to help reduce free radical damage. For people with melasma and stubborn dark marks, it is recommended you use something containing hydroquinone (2% is recommended).
However, there are some instances when over-the-counter products just aren't working. That's when it is best to see a dermatologist first in order to keep acne scarring to a minimum. Then once the dermatologist helps get your acne under control, regularly using a regimen such as UNBLEMISH will help keep acne under control.
Exposure to the sun and environment can leave you with dull-looking skin premature aging, including brown spots, dullness, discoloration, melasma, age spots and fine lines. Look for products with ingredients such as Vitamin C, alpha-hydroxy acid, kojic acid, salicylic acid, licorice, retinol and antioxidants to help reduce free radical damage. For people with melasma and stubborn dark marks, it is recommended you use something containing hydroquinone (2% is recommended).
It's great to be able to go to one company for your different skincare needs and issues. Depending on the time of year, skin changes. Most people probably don't even realize that they need to switch up their routine to address changes throughout the year. R+F takes care of all this for you.
Looking for an effective skincare routine specific to your skin type, issues and concerns? Learn how multi-med therapy products can help transform your skin to become more healthy and youthful-looking!
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Inventore, perspiciatis adipisci accusamus laudantium odit aliquam repellat tempore quos aspernatur vero.


Routing Audio Between Applications Using Soundflower
Quick Tip: Routing Audio Between Applications Using Soundflower
Soundflower is a lesser known application among computer musicians which allows inter-application audio routing for Mac OS X. Soundflower creates a virtual audio interface which has a number of inputs and outputs. This virtual interface can be selected as your audio interface in your software to route audio from one application to another for further processing.
Soundflower creates two devices in your audio device list for your use, a 2-channel and a 16-channel variant. The 2-channel variant should be enough in most cases while the 16-channel Soundflower provides opportunities for more complex routing.
Download and Install Soundflower
Soundflower is developed by the great folks at Cycling’74 and is provided as a free download from their website. You can head over to the downloads page on their site and download Soundflower. The installation process is simple and should be done in minutes. Once that is done, you will have Soundflower listed as another audio interface and ready for use.
Setup the Audio Interface in Your Software
Sending audio with Soundflower is really simple. The concept is to have the source application use Soundflower as an output device and have the destination use Soundflower as an input device.
If your software allows separate input and output audio interfaces like Ableton Live, you can select Soundflower as just your input if you would like to send audio into Live or as your output interface if you want to route Live’s output to another software. If your software requires both the input and output device to be the same, you will need to manage the audio routing within your software to make sure you do not create a feedback loop.
Note that I mentioned audio software instead of just DAWs. It does not make much sense routing audio from one DAW to anther considering that most DAWs have Rewire support to handle that. With some creativity, you can route audio from anywhere. You could route the audio from standalone software to your DAW to record the output, or even route your DAW output to Skype.
Extending Soundflower with Soundflowerbed
Soundflower is extremely transparent once you have installed it. There are no preferences and no application to launch, just an additional audio interface listed in your audio preferences. This simpicity is the beauty of Soundflower.
However, power users that demand more flexibility can have more control over Soundflower with the use of Soundflowerbed. Soundflowerbed is a menubar app that allows additional routing possibilities and configuration of Soundflower.
Being Creative With Routing
Like I have mentioned earlier, the power of Soundflower really depends on how creative you can get. I am going to list some ways I use Soundflower that you will hopefully find useful.
Route System Audio to Your DAW
You can set your system to use Soundflower as your primary audio interface and all your system audio will be routed to Soundflower. This allows you to route your system audio to your DAW or any other software of your choice. This allows you to record audio from software that do not have preference setting for audio such as your web browser or other basic applications. You can record audio from your web browser such as podcasts, etc.
Route Audio from MAX/MSP Patches
There are lots of cool MAX/MSP patches on the web which can do some really interesting things. However, MAX patches generally run as standalone applications with the exception of MAX for Live patches. Soundflower was originally built with this purpose in mind for integrating MAX patches with an external environment. You can integrate the MAX patches as either sound sources or effects with your DAW.
The possibilities are endless with the ability to route audio between applications on the same computer. Complex routing can create new combinations of tools as you merge the processing abilities of various audio software.


| module ti.sysbios.knl.Idle |
|
|
|
Idle Thread Manager
The Idle module is used to specify a list of functions to be called
when no other tasks are running in the system.
[
more ... ]
#include <ti/sysbios/knl/Idle.h>
Functions |
Void | |
Functions common to all target modules |
|
|
Typedefs |
typedef Void | |
DETAILS
The Idle module is used to specify a list of functions to be called
when no other tasks are running in the system.
If tasking is enabled (ie
BIOS.taskEnabled = true), then the Task module will create an "Idle task"
with the lowest possible priority. When no other tasks are running, this
idle task runs in an infinite loop, calling the list of functions
specified by the Idle module.
If tasking is disabled (ie
BIOS.taskEnabled = false), then the idle functions are called in an
infinite loop within the
BIOS_start
function called within main().
The list of idle functions is only statically configurable; it cannot be
modified at runtime.
| typedef Idle_FuncPtr |
|
Idle function type definition
typedef Void (*Idle_FuncPtr)();
| Idle_run() // module-wide |
|
Make one pass through idle functions
DETAILS
This function is called repeatedly by the Idle task when
the Idle task has been enabled in the Task module
(see
Task.enableIdleTask).
This function makes one pass through an internal static array
of functions made up of functions added using the
Idle.addFunc() API as well as any functions
defined in the GUI tool's
Idle.idleFxns[] array.
This function returns after all functions have been executed one
time.
SEE
| Module-Wide Built-Ins |
|
// Get this module's unique id
Bool Idle_Module_startupDone();
// Test if this module has completed startup
// The heap from which this module allocates memory
Bool Idle_Module_hasMask();
// Test whether this module has a diagnostics mask
Bits16 Idle_Module_getMask();
// Returns the diagnostics mask for this module
Void Idle_Module_setMask(Bits16 mask);
// Set the diagnostics mask for this module
var Idle = xdc.useModule('ti.sysbios.knl.Idle');
module-wide constants & types
module-wide config parameters
null,
null,
null,
null,
null,
null,
null,
null
];
module-wide functions
generated on Wed, 28 Aug 2019 17:00:28 GMT


6 MLM, 3 levels: Nurse’s Stress Intervention
library(tidyverse) # basically everything ;)
library(haven) # read in SPSS dataset
library(furniture) # nice table1() descriptives
library(stargazer) # display nice tables: summary & regression
library(texreg) # Convert Regression Output to LaTeX or HTML Tables
library(psych) # contains some useful functions, like headTail
library(car) # Companion to Applied Regression
library(lme4) # Linear, generalized linear, & nonlinear mixed models
library(lmerTest) # Tests on lmer objects
library(performance) # ICC calculations
library(interactions) # plotting interactions
library(effects) # Effects for regression models
library(optimx) # Different optimizers to solve mlm's
6.1 Background
The text “Multilevel Analysis: Techniques and Applications, Third Edition” (Hox, Moerbeek, and Van de Schoot 2017) has a companion website which includes links to all the data files used throughout the book (housed on the book’s GitHub repository).
The following example is used through out Hox, Moerbeek, and Van de Schoot (2017)’s chapater 2.
From Appendix E:
The nurses.sav file contains three-level simulated data from a hypothetical study on stress in hospitals. The data are from nurses working in wards nested within hospitals. It is a cluster-randomized experiment. In each of 25 hospitals, four wards are selected and randomly assigned to an experimental and a control condition. In the experimental condition, a training program is offered to all nurses to cope with job-related stress. After the program is completed, a sample of about 10 nurses from each ward is given a test that measures job-related stress. Additional variables (covariates) are: nurse age (years), nurse experience (years), nurse gender (0=male, 1 = female), type of ward (0=general care, 1=special care), and hospital size (0=small, 1 = medium, 2=large). The data have been generated to illustrate three-level analysis with a random slope for the effect of the intervention.
Here the data is read in and the SPSS variables with labels are converted to \(R\) factors.
<- haven::read_spss("https://github.com/MultiLevelAnalysis/Datasets-third-edition-Multilevel-book/raw/master/chapter%202/Nurses/SPSS/Nurses.sav") %>%
data_raw ::as_factor() # retain the labels from SPSS --> factor haven
6.1.1 Unique Identifiers
All standardized (starts with “Z”) and mean centered (starts with “C”) variables will be remove so that their creation may be shown later. A new indicator varible for nurses with be created by combining the hospital
, ward
, and nurse
indicators. Having a unique, distinct identifier variable for each of the units on lower (Level 1 and 2) levels is helpful for multilevel anlayses.
<- data_raw %>%
data_nurse ::mutate(genderF = factor(gender,
dplyrlabels = c("Male", "Female"))) %>% # apply factor labels
::mutate(id = paste(hospital, ward, nurse,
dplyrsep = "_") %>% # unique id for each nurse
factor()) %>% # declare id is a factor
::mutate_at(vars(hospital, ward,
dplyr%>% # declare to be factors
wardid, nurse), factor) ::mutate(age = age %>% as.character %>% as.numeric) %>% # declare to be numeric
dplyr::select(id, wardid, nurse, ward, hospital,
dplyr
age, gender, genderF, experien,
wardtype, hospsize,# reduce variables included
expcon, stress)
::glimpse(data_nurse) tibble
Rows: 1,000
Columns: 13
$ id <fct> 1_1_1, 1_1_2, 1_1_3, 1_1_4, 1_1_5, 1_1_6, 1_1_7, 1_1_8, 1_1_9…
$ wardid <fct> 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 1…
$ nurse <fct> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18…
$ ward <fct> 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3…
$ hospital <fct> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ age <dbl> 36, 45, 32, 57, 46, 60, 23, 32, 60, 45, 57, 47, 32, 42, 42, 5…
$ gender <dbl> 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1…
$ genderF <fct> Male, Male, Male, Female, Female, Female, Female, Female, Mal…
$ experien <dbl> 11, 20, 7, 25, 22, 22, 13, 13, 17, 21, 24, 24, 14, 13, 17, 20…
$ wardtype <fct> general care, general care, general care, general care, gener…
$ hospsize <fct> large, large, large, large, large, large, large, large, large…
$ expcon <fct> experiment, experiment, experiment, experiment, experiment, e…
$ stress <dbl> 7, 7, 7, 6, 6, 6, 6, 7, 7, 6, 6, 6, 6, 6, 6, 5, 5, 6, 5, 5, 4…
6.1.2 Centering Variables
When variables are involved in an interaction, it may be advantageous to center the variables. Hox, Moerbeek, and Van de Schoot (2017) covers this in chapter 4.
To center categorical variables:
1. Convert then to integers, starting with zero: \(0, 1, \dots\)
2. Subtract the mean
%>%
data_nurse ::mutate(expconN = as.numeric(expcon) - 1) %>% # Numeric Version of experimental condition
dplyr::mutate(hospsizeN = as.numeric(hospsize) - 1) %>% # Numeric Version of hospital size
dplyr::select(expcon, expconN, hospsize, hospsizeN) %>%
dplyrsummary()
expcon expconN hospsize hospsizeN
control :496 Min. :0.000 small :374 Min. :0.000
experiment:504 1st Qu.:0.000 medium:476 1st Qu.:0.000
Median :1.000 large :150 Median :1.000
Mean :0.504 Mean :0.776
3rd Qu.:1.000 3rd Qu.:1.000
Max. :1.000 Max. :2.000
<- data_nurse %>%
data_nurse ::mutate(expconN = as.numeric(expcon) - 1) %>% # Numeric Version of experimental condition
dplyr::mutate(hospsizeN = as.numeric(hospsize) - 1) %>% # Numeric Version of hospital size
dplyr::mutate(expconNG = expconN - 0.504) %>% # Grand-Mean Centered version of experimental condition
dplyr::mutate(hospsizeNG = hospsizeN - 0.776) # Grand-Mean Centered version of ehospital size dplyr
%>%
data_nurse ::select(expcon, expconNG) %>%
dplyrtable()
expconNG
expcon -0.504 0.496
control 496 0
experiment 0 504
%>%
data_nurse ::select(hospsize, hospsizeNG) %>%
dplyrtable()
hospsizeNG
hospsize -0.776 0.224 1.224
small 374 0 0
medium 0 476 0
large 0 0 150
6.2 Exploratory Data Analysis
6.2.1 Summarize Descriptive Statistics
<IP_ADDRESS> The stargazer
package
Most posters, journal articles, and reports start with a table of descriptive statistics. Since it tends to come first, this type of table is often refered to as Table 1. The stargazer()
function can be used to create such a table, but only for the entire dataset (Hlavac 2022). I haven’t been able to find a way to get it to summarize subsamples and compare them in the standard format.
# Knit to Website: type = "html"
# Knit to PDF: type = "latex"
# View on Screen: type = "text"
%>%
data_nurse data.frame() %>%
::stargazer(title = "Descriptive statistics, aggregate over entire sample",
stargazerheader = FALSE,
type = "text")
| Statistic | N | Mean | St. Dev. | Min | Max |
| age | 1,000 | 43.005 | 12.042 | 23 | 64 |
| gender | 1,000 | 0.735 | 0.442 | 0 | 1 |
| experien | 1,000 | 17.057 | 6.042 | 1 | 38 |
| stress | 1,000 | 4.977 | 0.980 | 1 | 7 |
| expconN | 1,000 | 0.504 | 0.500 | 0 | 1 |
| hospsizeN | 1,000 | 0.776 | 0.689 | 0 | 2 |
| expconNG | 1,000 | -0.000 | 0.500 | -0.504 | 0.496 |
| hospsizeNG | 1,000 | -0.000 | 0.689 | -0.776 | 1.224 |
<IP_ADDRESS> The furniture
package
Tyson Barrett’s furniture package includes the extremely useful function table1()
which simplifies the common task of creating a stratified, comparative table of descriptive statistics. Full documentation can be accessed by executing ?furniture::table1
.
# Knit to Website: output = "html"
# Knit to PDF: output = "latex2"
# View on Screen: output = ""text", or "markdown", "html"
%>%
data_nurse ::table1(age, genderF, experien, wardtype, hospsize, hospsizeN, hospsizeNG,
furnituresplitby = ~ expcon, # var to divide sample by
test = TRUE, # test groups different?
type = "full", # give the test statistic
output = "text", # output for html
caption = "Compare Intervention groups on five main variables") # title
| control | experiment | Test | P-Value | |
|---|---|---|---|---|
| n = 496 | n = 504 | |||
| age | T-Test: 0.82 | 0.411 | ||
| 43.3 (11.6) | 42.7 (12.5) | |||
| genderF | Chi Square: 0.19 | 0.661 | ||
| Male | 135 (27.2%) | 130 (25.8%) | ||
| Female | 361 (72.8%) | 374 (74.2%) | ||
| experien | T-Test: 0.69 | 0.492 | ||
| 17.2 (5.8) | 16.9 (6.3) | |||
| wardtype | Chi Square: 0 | 1 | ||
| general care | 247 (49.8%) | 252 (50%) | ||
| special care | 249 (50.2%) | 252 (50%) | ||
| hospsize | Chi Square: 0.01 | 0.993 | ||
| small | 185 (37.3%) | 189 (37.5%) | ||
| medium | 237 (47.8%) | 239 (47.4%) | ||
| large | 74 (14.9%) | 76 (15.1%) | ||
| hospsizeN | T-Test: 0.01 | 0.992 | ||
| 0.8 (0.7) | 0.8 (0.7) | |||
| hospsizeNG | T-Test: 0.01 | 0.992 | ||
| 0.0 (0.7) | -0.0 (0.7) |
The t-test performed by the furniture::table1()
function
will always assume indepent groups and that HOV is not violated. This
may or may not be appropriate.
6.3 MLM: Null Model
In a Null, intercept-only, or Empty model, no predictors are included.
<IP_ADDRESS> Fit the Model
Fit the model to the data, with both ML and REML.
<- lmerTest::lmer(stress ~ 1 + # Fixed Intercept for all nurses
nurse_lmer_0_re 1|hospital/ward), # Random Intercepts for wards within hospitals
(data = data_nurse,
REML = TRUE) # fit via REML (the default) for ICC calculations
<- lmerTest::lmer(stress ~ 1 + # Fixed Intercept for all nurses
nurse_lmer_0_ml 1|hospital/ward), # Random Intercepts for wards within hospitals
(data = data_nurse,
REML = FALSE) # fit via ML for comparing FIXED effects inclusion
::knitreg(list(nurse_lmer_0_ml,
texreg
nurse_lmer_0_re),custom.model.names = c("M0: Null, ML",
"M0: Null, REML"),
caption = "NULL Model: different estimation methods",
caption.above = TRUE,
single.row = TRUE)
| M0: Null, ML | M0: Null, REML | |
|---|---|---|
| (Intercept) | 5.00 (0.11)*** | 5.00 (0.11)*** |
| AIC | 1950.36 | 1952.95 |
| BIC | 1969.99 | 1972.58 |
| Log Likelihood | -971.18 | -972.48 |
| Num. obs. | 1000 | 1000 |
| Num. groups: ward:hospital | 100 | 100 |
| Num. groups: hospital | 25 | 25 |
| Var: ward:hospital (Intercept) | 0.49 | 0.49 |
| Var: hospital (Intercept) | 0.16 | 0.17 |
| Var: Residual | 0.30 | 0.30 |
| ***p < 0.001; **p < 0.01; *p < 0.05 |
6.4 Estimate the ICC
The ICC is calculated by dividing the between-group-variance (random intercept variance) by the total variance (i.e. sum of between-group-variance and within-group (residual) variance).
::VarCorr(nurse_lmer_0_re) lme4
Groups Name Std.Dev.
ward:hospital (Intercept) 0.69916
hospital (Intercept) 0.41749
Residual 0.54887
::VarCorr(nurse_lmer_0_re) %>%
lme4print(comp = c("Variance", "Std.Dev"),
digits = 3)
Groups Name Variance Std.Dev.
ward:hospital (Intercept) 0.489 0.699
hospital (Intercept) 0.174 0.417
Residual 0.301 0.549
<- lme4::VarCorr(nurse_lmer_0_re) %>%
vc data.frame()
pie(x = vc$vcov,
labels = vc$grp)
The performance
package has a few really helpful funcitons:
::VarCorr(nurse_lmer_0_re) lme4
Groups Name Std.Dev.
ward:hospital (Intercept) 0.69916
hospital (Intercept) 0.41749
Residual 0.54887
::get_variance(nurse_lmer_0_re) insight
$var.fixed
[1] 0
$var.random
[1] 0.6631239
$var.residual
[1] 0.3012569
$var.distribution
[1] 0.3012569
$var.dispersion
[1] 0
$var.intercept
ward:hospital hospital
0.4888231 0.1743008
\[ \begin{align*} \text{hospitals} \rightarrow \; & \sigma^2_{v0} = 0.417^2 = 0.174\\ \text{wards within hospitals} \rightarrow \; & \sigma^2_{u0} = 0.699^2 = 0.489\\ \text{nurses within wards within hospitals} \rightarrow \; & \sigma^2_{e} = 0.549^2 = 0.301\\ \end{align*} \]
Intraclass Correlation (ICC) Formula, 3 level model - Davis and Scott Method \[ \overbrace{\rho_{mid}}^{\text{ICC}\atop\text{at level 2}} = \frac{\overbrace{\sigma^2_{u0}}^{\text{Random Intercept}\atop\text{Variance Level 2}}} {\underbrace{\sigma^2_{v0}+\sigma^2_{u0}+\sigma^2_{e}}_{\text{Total}\atop\text{Variance}}} \tag{Hox 2.16} \] \[ \overbrace{\rho_{top}}^{\text{ICC}\atop\text{ at level 3}} = \frac{\overbrace{\sigma^2_{v0}}^{\text{Random Intercept}\atop\text{Variance Level 3}}} {\underbrace{\sigma^2_{v0}+\sigma^2_{u0}+\sigma^2_{e}}_{\text{Total}\atop\text{Variance}}} \tag{Hox 2.17} \]
0.489 / (0.174 + 0.489 + 0.301) # middle level (wards)
[1] 0.5072614
0.174 / (0.174 + 0.489 + 0.301) # top level (hospitals)
[1] 0.1804979
For more than two levels, the ‘performance::icc()’ function computes ICC’s by the Davis and Scott method.
::icc(nurse_lmer_0_re) performance
# Intraclass Correlation Coefficient
Adjusted ICC: 0.688
Unadjusted ICC: 0.688
::icc(nurse_lmer_0_re, by_group = TRUE) performance
# ICC by Group
Group | ICC
---------------------
ward:hospital | 0.507
hospital | 0.181
The proportion of variance in nurse stress level is 0.51 at the ward level and 0.18 at the hospital level, for a total of 0.69.
To test if the three level model is justified statistically, compare the null models with and without the nesting of wards in hospitals.
<- lmerTest::lmer(stress ~ 1 + (1|wardid), # each hospital contains several wards
nurse_lmer_0_re_2level data = data_nurse,
REML = TRUE) # fit via REML (the default) for ICC calculations
::knitreg(list(nurse_lmer_0_re_2level,
texreg
nurse_lmer_0_re),custom.model.names = c("2 levels",
"3 levels"),
caption = "MLM: Two or Three Levels?",
caption.above = TRUE,
single.row = TRUE)
| 2 levels | 3 levels | |
|---|---|---|
| (Intercept) | 5.00 (0.08)*** | 5.00 (0.11)*** |
| AIC | 1958.43 | 1952.95 |
| BIC | 1973.15 | 1972.58 |
| Log Likelihood | -976.21 | -972.48 |
| Num. obs. | 1000 | 1000 |
| Num. groups: wardid | 100 | |
| Var: wardid (Intercept) | 0.66 | |
| Var: Residual | 0.30 | 0.30 |
| Num. groups: ward:hospital | 100 | |
| Num. groups: hospital | 25 | |
| Var: ward:hospital (Intercept) | 0.49 | |
| Var: hospital (Intercept) | 0.17 | |
| ***p < 0.001; **p < 0.01; *p < 0.05 |
The deviance test or likelihood-ratio test shows that the inclusion of the nesting of wards within hospitals better explains the variance in nurse stress levels.
anova(nurse_lmer_0_re, nurse_lmer_0_re_2level,
refit = FALSE)
Data: data_nurse
Models:
nurse_lmer_0_re_2level: stress ~ 1 + (1 | wardid)
nurse_lmer_0_re: stress ~ 1 + (1 | hospital/ward)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
nurse_lmer_0_re_2level 3 1958.4 1973.2 -976.21 1952.4
nurse_lmer_0_re 4 1953.0 1972.6 -972.48 1945.0 7.4738 1 0.00626
nurse_lmer_0_re_2level
nurse_lmer_0_re **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
6.5 MLM: Add Fixed Effects
6.5.1 Fit the Model
Hox, Moerbeek, and Van de Schoot (2017), page 22:
“In this example, the variable
expcon
is of main interest, and the other variables are covariates. Their funciton is to control for differences between the groups, which can occur even if randomization is used, especially with small samples, and to explain variance in the outcome variable stress. To the extent that these variables successfully explain the variance, the power of the test for the effect ofexpcon
will be increased.”
<- lmerTest::lmer(stress ~ expcon + # experimental condition = CATEGORICAL FACTOR
nurse_lmer_1_ml + gender + experien + # level 1 covariates
age + # level 2 covariates
wardtype + # level 3 covariates, hospital size = CATEGORICAL FACTOR
hospsize 1|hospital/ward), # Random Intercepts for wards within hospitals
(data = data_nurse,
REML = FALSE) # fit via ML for nested FIXED effects
::knitreg(list(nurse_lmer_0_ml,
texreg
nurse_lmer_1_ml),custom.model.names = c("M0: null",
"M1: fixed pred"),
caption = "Nested Models: Fixed effects via ML",
caption.above = TRUE,
single.row = TRUE)
| M0: null | M1: fixed pred | |
|---|---|---|
| (Intercept) | 5.00 (0.11)*** | 5.38 (0.18)*** |
| expconexperiment | -0.70 (0.12)*** | |
| age | 0.02 (0.00)*** | |
| gender | -0.45 (0.03)*** | |
| experien | -0.06 (0.00)*** | |
| wardtypespecial care | 0.05 (0.12) | |
| hospsizemedium | 0.49 (0.19)** | |
| hospsizelarge | 0.90 (0.26)*** | |
| AIC | 1950.36 | 1626.32 |
| BIC | 1969.99 | 1680.30 |
| Log Likelihood | -971.18 | -802.16 |
| Num. obs. | 1000 | 1000 |
| Num. groups: ward:hospital | 100 | 100 |
| Num. groups: hospital | 25 | 25 |
| Var: ward:hospital (Intercept) | 0.49 | 0.33 |
| Var: hospital (Intercept) | 0.16 | 0.10 |
| Var: Residual | 0.30 | 0.22 |
| ***p < 0.001; **p < 0.01; *p < 0.05 |
6.5.2 Assess Significance
anova(nurse_lmer_0_ml, nurse_lmer_1_ml)
Data: data_nurse
Models:
nurse_lmer_0_ml: stress ~ 1 + (1 | hospital/ward)
nurse_lmer_1_ml: stress ~ expcon + age + gender + experien + wardtype + hospsize + (1 | hospital/ward)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
nurse_lmer_0_ml 4 1950.4 1970.0 -971.18 1942.4
nurse_lmer_1_ml 11 1626.3 1680.3 -802.16 1604.3 338.04 7 < 2.2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
It is clear that the inclusing of these fixed, main effects improves the model’s fit, but it is questionable that the type of ward is significant (Wald test is non-significant). Rather than test it directly, we will leave it in the model. This is common practice to show that an expected variable is not significant.
6.5.3 Centering Variables
Because we will will find that the experimental condition is moderated by hospital size (in other words there is a significant interaction between expcon
and hospsize
), Hox, Moerbeek, and Van de Schoot (2017) presents the models fit with centered values for these two variables. Let us see how this changes the model.
(1) Experimental Condition
Experimental conditon is a BINARY or two-level factor.
When it is alternatively coded as a numeric, continuous variable taking the values of zero (\(0\)) for the reference category and one (\(1\)) for the other category, the model estimates are exactly the same, including the paramters for the variables and the intercept, AND the model fit statistics.
When the numeric, continuous variable is further grand-mean centered by additionally subtraction the MEAN of the numberic version, the value of the intercept is the only estimate that changes.
<- lmerTest::lmer(stress ~ expconN + # experimental condition = CONTINUOUS CODED 0/1
nurse_lmer_1a_ml + gender + experien +
age +
wardtype + # hospital size = CATEGORICAL FACTOR
hospsize 1|hospital/ward),
(data = data_nurse,
REML = FALSE)
<- lmerTest::lmer(stress ~ expconNG + # experimental condition = CONTINUOUS GRAND-MEAN CENTERED
nurse_lmer_1b_ml + gender + experien +
age +
wardtype + # hospital size = CATEGORICAL FACTOR
hospsize 1|hospital/ward),
(data = data_nurse,
REML = FALSE)
::knitreg(list(nurse_lmer_1_ml,
texreg
nurse_lmer_1a_ml,
nurse_lmer_1b_ml),custom.model.names = c("Factor",
"0 vs 1",
"Centered"),
caption = "MLM: Model 1 - Expereimental Condiditon Coding (2-levels)",
caption.above = TRUE,
single.row = TRUE)
| Factor | 0 vs 1 | Centered | |
|---|---|---|---|
| (Intercept) | 5.38 (0.18)*** | 5.38 (0.18)*** | 5.03 (0.17)*** |
| expconexperiment | -0.70 (0.12)*** | ||
| age | 0.02 (0.00)*** | 0.02 (0.00)*** | 0.02 (0.00)*** |
| gender | -0.45 (0.03)*** | -0.45 (0.03)*** | -0.45 (0.03)*** |
| experien | -0.06 (0.00)*** | -0.06 (0.00)*** | -0.06 (0.00)*** |
| wardtypespecial care | 0.05 (0.12) | 0.05 (0.12) | 0.05 (0.12) |
| hospsizemedium | 0.49 (0.19)** | 0.49 (0.19)** | 0.49 (0.19)** |
| hospsizelarge | 0.90 (0.26)*** | 0.90 (0.26)*** | 0.90 (0.26)*** |
| expconN | -0.70 (0.12)*** | ||
| expconNG | -0.70 (0.12)*** | ||
| AIC | 1626.32 | 1626.32 | 1626.32 |
| BIC | 1680.30 | 1680.30 | 1680.30 |
| Log Likelihood | -802.16 | -802.16 | -802.16 |
| Num. obs. | 1000 | 1000 | 1000 |
| Num. groups: ward:hospital | 100 | 100 | 100 |
| Num. groups: hospital | 25 | 25 | 25 |
| Var: ward:hospital (Intercept) | 0.33 | 0.33 | 0.33 |
| Var: hospital (Intercept) | 0.10 | 0.10 | 0.10 |
| Var: Residual | 0.22 | 0.22 | 0.22 |
| ***p < 0.001; **p < 0.01; *p < 0.05 |
(2) Hospital Size
Experimental conditon is a three-level factor.
When it is alternatively coded as a numeric, continuous variables taking the values of whole numbers, starting with zero (\(0, 1, 2, \dots\)), the model there will only be ONE parameter estimated instead of several (one less than the number of categories). This is becuase the levels are treated as being equally different from each other in terms of the outcome. This treats the effect of the categorical variable as if it is linear, which may or may not be appropriate. User beware!
When the numeric, continuous variable is further grand-mean centered by additionally subtraction the MEAN of the numberic version, the value of the intercept is the only estimate that changes.
<- lmerTest::lmer(stress ~ expconNG + # experimental condition = CONTINUOUS GRAND-MEAN CENTERED
nurse_lmer_1c_ml + gender + experien +
age +
wardtype + # hospital size = CONTINUOUS CODED 0/1
hospsizeN 1|hospital/ward),
(data = data_nurse,
REML = FALSE)
<- lmerTest::lmer(stress ~ expconNG + # experimental condition = CONTINUOUS GRAND-MEAN CENTERED
nurse_lmer_1d_ml + gender + experien +
age +
wardtype + # hospital size = CONTINUOUS GRAND-MEAN CENTERED
hospsizeNG 1|hospital/ward),
(data = data_nurse,
REML = FALSE)
::knitreg(list(nurse_lmer_1b_ml,
texreg
nurse_lmer_1c_ml,
nurse_lmer_1d_ml),custom.model.names = c("Factor",
"0 vs 1",
"Centered"),
caption = "MLM: Model 1 - Hospital Coding (3-levels)",
caption.above = TRUE,
single.row = TRUE)
| Factor | 0 vs 1 | Centered | |
|---|---|---|---|
| (Intercept) | 5.03 (0.17)*** | 5.04 (0.16)*** | 5.40 (0.12)*** |
| expconNG | -0.70 (0.12)*** | -0.70 (0.12)*** | -0.70 (0.12)*** |
| age | 0.02 (0.00)*** | 0.02 (0.00)*** | 0.02 (0.00)*** |
| gender | -0.45 (0.03)*** | -0.45 (0.03)*** | -0.45 (0.03)*** |
| experien | -0.06 (0.00)*** | -0.06 (0.00)*** | -0.06 (0.00)*** |
| wardtypespecial care | 0.05 (0.12) | 0.05 (0.12) | 0.05 (0.12) |
| hospsizemedium | 0.49 (0.19)** | ||
| hospsizelarge | 0.90 (0.26)*** | ||
| hospsizeN | 0.46 (0.12)*** | ||
| hospsizeNG | 0.46 (0.12)*** | ||
| AIC | 1626.32 | 1624.36 | 1624.36 |
| BIC | 1680.30 | 1673.44 | 1673.44 |
| Log Likelihood | -802.16 | -802.18 | -802.18 |
| Num. obs. | 1000 | 1000 | 1000 |
| Num. groups: ward:hospital | 100 | 100 | 100 |
| Num. groups: hospital | 25 | 25 | 25 |
| Var: ward:hospital (Intercept) | 0.33 | 0.33 | 0.33 |
| Var: hospital (Intercept) | 0.10 | 0.10 | 0.10 |
| Var: Residual | 0.22 | 0.22 | 0.22 |
| ***p < 0.001; **p < 0.01; *p < 0.05 |
6.6 MLM: Add Random Slope
Hox, Moerbeek, and Van de Schoot (2017), page 22:
“Although logically we can test if explanatory variables at the first level have random coefficients (slopes) at the second or third level, and if explanatory variables at teh second level have random coefficients (slopes) at the third level, these possibilities are not pursued. We DO test a model with a random coefficient (slope) for
expcon
at the third level, where there turns out to be significant slope variation.”
6.6.1 Fit the Model
<- lmerTest::lmer(stress ~ expconNG + # experimental condition = CONTINUOUS GRAND-MEAN CENTERED
nurse_lmer_1d_re + gender + experien + # level 1 covariates
age + # level 2 covariate
wardtype + # level 3 covariate, hospital size = CONTINUOUS GRAND-MEAN CENTERED
hospsizeNG 1|hospital/ward), # Random Intercepts for wards within hospitals
(data = data_nurse,
REML = TRUE) # fit via REML for nested Random Effects
<- lmerTest::lmer(stress ~ expconNG + # experimental condition = CONTINUOUS GRAND-MEAN CENTERED
nurse_lmer_2_re + gender + experien + # level 1 covariates
age + # level 2 covariate
wardtype + # level 3 covariate, hospital size = CONTINUOUS GRAND-MEAN CENTERED
hospsizeNG 1|hospital/ward) + # Random Intercepts for wards within hospitals
(0 + expconNG|hospital), # RANDOM SLOPES for exp cond within hospital (does not vary witin a ward!)
(data = data_nurse,
REML = TRUE) # fit via REML for nested Random Effects
::knitreg(list(nurse_lmer_1d_re,
texreg
nurse_lmer_2_re),custom.model.names = c("M1: RI",
"M2: RIAS"),
caption = "Nested Models: Random Slope via REML",
caption.above = TRUE,
single.row = TRUE)
| M1: RI | M2: RIAS | |
|---|---|---|
| (Intercept) | 5.40 (0.12)*** | 5.39 (0.11)*** |
| expconNG | -0.70 (0.12)*** | -0.70 (0.18)*** |
| age | 0.02 (0.00)*** | 0.02 (0.00)*** |
| gender | -0.45 (0.03)*** | -0.45 (0.03)*** |
| experien | -0.06 (0.00)*** | -0.06 (0.00)*** |
| wardtypespecial care | 0.05 (0.12) | 0.05 (0.07) |
| hospsizeNG | 0.46 (0.13)*** | 0.46 (0.13)*** |
| AIC | 1659.89 | 1633.18 |
| BIC | 1708.97 | 1687.17 |
| Log Likelihood | -819.94 | -805.59 |
| Num. obs. | 1000 | 1000 |
| Num. groups: ward:hospital | 100 | 100 |
| Num. groups: hospital | 25 | 25 |
| Var: ward:hospital (Intercept) | 0.34 | |
| Var: hospital (Intercept) | 0.11 | 0.17 |
| Var: Residual | 0.22 | 0.22 |
| Var: ward.hospital (Intercept) | 0.11 | |
| Var: hospital.1 expconNG | 0.69 | |
| ***p < 0.001; **p < 0.01; *p < 0.05 |
6.6.2 Assess Significance
anova(nurse_lmer_1d_re, nurse_lmer_2_re, refit = FALSE)
Data: data_nurse
Models:
nurse_lmer_1d_re: stress ~ expconNG + age + gender + experien + wardtype + hospsizeNG + (1 | hospital/ward)
nurse_lmer_2_re: stress ~ expconNG + age + gender + experien + wardtype + hospsizeNG + (1 | hospital/ward) + (0 + expconNG | hospital)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
nurse_lmer_1d_re 10 1659.9 1709.0 -819.94 1639.9
nurse_lmer_2_re 11 1633.2 1687.2 -805.59 1611.2 28.708 1 8.417e-08 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
The inclusion of a random slope effect for the experimental condition expcon
significantly improves the models’s fit, thus is should be retained.
6.7 MLM: Add Cross-Level Interaction
Hox, Moerbeek, and Van de Schoot (2017), page 22:
“The varying slope can be predicted by adding a cross-level interaction between the variables
expcon
andhospsize
. In view of this interaction, the variablesexpcon
andhospsize
have been centered on tehir overal means.”
6.7.1 Fit the Model
<- lmerTest::lmer(stress ~ expconNG + # experimental condition = CONTINUOUS GRAND-MEAN CENTERED
nurse_lmer_2_ml + gender + experien + # level 1 covariates
age + # level 2 covariate
wardtype + # level 3 covariate, hospital size = CONTINUOUS GRAND-MEAN CENTERED
hospsizeNG 1|hospital/ward) + # Random Intercepts for wards within hospitals
(0 + expconNG|hospital), # RANDOM SLOPES for exp cond within hospital (does not vary witin a ward!)
(data = data_nurse,
REML = FALSE) # fit via ML for nested FIXED Effects
<- lmerTest::lmer(stress ~ expconNG + # experimental condition = CONTINUOUS GRAND-MEAN CENTERED
nurse_lmer_3_ml + gender + experien + # level 1 covariates
age + # level 2 covariate
wardtype + # level 3 covariate, hospital size = CONTINUOUS GRAND-MEAN CENTERED
hospsizeNG *hospsizeNG + # CROSS-LEVEL interaction
expconNG1|hospital/ward) + # Random Intercepts for wards within hospitals
(0 + expconNG|hospital), # RANDOM SLOPES for exp cond within hospital (does not vary within a ward!)
(data = data_nurse,
REML = FALSE) # fit via ML for nested FIXED Effects
::knitreg(list(nurse_lmer_2_ml,
texreg
nurse_lmer_3_ml),custom.model.names = c("M2: RAIS",
"M3: Xlevel Int"),
caption = "Nested Models: Fixed Cross-Level Interaction via ML",
caption.above = TRUE,
single.row = TRUE)
| M2: RAIS | M3: Xlevel Int | |
|---|---|---|
| (Intercept) | 5.39 (0.11)*** | 5.39 (0.11)*** |
| expconNG | -0.70 (0.18)*** | -0.72 (0.11)*** |
| age | 0.02 (0.00)*** | 0.02 (0.00)*** |
| gender | -0.46 (0.03)*** | -0.46 (0.03)*** |
| experien | -0.06 (0.00)*** | -0.06 (0.00)*** |
| wardtypespecial care | 0.05 (0.07) | 0.05 (0.07) |
| hospsizeNG | 0.46 (0.12)*** | 0.46 (0.12)*** |
| expconNG:hospsizeNG | 1.00 (0.16)*** | |
| AIC | 1597.48 | 1576.07 |
| BIC | 1651.47 | 1634.96 |
| Log Likelihood | -787.74 | -776.03 |
| Num. obs. | 1000 | 1000 |
| Num. groups: ward:hospital | 100 | 100 |
| Num. groups: hospital | 25 | 25 |
| Var: ward.hospital (Intercept) | 0.11 | 0.11 |
| Var: hospital (Intercept) | 0.15 | 0.15 |
| Var: hospital.1 expconNG | 0.66 | 0.18 |
| Var: Residual | 0.22 | 0.22 |
| ***p < 0.001; **p < 0.01; *p < 0.05 |
6.7.2 Assess Significance
anova(nurse_lmer_2_ml, nurse_lmer_3_ml)
Data: data_nurse
Models:
nurse_lmer_2_ml: stress ~ expconNG + age + gender + experien + wardtype + hospsizeNG + (1 | hospital/ward) + (0 + expconNG | hospital)
nurse_lmer_3_ml: stress ~ expconNG + age + gender + experien + wardtype + hospsizeNG + expconNG * hospsizeNG + (1 | hospital/ward) + (0 + expconNG | hospital)
npar AIC BIC logLik deviance Chisq Df Pr(>Chisq)
nurse_lmer_2_ml 11 1597.5 1651.5 -787.74 1575.5
nurse_lmer_3_ml 12 1576.1 1635.0 -776.03 1552.1 23.413 1 1.307e-06 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
There is evidence that hospital size moderated the effect of the intervention. We will want to plot the estimated marginal means to interpret the meaning of this interaction.
6.8 Final Model
6.8.1 Fit the model
The final model should be fit via REML.
I’m going to revert back to the factor versions of hospital size and experimental condition, but grand-mean center age and experience
%>%
data_nurse ::select(age, experien) %>%
dplyr::summarise_all(mean) dplyr
# A tibble: 1 × 2
age experien
<dbl> <dbl>
1 43.0 17.1
<- lmerTest::lmer(stress ~ expcon + # experimental condition = CONTINUOUS GRAND-MEAN CENTERED
nurse_lmer_final I(age - 43.01) + gender + I(experien - 17.06) + # level 1 covariates
+ # level 2 covariate
wardtype + # level 3 covariate, hospital size = CONTINUOUS GRAND-MEAN CENTERED
hospsize *hospsize + # CROSS-LEVEL interaction
expcon1|hospital/ward) + # Random Intercepts for wards within hospitals
(0 + expconNG|hospital), # RANDOM SLOPES for exp condition within hospital (does not vary within a ward!)
(data = data_nurse,
REML = TRUE) # fit via REML for final model
6.8.2 Table of Estimated Parameters
anova(nurse_lmer_final)
Type III Analysis of Variance Table with Satterthwaite's method
Sum Sq Mean Sq NumDF DenDF F value Pr(>F)
expcon 3.532 3.532 1 22.04 16.2512 0.0005573 ***
I(age - 43.01) 22.400 22.400 1 909.68 103.0680 < 2.2e-16 ***
gender 36.949 36.949 1 914.46 170.0117 < 2.2e-16 ***
I(experien - 17.06) 41.656 41.656 1 918.66 191.6692 < 2.2e-16 ***
wardtype 0.115 0.115 1 49.10 0.5278 0.4709777
hospsize 2.622 1.311 2 22.00 6.0321 0.0081539 **
expcon:hospsize 7.608 3.804 2 22.01 17.5040 2.822e-05 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
::knitreg(list(nurse_lmer_final),
texregcustom.model.names = c("M3: Xlevel Int"),
caption = "Final Model: with REML",
caption.above = TRUE,
single.row = TRUE)
| M3: Xlevel Int | |
|---|---|
| (Intercept) | 5.70 (0.19)*** |
| expconexperiment | -1.55 (0.20)*** |
| age - 43.01 | 0.02 (0.00)*** |
| gender | -0.46 (0.03)*** |
| experien - 17.06 | -0.06 (0.00)*** |
| wardtypespecial care | 0.05 (0.07) |
| hospsizemedium | -0.07 (0.24) |
| hospsizelarge | -0.07 (0.33) |
| expconexperiment:hospsizemedium | 1.12 (0.26)*** |
| expconexperiment:hospsizelarge | 1.94 (0.35)*** |
| AIC | 1617.76 |
| BIC | 1686.47 |
| Log Likelihood | -794.88 |
| Num. obs. | 1000 |
| Num. groups: ward:hospital | 100 |
| Num. groups: hospital | 25 |
| Var: ward.hospital (Intercept) | 0.11 |
| Var: hospital (Intercept) | 0.18 |
| Var: hospital.1 expconNG | 0.21 |
| Var: Residual | 0.22 |
| ***p < 0.001; **p < 0.01; *p < 0.05 |
Interpretation: After accounting for the a nurses’ age, gender, and experience, as well as the ward type, the effect of the intervention is moderated by hospital size, b = 1.96, SE = 0.35, p < .001,
6.8.3 Visualization: Estimated Marginal Means Plot
Although there are many variables in this model, only two are involved in any interaction(s). For this reason, we will choose to display the estimated marginal means across only experimental condition and hospital size. For this illustration, all other continuous predictors are taken to be at their mean and categorical predictors at their reference category.
<IP_ADDRESS> Using interactions::interact_plot()
All Defaults:
::cat_plot(model = nurse_lmer_final,
interactionspred = hospsize, # main predictor/independent variable, for x-axis
modx = expcon, # moderating independent variable, for different lines
interval = TRUE)
Look: We can make NASTY dynamite plots! DO NOT EVER USE THESE!
From the help menu: “Many applied researchers advise against this type of plot because it does not represent the distribution of the observed data or the uncertainty of the predictions very well.”
::cat_plot(model = nurse_lmer_final,
interactionspred = hospsize, # main predictor/independent variable, for x-axis
modx = expcon, # moderating independent variable, for different lines
interval = TRUE,
geom = "bar")
6.8.4 Post Hoc Pairwise Tests
When an interactions is between two categorical predictors, compare pairs of mean predictions.
%>%
nurse_lmer_final ::emmeans(~ expcon | hospsize) %>%
emmeanspairs()
hospsize = small:
contrast estimate SE df t.ratio p.value
control - experiment 1.545 0.196 21.9 7.898 <.0001
hospsize = medium:
contrast estimate SE df t.ratio p.value
control - experiment 0.427 0.170 22.0 2.518 0.0196
hospsize = large:
contrast estimate SE df t.ratio p.value
control - experiment -0.392 0.294 22.2 -1.332 0.1964
Results are averaged over the levels of: gender, wardtype
Degrees-of-freedom method: kenward-roger
Interpretation: For hospitals that are small in size, the intervention does substantially decrease stress levels by 1.55 points, SE = 0.20, p <.001. For hospitals that are medium sizes, the intervention does decrease stress, but by a modest 0.43 points, SD = 0.17, p = .020. For large hospitals the intervention was not effective at reducing stress, p = .200.
6.8.5 Effect Sizes
From the help page for emmeans::eff_size
:
For models having a single random effect, such as those fitted using lm
; in that case, the stats::sigma()
and stats::df.residual()
functions may be useful for specifying sigma
and edf
.For models with **more than one random effect**,
sigma` may be based on some combination of the random-effect variances.
Specifying edf
can be rather un-intuitive but is also relatively un-critical; but the smaller the value, the wider the confidence intervals for effect size. The value of sqrt(2/edf)
can be interpreted as the relative accuracy of sigm
a; for example, with edf = 50
, \(\sqrt{\frac{2}{50}}\) = 0.2, meaning that sigma
is accurate to plus or minus 20 percent. Note in an example below, we tried two different edf
values as kind of a bracketing/sensitivity-analysis strategy. A value of Inf
is allowable, in which case you are assuming that sigma
is known exactly. Obviously, this narrows the confidence intervals for the effect sizes – unrealistically if in fact sigma
is unknown.
<IP_ADDRESS> Compute Standardized Mean Differences
FIRST: We need to compute the values to standardize by…“Sigma”.
Option 1) Pooled SD <– My favorite
- added all the model’s variance components
- took the standard deviation
<- VarCorr(nurse_lmer_final) %>%
totalSD data.frame() %>%
::summarise(tot_var = sum(vcov)) %>%
dplyr::pull(tot_var) %>%
dplyrsqrt()
totalSD
[1] 0.8465793
Option 2) SD of all stress levels for all participants
%>%
data_nurse ::summarise(sd(stress)) dplyr
# A tibble: 1 × 1
`sd(stress)`
<dbl>
1 0.980
Option 3) SD of stress levels for participants in the control group
%>%
data_nurse ::filter(expcon == "control") %>%
dplyr::summarise(sd(stress)) dplyr
# A tibble: 1 × 1
`sd(stress)`
<dbl>
1 0.724
SECOND: We need to compute the numeric scalar that specifies the equivalent degrees of freedom for the sigma
.
This is a way of specifying the uncertainty in sigma
, in that we regard our estimate of sigma^2
as being proportional to a chi-square random variable with edf
degrees of freedom. (edf
should not be confused with the df
argument that may be passed via … to specify the degrees of freedom to use in t statistics and confidence intervals.)
This value has an effect the SE and confidence intervals, which I suggest you do not report, so just throw any old number in there ;)
%>%
nurse_lmer_final ::emmeans(~ expcon | hospsize) %>%
emmeans::eff_size(sigma = totalSD, # which SD to divide by???
emmeansedf = 10) # df
hospsize = small:
contrast effect.size SE df lower.CL upper.CL
control - experiment 1.826 0.469 37.5 0.875 2.776
hospsize = medium:
contrast effect.size SE df lower.CL upper.CL
control - experiment 0.505 0.230 37.7 0.039 0.971
hospsize = large:
contrast effect.size SE df lower.CL upper.CL
control - experiment -0.463 0.363 37.6 -1.198 0.272
Results are averaged over the levels of: gender, wardtype
sigma used for effect sizes: 0.8466
Degrees-of-freedom method: inherited from kenward-roger when re-gridding
Confidence level used: 0.95
%>%
nurse_lmer_final ::emmeans(~ expcon | hospsize) %>%
emmeans::eff_size(sigma = totalSD,
emmeansedf = 100)
hospsize = small:
contrast effect.size SE df lower.CL upper.CL
control - experiment 1.826 0.265 37.5 1.2894 2.362
hospsize = medium:
contrast effect.size SE df lower.CL upper.CL
control - experiment 0.505 0.204 37.7 0.0925 0.917
hospsize = large:
contrast effect.size SE df lower.CL upper.CL
control - experiment -0.463 0.349 37.6 -1.1705 0.244
Results are averaged over the levels of: gender, wardtype
sigma used for effect sizes: 0.8466
Degrees-of-freedom method: inherited from kenward-roger when re-gridding
Confidence level used: 0.95
FULL INTERPRETATION: After accounting for the a nurses’ age, gender, and experience, as well as the ward type, the effect of the intervention is moderated by hospital size, F(2, 22) = 17.50, p < .001. For hospitals that are small in size, the intervention does substantially decrease stress levels by 1.55 points, SE = 0.20, p <.001, Cohen’s d = 1.83. For hospitals that are medium sizes, the intervention does decrease stress, but by a modest 0.43 points, SD = 0.17, p = .020, Cohen’s d = 0.51. For large hospitals the intervention was not effective at reducing stress, p = .200.
Adding more options:
::cat_plot(nurse_lmer_final,
interactionspred = "hospsize",
modx = "expcon",
interval = TRUE,
y.label = "Estimated Marginal Mean Norse's Stress Score",
x.label = "Hospital Size",
legend.main = "Condition:",
modx.labels = c("Control", "Intervention"),
colors = c("gray40", "black"),
point.shape = TRUE,
pred.point.size = 5,
dodge.width = .3,
errorbar.width = .25,
geom = "line") +
theme_bw() +
theme(legend.key.width = unit(2, "cm"),
legend.background = element_rect(color = "Black"),
legend.position = c(1, 0),
legend.justification = c(1.1, -0.1)) +
scale_y_continuous(breaks = seq(from = 0, to = 10, by = 1))
<IP_ADDRESS> Using sjPlot::plot_model()
All Defaults:
::plot_model(nurse_lmer_final,
sjPlottype = "pred",
terms = c("hospsize", "expcon"))
Adding more options:
::plot_model(nurse_lmer_final,
sjPlottype = "pred",
terms = c("hospsize",
"expcon")) +
labs(title = "Multilevel Modeling of Hospital Nurse Stress Intervention",
subtitle = "Error bars display 95% Confidene Intervals",
x = "Hospital Size",
y = "Estimated Marginal Mean\nNorse's Stress Score",
color = "Condition") +
theme_bw()
<IP_ADDRESS> Using effects::Effect()
and ggplot
Get Estimated Marginal Means - default ‘nice’ predictor values:
Focal predictors: All combinations of…
expcon
categorical, both levelscontrol
andexperiment
hospsize
categorical, all three levelssmall
,medium
,large
Always followed by:
fit
estimated marginal meanse
standard error for the marginal meanlower
lower end of the 95% confidence interval around the estimated marginal meanupper
upper end of the 95% confidence interval around the estimated marginal mean
::Effect(focal.predictors = c("expcon", "hospsize"),
effectsmod = nurse_lmer_final) %>%
data.frame()
expcon hospsize fit se lower upper
1 control small 5.394485 0.1814379 5.038438 5.750532
2 experiment small 3.849007 0.1808593 3.494096 4.203919
3 control medium 5.324360 0.1572391 5.015800 5.632920
4 experiment medium 4.897002 0.1567719 4.589358 5.204645
5 control large 5.326344 0.2726473 4.791311 5.861377
6 experiment large 5.718468 0.2717250 5.185245 6.251691
::Effect(focal.predictors = c("expcon", "hospsize"),
effectsmod = nurse_lmer_final) %>%
data.frame()
expcon hospsize fit se lower upper
1 control small 5.394485 0.1814379 5.038438 5.750532
2 experiment small 3.849007 0.1808593 3.494096 4.203919
3 control medium 5.324360 0.1572391 5.015800 5.632920
4 experiment medium 4.897002 0.1567719 4.589358 5.204645
5 control large 5.326344 0.2726473 4.791311 5.861377
6 experiment large 5.718468 0.2717250 5.185245 6.251691
::Effect(focal.predictors = c("expcon", "hospsize"),
effectsmod = nurse_lmer_final) %>%
data.frame() %>%
ggplot() +
aes(x = hospsize,
y = fit,
group = expcon,
shape = expcon,
color = expcon) +
geom_errorbar(aes(ymin = fit - se, # mean plus/minus one Std Error
ymax = fit + se),
width = .4,
position = position_dodge(width = .2)) +
geom_errorbar(aes(ymin = lower, # 95% CIs
ymax = upper),
width = .2,
position = position_dodge(width = .2)) +
geom_line(aes(linetype = expcon),
position = position_dodge(width = .2)) +
geom_point(size = 4,
position = position_dodge(width = .2)) +
theme_bw() +
labs(x = "Hospital Size",
y = "Estimated Marginal Mean, Stress",
shape = "Condition",
color = "Condition",
linetype = "Condition") +
theme(legend.key.width = unit(2, "cm"),
legend.background = element_rect(color = "black"),
legend.position = c(0, 0),
legend.justification = c(-0.1, -0.1))
This plot illustrates the estimated marginal means among male (gender’s reference category) nurses at the overall mean age (43.01 years), with the mean level experience (17.06 years), since thoes variables were not included as focal.predictors
in the effects::Effect()
function. Different values for those predictors would yield the exact sample plot, shifted as a whole either up or down.
6.9 Interpretation
There is evidence this intervention lowered stress among nurses working in small hospitals and to a smaller degree in medium sized hospitals. The intervention did not exhibit an effect in large hospitals.
6.9.1 Strength
This analysis was able to incorporated all three levels of clustering while additionally controlling for many co0-variates, both categorical (nurse gender and ward type) and continuous (nurse age and experience in years). Also heterogeneity was accounted for in terms of the intervention’s effect at various hospitals. This would NOT be possible via any ANOVA type analysis.
6.9.2 Weakness
The approach presented by Hox, Moerbeek, and Van de Schoot (2017) and shown above involved mean-centering categorical variables. This would only be appropriate for a factor with more than two levels if its effect on the outcome was linear. Also, as the mean-centered variables are treated as continuous variables, post hoc tests are increasingly difficult. That is why I did that in the final model.
6.10 Reproduction of Table 2.5
Hox, Moerbeek, and Van de Schoot (2017) presents a table on page 23 comparing various models. Note, that table includes models only fit via maximum likelihood, not REML. Also, the model \(M_3\): with cross-level interaction is slightly different for an unknown reason.
::knitreg(list(nurse_lmer_0_ml,
texreg
nurse_lmer_1d_ml,
nurse_lmer_2_ml,
nurse_lmer_3_ml),custom.model.names = c("M0", "M1", "M2", "M3"),
caption = "Hox Table 2.5: Models for stress in hospitals and wards",
caption.above = TRUE,
single.row = TRUE)
| M0 | M1 | M2 | M3 | |
|---|---|---|---|---|
| (Intercept) | 5.00 (0.11)*** | 5.40 (0.12)*** | 5.39 (0.11)*** | 5.39 (0.11)*** |
| expconNG | -0.70 (0.12)*** | -0.70 (0.18)*** | -0.72 (0.11)*** | |
| age | 0.02 (0.00)*** | 0.02 (0.00)*** | 0.02 (0.00)*** | |
| gender | -0.45 (0.03)*** | -0.46 (0.03)*** | -0.46 (0.03)*** | |
| experien | -0.06 (0.00)*** | -0.06 (0.00)*** | -0.06 (0.00)*** | |
| wardtypespecial care | 0.05 (0.12) | 0.05 (0.07) | 0.05 (0.07) | |
| hospsizeNG | 0.46 (0.12)*** | 0.46 (0.12)*** | 0.46 (0.12)*** | |
| expconNG:hospsizeNG | 1.00 (0.16)*** | |||
| AIC | 1950.36 | 1624.36 | 1597.48 | 1576.07 |
| BIC | 1969.99 | 1673.44 | 1651.47 | 1634.96 |
| Log Likelihood | -971.18 | -802.18 | -787.74 | -776.03 |
| Num. obs. | 1000 | 1000 | 1000 | 1000 |
| Num. groups: ward:hospital | 100 | 100 | 100 | 100 |
| Num. groups: hospital | 25 | 25 | 25 | 25 |
| Var: ward:hospital (Intercept) | 0.49 | 0.33 | ||
| Var: hospital (Intercept) | 0.16 | 0.10 | 0.15 | 0.15 |
| Var: Residual | 0.30 | 0.22 | 0.22 | 0.22 |
| Var: ward.hospital (Intercept) | 0.11 | 0.11 | ||
| Var: hospital.1 expconNG | 0.66 | 0.18 | ||
| ***p < 0.001; **p < 0.01; *p < 0.05 |
Deviance:
c(deviance(nurse_lmer_0_ml),
deviance(nurse_lmer_1d_ml),
deviance(nurse_lmer_2_ml),
deviance(nurse_lmer_3_ml)) %>%
round(1)
[1] 1942.4 1604.4 1575.5 1552.1


[1]
food was not spectacular but simply good with enough variance.
[2]
the water and certainly during the summer is a true asset.


Login with QR Code
Scan the QR code below, receive a push notification on your device. Approve and sign in!


Windows
Server
- 3GB RAM
- Windows Server 2019
- 256 GB SSD
- Intel Xeon
- Unlimited bandwidth
VPS-at ma t'mire n'sheher
Bill Gates, one of our first customers: Absolutely love it! One of the best VPS Hosting providers i have ever worked with. Lightning fast VPSes, Great communication and unbelievable costumer service is all you can expect from such a reliable company. So if you're looking for extremely reliable support and performance-focused resources, you can't go wrong in choosing Alboturbo as your web host or server provider."


Topological Sorting
Topological sorting is a method of linear ordering of the vertices of a directed graph, such that if there is a directed edge xy from vertex x to vertex y, then x comes before y in the ordering. This sorting technique is based on the strategy of Depth First Search (DFS).
Consider a task that is to be performed. In a directed acyclic graph (dag), the vertices of the directed graph represent the tasks, the edges represent the constraint to be performed on the task, and a topological ordering is the valid sequence of the task.
Topological sorting is only possible if the graph has no directed cycles, that is, it is a directed acyclic graph. The vertices are ordered in a horizontal line such that all the directed edges go from left to right. In this linear ordering of vertices or nodes, if any edge or set of edges direct to left, then it is not a valid solution or ordering.
It is also possible for a graph to have more than one valid linear ordering of vertices for a topological sort.
Algorithm:
// Topological sort algorithm in a graph using DFS concept
E Empty list that contains the sorted elements
I Set of all nodes which have no incoming edges
while S is non-empty
do
remove a node n from I
insert n into E
for each node m with an edge e from n to m
do
remove edge e from the graph
if m has no other incoming edges then
insert m into I
if graph has edges then
return error (graph has at least one cycle)
else
return E (a topologically sorted order)
Consider the diagram given below:
Start traversing the directed acyclic graph given above from node m which is the starting node of the graph. Being a starting or a source node, its discovery time is taken as 1.
After visiting the source node m, the next node traversed is q. Thus, its discovery time is after node m, which is 2.
The node that will be traversed next is t, and its discovery time is taken as 3.
After t, there is no path or an edge directed towards any other node. Hence, the search or traversing cannot proceed in the forward direction and backtracking will start from this point.
Thus, after visiting t, backtrack to m and proceed in this way, incrementing the discovery time of each node accordingly, as per the order of traversing.
During the process, Finishing Time of each node is also considered which is the total time taken when all the vertices adjacent to a particular vertex are completely traversed in the process.
Here, finishing time for vertex t is 4 because traversing is done from m to t via q and again back to m. Thus, this time is considered when roles of q and t are completed during the track.
Table showing the Discovery Time and Finishing Time of each node is given below:
|
Vertex |
Discovery time |
Finishing time |
|
m |
1 |
20 |
|
n |
21 |
26 |
|
o |
22 |
25 |
|
p |
27 |
28 |
|
q |
2 |
5 |
|
r |
6 |
19 |
|
s |
23 |
24 |
|
t |
3 |
4 |
|
u |
7 |
8 |
|
v |
10 |
17 |
|
w |
11 |
14 |
|
x |
15 |
16 |
|
y |
9 |
18 |
|
z |
12 |
13 |
Thus, the topological order obtained is according to the finishing time of the vertices of the graph as shown in the table. As the finishing time of p is maximum, it is in the first position of the order. The second maximum is n and hence, it is next in the order. Similarly, other points are placed in the traversing process according to the descending order of their finishing time.
The resulting order is,
The above order has p as the starting point and t as the ending point. According to the above table, p has a finishing time of 28 units (maximum of all the vertex points) and t has a finishing time of 4 units.
Thus, this ordering of vertices is produced by TOPOLOGICAL-SORT, when it runs on the dag of the above diagram (graph).
The algorithm COUNT_SIMPLE_PATHS (x, y) is as follows:
COUNT_SIMPLE_PATH(x, y)
1 if (x==y)
2 return 1
3 else if x.pathNIL
4 for each do
5 x.path=x.path+COUNT_SIMPLE_PATH(z, y)
6 end for
7 return x.path
8 end if
The algorithm works as follows:
• If the starting and the ending nodes are the same, return 1.
• Count the path, starting from the vertex x. At each point, the value of x is updated but the value of y is fixed.
• Now, sum the number of paths recursively, which leave from the starting node x’s neighbors, that is the nodes which are adjacent to x.
• Do not add the partially completed paths as there are no cycles.
• Return the number of paths which have been counted starting from the vertex x to y.
• The total number of executions are
• Thus, call the algorithm recursively.
A TOPOLOGICAL-SORT is a type of sorting algorithm which works on directed graphs. If the TOPLOGICAL-SORT is applied on a directed graph then it sorts the vertices of the graph in the linear order. That is, if the graph G contains an edge (u, v) then vertex u must come before vertex v in the linear order or sorted list.
• TOPOLOGICAL-SORT algorithm uses depth first search algorithm to find the finishing times of all vertices.
• Then adds a vertex to the sorted list, as soon as the vertex is finished.
• Finally it returns a linked list, in which there are edges from right to left only.
TOPOLOGICAL-SORT produces no linear ordering, if the graph contains a cycle:
• If the graph contains a cycle, then the TOPOLOGICAL-SORT cannot produces linear ordering, because the ordering contains inconsistent edges or bad edges.
• Here, bad edges are nothing but the back edges. A back edge is edge from a vertex to its ancestor.
• For example, consider a simple graph with three vertices a, b and c. and there are edges from a to b, b to c and c to a. Thus, the graph contains a cycle a->b->c->a.
• If DFS is applied on the graph, c finished first, then b and finally a.
• According to TOPOLOGICAL-SORT c is added first to the list, and then b is added next. Finally a is added last to the list. That is, the order is a-b-c.
• From the definition of linear order, if there is an edge (u,v) in the graph, then vertex u must appear before vertex v in the ordered list.
• There is an edge (c,a) in the graph, thus c must appear before a in the order. But, vertex a is appeared before c in the ordered list.
Therefore, TOPOLOGICAL-SORT does not produce linear order, if the graph contains a cycle.
TOPOLOGICAL-SORT does not minimize the bad edges:
• TOPOLOGICAL-SORT calls DFS first to find the finishing times of all vertices.
• According to Lemma 22.11, DFS yields back edges, if the graph G contains cycles. The number of back edges yielded equals to number of cycles in the graph.
• If TOPOLOGICAL-SORT is applied on the graph that contains cycles, then it produces a vertex ordering that contains back edges (bad edges).
• That is, the ordering contains edges from left to right. Here, the number of bad edges equals to number of back edges.
• Since the number of bad edges equals to number of cycles in the graph, TOPLOGICAL-SORT did not minimizes the bad edges.
Hence it is disproved that “if the graph contains cycles, TOPOLOGICAL-SORT produces vertex ordering that minimizes the number of bad edges”.
A Graph G has a cycle if and only if a back edge is encountered while DFS is running on that graph. An edge (u,v) is said to be a back edge, if v is an ancestor of u and v is visited before u. Hence, by running DFS algorithm on a graph, it can be determined that whether the graph is acyclic or not.
Now, consider the following algorithm that determines whether there is a cycle in an undirected graph or not.
Algorithm:
//Define the procedure DFS
DFS ()
//for loop is used to iterate every nodes
1. for every vertex
//Set the color of the vertex as WHITE
2.
3.
//Set a global timestamp
4. //set a global timestamp
//for loop is used to iterate every nodes
5. for each vertex
//Check the color of the vertex is WHITE or not
6. if
// If the color of the vertex is WHITE then
//call DFS-VISIT- FINDCYCLE(G,p)
7. DFS-VISIT-FINDCYCLE(G,p)
//Definition of sub-procedure DFS-VISIT-FINDCYCLE(G,p)
DFS-VISIT-FINDCYCLE (G,)
//Set the color of the vertex as GREY
1.
//for loop is used to iterate every nodes q adjacent to p
2. for each
//check wether the edge (p,q) is a back edge or not
3. if
// If the above condition is true, then the edge (p,q) is a back
// edge. Thus return “cycle found”.
4. return “cycle found”
//If (p,q) is not a back edge, then set p as a predecessor of q.()
5. if
6.
//Call recursively DFS-VISIT-FINDCYCLE(G,)
7. DFS-VISIT-FINDCYCLE(G,)
8.
The above algorithm uses DFS() to find cycle in a graph. Since the graph may be disconnected so one should run DFS() on every vertex which has not been visited yet.
Explanation:
• The DFS() mentioned above is used to initialize the color predecessor and then FINDCYCLE routine is called to check if cycle exist with that particular node.
• In FINDCYCLE first line is used to color the vertex on which this routine is working.
• Now if any of the adjacent vertex is of color white that means it is unexplored, so adding that vertex to tree will not form a cycle and hence program run FINDCYCLE routine on that vertex.
• If any vertex is of color grey that means there already exist an edge to reach that vertex and if program add that vertex to that DFS tree it will result in cycle. So if program gets a grey vertex then it simply returns “cycle found”.
• Now consider a case in which there are actually two components of a graph and in first component there is no cycle but it exists in second component.
• In that case, all vertices in that component will be colored as grey. After this, function return to DFS () in which for loop again start searching white node which exist in second component and do the normal routine again.
Running time complexity of above algorithm:
• Since the above algorithm is the DFS algorithm with little modification, the complexity should be . But here the actual complexity of the above algorithm is .
• An undirected and acyclic forest with nodes contains not more than edges, according to Properties of free trees. That is, .
• Therefore, the above algorithm visits at most edges.
Thus the time complexity of the algorithm is independent of and it is .


649 patients waiting for beds in Irish hospitals
by By Digital Desk staffThere are 649 patients waiting for beds in Irish hospitals today.
The INMO's Trolley Watch figures found 464 patients are waiting in the emergency department, while 185 are in wards elsewhere in the hospital.
The worst-hit hospitals today are:
- Cork University Hospital – 65
- University Hospital Limerick – 57
- Letterkenny University Hospital - 48
- Sligo University Hospital - 42
The number is down from yesterday's figure of 679 which was the highest figure of the year so far.
Speaking yesterday, Phil Ní Sheaghdha - INMO General Secretary - said the numbers were "simply obscene".
"Winter has not even started, and Irish hospitals are overwhelmed. Our members are faced with an inhumane working environment, while patients are put at ever-increasing risk."
The INMO had earlier found that last month was the worst-ever October for overcrowding and the second-worst month since records began.
There were 11,452 patients on trolleys in Irish hospitals over the course of the month.
READ MORE
Horrifying CCTV footage shows man in UK setting dog on pet cat


---
title: Project Guides
navbar: Guides
layout: default
---
{% for post in site.categories['project'] reversed %}
- {{ post.title }} {% if post.label %}{{ post.label }}{% endif %}
{% endfor %}
{% for post in site.categories['writeups'] reversed %}
- {{ post.title }} {% if post.label %}{{ post.label }}{% endif %}
{% endfor %}
{% include section.html level="h2" name="Video Walkthrough" %}
This video walkthrough will illustrate this entire process on a Mac OSX system.
Please note this video was recorded for a previous semester. The Github organization and teacher assistants have changed since then.


Comment
×
rxn00148: ATP + Pyruvate <=> ADP + Phosphoenolpyruvate + H+
Star YAL038W: pyruvate kinase CDC19


Computer Science
A career in technology
Created by Richard Reis /<EMAIL_ADDRESS>Personal Intro
Grew up in Motley, MN
Graduated school from Staples/Motley High School
Went to college @ St. John's University in Collegeville, MN
what was I doing when I was in 8th grade?
took advanced placement courses in High School.
give a perspective of gaming and computer systems at the time.
http://www.trailingedge.com/comphave.html?theKey=laser128ex&byCompany=0
I didn't really know what I would do with my life after graduating High School.
I took the ACT
Visit schools and research programs of interest
Work with your counsellor to help discern.
Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
Universal Pensions - 1999 - Brainerd, MN
Started out as a Programmer working on supporting a website: IRA Service Center
Learned how to work on visual basic scripting
Worked on Microsoft SQL Server 2000 database
Helped work through Y2K bug issues
Created Java code
Micronet - 2001 - Brainerd, MN
Small start-up software company - developing software for Chambers of Commerce
Worked on chambermaster: www.chambermaster.com
Built a component called Hot Deals: www.explorebrainerdlakes.com
Helped design and create the concept of member master
Converted data for Chambers of Commerce
I worked on a small team of two developers
We worked through a lot of ideas through meetings and brainstorming
The company did not have enough funding to continue and I was laid off just after 9/11
Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
BISYS - 2002 - Brainerd, MN
Started working on a standalone application installer
Converted the IRA Service Center web application that I worked on with Unversal Pensions
Titles changed from a Programmer/Analyst to Web Architect
Helped lead a major payroll processing software development project with consulting firms
My oldest son, Isaiah, was born on March 16, 2002
BISYS bought Universal Pensions - returning to my old company
As a Programmer/Analyst - perform assigned tasks and basic analysis from project to project
As a Web Architect - determine technology direction and architecture for all applications
- provide direction for software developers
Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
DRN - 2005 - Ellendale, ND
Internet Service Provider (ISP) - what does that mean?
Working at a small shop again - four person team
Built internal administrative applications: Tickets, IUM
Helped rewrite the DRN website in 2007
Worked with my co-worker and converted 3 racks of physical servers into 3 virtual servers
We moved to ND. My family and I lived in Jamestown for almost 5 months.
DNS - Anyone know what it stands for, what it does?
Email - how it works - Envelope - From, To, Body
Learned about the hardware side of things
- virtualization, describe the concept
- SAN - storage area network
- ISP servers - describe
Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
Ascensus - 2011 - Ellendale, ND
Supported applications within Oracle product
Working almost 100% remote from my home
Developed Java and .NET components
Responsible for Entity Relationship Diagram (ERD)
Lead full-time/contract developers and provide guidance/oversight on projects
Performance tuner
Started working remotely
Was part of the Ascensus leadership team
Learned Oracle Business Process Management (BPM)
Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
DRN - 2013 - Ellendale, ND
Mine Data
Provide technical direction
Upgrade Software Development Tools
Implemented Microsoft SQL Server Reporting Services
Branded drtel.net webmail: https://mail.drtel.net
Partner liaison
Providing technical oversight in many areas of the company.
Build applications and websites for organizations
Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
Education
I attended college @ St. John's University in Collegeville, MN which is a 4-year liberal arts school in central Minnesota well known for their NCAA Division 3 football program.
As a freshman in College i started into Physics - I liked math and science
Internship - Junior year of College


WITNESS LIST Natural Resources Committee February 19, 2003-3:00P groundwater issues On: Ellis, Gregory M. (Edwards Aquifer Authority) Everheart, Harvey (Mesa Underground Water Conservation District and Texas Alliance Groundwater Districts) Petersen, Ken (Texas Rural Water Assn.)


--- layout: post authors: ["Greg Wilson"] title: "Plans for 2015: Mentorship and Assessment" date: 2014-12-03 time: "09:25:00" tags: ["Administration"] ---
The previous posts in this set looked at instructor training and workshop organization. In this one, I'd like to look at mentorship and assessment, which are two of the biggest challenges we need need to address in the coming year, and are good examples of the kinds of tasks that Steering Committee members will be asked to take on.
Azalee Bostroem did a great job summarizing why we need to mentor our new instructors (and keep those who've been with us a while up to date with changes to our lessons and procedures). The question is, how? Or more precisely, where will the hours come from? I said in September that I would organize a weekly meeting for instructors from recent and upcoming workshops. Only one took place, and saying "we just need to try harder" won't make the necessary hours appear.
The same is true of assessment. Jory Schossau has done valuable service analyzing survey data and interviewing bootcamp participants, and Daniel Chen and others are working hard to revise the instructors' post-workshop questionnaire, but despite several attempts, we haven't found anyone willing to fund a systematic look at what we're actually doing and what impact it's having. Once again, we can either say "we need to try harder" or come up with an alternative plan.
That plan ties back to our new bylaws. Broadly speaking, the people who run a non-profit can be either active or passive, i.e., they can either do the work needed to actually run the operation, or check in once in a while to make sure it's being run properly. Most open source foundations' boards are activist, and ours will be too. People who are elected to the Steering Committee will be expected to volunteer 2-3 hours a week to take charge of specific things, and two of those things to be overseeing mentorship and running assessment. In particular, one Steering Committee member will be asked to organize a half-hour call each week in which recent and upcoming instructors can talk about what's working (or isn't) in our lessons, while another will keep the post-workshop assessment questionnaire up to date, analyze the data we collect from it, and poke instructors to make sure they actually fill it in.
Doing this isn't a small commitment, but we're no longer a small organization. A dozen people are already serving as maintainers for specific topics, and I hope that formalizing our governance will make it easier for others to play a larger role as well.


CSA is a C++ header-only library for Coupled Simulated Annealing, a class of optimization methods that doesn't depend on computing the gradient. The source code is based on the original implementation by the authors of the paper.
The only requirement for CSA is a compiler with OpenMP support.
Features
- Global optimization of arbitrary functions: CSA represents a class of global optimization algorithms that do not make use of the derivative.
- Highly parallel: The source code is implemented with OpenMP.
- Callback interface: The optimization method recieves the current cost and next step via a callback interface. Progress updates can also be given through a callback interface.
Quick example
In this example we will try to minimize the Schwefel function. We start by defining the function itself:
#include <cmath>
#define DIM 10
// Schwefel function
double f(void* instance, double* x)
{
double sum = 0.;
for (int i = 0; i < DIM; ++i)
sum += 500 * x[i] * std::sin(std::sqrt(std::fabs(500 * x[i])));
return 418.9829 * DIM - sum;
}
The next thing we need is the random step function:
#define PI 3.14159265358979323846264338327
// This function will take a random step from `x` to `y`. The value `tgen`,
// the "generation temperature", determines the variance of the distribution of
// the step. `tgen` will decrease according to fixed a schedule throughout the
// annealing process, which corresponds to a decrease in the variance of steps.
void step(void* instance, double* y, const double* x, float tgen)
{
int i;
double tmp;
for (i = 0; i < DIM; ++i) {
tmp = std::fmod(x[i] + tgen * std::tan(PI * (drand48() - 0.5)), 1.);
y[i] = tmp;
}
}
Optionally, we can define a progress function, which will print updates to the terminal every time a new minimum cost is found:
// This will receive progress updates from the CSA process and print updates
// to the terminal.
void progress(
void* instance, double cost, float tgen, float tacc, int opt_id, int iter)
{
printf(
"bestcost=%1.3e \t tgen=%1.3e \t tac=%1.3e \t thread=%d\n",
cost,
tgen,
tacc,
opt_id);
return ;
}
The minimization process is then ran like this:
#include <iostream>
#include <csa.hpp>
int main()
{
srand(0);
// Create initial solution.
double* x = new double[DIM];
for (int i = 0; i < DIM; ++i)
x[i] = drand48();
double cost = f(nullptr, x);
printf("Initial cost: %f\n", cost);
// Initialize CSA solver.
CSA::Solver<double, double> solver;
solver.m = 2; // number of threads = number of solvers = 2
// Start the annealing process.
solver.minimize(DIM, x, f, step, progress, nullptr);
cost = f(nullptr, x);
printf("Best cost: %f\nx =\n", cost);
for (int i = 0; i < DIM; ++i)
std::cout << 500 * x[i] << " ";
std::cout << std::endl;
// Clean up.
delete[] x;
return EXIT_SUCCESS;
}
The last few lines of output should look like this:
...
bestcost=1.338e-04 tgen=1.161e-05 tacc=7.006e-44 thread=1
bestcost=1.332e-04 tgen=9.740e-06 tacc=7.006e-44 thread=1
bestcost=1.314e-04 tgen=9.240e-06 tacc=7.006e-44 thread=1
bestcost=1.285e-04 tgen=5.911e-06 tacc=7.006e-44 thread=1
bestcost=1.283e-04 tgen=3.647e-06 tacc=7.006e-44 thread=1
bestcost=1.280e-04 tgen=3.523e-06 tacc=7.006e-44 thread=1
bestcost=1.279e-04 tgen=3.337e-06 tacc=7.006e-44 thread=1
bestcost=1.277e-04 tgen=2.924e-06 tacc=7.006e-44 thread=1
bestcost=1.276e-04 tgen=2.187e-06 tacc=7.006e-44 thread=1
bestcost=1.275e-04 tgen=2.129e-06 tacc=7.006e-44 thread=1
bestcost=1.275e-04 tgen=1.880e-06 tacc=7.006e-44 thread=1
bestcost=1.275e-04 tgen=1.507e-06 tacc=7.006e-44 thread=1
bestcost=1.275e-04 tgen=1.470e-06 tacc=7.006e-44 thread=1
Best cost: 0.000128
x =
420.969 420.969 420.968 420.969 420.968 420.969 420.968 420.969 420.969 420.969
This is pretty good, since the true minimum is 0 = f(420.9687, ..., 420.9687)
.
Check out exampe.cpp
for the full source code to this example.
Documentation
The full API documentation can be found here: epwalsh.github.io/CSA/api/.
License
The source code for CSA is under the MIT License.


{% extends "mod_base.html" %} {% block title %}Modify board{% endblock %} {% import "widget/dynamic_config.html" as dynamic_config_widget %} {% block content %}
Modify the roles of the moderators of the board.
Creator The creator of the board.
Full permission Can change the roles of other moderators.
Janitor Manage reports, remove posts, request bans.
Config Change the board configuration.
| Name | Roles | |
|---|---|---|
| {{ board_moderator.moderator.username }} |


Developing quality software means addressing the concepts, methods, techniques, procedures, and standards necessary to produce high-quality software products and processes.
We are specialists in guiding teams to achieve sustainable and quality software development.
Es posible y así es como te ayudamos a conseguirlo.
Continuous Inspection is a holistic, fully-realized process designed to make internal code quality an integral part of the software development life cycle.
Forget about the past. Fixing the leak means putting the focus on the “new” code, i.e. the code that was added or changed since the last release. Things then get much easier.
Continuous integration helps you to automate build, testing, packaging, code inspection and all the task needed to release a new version.
We can help you to develop the best strategy: no branches, feature branching, release branching, team branching, and everything that you need.
You must manage the source code, the generated packaged product and its dependencies, including your own libraries and third-party libraries.
Using our own testing framework (or using a third-party solution) we can help you to reduce time, increase test coverage and improve your testing strategy.
Because code quality must be certified against standards. Using quality models like SQALE, CISQ or ISO 25000 your software could be recognized with well-known quality certificate.
Software Development best practises, tools, continuous inspection, continuous integration, continuous deployment, unit testing, and much more. We love to transfer our knowledge.
Because code quality improvement is boring.
Fill in the form and ask us everything you need.


{% extends 'gridMng/wizard/gridWizard_base.html' %} {% load wizard_extras %} {% block stylesheet %} {{ block.super }} {% endblock stylesheet %} {% block javascript %} {% endblock javascript %} {% block step_info %}
In this step you can select an alternative, and rate it against the concerns.
Alternatives marked with red color are not completed. Make sure that you have rated every alternative against each concern.
Select a rating for each concern, for the alternative .
| Left Pole | Rating | Right Pole | {% for i in concerns_data_in_pairs|length|get_range %}
|---|---|---|
|
{{ concerns_data_in_pairs|get_left_concern_value:forloop.counter }}
|
{{ concerns_data_in_pairs|get_right_concern_value:forloop.counter }}
|
{{ error }}
{% endfor %}


Alan Mannus caught up in Irish anthem row as former St Johnstone keeper wins FAI Cup
The 37-year-old is in his second spell with Shamrock Rovers and angered Irish fans before the FAI Cup Final.
by Mark McDougall, https://www.dailyrecord.co.uk/authors/mark-mcdougall/Former St Johnstone goalkeeper Alan Mannus has been caught up in a row over the Irish national anthem.
Mannus was lining out for Shamrock Rovers in the FAI Cup Final against Dundalk and helped his side end their long wait to lift the trophy.
It was the first time in 32 years they won Ireland's biggest cup competition but it was something that happened prior to it that has caused a row.
As the Irish national anthem played, players turned to face the Irish tricolor flying from the stadium as is custom in the country.
Of the 22 players lined up, 21 turned to face the flag but Mannus refused to do so and stood facing forward as the anthem played.
The decision not to face the flag angered many supporters who felt he was disrespecting the anthem while others insisted he had a right to do as he pleased.
One fan tweeted to say: "Alan Mannus not respecting our anthem. Doesn't have to sing but respect costs nothing."
Another added: "Alan Mannus turning away from the flag. He really doesn't help himself."
But others compared his decision to that of James McClean who often receives abuse for not wearing a poppy while playing football in England for the likes of Sunderland, Wigan and Stoke.
One said: "The same people slaughtering Alan Mannus are the same people who do be up in arms when James McClean gets hate for standing up for his beliefs."
Mannus is in his second spell at Shamrock Rovers having spent seven years at St Johnstone in between.
He started his career at Linfield before his move to Dublin and has earned nine caps for Northern Ireland.
The 37-year-old was part of the St Johnstone team that won the Scottish Cup in 2014 after beating Dundee United in the final.


Gecode::Search::ReCoStack Class Reference
#include <search.hh>
Detailed Description
Stack of nodes supporting recomputation.Maintains the invariant that it contains the path of the node being currently explored. This is required to support recomputation, of course.
The stack supports adaptive recomputation controlled by the value of a_d: only if the recomputation distance is at least this large, an additional clone is created.
Definition at line 329 of file search.hh.
Public Member Functions | |
| ReCoStack (unsigned int a_d) | |
| Initialize with adaptive recomputation distance a_d. | |
| const BranchingDesc * | push (Space *s, Space *c) |
| Push space c (a clone of s or NULL). | |
| template<class DescType> | |
| const BranchingDesc * | nextDesc (EngineCtrl &s, int &alt, int &closedDescs) |
| Generate path for next node and return BranchingDesc for next node if its type is DescType, or NULL otherwise. | |
| template<class DescType, bool inclusive> | |
| void | closeBranch (EngineCtrl &s) |
| Generate path for next node with BranchingDesc type DescType. | |
| bool | next (EngineCtrl &s) |
| Generate path for next node and return whether a next node exists. | |
| int | lc (Space *&s) const |
| Return position on stack of last copy. | |
| void | unwind (int l) |
| Unwind the stack up to position l (after failure). | |
| void | commit (Space *s, int i) const |
| Commit space s as described by stack entry at position i. | |
| template<bool constrained> | |
| Space * | recompute (unsigned int &d, EngineCtrl &s) |
| Recompute space according to path with copying distance d. | |
| int | entries (void) const |
| Return number of entries on stack. | |
| size_t | stacksize (void) const |
| Return stack size used. | |
| void | reset (void) |
| Reset stack. |
Constructor & Destructor Documentation
| Gecode::Search::ReCoStack::ReCoStack | ( | unsigned int | a_d | ) | [inline] |
Member Function Documentation
| const BranchingDesc * Gecode::Search::ReCoStack::push | ( | Space * | s, | |
| Space * | c | |||
| ) | [inline] |
| const BranchingDesc * Gecode::Search::ReCoStack::nextDesc | ( | EngineCtrl & | s, | |
| int & | alt, | |||
| int & | closedDescs | |||
| ) | [inline] |
Generate path for next node and return BranchingDesc for next node if its type is DescType, or NULL otherwise.
Definition at line 101 of file reco-stack.icc.
| void Gecode::Search::ReCoStack::closeBranch | ( | EngineCtrl & | s | ) | [inline] |
Generate path for next node with BranchingDesc type DescType.
Definition at line 119 of file reco-stack.icc.
| bool Gecode::Search::ReCoStack::next | ( | EngineCtrl & | s | ) | [inline] |
Generate path for next node and return whether a next node exists.
Definition at line 134 of file reco-stack.icc.
| int Gecode::Search::ReCoStack::lc | ( | Space *& | s | ) | const [inline] |
| void Gecode::Search::ReCoStack::unwind | ( | int | l | ) | [inline] |
| void Gecode::Search::ReCoStack::commit | ( | Space * | s, | |
| int | i | |||
| ) | const [inline] |
Commit space s as described by stack entry at position i.
Definition at line 148 of file reco-stack.icc.
| Space * Gecode::Search::ReCoStack::recompute | ( | unsigned int & | d, | |
| EngineCtrl & | s | |||
| ) | [inline] |
Recompute space according to path with copying distance d.
The template parameter constrained describes whether the stack might contain spaces not propagated (from constraining during branch-and-bound).
Definition at line 189 of file reco-stack.icc.
| int Gecode::Search::ReCoStack::entries | ( | void | ) | const [inline] |
| size_t Gecode::Search::ReCoStack::stacksize | ( | void | ) | const [inline] |
| void Gecode::Search::ReCoStack::reset | ( | void | ) | [inline] |
The documentation for this class was generated from the following files:
- gecode/search.hh (Revision: 7310)
- gecode/search/reco-stack.icc (Revision: 7658)


Web Browser:
- Web Broser
- A web browser is a software application for accessing information on the World Wide Web.
-
- Internet Explorer
- Internet Explorer is a series of graphical web browsers developed by Microsoft and included in the Microsoft Windows line of operating systems.
-
- Google chrome
- Google Chrome is a cross-platform web browser developed by Google.
- It was first released in 2008 for Microsoft Windows, and was later ported to Linux, macOS, iOS, and Android where it is the default browser built into the OS.
-
- Mozila firefox
- A free, open source, cross-platform, graphical web browser developed by the Mozilla Corporation and hundreds of volunteers.
- Firefox uses the Gecko layout engine to render web pages, which implements current and anticipated web standards.
-
- Safari
- Safari is a graphical web browser developed by Apple, based on the WebKit engine.
-
- Opera
- Opera is a multi-platform web browser developed by Opera Software. Opera is a Chromium-based browser.


ok
Artist/Band Name:
Album Title:
Album Track Count:
Album Length in seconds:
Album Thumbnail:
songs
seconds


Installing VS 2008. Hopes are high for .Net framework source code and Javascript debugging.
1/17/2008, 12:51:23 PM
Favs: 0
Retweets: 0
link--- layout: tweet ---
Installing VS 2008. Hopes are high for .Net framework source code and Javascript debugging.
1/17/2008, 12:51:23 PM
Favs: 0
Retweets: 0
link


Your choice in Albuquerque for eco-friendly, professional, and insured automotive detailing; from maintenance washes to ceramic coating. Living in a desert we are constantly in a drought. While an automatic car wash can be the most convenient solution, we cannot afford to waste the 150 gallons of water they use to wash a single car. At Steam Dream Auto Detailing we use the power of steam to cut water consumption to only two gallons while providing a scratch free surface.
Premium steam wash clay decontamination and wax applied.
Premium steam and hand shine.
Premium Paint Correction