{% load i18n %}
{# XXX Horrible hack to force browser to ignore the outer form scope so that the top button actuall works. This is needed to allow CSRF protection instead of just using a GET #} {# {% blocktrans %}Hijack {{ username }}{% endblocktrans %} #}


| Heavy Plates |
Over 4,000 lbs. heavy plate, bars, chunks, heavy walled pipe. |
$500.00 |
| sch 40 pipe |
Over 400 ft of sch 40 pipe apprx. ¾ to 1”. |
$250.00 |
| extra tooling |
Ring roller on base/ stand 36”h extra tooling |
$250.00 |
| Lock box |
Lock box for pick up truck |
$50.00 |
| propane tanks |
100 lb. propane tanks |
$75.00 |
| h2o tank |
85 gallon steel h2o tank used |
$75.00 |
| shade structure frame |
10’x12’ galvanized steel, pole shade structure frame |
$100.00 |
| utility spools |
8’ dia. utility spools of 1½” sq, tubing |
$100.00 |
| saw horses |
foldable saw horses heavy pipe |
$100.00 |
| forge stands |
adjustable forge stands 36” h |
$100.00 |
| jack stands |
screw jack stands 16” h |
$100.00 |


Full Name
Email
Password
Confirm password
I accept the Terms of Use & Privacy Policy
Already have an account?Login


Home
Division B
Division C
Circuit Lab B
Home
Division B
Division C
Circuit Lab B
Topic:
DC Circuits
Topic
Score:


Distraught young girl taught blunt lesson by brother after she was dumped
A young boy's sage advice to his sister when she was left broken-hearted by a break-up has seen him win thousands of fans after the hilarious the video was posted on Twitter
by Luke Matthews, https://www.mirror.co.uk/authors/luke-matthews/Break-ups never seem to get any easier but the first can be the hardest to deal with.
The love of your life has gone and it feels like you'll never find another like it.
For many, the first heartbreak comes in primary school, when the reality of a 'break-up' means you stop saying hello to your playground boyfriend or girlfriend in the morning.
You may look back on it now and laugh, but at the time it can seem like your world has ended.
When one young girl struggled to cope with the end of a relationship, she turned to her family for comfort.
Unfortunately, any hopes of receiving sympathy from her brother was short-lived, with his blunt reaction winning him a legion of fans online.

As the dad lovingly rubs her back, he looks to his son for help and gently says 'Chris broke her heart today', which sees the crying girl also turn to face her brother, ready for his comforting words.
The camera then pans to the boy, who is standing in the middle room in what many have labelled an 'absolute power stance', as he remains deadpan with his arms by his sides to deliver the line: "Well, that's what happens in life."
The wise-beyond-his-years snippet of advice has seen the video rack up more than 630,000 likes, with one saying: "Sounds like this little man has lived a hard life."
Another said: "Big brother coming with straight facts like he's been there done that all his life."
A third wrote: "You can tell this little boy has been through a lot.
"All his puppy loves ended in heartbreak along with the three bankrupt lemonade stands."
He may not have told her what she wanted to hear, but he told her what she needed to know.


Men and women are likely (and understandably) to be disturbed by the acidly amusing and intoxicating "In the Company of Men," a new film about how pernicious and hateful men are towards women, and men. The film is a devilish surprise: a morbidly comical and terrifyingly real expose on what happens between men and women in today's society.
Newcomer Aaron Eckhart (resembling a young Harrison Ford) stars as Chad, a malignant office worker who continually shares his hateful views on other workers and women to his bumbling colleague, Howard (Matt Malloy).  One night at a restaurant, Chad proposes an idea to Howard: they will find an insecure, sweet woman whom they will woo and then dump with a major thud. The idea is that they must be complicit in their wounding an innocent woman, which leaves Howard unsure whether to proceed with such a plan. Chad finds the right victim - a fragile, deaf secretary named Christine (Stacy Edwards). Chad's only objective in this game is to inflict emotional injury by only pretending to love Christine. Howard, however, really starts to develop feelings for her, and feels that this game is immoral.
There are many ways in which "In the Company of Men" makes us see how complex this triad is. Chad is eminently lethal and hateful whereas Howard is more caring and has some shred of humanity. The film doesn't make Christine a complete saint, though, considering she dates both men simultaneously until Chad tells her he really loves her. Essentially, Christine dumps Howard for Chad. Then Howard becomes envious and feels he has to do something to prevent this false union. But does Howard suddenly care because she's deaf, or because he loves her? And is Chad really doing more damage to Howard than to Christine?
"In the Company of Men" is both darkly comic and scathingly serious in its treatment of a curious subject - it is written by first-time writer-director Neil LaBute, and at times, you won't know whether to laugh or cringe. A major reason for this imbalance is the depiction of its characters who are acutely performed by all three leads: Eckhart is brilliantly effective as the insulting and obnoxious Chad; Matt Malloy makes Howard as pathetic and cumbersome as you can imagine; and Stacy Edwards is a revelation as the flattered Christine unaware of her doomed relationship with Chad; she projects sympathy and heedfulness.
"In the Company of Men" is a film you're not likely to forget and shouldn't - it is profound, shrewdly written and masterfully directed. LaBute composes this world in bland, colorless ways such as the anonymous offices; the employees dressed in white shirts; the dreary cafes, restaurants and rental cars; and roofs that seem to offer no discernible view.
For more reviews, check out JERRY AT THE MOVIES at http://buffs.moviething.com/buffs/faust/
E-mail me with comments, suggestions or complaints at<EMAIL_ADDRESS>or<EMAIL_ADDRESS>The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Pepperoni Pizza
tomato sauce , thin dough style, pepperoni, cheese
6.5 JD
Margherita Pizza
tomato sauce , thin dough style, cheese
5.5 JD
Mixed Pizza
tomato sauce , thin dough style, cheese, vegetables, meat


Update 19/March/2005. Most of the improvements were made in the context of the Tentacle application.
Update 1/July/2004. Tentacle demonstration applications now available.
Updates 3/February/2002 with yellow background.
Much of the core requirements of Scintilla, including text and style buffers, line positions, undo, and lexing are working. There is one example lexer for C++ although it doesn't handle keywords yet. The style buffer may contain 0, 1, 2, or 4 bytes for each byte of text.
SinkWorld is a project to investigate changes to the core of Scintilla to make it more flexible, robust, perform better and run on the .NET and Java virtual machines.
This is an experimental project. It is not certain that the techniques discussed here will produce useful results. Possible outcomes include a completely new set of classes that replace Scintilla; interesting algorithms, classes and concepts that can be copied from SinkWorld into Scintilla; or complete failure.
The Portability section has seen the most work and so has the most visible outputs.
The results of the SinkWorld project may be made available under more than one license. Much of the lowest level code and utilities may be released to the public domain to encourage maximum use and to avoid spending time on license questions. Other resulting code, such as platform adaptation layers, may become closed-source products.
Site created by Neil Hodgson.
Graphics Copyright 2001 Stephen Neal - Virtually There


|
||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |
See:
Description
| Class Summary | |
|---|---|
| Pack200CompressorInputStream | An input stream that decompresses from the Pack200 format to be read as any other stream. |
| Pack200CompressorOutputStream | An output stream that compresses using the Pack200 format. |
| Pack200Utils | Utility methods for Pack200. |
| Enum Summary | |
|---|---|
| Pack200Strategy | The different modes the Pack200 streams can use to wrap input and output. |
Provides stream classes for compressing and decompressing streams using the Pack200 algorithm used to compress Java archives.
The streams of this package only work on JAR archives, i.e. a
Pack200CompressorOutputStream
expects to be wrapped around a
stream that a valid JAR archive will be written to and a Pack200CompressorInputStream
provides a stream to read from a
JAR archive.
JAR archives compressed with Pack200 will in general be different from the original archive when decompressed again. For details see the API documentation of Pack200.
The streams of this package work on non-deflated streams,
i.e. archives like those created with the --no-gzip
option of the JDK's pack200
command line tool. If
you want to work on deflated streams you must use an additional
stream layer - for example by using Apache Commons Compress'
gzip package.
The Pack200 API provided by the Java class library doesn't lend
itself to real stream
processing. Pack200CompressorInputStream
will
uncompress its input immediately and then provide
an InputStream
to a cached result.
Likewise Pack200CompressorOutputStream
will not
write anything to the given OutputStream
until finish
or close
is called - at
which point the cached output written so far gets
compressed.
Two different caching modes are available - "in memory", which is the default, and "temporary file". By default data is cached in memory but you should switch to the temporary file option if your archives are really big.
Given there always is an intermediate result
the getBytesRead
and getCount
methods
of Pack200CompressorInputStream
are meaningless
(read from the real stream or from the intermediate result?)
and always return 0.
During development of the initial version several attempts have
been made to use a real streaming API based for example
on Piped(In|Out)putStream
or explicit stream
pumping like Commons Exec's InputStreamPumper
but
they have all failed because they rely on the output end to be
consumed completely or else the (un)pack
will block
forever. Especially for Pack200InputStream
it is
very likely that it will be wrapped in
a ZipArchiveInputStream
which will never read the
archive completely as it is not interested in the ZIP central
directory data at the end of the JAR archive.
|
||||||||||
| PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES |


Google Code offered in: English - Español - 日本語 - 한국어 - Português - Pусский - 中文(简体) - 中文(繁體)
Often, you will need to integrate GWT with existing handwritten JavaScript or with a third-party JavaScript library. Occasionally you may need to access low-level browser functionality not exposed by the GWT class API's. The JavaScript Native Interface (JSNI) feature of GWT can solve both of these problems by allowing you to integrate JavaScript directly into your application's Java source code.
The GWT compiler translates Java source into JavaScript. Sometimes it's very useful to mix handwritten JavaScript into your Java source code. For example, the lowest-level functionality of certain core GWT classes are handwritten in JavaScript. GWT borrows from the Java Native Interface (JNI) concept to implement JavaScript Native Interface (JSNI). Writing JSNI methods is a powerful technique, but should be used sparingly because writing bulletproof JavaScript code is notoriously tricky. JSNI code is potentially less portable across browsers, more likely to leak memory, less amenable to Java tools, and harder for the compiler to optimize.
We think of JSNI as the web equivalent of inline assembly code. You can use it in many ways:
JSNI methods are declared native and contain JavaScript code in a specially formatted comment block between the end of the parameter list and the trailing semicolon. A JSNI comment block begins with the exact token /*-{ and ends with the exact token }-*/. JSNI methods are called just like any normal Java method. They can be static or instance methods.
The JSNI syntax is a directive to the Java-to-JavaScript Compiler to accept any text between the comment statements as valid JS code and inject it inline in the generated GWT files. At compile time, the GWT compiler performs some syntax checks on the JavaScript inside the method, then generates interface code for converting method arguments and return values properly.
As of the GWT 1.5 release, the Java varargs construct is supported. The GWT compiler will translate varargs calls between 2 pieces of Java code. However, calling a varargs JavaScript method from Java will result in the callee receiving the arguments in an array.
Here is a simple example of how to code a JSNI method that puts up a JavaScript alert dialog:
public static native void alert(String msg) /*-{ $wnd.alert(msg); }-*/;
Note that the code did not reference the JavaScript window object directly inside the method. When accessing the browser's window and document objects from JSNI, you must reference them as $wnd and $doc, respectively. Your compiled script runs in a nested frame, and $wnd and $doc are automatically initialized to correctly refer to the host page's window and document.
Here is another example with a problem:
public static native int badExample() /*-{ return "Not A Number"; }-*/; public void onClick () { try { int myValue = badExample(); GWT.log("Got value " + myValue, null); } catch (Exception e) { GWT.log("JSNI method badExample() threw an exception:", e); } }
This example compiles as Java, and its syntax is verified by the GWT compiler as valid JavaScript. But when you run the example code in development mode, it returns an exception. Click on the line in the log window to display the exception in the message area below:
com.google.gwt.dev.shell.HostedModeException: invokeNativeInteger(@com.example.client.GWTObjectNotifyTest::badExample()): JS value of type string, expected int at com.google.gwt.dev.shell.JsValueGlue.getIntRange(JsValueGlue.java:343) at com.google.gwt.dev.shell.JsValueGlue.get(JsValueGlue.java:179) at com.google.gwt.dev.shell.ModuleSpace.invokeNativeInt(ModuleSpace.java:233) at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeInt(JavaScriptHost.java:97) at com.example.client.GWTObjectNotifyTest.badExample(GWTObjectNotifyTest.java:29) at com.example.client.GWTObjectNotifyTest$1.onClick(GWTObjectNotifyTest.java:52) ...
In this case, neither the Java IDE nor the GWT compiler could tell that there was a type mismatch between the code inside the JSNI method and the Java declaration. The GWT generated interface code caught the problem at runtime in development mode. When running in production mode, you will not see an exception. JavaScript's dynamic typing obscures this kind of problem.
Tip: Since JSNI code is just regular JavaScript, you will not be able to use Java debugging tools inside your JSNI methods when running in development mode. However, you can set a breakpoint on the source line containing the opening brace of a JSNI method, allowing you to see invocation arguments. Also, the Java compiler and GWT compiler do not perform any syntax or semantic checks on JSNI code, so any errors in the JavaScript body of the method will not be seen until run time.
It can be very useful to manipulate Java objects from within the JavaScript implementation of a JSNI method. However, since JavaScript uses dynamic typing and Java uses static typing, you must use a special syntax.
When writing JSNI code, it is helpful to occasionally run in production mode. The JavaScript compiler checks your JSNI code and can flag errors at compile time that you would not catch until runtime in development mode.
Calling Java methods from JavaScript is somewhat similar to calling Java methods from C code in JNI. In particular, JSNI borrows the JNI mangled method signature approach to distinguish among overloaded methods. JavaScript calls into Java methods are of the following form:
[instance-expr.]@class-name::method-name(param-signature)(arguments)
Calling Java constructors from JavaScript is identical to the above use case, except that the method name is alway new.
Given the following Java classes:
package pkg; class TopLevel { public TopLevel() { ... } public TopLevel(int i) { ... } static class StaticInner { public StaticInner() { ... } } class InstanceInner { public InstanceInner(int i) { ... } } }
We compare the Java expression versus the JSNI expression:
Static and instance fields can be accessed from handwritten JavaScript. Field references are of the form
[instance-expr.]@class-name::field-name
Here's an example of accessing static and instance fields from JSNI.
public class JSNIExample { String myInstanceField; static int myStaticField; void instanceFoo(String s) { // use s } static void staticFoo(String s) { // use s } public native void bar(JSNIExample x, String s) /*-{ // Call instance method instanceFoo() on this this.@com.google.gwt.examples.JSNIExample::instanceFoo(Ljava/lang/String;)(s); // Call instance method instanceFoo() on x x.@com.google.gwt.examples.JSNIExample::instanceFoo(Ljava/lang/String;)(s); // Call static method staticFoo() @com.google.gwt.examples.JSNIExample::staticFoo(Ljava/lang/String;)(s); // Read instance field on this var val = this.@com.google.gwt.examples.JSNIExample::myInstanceField; // Write instance field on x x.@com.google.gwt.examples.JSNIExample::myInstanceField = val + " and stuff"; // Read static field (no qualifier) @com.google.gwt.examples.JSNIExample::myStaticField = val + " and stuff"; }-*/; }
Tip: As of the GWT 1.5 release, the Java varargs construct is supported. The GWT compiler will translate varargs calls between two pieces of Java code, however, calling a varargs Java method from JSNI will require the JavaScript caller to pass an array of the appropriate type.
Sometimes you need to access a method or constructor defined in GWT from outside JavaScript code. This code might be hand-written and included in another java script file, or it could be a part of a third party library. In this case, the GWT compiler will not get a chance to build an interface between your JavaScript code and the GWT generated JavaScript directly.
A way to make this kind of relationship work is to assign the method via JSNI to an external, globally visible JavaScript name that can be referenced by your hand-crafted JavaScript code.
package mypackage; public MyUtilityClass { public static int computeLoanInterest(int amt, float interestRate, int term) { ... } public static native void exportStaticMethod() /*-{ $wnd.computeLoanInterest = $entry(@mypackage.MyUtilityClass::computeLoanInterest(IFI)); }-*/; }
Notice that the reference to the exported method has been wrapped in a call to the $entry function. This implicitly-defined function ensures that the Java-derived method is executed with the uncaught exception handler installed and pumps a number of other utility services. The $entry function is reentrant-safe and should be used anywhere that GWT-derived JavaScript may be called into from a non-GWT context.
On application initialization, call MyUtilityClass.exportStaticMethod() (e.g. from your GWT Entry Point). This will assign the function to a variable in the window object called computeLoanInterest.
Parameters and return types in JSNI methods are declared as Java types. There are very specific rules for how values passing in and out of JavaScript code must be treated. These rules must be followed whether the values enter and leave through normal Java method call semantics or through the special syntax by which Java methods are invoked from JSNI code.
| Incoming Java type | How it appears to JavaScript code |
|---|---|
String |
JavaScript string, as in var s = "my string"; |
boolean |
JavaScript boolean value, as in var b = true; |
long |
disallowed (see notes) |
| other numeric primitives | JavaScript numeric value, as in var x = 42; |
| JavaScriptObject | JavaScriptObject that must have originated from JavaScript code, typically as the return value of some other JSNI method
(see notes) |
| Java array | opaque value that can only be passed back into Java code |
any other Java Object |
opaque value accessible through special syntax |
| Outgoing Java type | What must be passed |
|---|---|
String |
JavaScript string, as in return "boo"; |
boolean |
JavaScript boolean value, as in return false; |
long |
disallowed (see notes) |
| Java numeric primitive | JavaScript numeric value, as in return 19; |
| JavaScriptObject | native JavaScript object, as in return document.createElement("div") (see notes) |
any other Java Object (including arrays) |
Java Object of the correct type that must have originated in Java code; Java objects cannot be constructed from "thin
air" in JavaScript |
An exception can be thrown during the execution of either normal Java code or the JavaScript code within a JSNI method. When an exception generated within a JSNI method propagates up the call stack and is caught by a Java catch block, the thrown JavaScript exception is wrapped as a JavaScriptException object at the time it is caught. This wrapper object contains only the class name and description of the JavaScript exception that occurred. The recommended practice is to handle JavaScript exceptions in JavaScript code and Java exceptions in Java code.
A Java exception can safely retain identity while propagating through a JSNI method.
For example,
The exception thrown from fooImpl() will propagate through nativeFoo() and can be caught in doFoo(). The exception will retain its type and identity.


#include <arpa/inet.h> uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);
The htons() function converts the unsigned short integer hostshort from host byte order to network byte order.
The ntohl() function converts the unsigned integer netlong from network byte order to host byte order.
The ntohs() function converts the unsigned short integer netshort from network byte order to host byte order.
On the i386 the host byte order is Least Significant Byte first, whereas the network byte order, as used on the Internet, is Most Significant Byte first.
Some systems require the inclusion of <netinet/in.h> instead of <arpa/inet.h>.


%[if edit]%
This stack demonstrates the use use of "-addType" parameter to the %slice% template.
- The outer stack creates an <ul> tag and allows only a specific type to be added.
- Many inner stacks can be added by clicking the plus button.
- The inner stacks can be added, removed, rearranged and moved between similar stacks.
- The inner stacks can NOT be moved out of the outer stack, nor can any other stack be moved in.
- The inner stack has a "hidden" property, so does not appear in the stacks library.
- Each inner stack adds a <li> tag containing an image.
- The inner stack has an "inline" property so will be exported without a stacks-out and stacks-in wrapper.
- The %image% template is used to export a small and a large sized image.
- Javascript and jQuery are used to add behavior to the exported images.
%[endif]%
%[if !edit]%
%[endif]%
%slice -addTypes="com.yourhead.stacks.listItem,text" -allowedTypes="com.yourhead.stacks.listItem,text"%
%[if !edit]%
%[endif]%


p
Food Cart
Check Out
Thank You!
Thank You!
Your order #4321 has been placed.
It will be ready in 15 minutes!


| DOSE: |
18 mg |
oral |
2C-I |
(powder / crystals) |
User background- Very experienced user of psychedelics with over 30 years of experience with LSD, peyote, morning glory seeds, cubensis. Experienced user of Ecstasy...first time user of 2c-I
Purchased 2C-i through legal channels. Purity attested to be 98%
Dosage level measured using accurate mg. scale.
Having never tried 2CI before I started out with a moderate dose for my body weight.
Taken at 1:00 PM on a nice sunny afternoon.
First hour did not feel much at all but after about 65 minutes began having first alert.
Next hour felt very speedy and circular thinking ,needing to be doing something enjoyable. Attribute mindset to heightened sense of anxiety around work issues which I was dwelling on even before started trip. Decided to go outside and work in the garden...much better.
At three hours noticed thinking was lucid and felt a sense of calm and pleasure at the beauty around me though this was not too much different than I usually feel. Noticed a very little bit of the plants and grass breathing which I usually see when I am taking acid but very moderate psychedelic effects. In comparison to other psychedelics this dose level is more like Fisher Price- my first trip. Not much in the way of introspection that comes with LSD or peyote or morning glory seeds or mushrooms. Similar to taking about 1/4 hit of LSD.
Later partner comes home and I notice I am very empathetic to her in our interaction.
We go out for dinner. I am not hungry but she is, so I sit and spend time with her and watch the other people in the restaurant whom all seem quite individual. I get a more pronounced sense of the disconnect and connect that goes on between people in social situation and feel very strongly like taking the initiative in my own life to live my Life without being dictated to by social mores.
We go home and I watch 10 minutes of Jon Stewarts DAILY SHOW which I always find funny and it is especially funny tonight.
Then my partner asks me to help her with her leg and knee which is injured by doing energy work. I consent to doing energy work for her and find my ability to speak and see the energy fields with my hands is heightened. It is now 8:00 PM. I feel like I am 'down' but still feel quite energetic. I end up staying up until midnight and get up early the next morning (6:00 AM) to go to work my job which is quite physical. No ill effects on my body, not tired or 'hungover'. Able to work hard the next day. Feel quite cheerful.
Over all I would say 2C-I is fascinating to me because in the environment I work in there are random drug tests done so no illicit drugs for me or I would lose my job, I may be a bit late to the party but for now 2C-I is still legal. Doubt that will last.
At 18mg...not that interesting from a psychedelic point of view but recreational and not tiring.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


@helper.inputText(targetForm("formUrl"),
'_label -> "Seed URL(s) ",
'id -> "fieldUrls",
'class -> "form-control",
'placeholder -> "url1, url2",
'_description -> "(One or more URLs, separated by commas, including the http://)",
'_error -> targetForm("formUrl").error.map(_.withMessage("Enter URLs"))
)(FieldConstructor(genericMandatoryInput.f), lang)
@helper.inputText(targetForm("synonyms"),
'_label -> "Aliases/Synonyms ",
'class -> "form-control",
'_description -> "(If this content is also hosted at another URL, record it here. For example, if www.company.co.uk is the same as www.company.com)"
)(FieldConstructor(genericInput.f), lang)
@inputRadioGroup2(
field = targetForm("liveSiteStatus"),
options = options(siteStatuses),
args =
'_label -> "Live Site Status ",
'_description -> "(If known, please add the current status of the site)"
)(FieldConstructor(genericInput.f))
@helper.checkbox(targetForm("keySite"),
args =
'_label -> "Key Site ",
'_description -> "(Is this a 'key site', i.e. one of such significance that it requires higher levels of QA and archival management)"
)(FieldConstructor(genericInput.f), lang)
@if(user.hasArchivistRights) {
@select(
targetForm("authorUser.id"),
options(authors),
args =
'class -> "form-control",
'_label -> "Owner ",
'_description -> "(The user that is responsible for this target record and manages publisher relationship)",
'_showConstraints -> true)(FieldConstructor(genericMandatoryInput.f), lang)
} else {
@input(targetForm("authorUser.id"),
'_label -> "Owner (The user that nominated this web site):") { (id, name, value, args) =>
@targetForm("authorUser.name").value
}
}
@select(
targetForm("language"),
options(languages),
args =
'class -> "form-control",
'_label -> "Language ",
'_description -> "(The predominant language in which the page is written)",
'_default -> "-- None --",
'_showConstraints -> false
)(FieldConstructor(genericInput.f), lang)
@select(
targetForm("secondLanguage"),
options(languages),
args =
'class -> "form-control",
'_label -> "Second Language ",
'_description -> "(The second language in which the page is written)",
'_default -> "-- None --",
'_showConstraints -> false
)(FieldConstructor(genericInput.f), lang)
@textarea(field = targetForm("archivistNotes"),
args = 'rows -> 1, 'cols -> 100,
'_label -> "Archivist Notes ",
'_description -> "(This field should include any information provided by curators justifying the creation of the record. This field is NOT public.)",
'_id -> "input_archivist_notes",
'class -> "form-control"
)(FieldConstructor(genericInput.f), lang)
@select(
targetForm("selectionType"),
options(selectionTypes),
args =
'class -> "form-control",
'_label -> "Selection Type ",
'_description -> "(This records if the selection was a Nomination (e.g. via UKWA website or other means) or a Selection (via an ACT User))",
'_id -> "selectionType",
'_showConstraints -> false
)(FieldConstructor(genericMandatoryInput.f), lang)
@textarea(field = targetForm("selectorNotes"),
args = 'rows -> 1, 'cols -> 100,
'_label -> "Selector Notes ",
'_description -> "(Any further notes on the record for the use of the web archive team, not already captured under Justification)",
'id -> "input_selector_notes",
'class -> "form-control"
)(FieldConstructor(genericInput.f), lang)
@helper.inputText(targetForm("legacySiteId"),
'_label -> "Legacy site ID ",
'_description -> "(ID used to identify paper licences.)",
'class -> "form-control",
'id -> "legacy_site_id"
)(FieldConstructor(genericInput.f), lang)
@for((tag, index) <- tags.zipWithIndex) {
}
In order to be considered as in scope for Non-Print Legal Deposit, a resource must pass one of a series of tests.
@if(FormHelper.INSTANCE.indicateNpldStatus(id)) {
NB. There are other records within this domain for which data has already been provided.
@for(targetObj <- FormHelper.INSTANCE.getNpldStatusList(id)) {
@if(FormHelper.INSTANCE.isUkHosting(id)) {
yes
} else {
no
}
@if(FormHelper.INSTANCE.isTopLevelDomain(id)) {
yes
} else {
no
}
@if(FormHelper.INSTANCE.isUkRegistration(id)) {
yes
} else {
no
}
@helper.checkbox(targetForm("ukPostalAddress"),
'_label -> "UK Postal Address ",
'_description -> "(The 'about us' or other contact page contains a UK address for a significant part of the organisation (e.g. it is not just a PO box))"
)(FieldConstructor(genericInput.f), lang)
@helper.inputText(targetForm("ukPostalAddressUrl"),
'_label -> "Postal Address URL ",
'_description -> "(The URL on the site that contains the postal address used to determine that the site is in the UK)",
'class -> "form-control",
'id -> "legacy_site_id"
)(FieldConstructor(genericInput.f), lang)
@helper.checkbox(targetForm("viaCorrespondence"),
'_label -> "Via Correspondence ",
'_description -> "(Previous correspondence with the web site owner by a Curator contains evidence of a UK address)"
)(FieldConstructor(genericInput.f), lang)
@textarea(field = targetForm("value"),
args = 'rows -> 1, 'cols -> 100,
'_label -> "Via Correspondence: Notes ",
'_description -> "(Please record details of correspondence with site owner)",
'class -> "form-control"
)(FieldConstructor(genericInput.f), lang)
@helper.checkbox(targetForm("professionalJudgement"),
'_label -> "Professional Judgement ",
'_description -> "(In your professional judgement, does this site qualify as a UK Publication under the terms of the Legal Deposit Legislation. Please provide details of evidence used in the box below)"
)(FieldConstructor(genericInput.f), lang)
@helper.checkbox(targetForm("noLdCriteriaMet"),
'_label -> "No LD Criteria Met ",
'_description -> "(Use this to indicate that no LD criteria apply, and so this site cannot be archived under Legal Deposit)"
)(FieldConstructor(genericInput.f), lang)
@select(
targetForm("scope"),
options(scopeTypes),
args =
'class -> "form-control",
'_label -> "Scope ",
'_description -> "(Determines the scope of the crawl around this URL. To capture a whole site, specify the homepage and select 'All URLs that start like this'. To include all subdomains (e.g. example.co.uk but also anything like www.example.co.uk, images.example.co.uk, etc.) then select the 'any subdomains' option)",
'_showConstraints -> false
)(FieldConstructor(genericMandatoryInput.f), lang)
@select(
targetForm("depth"),
options(depthTypes),
args =
'class -> "form-control",
'_label -> "Depth ",
'_description -> "(Determines the depth of the crawl. Most crawls will be capped at 500MB)",
'_showConstraints -> false
)(FieldConstructor(genericMandatoryInput.f), lang)
@helper.checkbox(field = targetForm("ignoreRobotsTxt"),
'_label -> "Ignore Robots.txt ",
'_description -> "(Should we ignore Robots.txt while crawling this site? Note that although this may lead to us exploring more crawler traps, this does not present much of a problem to our crawling systems)",
'_showConstraints -> false
)(FieldConstructor(genericMandatoryInput.f), lang)
} else {
}
@if(user.hasRole("sys_admin")) {
@helper.checkbox(field = targetForm("ignoreCookies"),
'_label -> "Ignore Cookies",
'_description -> "Should we ignore Cookies while crawling this web host? (This applies to all Targets on this host, and should be set only on the host-level Target record.)",
'_showConstraints -> false
)(FieldConstructor(genericMandatoryInput.f), lang)
@select(
targetForm("crawlRate"),
options = Seq(
"default" -> "No faster than 2 URI/s, backing-off based on site response time (default).",
"extraPolite" -> "No faster than 10 URI/s (extra polite).",
"fast-2ps" -> "2 URI/s (fast, no back-off).",
"fast-10ps" -> "10 URI/s (really fast, no back-off)."
),
'class -> "form-control",
'_label -> "Crawl Rate",
'_description -> "How fast should the crawler run for all Targets this host? Faster settings should only be used with site owners permission, on the host-level Target record.",
'_showConstraints -> false
)(FieldConstructor(genericMandatoryInput.f), lang)
@select(
targetForm("parallelQueues"),
options = Seq(
"default" -> "One queue for this host (default).",
"parallel-queues-2" -> "Two parallel queues",
"parallel-queues-4" -> "Four parallel queues.",
"parallel-queues-8" -> "Eight parallel queues."
),
'class -> "form-control",
'_label -> "Parallel Queues",
'_description -> "How many simultaneous downloads can the crawler do for this host? (This multiplies the crawl rate! And applies to all Targets on this web host! Use sparingly!)",
'_showConstraints -> false
)(FieldConstructor(genericMandatoryInput.f), lang)
@select(
targetForm("crawlFrequency"),
options(crawlFrequencies),
args =
'class -> "form-control",
'_label -> "Crawl Frequency ",
'_description -> "(How often should this site be archived?)",
'_showConstraints -> false
)(FieldConstructor(genericMandatoryInput.f), lang)
NB. There is already a licence request either pending, or granted, or refused, for a target at a higher level in this domain. There is no need to request another one.
@for(target <- FormHelper.INSTANCE.getUkwaLicenceStatusList(id)) {
@if(user.hasRole("sys_admin") || user.hasRole("archivist")) {
@select(
targetForm("licenseStatus"),
options(licenseStatuses),
args =
'class -> "form-control",
'_label -> "Open UKWA licence requests ",
'_description -> "(This shows the current status of any requests to site owners for Open UKWA licences. If this has not yet been initiated, you can begin the process using the 'Open Licence Request' button)",
'_showConstraints -> false
)(FieldConstructor(genericInput.f), lang)
} else {
@if(targetForm("licenseStatus") != null && targetForm("licenseStatus").value != null) {
@targetForm("licenseStatus").value
} else {
None
}
}
Before you can request an Open UKWA licence, you need to save the target record.
Also, note that you cannot open a new licence request if a request is already queued.
@helper.inputText(targetForm("watchedTarget.documentUrlScheme"),
'_label -> "Document URL Scheme",
'id -> "watchedTarget.documentUrlScheme",
'class -> "form-control",
'spellcheck -> "true",
'contenteditable -> "true",
'_error -> targetForm("name").error.map(_.withMessage("Enter Title")),
'_description -> "(it should not be necessary to set a document URL scheme, but this can be used to limit the scope of the document detection process. It cannot be used to grow the scope of the crawl)"
)(FieldConstructor(genericMandatoryInput.f), lang)
@if(Target.findById(id).watchedTarget != null) {
@textarea(field = targetForm("watchedTarget.archivistNotesWT"),
'_label -> Html("Archivist Notes "),
'_description -> "(this field should include any information provided by curators justifying the creation of the record. This field is NOT public.)",
'_id -> "archivistNotesWT",
'class -> "form-control"
)(FieldConstructor(genericInput.f), lang)


Logs entries by sending network messages using the NetMessageBufferSend native function.
For a list of all members of this type, see NetSendAppender Members.
System.Object
log4net.Appender.AppenderSkeleton
log4net.Appender.NetSendAppender
This type is not safe for multithreaded operations.
You can send messages only to names that are active on the network. If you send the message to a user name, that user must be logged on and running the Messenger service to receive the message.
The receiver will get a top most window displaying the messages one at a time, therefore this appender should not be used to deliver a high volume of messages.
The following table lists some possible uses for this appender :
| Action | Property Value(s) |
|---|---|
| Send a message to a user account on the local machine |
Server = <name of the local machine> Recipient = <user name> |
| Send a message to a user account on a remote machine |
Server = <name of the remote machine> Recipient = <user name> |
| Send a message to a domain user account |
Server = <name of a domain controller | uninitialized> Recipient = <user name> |
| Send a message to all the names in a workgroup or domain |
Recipient = <workgroup name | domain name>* |
| Send a message from the local machine to a remote machine |
Server = <name of the local machine | uninitialized> Recipient = <name of the remote machine> |
Note : security restrictions apply for sending network messages, see NetMessageBufferSend for more information.
An example configuration section to log information using this appender from the local machine, named LOCAL_PC, to machine OPERATOR_PC :
[XML]
<appender name="NetSendAppender_Operator" type="log4net.Appender.NetSendAppender">
<server value="LOCAL_PC" />
<recipient value="OPERATOR_PC" />
<layout type="log4net.Layout.PatternLayout" value="%-5p %c [%x] - %m%n" />
</appender>
Namespace: log4net.Appender
Assembly: log4net (in log4net.dll)
NetSendAppender Members | log4net.Appender Namespace


12 Tree-based models
12.1 Decision Trees
12.1.1 Model form
Decision trees can be used for either classification or regression problems. The model structure is a series of yes/no questions. Depending on how each observation answers these questions, a prediction is made.
The below example shows how a single tree can predict health claims.
- For non-smokers, the predicted annual claims are 8,434. This represents 80% of the observations
- For smokers with a
bmi
of less than 30, the predicted annual claims are 21,000. 10% of patients fall into this bucket. - For smokers with a
bmi
of more than 30, the prediction is 42,000. This bucket accounts for 11% of patients.
We can cut the data set up into these groups and look at the claim costs. From this grouping, we can see that smoker
is the most important variable as the difference in average claims is about 20,000.
| smoker | bmi_30 | mean_claims | percent |
|---|---|---|---|
| no | bmi < 30 | $7,977.03 | 0.38 |
| no | bmi >= 30 | $8,842.69 | 0.42 |
| yes | bmi < 30 | $21,363.22 | 0.10 |
| yes | bmi >= 30 | $41,557.99 | 0.11 |
This was a very simple example because there were only two variables. If we have more variables, the tree will get large very quickly. This will result in overfitting; there will be good performance on the training data but poor performance on the test data.
The step-by-step process of building a tree is
Step 1: Choose a variable at random.
This could be any variable in age
, children
, charges
, sex
, smoker
, age_bucket
, bmi
, or region
.
Step 2: Find the split point which best seperates observations out based on the value of \(y\). A good split is one where the \(y\)’s are very different. *
In this case, smoker
was chosen. Then we can only split this in one way: smoker = 1
or smoker = 0
.
Then for each of these groups, smokers and non-smokers, choose another variable at random. In this case, for no-smokers, age
was chosen. To find the best cut point of age
, look at all possible age cut points from 18, 19, 20, 21, …, 64 and choose the one which best separates the data.
There are three ways of deciding where to split
- Entropy (aka, information gain)
- Gini
- Classification error
Of these, only the first two are commonly used. The exam is not going to ask you to calculate either of these. Just know that neither method will work better on all data sets, and so the best practice is to test both and compare the performance.
Step 3: Continue doing this until a stopping criteria is reached. For example, the minimum number of observations is 5 or less.
As you can see, this results in a very deep tree.
tree <- rpart(formula = charges ~ ., data = health_insurance,
control = rpart.control(cp = 0.003))
rpart.plot(tree, type = 3)
Step 4: Apply cost comlexity pruning to simplify the tree
Intuitively, we know that the above model would perform poorly due to overfitting. We want to make it simpler by removing nodes. This is very similar to how in linear models we reduce complexity by reducing the number of coefficients.
A measure of the depth of the tree is the complexity. A simple way of measuring this from the number of terminal nodes, called \(|T|\). This is similar to the “degrees of freedom” in a linear model. In the above example, \(|T| = 8\). The amount of penalization is controlled by \(\alpha\). This is very similar to \(\lambda\) in the Lasso.
Intuitively, merely only looking at the number of nodes by itself is too simple because not all data sets will have the same characteristics such as \(n\), \(p\), the number of categorical variables, correlations between variables, and so fourth. In addition, if we just looked at the error (squared error in this case) we would overfit very easily. To address this issue, we use a cost function which takes into account the error as well as \(|T|\).
To calculate the cost of a tree, number the terminal nodes from \(1\) to \(|T|\), and let the set of observations that fall into the \(mth\) bucket be \(R_m\). Then add up the squared error over all terminal nodes to the penalty term.
\[ \text{Cost}_\alpha(T) = \sum_{m=1}^{|T|} \sum_{R_m}(y_i - \hat{y}_{Rm})^2 + \alpha |T| \]
Step 5: Use cross-validation to select the best alpha
The cost is controlled by the CP
parameter. In the above example, did you notice the line rpart.control(cp = 0.003)
? This is telling rpart
to continue growing the tree until the CP reaches 0.003. At each subtree, we can measure the cost CP
as well as the cross-validation error xerror
.
This is stored in the cptable
tree <- rpart(formula = charges ~ ., data = health_insurance,
control = rpart.control(cp = 0.0001))
cost <- tree$cptable %>%
as_tibble() %>%
select(nsplit, CP, xerror)
cost %>% head()
## # A tibble: 6 x 3
## nsplit CP xerror
## <dbl> <dbl> <dbl>
## 1 0 0.620 1.00
## 2 1 0.144 0.382
## 3 2 0.0637 0.240
## 4 3 0.00967 0.179
## 5 4 0.00784 0.169
## 6 5 0.00712 0.167
As more splits are added, the cost continues to decrease, reaches a minimum, and then begins to increase.
To optimize performance, choose the number of splits which has the lowest error. Often, though, the goal of using a decision tree is to create a simple model. In this case, we can err or the side of a lower nsplit
so that the tree is shorter and more interpretable. All of the questions on so far have only used decision trees for interpretability, and a different model method has been used when predictive power is needed.
Once we have selected \(\alpha\), the tree is pruned. Sometimes the CP with the lowest error has a large number of splits, such as the case is here.
## # A tibble: 6 x 3
## nsplit CP xerror
## <dbl> <dbl> <dbl>
## 1 14 0.00119 0.151
## 2 15 0.00116 0.151
## 3 7 0.00196 0.151
## 4 13 0.00134 0.152
## 5 22 0.000759 0.153
## 6 12 0.00137 0.153
The SOA will give you code to find the lowest CP value such as below. This may or may not be useful depending on if they are asking for predictive performance or interpretability.
To make a simple tree, there are a few options
- Set the maximum depth of a tree with
maxdepth
- Manually set
cp
to be higher - Use fewer input variables and avoid categories with many levels
- Force a high number of minimum observations per terminal node with
minbucket
For instance, using these suggestions allows for a simpler tree to be fit.
library(caret)
set.seed(42)
index <- createDataPartition(y = health_insurance$charges,
p = 0.8, list = F)
train <- health_insurance %>% slice(index)
test <- health_insurance %>% slice(-index)
simple_tree <- rpart(formula = charges ~ .,
data = train,
control = rpart.control(cp = 0.0001,
minbucket = 200,
maxdepth = 10))
rpart.plot(simple_tree, type = 3)
We evaluate the performance on the test set. Because the target variable charges
is highly skewed, we use the Root Mean Squared Log Error (RMSLE). We see that the complex tree has the best (lowest) error, but also has 8 terminal nodes. The simple tree with only three terminal nodes has worse (higher) error, but this is still an improvement over the mean prediction.
tree_pred <- predict(tree, test)
simple_tree_pred <- predict(simple_tree, test)
get_rmsle <- function(y, y_hat){
sqrt(mean((log(y) - log(y_hat))^2))
}
get_rmsle(test$charges, tree_pred)
## [1] 0.3920546
## [1] 0.5678457
## [1] 0.9996513
12.1.2 Advantages and disadvantages
Advantages
- Easy to interpret
- Captures interaction effects
- Captures non-linearities
- Handles continuous and categorical data
- Handles missing values
Disadvantages
- Is a “weak learner” because of low predictive power
- Does not work on small data sets
- Is often a simplification of the underlying process because all observations at terminal nodes have equal predicted values
- Is biased towards selecting high-cardinality features because more possible split points for these features tend to lead to overfitting
- High variance (which can be alleviated with stricter parameters) leads the “easy to interpret results” to change upon retraining Unable to predict beyond the range of the training data for regression (because each predicted value is an average of training samples)
| Readings | |
|---|---|
| ISLR 8.1.1 Basics of Decision Trees | |
| ISLR 8.1.2 Classification Trees | |
| rpart Documentation (Optional) |
12.2 Ensemble learning
The “wisdom of crowds” says that often many are smater than the few. In the context of modeling, the models which we have looked at so far have been single guesses; however, often the underlying process is more complex than any single model can explain. If we build separate models and then combine them, known as ensembling, performance can be improved. Instead of trying to create a single perfect model, many simple models, known as weak learners are combined into a meta-model.
The two main ways that models are combined are through bagging and boosting.
12.2.1 Bagging
To start, we create many “copies” of the training data by sampling with replacement. Then we fit a simple model, typically a decision tree or linear model, to each of the data sets. Because each model is looking at different areas of the data, the predictions are different. The final model is a weighted average of each of the individual models.
12.2.2 Boosting
Boosting always uses the original training data and iteratively fits models to the error of the prior models. These weak learners are ineffective by themselves but powerful when added together. Unlike with bagging, the computer must train these weak learners sequentially instead of in parallel.
12.3 Random Forests
12.3.1 Model form
A random forest is the most common example of bagging. As the name implies, a forest is made up of trees. Seperate trees are fit to sampled datasets. For random forests, there is one minor modification: in order to make each model even more different, each tree selects a random subset of variables.
- Assume that the underlying process, \(Y\), has some signal within the data \(\mathbf{X}\).
- Introduce randomness (variance) to capture the signal.
- Remove the variance by taking an average.
When using only a single tree, there can only be as many predictions as there are terminal nodes. In a random forest, predictions can be more granular due to the contribution of each of the trees.
The below graph illustrates this. A single tree (left) has stair-like, step-wise predictions whereas a random forest is free to predict any value. The color represents the predicted value (yellow = highest, black = lowest).
Unlike decision trees, random forest trees do not need to be pruned. This is because overfitting is less of a problem: if one tree overfits, there are other trees which overfit in other areas to compensate.
In most applications, only the mtry
parameter, which controls how many variables to consider at each split, needs to be tuned. Tuning the ntrees
parameter is not required; however, the soa may still ask you to.
12.3.2 Example
Using the basic randomForest
package we fit a model with 500 trees.
This expects only numeric values. We create dummy (indicator) columns.
rf_data <- health_insurance %>%
mutate(sex = ifelse(sex == "male", 1, 0),
smoker = ifelse(smoker == "yes", 1, 0),
region_ne = ifelse(region == "northeast", 1,0),
region_nw = ifelse(region == "northwest", 1,0),
region_se = ifelse(region == "southeast", 1,0),
region_sw = ifelse(region == "southwest", 1,0)) %>%
select(-region)
rf_data %>% glimpse(50)
## Observations: 1,338
## Variables: 10
## $ age <dbl> 19, 18, 28, 33, 32, 31, 46,...
## $ sex <dbl> 0, 1, 1, 1, 1, 0, 0, 0, 1, ...
## $ bmi <dbl> 27.900, 33.770, 33.000, 22....
## $ children <dbl> 0, 1, 3, 0, 0, 0, 1, 3, 2, ...
## $ smoker <dbl> 1, 0, 0, 0, 0, 0, 0, 0, 0, ...
## $ charges <dbl> 16884.924, 1725.552, 4449.4...
## $ region_ne <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 1, ...
## $ region_nw <dbl> 0, 0, 0, 1, 1, 0, 0, 1, 0, ...
## $ region_se <dbl> 0, 1, 1, 0, 0, 1, 1, 0, 0, ...
## $ region_sw <dbl> 1, 0, 0, 0, 0, 0, 0, 0, 0, ...
library(caret)
set.seed(42)
index <- createDataPartition(y = rf_data$charges,
p = 0.8, list = F)
train <- rf_data %>% slice(index)
test <- rf_data %>% slice(-index)
We again use RMSLE. This is lower (better) than a model that uses the average as a baseline.
pred <- predict(rf, test)
get_rmsle <- function(y, y_hat){
sqrt(mean((log(y) - log(y_hat))^2))
}
get_rmsle(test$charges, pred)
## [1] 0.4772576
## [1] 0.9996513
12.3.3 Variable Importance
Variable importance is a way of measuring how each variable contributes to overall model. For single decision trees, if a variable was “higher” up in the tree, then this variable would have greater influence. Statistically, there are two ways of measuring this:
Look at the reduction in error when a the variable is randomly permuted verses using the actual values. This is done with
type = 1
.Use the total decrease in node impurities from splitting on the variable, averaged over all trees. For classification, the node impurity is measured by the Gini index; for regression, it is measured by the residual sum of squares \(\text{RSS}\). This is
type = 2
.
smoker
, bmi
, and age
are the most importance predictors of charges. As you can imagine, variable importance is a highly useful tool for building models. We could use this to test out newly engineered features, or perform feature selection by taking the top-n features and use them in a different model. Random forests can handle very high dimensional data which allows for many tests to be run at once.
12.3.4 Partial dependence
We know which variables are important, but what about the direction of the change? In a linear model we would be able to just look at the sign of the coefficient. In tree-based models, we have a tool called partial dependence. This attempts to measure the change in the predicted value by taking the average \(\hat{\mathbf{y}}\) after removing the effects of all other predictors.
Although this is commonly used for trees, this approach is model-agnostic in that any model could be used.
Take a model of two predictors, \(\hat{\mathbf{y}} = f(\mathbf{X}_1, \mathbf{X_2})\). For simplicity, say that \(f(x_1, x_2) = 2x_1 + 3x_2\).
The data looks like this
## # A tibble: 4 x 3
## x1 x2 f
## <dbl> <dbl> <dbl>
## 1 1 3 11
## 2 1 4 14
## 3 2 5 19
## 4 2 6 22
Here is the partial dependence of x1
on to f
.
## # A tibble: 2 x 2
## x1 f
## <dbl> <dbl>
## 1 1 12.5
## 2 2 20.5
This method of using the mean is know as the Monte Carlo method. There are other methods for partial dependence that are not on the syllabus.
For the RandomForest, this is done with pdp::partial()
.
library(pdp)
bmi <- pdp::partial(rf, pred.var = "bmi",
grid.resolution = 20) %>%
autoplot() + theme_bw()
age <- pdp::partial(rf, pred.var = "age",
grid.resolution = 20) %>%
autoplot() + theme_bw()
ggarrange(bmi, age)
12.3.5 Advantages and disadvantages
Advantages
- Resilient to overfitting due to bagging
- Only one parameter to tune (mtry, the number of features considered at each split)
- Very good a multi-class prediction
- Nonlinearities
- Interaction effects
- Handles missing data
- Deals with unbalanced after over/undersampling
Disadvantages
- Does not work on small data sets
- Weaker performance than other methods (GBM, NN)
- Unable to predict beyond training data for regression
| Readings | |
|---|---|
| ISLR 8.2.1 Bagging | |
| ISLR 8.1.2 Random Forests |
12.4 Gradient Boosted Trees
Another ensemble learning method is gradient boosting, also known as the Gradient Boosted Machine (GBM). Although this is unlikely to get significant attention on the PA exam due to the complexity, this is the most widely-used and powerful machine learning algorithms that are in use today.
We start with an initial model, which is just a constant prediction of the mean.
\[f = f_0(\mathbf{x_i}) = \frac{1}{n}\sum_{i=1}^ny_i\]
Then we update the target (what the model is predicting) by subtracting off the previously predicted value.
\[ \hat{y_i} \leftarrow y_i - f_0(\mathbf{x_i})\]
This \(\hat{y_i}\) is called the residual. In our example, instead of predicting charges
, this would be predicting the residual of \(\text{charges}_i - \text{Mean}(\text{charges})\). We now use this model for the residuals to update the prediction.
If we updated each prediction with the prior residual directly, the algorithm would be unstable. To make this process more gradual, we use a learning rate parameter.
At step 2, we have
\[f = f_0 + \alpha f_1\]
Then we go back and fit another weak learner to this residual and repeat.
\[f = f_0 + \alpha f_1 + \alpha f_2\]
We then iterate through this process hundreds or thousands of times, slowly improving the prediction.
Because each new tree is fit to residuals instead of the response itself, the process continuously improves the prediction. As the prediction improves, the residuals get smaller and smaller. In random forests, or other bagging algorithms, the model performance is more limited by the individual trees because each only contributes to the overall average. The name is gradient boosting because the residuals are an approximation of the gradient, and gradient descent is how the loss functions are optimized.
Similarly to how GLMs can be used for classification problems through a logit transform (aka logistic regression), GBMs can also be used for classification.
12.4.1 Parameters
For random forests, the individual tree parameters do not get tuned. For GBMs, however, these parameters can make a significant difference in model performance.
Boosting parameters:
n.trees
: Integer specifying the total number of trees to fit. This is equivalent to the number of iterations and the number of basis functions in the additive expansion. Default is 100.shrinkage
: a shrinkage parameter applied to each tree in the expansion. Also known as the learning rate or step-size reduction; 0.001 to 0.1 usually work, but a smaller learning rate typically requires more trees. Default is 0.1.
Tree parameters:
interaction.depth
: Integer specifying the maximum depth of each tree (i.e., the highest level of variable interactions allowed). A value of 1 implies an additive model, a value of 2 implies a model with up to 2-way interactions, etc. Default is 1.n.minobsinnode
: Integer specifying the minimum number of observations in the terminal nodes of the trees. Note that this is the actual number of observations, not the total weight.
GBMs are easy to overfit, and the parameters need to be carefully tuned using cross-validation. In the Examples section we go through how to do this.
Tip: Whenever fitting a model, use
?model_name
to get the documentation. The parameters below are from?gbm
.
12.4.2 Example
We fit a gbm below without tuning the parameters for the sake of example.
library(gbm)
gbm <- gbm(charges ~ ., data = train,
n.trees = 100,
interaction.depth = 2,
n.minobsinnode = 50,
shrinkage = 0.1)
## Distribution not specified, assuming gaussian ...
## [1] 0.4411494
## [1] 0.9996513
12.4.3 Advantages and disadvantages
This exam covers the basics of GBMs. There are many variations of GBMs not covered in detail such as xgboost
.
Advantages
- High prediction accuracy
- Shown to work empirically well on many types of problems
- Nonlinearities, interaction effects, resilient to outliers, corrects for missing values
- Deals with class imbalance directly by weighting observations
Disadvantages
- Requires large sample size
- Longer training time
- Does not detect linear combinations of features. These must be engineered Can overfit if not tuned correctly
| Readings | |
|---|---|
| ISLR 8.2.3 Boosting |
12.5 Exercises
Run this code on your computer to answer these exercises.
1. RF with randomForest
(Part 1 of 2)
The below code is set up to fit a random forest to the soa_mortality
data set to predict actual_cnt
.
There is a problem: all of the predictions are coming out to be 1. Find out why this is happening and fix it.
set.seed(42)
#For the sake of this example, only take 20% of the records
df <- soa_mortality %>%
sample_frac(0.2) %>%
mutate(target = as.factor(ifelse(actual_cnt == 0, 1, 0))) %>%
select(target, prodcat, distchan, smoker, sex, issage, uwkey) %>%
mutate_if(is.character, ~as.factor(.x))
#check that the target has 0's and 1's
df %>% count(target)
## # A tibble: 2 x 2
## target n
## <fct> <int>
## 1 0 1811
## 2 1 98189
library(caret)
index <- createDataPartition(y = df$target, p = 0.8, list = F)
train <- df %>% slice(index)
test <- df %>% slice(-index)
k = 0.1
cutoff=c(k,1-k)
model <- randomForest(
formula = target ~ .,
data = train,
ntree = 100,
cutoff = cutoff
)
pred <- predict(model, test)
confusionMatrix(pred, test$target)
(Part 2 of 2)
Downsample the majority class and refit the model, and then choose between the original data and the downsampled data based on the model performance. Use your own judgement when choosing how to evaluate the model based on accuracy, sensitivity, specificity, and Kappa.
down_train <- downSample(x = train %>% select(-target),
y = train$target)
down_test <- downSample(x = test %>% select(-target),
y = test$target)
down_train %>% count(Class)
model <- randomForest(
formula = Class ~ .,
data = down_train,
ntree = 100,
cutoff = cutoff
)
down_pred <- predict(model, down_test)
confusionMatrix(down_pred, down_test$Class)
Now up-sample the minority class and repeat the same procedure.
up_train <- upSample(x = train %>% select(-target),
y = train$target)
up_test <- upSample(x = test %>% select(-target),
y = test$target)
up_train %>% count(Class)
model <- randomForest(
formula = Class ~ .,
data = up_train,
ntree = 100,
cutoff = cutoff
)
up_pred <- predict(model, up_test)
confusionMatrix(up_pred, up_test$Class)
2. RF tuning with caret
The best practice of tuning a model is with cross-validation. This can only be done in the caret
library. If the SOA asks you to use caret
, they will likely ask you a question related to cross validation as below.
An actuary has trained a predictive model and chosen the best hyperparameters, cleaned the data, and performed feature engineering. They have one problem, however: the error on the training data is far lower than on new, unseen test data. Read the code below and determine their problem. Find a way to lower the error on the test data without changing the model or the data. Explain the rational behind your method.
library(caret)
set.seed(42)
#Take only 1000 records
#Uncomment this when completing this exercise
data <- health_insurance %>% sample_n(1000)
index <- createDataPartition(
y = data$charges, p = 0.8, list = F) %>%
as.numeric()
train <- health_insurance %>% slice(index)
test <- health_insurance %>% slice(-index)
control <- trainControl(
method='boot',
number=2,
p = 0.2)
tunegrid <- expand.grid(.mtry=c(1,3,5))
rf <- train(charges ~ .,
data = train,
method='rf',
tuneGrid=tunegrid,
trControl=control)
pred_train <- predict(rf, train)
pred_test <- predict(rf, test)
get_rmse <- function(y, y_hat){
sqrt(mean((y - y_hat)^2))
}
get_rmse(pred_train, train$charges)
get_rmse(pred_test, test$charges)
<IP_ADDRESS> Tuning a GBM with caret
If the SOA asks you to tune a GBM, they will need to give you starting hyperparameters which are close to the “best” values due to how slow the Prometric computers are. Another possibility is that they pre-train a GBM model object and ask that you use it.
This example looks at 27 combinations of hyper parameters.
tunegrid <- expand.grid(
interaction.depth = c(1,3,5),
n.trees = c(20, 40, 100),
shrinkage = c(0.01, 0.001, 0.0001),
n.minobsinnode = 20)
nrow(tunegrid)
gbm <- train(charges ~ bmi + age + sex + region,
data = health_insurance_train,
method='gbm',
tuneGrid=tunegrid,
trControl=control,
#Show detailed output
verbose = FALSE
)
The output shows the RMSE for each of the 27 models tested.
The summary.gbm
function, which R understands from the summary
function, shows the variable importance. The most predictive feature is age
, followed by bmi
.
12.6 Answers to Exercises
Answers to these exercises are available at ExamPA.net.


| Order Buy | Investment Amount | Description | Reinvestment Dividends/Capital Gains | ||
|---|---|---|---|---|---|
| {{transaction.orderType}} | {{transaction.investmentAmount}} | {{transaction.fundFamily}} ({{transaction.symbol}}) | {{transaction.reinvestment}} |
This fund participates in the no-load, no-transaction fee program. You pay no sales charges or transaction fees for this order. E*TRADE Securities will charge an Early Redemption Fee of $49.99 on redemptions or exchanges of no-load, no transaction fee funds that are held less than 90 days.
| Non-Marginable Securities/Options | Marginable Securities | ||
|---|---|---|---|
| Purchasing power before open orders: | {{purchasingPower.beforeOpenOrders | currency}} | $10,777.69 | |
| Reserve for other open orders: | {{purchasingPower.reserve | currency}} | $10,777.69 | |
| Purchasing power impact of this order: | {{purchasingPowerImpactThisOrder | currency}} | $10,777.69 | |
| Purchasing power after this order: | {{purchasingPowerAfterThisOrder | currency}} | $10,777.69 |
| Investment Amount | Sales Charge |
|---|---|
| {{charge.lowhigh}} | {{charge.percent}} |


I am a full stack software developer living in the Twin Cities. I love the daily problem solving develpment provides, along with the endless learning and ever changing industry. I was drawn to software engineering for the opportunity to solve problems with digital solutions.
When not coding, I enjoy spending time with friends and family, exploring everything Minnesota has to offer, and checking out a new restaurant. I also love trying out all of Minnesota's tap rooms! Please feel free to take a look around!
JavaScript
AngularJS
Node.js
PostgreSQL
HTML5
CSS3
Amazon Web Services (AWS)
MongoDB
Express
ES6
Passport
Ajax
Agile
jQuery
AngularJS Material
GitHub
Git
Bootstrap
Filestack
JSON
API
VirtualBox
A communication application for the Parent Athlete Coach triangle. It provides a layer of protection to athletes
while giving separation to the coach’s personal accounts. Coaches are able to send new messages or reply to
messages from parents/guardians and athletes. Coaches may also view and edit their team. They also have the
ability to track attendance and filter their view by date or athlete. Parents and athletes are able to send
a message to the coach only. Parents/Guardians receive copies of all messages between the coach and athlete.
Technologies Used: PostgreSQL, Express, AngularJS, Node.js, JavaScript, HTML 5, CSS 3, Angular MaterialJS,
Filestack, Moment.js, AngularJS carousel, Passport, Postico, Heroku, Git, GitHub
Live demo.
GitHub repository.
YouTube video walkthrough.
Currently in progress. Collaborating with a team of 4 to build a full stack scheduling application for on-call
staff at the Andrew Residence. Utilizing agile methodologies and participating in daily standups to communicate
progress, plans and impediments. Administrators are able to post shift openings for on-call staff. They also
have the ability to accept picked up shifts, send out urgent notifications and view upcoming shifts. On-call
staff may bid on open shifts, request partial shifts and view their upcoming shifts.
Technologies Used: PostgreSQL, Express, AngularJS, Node.js, JavaScript, HTML 5, CSS 3, Angular MaterialJS,
Moment.js, Passport, Postico, Heroku, Git, GitHub, VirtualBox, Plivo, NodeMailer
A basic real estate CRUD application showing both listings and rentals. Users are able to add, update and delete
properties for rent or sale. They may also sort by city, cost and locations.
Technologies Used: MongoDB, Express, AngularJS, Node.js, JavaScript, HTML5, CSS3 and Bootstrap for styling.
Live demo.
GitHub repository.
Facebook for Myself was the first application I built using AngularJS. While not perfect it was a great learning
experience and foundation to build from. Users are able to click on a picture to view a caption of the photo.
The application counts each time a picture is clicked. Users may also like a photo as many times as they wish.
Leave a comment, and view/hide comments.
Technologies Used: Express, AngularJS, Node.JS, HTML5, JavaScript, CSS3 and Bootstrap for styling.
Live demo.
GitHub repository.
A responsive real time messaging application. Using authenticaion users can sign in and post a message, view other
users and edit their profile. Users can also upload pictures to messages and vote.
Technologies Used: MongoDB, Express, AngularJS, Node.JS, HTML5, JavaScript, CSS3, Socket.io, Filestack, Angular
Material and Angular Moment.
GitHub repository.
A real time basic calculator application. Displays the last 10 equations from a user.
Technologies Used: MongoDB, Express, AngularJS, Node.JS, HTML5, JavaScript, CSS3 and Socket.io.
Live demo.
GitHub repository.
An interactive "To Do List" application. Allows users to input tasks to their "To Do List", check when completed
and delete tasks. Upon input of task - defaults that the task has not yet been completed.
Technologies Used: PostgreSQL, Express, jQuery, Node.JS, HTML5, JavaScript, CSS3 and Bootstrap for styling.
Live demo.
GitHub repository.


Sign Up
Username
Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.
Email
email address
Password
Your password can't be too similar to your other personal information.
Your password must contain at least 8 characters.
Your password can't be a commonly used password.
Your password can't be entirely numeric.
Password confirmation
Enter the same password as before, for verification.


- MATLAB m-files for Figures for Applied Partial Differential Equations Text by Richard Haberman
The figures for the fourth edition (2004) of my text Applied Partial Differential Equations (with Fourier Series and Boundary Value Problems) published by Prentice-Hall were prepared using MATLAB 4.2. Please feel free to copy (download) any or all of these MATLAB m-files. Just right click on the following links. For examples, F234.M is the MATLAB m file for Figure 2.3.4. and F1244.M is for Figure 12.4.4.
Chapter 2
F234.M,F235.M,F253A.M,F253B.M,F253C.M,F253D.M
Chapter 3
F338A.M,F338B.M
Chapter 4
F441A.M,F441B.M,F441C.M
Chapter 5
F581.M,F582.M,F583.M,F584.M
Chapter 6
F621.M,F635A.M,F635B.M,F636.M,F638.M,F641.M,F642.M,F643.M
Chapter 7
F732A.M,F732B.M,F732C.M,F771.M,F781.M,F782.M,F783A.M,F783B.M,F783C.M,F783D.M,F783E.M,
F792.M,F7101.M
Chapter 9
F934.M,F935.M,F936.M
Chapter 10
F1032.M,F1041.M,F1042.M,F1043.M,F1044.M,F1062.M,F1064A.M,F1064B.M
Chapter 11
F1122.M,F1131.M
Chapter 12
F1221.M,F1222.M,F1223.M,F1231.M,F1232A.M,F1232B.M,F1232C.M,F1233.M,F1234A.M,F1234B.M
F1244.M,F1263.M,F1264A.M,F1265B.M,F12610A.M,F12610B.M,F12612.M
Chapter 14
F1421.M,F1432.M,F1443.M,F1451.M,F1452.M,F1463.M,F1464.M,F1465.M,F1468.M
F1471.M,F1472.M,F1473.M,F1474.M,F1481.M,F1482.M,F1483.M,F1484.M,F14101.M,F14102.M
- Research Interests in Applied Mathematics
singular perturbation methods
ordinary and partial differential equations
matched asymptotic expansions
boundary layers
multiple scales
averaging
nonlinear dynamical systems
slow transitions
bifurcations
subharmonic resonances
homoclinic orbits
chaos
nonlinear wave motion
shocks
solitons
dispersive waves
multiphase waves
caustics
mathematical models
fluid dynamics
traffic flow
reaction-diffusion
hydrodynamic stability
critical layers
defects in fiber optics
Education
- B.S. in Applied Mathematics, M.I.T., June 1967
- Ph.D. in Applied Mathematics, M.I.T., September 1971
-
-
- Professional Experience
-
- Southern Methodist University
- Professor of Mathematics (1985-present), Associate Professor (1978-1985)
- The Ohio State University (1977-1978)
- Assistant Professor of Mathematics
- Rutgers University (1972-1977)
- Assistant Professor of Mathematics
- University of California, San Diego (1971-1972)
- Post-doctoral research, Institute of Geophysics and Planetary Physics
- Lecturer, Department of Applied Mechanics and Engineering Sciences
Publications
- 1. "Critical layers in parallel flows," Studies in Applied Math. 51 (1972), pp. 139-161.
-
- 2. "Note on slightly unstable nonlinear wave systems," J. of Fluid Mechanics 58 (1973), pp. 129-142.
-
- 3. "Wave induced distortions of a slightly stratified shear flow - a nonlinear critical layer effect,"
- Journal of Fluid Mechanics 58 (1973), pp. 727-735.
-
- 4. "Nonlinear perturbations of the Orr-Sommerfeld
equation - asymptotic expansion of the logarithmic phase shift across
- the critical layer," SIAM J.
Math. Analysis 7 (1976), pp. 70-81.
-
- 5. "Resonantly coupled nonlinear evolution equations," (with M. J. Ablowitz), Math. Phys. 16 (1975), pp. 2301-2305.
-
- 6. "Some higher order nonlinear evolution equations," Studies in Applied Math. 54 (1975), pp. 275-282.
-
- 7. "Note on generating nonlinear evolution equations," SIAM J. Applied Math. 31 (1976), pp. 47-51.
-
- 8. "Nonlinear evolution equations - two and three
dimensions," (with M. J. Ablowitz),
- Physical Review Letters 35
(1975), pp. 1185-1188.
-
- 9. "On the singular behavior of spatially dependent
nonlinear wave envelopes,"
- SIAM J. Applied Math. 32 (1977),
pp. 154-163.
-
- 10. "An infinite number of conservation laws for
coupled nonlinear evolution equations,"
- J. Math. Phys. 18 (1977),
pp. 1137-1139.
-
- 11. "Nonlinear transition layers - the second Painleve transcendent," Studies in Applied Math. 57 (1977), pp. 247-270.
-
- 12. "Slowly varying jump and transition phenomena
associated with algebraic bifurcation problems,"
- SIAM J. Applied Math. 37 (1979),
pp. 69-106.
-
- 13. "Energy bounds for the slow capture by a center
in sustained resonance,"
- SIAM J. Applied Math. 43 (1983),
pp. 244-256.
-
- 14. "Nonlinear cusped caustics for dispersive waves," (with Ren-ji Sun), Studies in Applied Math. 72 (1985), pp. 1-37.
-
- 15. "Slowly varying solitary wave tails: Focusing,
cusped caustics, wave number shocks and birth of tails,"
- (with D. Allgaier), SIAM J.
Applied Math. 45 (1985), pp. 919-927.
-
- 16. "Note on the initial formation of shocks," SIAM J. Applied Math. 46 (1986), pp. 16-19.
-
- 17. "The initial formation and structure of two-dimensional diffusive shock waves," Wave Motion 8 (1986), pp. 267-276.
-
- 18. "The modulated phase shift for strongly
nonlinear, slowly varying, and weakly damped oscillators,"
- (with F. J. Bourland), SIAM J.
Applied Math. 48 (1988), pp. 737-748.
-
- 19. "Variation of wave action: modulations of the
phase shift for strongly nonlinear dispersive waves with weak
- dissipation," (with F. J.
Bourland), Physica 32D (1988), pp. 72-82.
-
- 20. "The modulated phase shift for weakly dissipated
nonlinear oscillatory waves of the Korteweg-deVries type,"
- Studies in Applied Math. 78
(1988), pp. 73-90.
-
- 21. "The slowly varying phase shift for perturbed, single
and multi-phased, strongly nonlinear, dispersive waves,"
- (with F. J. Bourland), Physica
35D (1989), pp. 127-147.
-
- 22. "Wave number shocks for the leading tail of
Korteweg-deVries solitary waves in slowly varying media,"
- (with D. Allgaier), Wave Motion
12 (1990), pp. 569-581.
-
- 23. "Separatrix crossing: time-invariant potentials
with dissipation", (with F. J. Bourland),
- SIAM J. Applied Math. 50 (1990),
pp. 1716-1744.
-
- 24. "Averaging method for the phase shift of
arbitrarily perturbed strongly nonlinear oscillators with an application to
- capture", (with F. J. Bourland
and W. L. Kath), SIAM J. Applied Math. 51 (1991), pp. 1150-1167.
-
- 25. "Phase shift modulations for stable,
oscillatory, traveling, strongly nonlinear waves",
- Studies in Applied Math. 84
(1991), pp. 57-69.
-
- 26. "Standard form and a method of averaging for
strongly nonlinear oscillatory dispersive traveling waves",
- SIAM J. Applied Math. 51 (1991),
pp. 1638-1652.
-
- 27. "The accommodation of traveling waves of
Fisher's type to the dynamics of the leading tail",
- (with M. R. Booty and A. A.
Minzoni), SIAM J. Applied Math. 53 (1993), pp. 1009-1025.
-
- 28. "Connection across a separatrix with
dissipation", (with F. J. Bourland),
- Studies in Applied Math. 91
(1994), pp. 95-124.
-
- 29. "Higher-order change of the Hamiltonian (energy) for nearly homoclinic orbits", (with E. K. Ho),
- Meth. Appl. Anal. 1 (1994), pp. 446-464.
-
- 30. "Boundary of the basin of attraction for weakly damped primary resonance", (with E. K. Ho),
- ASME J. Applied Mech. 62 (1995), pp. 941-946.
-
- 31. "Logarithmic correction to the probability of capture for dissipatively
perturbed Hamiltonian systems", (with E. K. Ho),
- Chaos 5 (1995), pp. 374-384.
-
- 32. "Higher-order change of the Hamiltonian between
saddle approaches by phase plane matching", (with E. K. Ho),
- Int. J. Non-Linear Mech. 31
(1996), pp. 239-254.
-
- 33. "Accurate phase after slow passage through subharmonic resonance", (with J. D. Brothers),
- SIAM J. Appl. Math. 59 (1998), pp. 347-364.
-
- 34. "Slow passage through a homoclinic orbit with
subharmonic resonances", (with J. D. Brothers),
- Studies in Applied Math. 101
(1998), pp. 211-232.
-
- 35. "Resonant capture and separatrix crossing in dual-spin spacecraft", (with R. Rand and T. Yuster),
- Nonlinear Dynamics 18 (1999), pp.
159-184.
-
- 36. "Sequences of orbits and the boundaries of the
basin of attraction for two double heteroclinic orbits", (with R. Rand),
- Int. J. Non-Linear Mech. 34
(1999), pp. 1047-1059.
-
- 37. "Slow passage through a saddle-center bifurcation", (with D.
C. Diminnie),
- J. Nonlinear Science 10 (2000),
pp. 197-221.
-
- 38. "Weakly nonlinear long waves in channel flow
with internal dissipation", (with J. Yu and J. Kevorkian),
- Studies in Applied Math. 105
(2000), pp. 143-163.
-
- 39. "Slow passage through a transcritical
bifurcation for Hamiltonian systems and the change in action due to a
- nonhyperbolic homoclinic orbit",
Chaos 10 (2000), pp. 641-648.
-
- 40. "Slow passage through the nonhyperbolic homoclinic orbit associated with a subcritical
pitchfork bifurcation for
- Hamiltonian systems and the
change in action", SIAM J. Appl. Math 62 (2001), pp. 488-513.
-
- 41. "Slow passage through the nonhyperbolic homoclinic orbit
of the saddle-center Hamiltonian bifurcation",
- (with D.C. Diminnie) Studies in
Applied Math. 108 (2002), pp. 65-75.
-
- 42. "Slow passage through homoclinic orbits for the
unfolding of a saddle-center bifurcation and the change in adiabatic
- invariant", (with D.C. Diminnie)
Physica D 162 (2002), pp. 34-52.
-
- 43. "Action and period of homoclinic and periodic
orbits for the unfolding of a saddle-center bifurcation",
- (with D.C. Diminnie) Int. J.
Bifurcation and Chaos 13 (2003), pp. 3519-3530.
-
- 44. "Interaction of sine-Gordon kinks with defects:
The two-bounce resonance", (with Roy H. Goodman)
- Physica D (submitted).
-
Texts
- 1. Mathematical Models: Mechanical Vibrations,
Population Dynamics, and Traffic Flow An Introduction to Applied
- Mathematics, Prentice-Hall,
Englewood Cliffs, N.J., 1977, 402 pages. Also Japanese translation.
- Reprinted SIAM Classic Series
#21, 1998.
-
- 2. Applied Partial Differential Equations (with Fourier Series and Boundary Value Problems), Prentice-Hall,
- Upper Saddle River, N.J., 1983, 1987,
1998 (Fourth Edition, 2004, 759 pages).
- Also Instructor's Manual. Also
Spanish translation.
-
- 3. Introduction to Differential Equations with
Boundary Value Problems (with Stephen L. Campbell), Houghton-Mifflin,
- Boston, 1996, 729 pages. Also
Instructor's Manual. Also Spanish translation.
Conference Proceedings
- 1. "Energy bounds for the slow capture by a center," Trends in Theory and Practice of Nonlinear Differential Equations,
- ed. V. Lakshmikantham, Dekker, New York, 1984, pp. 227-230.
-
- 2. "Nonlinear focusing of dispersive waves," (with Ren-ji Sun), Lectures in Applied Mathematics: V. 23 - Part 2
- Nonlinear Systems of Partial Differential Equations in Applied Mathematics,
- ed. B. Nicolaenko, D. D. Holm, and J. M. Hyman, AMS, Providence, 1986, pp. 67-78.
-
- 3. "Phase shift for strongly nonlinear slowly varying oscillators with perturbations", (with F. J. Bourland),
- BAIL V Conf. Proc., Boole Press, Dublin, 1988, pp. 92-97.
-
- 4. "Focusing at a nonlinear penumbral caustic", (with Ren-ji Sun), BAIL V Conf. Proc., Boole
Press, Dublin, 1988,
- pp. 339-344.
-
- 5. "Capture and the connection formulas for the transition across a separatrix", (with F. J. Bourland), Asymptotic Analysis
- and the Numerical Solution of Partial Differential Equations,
- ed. H. G. Kaper and M. Garbey, Dekker, New York, 1991, pp. 17-30.
-
- 6. "Phase shift modulations for perturbed strongly nonlinear oscillatory dispersive waves", Nonlinear Dispersive Wave
- Systems, ed. L. Debnath, World Sci., Singapore, 1992, pp. 73-82.
-
- 7. "Matching across subharmonic resonance", (with J. D. Brothers), ICIAM 95 Conf. Proc. in ZAMM
76 (1996)
- pp. 489.
-
- 8. "On the dynamic unfolding of a saddle-center
bifurcation and the change in the action", (with D. C. Diminnie),
- Proc. Steklov Inst. Math (2003) pp.
S91-S97.
- Translated from Trudy Instituta
Mathematiki i Mekhaniki UrO RAN (2003)..
-
Ph.D. Students
- 1. Ren-ji Sun (Ph.D., SMU, 1984) Thesis entitled "Caustics for dispersive waves: asymptotics of nonlinear Schrodinger
- equation and its Riemann-Hilbert problems".
-
- 2. Darrell Allgaier (Ph.D., SMU, 1986) Thesis
entitled "Wave number shocks for the tail of Korteweg-deVries solitary
- waves in slowly varying media".
-
- 3. F. Jay Bourland (Ph.D., SMU, 1989) Thesis
entitled "Modulations of the phase shift for nonlinear oscillators and
- dispersive waves and connections
across a separatrix".
-
- 4. Eric K. Ho (Ph.D., SMU, 1993) Thesis entitled
"Hamiltonian systems with dissipation: basins of attraction and nearly
- homoclinic orbits".
-
- 5. Jerry D. Brothers (Ph.D., SMU, 1995) Thesis
entitled "Sequence of subharmonic resonances
- and slow separatrix crossing".
-
- 6. David C. Diminnie (Ph.D., SMU, 2000) Thesis
entitled "Slow passage through homoclinic orbits associated with the
- unfolding of a saddle-center
bifurcation"
-
The contents of this home page are the sole responsibility of Professor Haberman and its contributors, and do not necessarily represent the opinions or policies of Southern Methodist University. The administrator of this page is Professor Haberman, who may be contacted at<EMAIL_ADDRESS>Last revision: January 27, 2004.


Open Source Library for Angular Web Apps to integrate a material user interface built with ❤ for firebase authentication
Scroll down to see it in action!
This demo app uses a real connection of firebase. That means if you enable firestore's synchronisation, your account will be saved in the db. If you are just experimenting the demo app, please make sure to delete you account before to quit. That will remove your document from firestore (if it was enabled) and your account from the firebase authentication system.


| stat_summary_2d {ggplot2} | R Documentation |
stat_summary_2d()
is a 2d variation of stat_summary()
.
stat_summary_hex()
is a hexagonal variation of
stat_summary_2d()
. The data are divided into bins defined
by x
and y
, and then the values of z
in each cell is
are summarised with fun
.
stat_summary_2d( mapping = NULL, data = NULL, geom = "tile", position = "identity", ..., bins = 30, binwidth = NULL, drop = TRUE, fun = "mean", fun.args = list(), na.rm = FALSE, show.legend = NA, inherit.aes = TRUE ) stat_summary_hex( mapping = NULL, data = NULL, geom = "hex", position = "identity", ..., bins = 30, binwidth = NULL, drop = TRUE, fun = "mean", fun.args = list(), na.rm = FALSE, show.legend = NA, inherit.aes = TRUE )
mapping |
Set of aesthetic mappings created by |
data |
The data to be displayed in this layer. There are three options: If A A |
geom |
The geometric object to use display the data |
position |
Position adjustment, either as a string, or the result of a call to a position adjustment function. |
... |
Other arguments passed on to |
bins |
numeric vector giving number of bins in both vertical and horizontal directions. Set to 30 by default. |
binwidth |
Numeric vector giving bin width in both vertical and
horizontal directions. Overrides |
drop |
drop if the output of |
fun |
function for summary. |
fun.args |
A list of extra arguments to pass to |
na.rm |
If |
show.legend |
logical. Should this layer be included in the legends?
|
inherit.aes |
If |
x
: horizontal position
y
: vertical position
z
: value passed to the summary function
Location
Value of summary statistic.
stat_summary_hex()
for hexagonal summarization.
stat_bin2d()
for the binning options.
d <- ggplot(diamonds, aes(carat, depth, z = price)) d + stat_summary_2d() # Specifying function d + stat_summary_2d(fun = function(x) sum(x^2)) d + stat_summary_2d(fun = ~ sum(.x^2)) d + stat_summary_2d(fun = var) d + stat_summary_2d(fun = "quantile", fun.args = list(probs = 0.1)) if (requireNamespace("hexbin")) { d + stat_summary_hex() d + stat_summary_hex(fun = ~ sum(.x^2)) }


Hackathon at the University of Cincinnati - {{ site.data.config.eventData.fullDate }}
Fill out the interest form to get updates about RevolutionUC 2020
And be notified when registration goes live!
{% endif %} {% if site.data.config.homepage.timeline == "registration" %}Hackathon at the University of Cincinnati - {{ site.data.config.eventData.fullDate }}
Interested? Register to participate!
{% endif %} {% if site.data.config.homepage.timeline == "post-registration" %}Thank you all for participating in this year's RevolutionUC!
{% endif %}


Voting: Runoff
Implement a program that runs a runoff election, as shown below.
./runoff Alice Bob Charlie
Number of voters: 5
Rank 1: Alice
Rank 2: Bob
Rank 3: Charlie
Rank 1: Alice
Rank 2: Charlie
Rank 3: Bob
Rank 1: Bob
Rank 2: Charlie
Rank 3: Alice
Rank 1: Bob
Rank 2: Alice
Rank 3: Charlie
Rank 1: Charlie
Rank 2: Alice
Rank 3: Bob
Alice
Background
You already know about plurality elections, which follow a very simple algorithm for determining the winner of an election: every voter gets one vote, and the candidate with the most votes wins.
But the plurality vote does have some disadvantages. What happens, for instance, in an election with three candidates, and the ballots below are cast?
A plurality vote would here declare a tie between Alice and Bob, since each has two votes. But is that the right outcome?
There’s another kind of voting system known as a ranked-choice voting system. In a ranked-choice system, voters can vote for more than one candidate. Instead of just voting for their top choice, they can rank the candidates in order of preference. The resulting ballots might therefore look like the below.
Here, each voter, in addition to specifying their first preference candidate, has also indicated their second and third choices. And now, what was previously a tied election could now have a winner. The race was originally tied between Alice and Bob, so Charlie was out of the running. But the voter who chose Charlie preferred Alice over Bob, so Alice could here be declared the winner.
Ranked choice voting can also solve yet another potential drawback of plurality voting. Take a look at the following ballots.
Who should win this election? In a plurality vote where each voter chooses their first preference only, Charlie wins this election with four votes compared to only three for Bob and two for Alice. But a majority of the voters (5 out of the 9) would be happier with either Alice or Bob instead of Charlie. By considering ranked preferences, a voting system may be able to choose a winner that better reflects the preferences of the voters.
One such ranked choice voting system is the instant runoff system. In an instant runoff election, voters can rank as many candidates as they wish. If any candidate has a majority (more than 50%) of the first preference votes, that candidate is declared the winner of the election.
If no candidate has more than 50% of the vote, then an “instant runoff” occurrs. The candidate who received the fewest number of votes is eliminated from the election, and anyone who originally chose that candidate as their first preference now has their second preference considered. Why do it this way? Effectively, this simulates what would have happened if the least popular candidate had not been in the election to begin with.
The process repeats: if no candidate has a majority of the votes, the last place candidate is eliminated, and anyone who voted for them will instead vote for their next preference (who hasn’t themselves already been eliminated). Once a candidate has a majority, that candidate is declared the winner.
Let’s consider the nine ballots above and examine how a runoff election would take place.
Alice has two votes, Bob has three votes, and Charlie has four votes. To win an election with nine people, a majority (five votes) is required. Since nobody has a majority, a runoff needs to be held. Alice has the fewest number of votes (with only two), so Alice is eliminated. The voters who originally voted for Alice listed Bob as second preference, so Bob gets the extra two vote. Bob now has five votes, and Charlie still has four votes. Bob now has a majority, and Bob is declared the winner.
What corner cases do we need to consider here?
One possibility is that there’s a tie for who should get eliminated. We can handle that scenario by saying all candidates who are tied for last place will be eliminated. If every remaining candidate has the exact same number of votes, though, eliminating the tied last place candidates means eliminating everyone! So in that case, we’ll have to be careful not to eliminate everyone, and just declare the election a tie between all remaining candidates.
Some instant runoff elections don’t require voters to rank all of their preferences — so there might be five candidates in an election, but a voter might only choose two. For this problem’s purposes, though, we’ll ignore that particular corner case, and assume that all voters will rank all of the candidates in their preferred order.
Sounds a bit more complicated than a plurality vote, doesn’t it? But it arguably has the benefit of being an election system where the winner of the election more accurately represents the preferences of the voters.
Getting Started
Here’s how to download this problem’s “distribution code” (i.e., starter code) into your own CS50 IDE. Log into CS50 IDE and then, in a terminal window, execute each of the below.
- Create a folder called
runoff
in your CS50 IDE. - Click runoff.c to see the starting code and download it to your computer.
- Drag the
runoff.c
file from your computer and drop it on the folder in your IDE. Or create a new file in your IDE calledrunoff.c
and copy-and-paste the code into it
Understanding
Let’s open up runoff.c
to take a look at what’s already there. We’re defining two constants: MAX_CANDIDATES
for the maximum number of candidates in the election, and MAX_VOTERS
for the maximum number of voters in the election.
Next up is a two-dimensional array preferences
. The array preferences[i]
will represent all of the preferences for voter number i
, and the integer preferences[i][j]
here will store the index of the candidate who is the j
th preference for voter i
.
Next up is a struct
called candidate
. Every candidate
has a string
field for their name
, an int
representing the number of votes
they currently have, and a bool
value called eliminated
that indicates whether the candidate has been eliminated from the election. The array candidates
will keep track of all of the candidates in the election.
The program also has two global variables: voter_count
and candidate_count
.
Now onto main()
. Notice that after determining the number of candidates and the number of voters, the main voting loop begins, giving every voter a chance to vote. As the voter enters their preferences, the vote
function is called to keep track of all of the preferences. If at any point, the ballot is deemed to be invalid, the program exits.
Once all of the votes are in, another loop begins: this one’s going to keep looping through the runoff process of checking for a winner and eliminating the last place candidate until there is a winner.
The first call here is to a function called tabulate()
, which should look at all of the voters’ preferences and compute the current vote totals, by looking at each voter’s top choice candidate who hasn’t yet been eliminated. Next, the print_winner()
function should print out the winner if there is one; if there is, the program is over. But otherwise, the program needs to determine the fewest number of votes anyone still in the election received (via a call to find_min()
). If it turns out that everyone in the election is tied with the same number of votes (as determined by the is_tie()
function), the election is declared a tie; otherwise, the last-place candidate (or candidates) is eliminated from the election via a call to the eliminate()
function.
If you look a bit further down in the file, you’ll see that these functions — vote()
, tabulate()
, print_winner()
, find_min()
, is_tie()
, and eliminate()
— are all left up to you to complete!
Specification
Complete the implementation of runoff.c
in such a way that it simulates a runoff election. You should complete the implementations of the vote()
, tabulate()
, print_winner()
, find_min()
, is_tie()
, and eliminate()
functions, and you should not modify anything else in runoff.c
(except you may include additional header files, if you’d like).
vote()
Complete the vote()
function.
- The function takes arguments
voter
,rank
, andname
. Ifname
is a match for the name of a valid candidate, then you should update the global preferences array to indicate that the votervoter
has that candidate as theirrank
preference (where0
is the first preference,1
is the second preference, etc.). - If the preference is successfully recorded, the function should return
true
; the function should returnfalse
otherwise (if, for instance,name
is not the name of one of the candidates). - You may assume that no two candidates will have the same name.
Hints
- Recall that
candidate_count
stores the number of candidates in the election. - Recall that you can use
strcmp
to compare two strings. - Recall that
preferences[i][j]
stores the index of the candidate who is thej
th ranked preference for thei
th voter.
tabulate()
Complete the tabulate()
function.
- The function should update the number of
votes
each candidate has at this stage in the runoff. - Recall that at each stage in the runoff, every voter effectively votes for their top-preferred candidate who has not already been eliminated.
Hints
- Recall that
voter_count
stores the number of voters in the election. - Recall that for a voter
i
, their top choice candidate is represented bypreferences[i][0]
, their second choice candidate bypreferences[i][1]
, etc. - Recall that the
candidate
struct
has a field calledeliminated
, which will betrue
if the candidate has been eliminated from the election. - Recall that the
candidate
struct
has a field calledvotes
, which you’ll likely want to update for each voter’s preferred candidate.
print_winner()
Complete the print_winner()
function.
- If any candidate has more than half of the vote, their name should be printed and the function should return
true
. - If nobody has won the election yet, the function should return
false
.
Hints
- Recall that
voter_count
stores the number of voters in the election. Given that, how would you express the number of votes needed to win the election?
find_min()
Complete the find_min()
function.
- The function should return the minimum vote total for any candidate who is still in the election.
Hints
- You’ll likely want to loop through the candidates to find the one who is both still in the election and has the fewest number of votes. What information should you keep track of as you loop through the candidates?
is_tie()
Complete the is_tie()
function.
- The function takes an argument
min
, which will be the minimum number of votes that anyone in the election currently has. - The function should return
true
if every candidate remaining in the election has the same number of votes, and should returnfalse
otherwise.
Hints
- Recall that a tie happens if every candidate still in the election has the same number of votes. Note, too, that the
is_tie()
function takes an argumentmin
, which is the smallest number of votes any candidate currently has. How might you use that information to determine if the election is a tie (or, conversely, not a tie)?
eliminate()
Complete the eliminate()
function.
- The function takes an argument
min
, which will be the minimum number of votes that anyone in the election currently has. The function should eliminate the candidate (or candidates) who havemin
number of votes.
Walkthrough
Watch the following video for a step-by-step breakdown of the task:
Usage
Your program should function like the example below:
./runoff Alice Bob Charlie
Number of voters: 5
Rank 1: Alice
Rank 2: Charlie
Rank 3: Bob
Rank 1: Alice
Rank 2: Charlie
Rank 3: Bob
Rank 1: Bob
Rank 2: Charlie
Rank 3: Alice
Rank 1: Bob
Rank 2: Charlie
Rank 3: Alice
Rank 1: Charlie
Rank 2: Alice
Rank 3: Bob
Alice
Testing
Be sure to test your code to make sure it handles:
- An election with any number of candidate (up to the
MAX
of9
) - Voting for a candidate by name
- Invalid votes for candidates who are not on the ballot
- Printing the winner of the election if there is only one
- Not eliminating anyone in the case of a tie between all remaining candidates
Execute the below to evaluate the correctness of your code using check50. But be sure to compile and test it yourself as well!
check50 scienceacademy/problems/2020ap/runoff
Execute the below to evaluate the style of your code using style50.
style50 runoff.c
Submitting
Execute the below to submit your code:
submit50 scienceacademy/problems/2020ap/runoff


A brand new, lightweight (~4KB gzipped: no dependencies, jquery, nada), JavaScript plugin for picking time ranges in the browser.
Check out the Code & Documentation on my Github page.
Customizeable, lightweight, and unique.
apptPicker can be embedded directly into the DOM with HTML:
OR apptPickers can be created at any time (after DOM load) with JavaScript
var apptPicker = apptPicker('targetDivId').create({
start: '6:00am',
end: '6:00pm',
interval: 15,
subinterval: 120
});
apptPicker comes with an extensible API including 'on', 'toggleOpen', and 'getTimes':
var apptPicker = apptPicker('targetDivId').on('change',function(times){
console.log(times);
});


All visual expressions are always welcome, from an individual's digital art to an organization's visual display.
Upload images or links and share them with the world! Each pixel on the canvas doubles as a link.
You can buy Properties in either Ethereum or PixelPropertyToken. Properties can be traded with or sold to other users directly using PXL.
The digital canvas is similar to a visual arcade, where it costs PXL to play, and you may receive some tokens back for your consistent efforts in advancing the display.
If you create a free account, you will gain access to an exclusive members only chat. Interact with other PixelProperty users as you evolve the canvas.
Ethereum uses blockchain technology to enforce secure ownership of Properties and PXL. We have no ownership over your assets and can never freeze or alter them.