Doors
The purpose of this tutorial is to start placing doors in our dungeon. We want the doors to start out simple but be able to be expanded upon in the future.
- Doors can have 2 states: open or closed
- All doors start as closed
- A closed door blocks field-of-view
- A door can be opened by any actor (Player or Monster)
- Once a door is opened it cannot be closed again
- An actor entering the same cell as a door will open it automatically
- The symbol for a closed door will be a plus sign “+”
- The symbol for an open door will be a minus sign “-“
Setting Door Colors
We already set up the swatch of colors to use in our game but we never specified which colors doors should be. Let’s do that now. Open Colors.cs
and add the following code to pick colors from the Swatch for different parts of the door.
public static RLColor DoorBackground = Swatch.ComplimentDarkest;
public static RLColor Door = Swatch.ComplimentLighter;
public static RLColor DoorBackgroundFov = Swatch.ComplimentDarker;
public static RLColor DoorFov = Swatch.ComplimentLightest;
Creating the Door Class
Next we need a new class to represent all of the properties of a door that we outlined in our goals at the beginning. The door class should inherit from IDrawable
because we will want to draw it on the map console. Create a new file named Door.cs
in the Core
folder and place the following code in it.
public class Door : IDrawable
{
public Door()
{
Symbol = '+';
Color = Colors.Door;
BackgroundColor = Colors.DoorBackground;
}
public bool IsOpen { get; set; }
public RLColor Color { get; set; }
public RLColor BackgroundColor { get; set; }
public char Symbol { get; set; }
public int X { get; set; }
public int Y { get; set; }
public void Draw( RLConsole console, IMap map )
{
if ( !map.GetCell( X, Y ).IsExplored )
{
return;
}
Symbol = IsOpen ? '-' : '+';
if ( map.IsInFov( X, Y ) )
{
Color = Colors.DoorFov;
BackgroundColor = Colors.DoorBackgroundFov;
}
else
{
Color = Colors.Door;
BackgroundColor = Colors.DoorBackground;
}
console.Set( X, Y, Color, BackgroundColor, Symbol );
}
}
Notice that we use the colors and symbols for the door that we determined earlier.
Updating the DungeonMap Class
Before we can start placing doors in our dungeon it’s important to add a few helper methods to our DungeonMap class for working with doors. Open DungeonMap.cs
and add the following lines of code.
First add a new public property to the class at the top where we already have a list of rooms.
public List<Door> Doors { get; set; }
Be sure to initialize this list in the constructor
public DungeonMap()
{
// Previous constructor code omitted...
Doors = new List<Door>();
}
Next we need to add two new methods to the class. GetDoor(…)
and OpenDoor(…)
// Return the door at the x,y position or null if one is not found.
public Door GetDoor( int x, int y )
{
return Doors.SingleOrDefault( d => d.X == x && d.Y == y );
}
// The actor opens the door located at the x,y position
private void OpenDoor( Actor actor, int x, int y )
{
Door door = GetDoor( x, y );
if ( door != null && !door.IsOpen )
{
door.IsOpen = true;
var cell = GetCell( x, y );
// Once the door is opened it should be marked as transparent and no longer block field-of-view
SetCellProperties( x, y, true, cell.IsWalkable, cell.IsExplored );
Game.MessageLog.Add( $"{actor.Name} opened a door" );
}
}
Last we need to update SetActorPosition(…)
and call a the new method OpenDoor(…)
which we just made. Call this immediately after SetIsWalkable(…)
.
// Returns true when able to place the Actor on the cell or false otherwise
public bool SetActorPosition( Actor actor, int x, int y )
{
// Previous code omitted...
// Try to open a door if one exists here
OpenDoor( actor, x, y );
}
Note
Thanks to rmcrackan for pointing out that I forgot to show updating the Draw(…)
method to have a foreach loop for drawing each of the doors.
foreach ( Door door in Doors )
{
door.Draw( mapConsole, this );
}
Door Placement Strategy
Now that we are reasonably confident that we can draw doors and we have a few helper methods for working with them, how do we know where to put them? Think about where doors are placed in regard to rooms. They should be on an outer wall. So we should start by getting all of the cells along the boundaries of our rooms.
Once we have all of those cells we should look for any open floors that would be a good candidate for a door. And how do we know if a door should go there or not? We look at the floor’s neighboring cells to see if it fits.
A good Cell for a door placement is one that has two walls across from each other and two floors as opposing neighbors.
Updating the MapGenerator Class
Lets take the strategy that we just outlined for creating door and actually write the code. Open MapGenerator.cs
and add the following new methods.
private void CreateDoors( Rectangle room )
{
// The the boundries of the room
int xMin = room.Left;
int xMax = room.Right;
int yMin = room.Top;
int yMax = room.Bottom;
// Put the rooms border cells into a list
List<Cell> borderCells = _map.GetCellsAlongLine( xMin, yMin, xMax, yMin ).ToList();
borderCells.AddRange( _map.GetCellsAlongLine( xMin, yMin, xMin, yMax ) );
borderCells.AddRange( _map.GetCellsAlongLine( xMin, yMax, xMax, yMax ) );
borderCells.AddRange( _map.GetCellsAlongLine( xMax, yMin, xMax, yMax ) );
// Go through each of the rooms border cells and look for locations to place doors.
foreach ( Cell cell in borderCells )
{
if ( IsPotentialDoor( cell ) )
{
// A door must block field-of-view when it is closed.
_map.SetCellProperties( cell.X, cell.Y, false, true );
_map.Doors.Add( new Door
{
X = cell.X,
Y = cell.Y,
IsOpen = false
} );
}
}
}
// Checks to see if a cell is a good candidate for placement of a door
private bool IsPotentialDoor( Cell cell )
{
// If the cell is not walkable
// then it is a wall and not a good place for a door
if ( !cell.IsWalkable )
{
return false;
}
// Store references to all of the neighboring cells
Cell right = _map.GetCell( cell.X + 1, cell.Y );
Cell left = _map.GetCell( cell.X - 1, cell.Y );
Cell top = _map.GetCell( cell.X, cell.Y - 1 );
Cell bottom = _map.GetCell( cell.X, cell.Y + 1 );
// Make sure there is not already a door here
if ( _map.GetDoor( cell.X, cell.Y ) != null ||
_map.GetDoor( right.X, right.Y ) != null ||
_map.GetDoor( left.X, left.Y ) != null ||
_map.GetDoor( top.X, top.Y ) != null ||
_map.GetDoor( bottom.X, bottom.Y ) != null )
{
return false;
}
// This is a good place for a door on the left or right side of the room
if ( right.IsWalkable && left.IsWalkable && !top.IsWalkable && !bottom.IsWalkable )
{
return true;
}
// This is a good place for a door on the top or bottom of the room
if ( !right.IsWalkable && !left.IsWalkable && top.IsWalkable && bottom.IsWalkable )
{
return true;
}
return false;
}
That’s quite a bit of code but I hope that the comments help to understand what it is accomplishing. Now that we have the methods in place, we need to remember to call them. In the CreateMap() method we have a foreach where we call CreateRoom() on each room in the map. We also need to put a call for CreateDoors() in there.
// Iterate through each room that we wanted placed
// and dig out the room and create doors for it.
foreach ( Rectangle room in _map.Rooms )
{
CreateRoom( room );
CreateDoors( room );
}
If we run the program now we should see our doors in place and working as expected!
Code on GitHub
As always the code for the tutorial series so far can be found on GitHub:
Bored waiting for the next tutorial? The complete tutorial project is already finished and the source code is available on Github:
- Sample Roguelike game using RogueSharp and RLNet console
- Sample Roguelike game using RogueSharp and SadConsole


Wall Street starts holiday-shortened day in red
by Eren Sengezer- Falling crude oil prices drag energy shares lower.
- Defensive sectors post small daily gains on Friday.
Wall Street's main indexes started the day in the negative territory on Friday as investors returned from the Thanksgiving Day holiday break. As of writing, the Dow Jones Industrial Average was down 0.3% on the day while the S&P 500 and the Nasdaq Composite were both erasing 0.25%.
Stocks markets in the US will close early today and investors could look to book their profits on the last trading day of November following this week's rally that lifted them to fresh all-time highs.
Among the 11 major S&P 500 sectors, the Energy Index is losing 0.7% pressured by a 2.8% drop in crude oil prices. On the other hand, the defensive sectors, Utilities, Real Estate and Consumer Staples, are posting small daily gains to reflect a sour market mood.


Home
Our Clients
About Us
Jobs
We're not actively hiring now.
Please "Like"
our Facebook page
to get updates on future new openings.


--- layout: page title: Governance permalink: /governance/ ---
Student Robotics is governed by a Board of Trustees who are responsible for ensuring that we use our resources effectively to achieve our charitable goals. The way that we work is laid down in our constitution.
Members play an important role in supporting the Board of Trustees, contributing to the organisation's strategic direction and holding the Trustees to account.
Trustees and Members are volunteers. All Student Robotics volunteers (past and present) are invited to apply to become a Member of the charity. Anyone who is interested in becoming a Trustee who has the interest, time and skills to make a meaningful contribution to managing the charity should get in touch.
Diane works for the Raspberry Pi Foundation. She was previously Head of Computer Science at a Collyer's Sixth Form College in Horsham and has been involved in Student Robotics as a team supervisor since 2013. Diane became a Trustee in January 2018.
David is a retired teacher from Hills Road Sixth Form College, teaching physics and electronics A-level. He has been involved in sixth form robotics competitions since 2001 and has taken part in Student Robotics since 2012. He became a Trustee in January 2018.
Thomas, more commonly known as "Scarzy", is an electronics consultant based in Surrey. He started volunteering for Student Robotics when he joined Southampton Uni in 2009, and became a trustee in November 2020.


protected fun onParse(text: CharSequence): ResultType
Overrides AbstractTextParser.onParse
The method that is invoked on implementing subclasses in order to parse a specific (eventually pre-processed) text.


Locations
Froopyland
63
Froopyland
Artificially generated world
Replacement Dimension
['https://rickandmortyapi.com/api/character/350']


A manual game of tic tac toe, assumes two players and notifies when both one player or the other wins.


Cierra MiKayla Vereen was born to Angela Turner and Christopher Vereen in Memphis, TN on March 24, 1999. She has one older sister named Jasmine Smith, and has three pets. She is an extraordinary person and always doing the right thing with an optimistic outlook on life. Her favorite colors are purple and blue.
href="mailto:cierravereen24@gmail.com?">


If you want to grow, get outside your comfort zone.
Pick yourself up, dust yourself off, and start again.
Always be yourself, unless you can be a unicorn.


External communication with a JS9 display is supported by the js9 script, which is supplied with the JS9 source code. Alternatively, if you have installed a pre-built JS9 app (js9app or Voyager), you can export a messaging script using the File->export messaging script menu option. The script will be called js9msg for js9app and vger for Voyager. Note that it is not strictly necessary to install Node.js or Electron.js to send external messages: the js9 script utilizes wget or curl under the hood.
To display the js9 script options, type:
sh> js9 --help
The js9 script supports two types of syntax:
The console syntax offers a restricted set of commands suitable for quick interactive use. Results are returned as simple strings:
sh> js9 cmap heat # change colormap to heat OK sh> js9 cmap # return the current colormap heatThe console commands include:
analysis list/run analysis for current image (run) colormap set/get colormap for current image (cmap) colormaps get list of available colormaps (cmaps) global set/get a JS9.globalOpts parameter grid set/get coordinate grid for current image help get list of available commands helper set/get helper connection image get name of current image or display specified image images get list of currently loaded images load load image(s) pan set/get pan location for current image pix2wcs get image pixel value for specified wcs position print print image window refresh refresh image using specified file (def: use last file) regcnts counts in regions for current image regions add or list region(s) (reg, region) resize set/get display size for current image scale set/get scaling for current image scales get list of available scales section display section of current image status get status for specified (or current) image url display a url wcssys set/get wcs system for current image wcsu set/get wcs units used for current image wcssystems get list of available wcs systems wcsunits get list of available wcs units wcs2pix get wcs position for specified image pixel zoom set/get zoom for current image
The JS9 Public API syntax offers the full power of the public API. It passes and returns JSON-formatted strings with a richer set of options than is available via the console syntax:
# add a red circle region sh> js9 AddRegions circle '{"color":"red", "tags": "foo"}' # change color of all regions to violet and change the tags too sh> js9 ChangeRegions all '{"color":"violet","tags":"goo"}' # change color of selected regions to violet and change the tags too sh> js9 ChangeRegions selected '{"color":"violet","tags":"goo"}' # change color of red regions to violet sh> js9 ChangeRegions red '{"color":"violet"}' # change color of regions with "source" tag to violet sh> js9 ChangeRegions source '{"color":"violet"}' # get colormap sh> js9 GetColormap {"colormap":"grey","contrast":"3","bias":"0.8"} # set colormap sh> js9 SetColormap viridis 1 0.5 # get scale parameters sh> js9 GetScale {"scale":"log","scalemin":0,"scalemax":51} # set scale in a different display sh> js9 SetScale linear '{"display":"myJS9"}'Passed arguments are the same as the public API arguments, except that objects are passed as JSON strings. Returned objects are also in JSON format. Note in the last example above that the display object argument of the public API calls is supported. See JS9 Public API for more information.
An example of the use of the public API is given in the shell script below, where we load the Chandra image of the Kes 75 supernova remnant, display three energy cuts as separate images, assign red, green, and blue colormaps to the three energy cuts, and then blend them into a single display:
#!/bin/bash # Chandra event file of the Kes75 SNR file="kes75/kes75_evt2.fits.gz" # some Chandra energy filters filter[1]="energy=500:1500" filter[2]="energy=1500:2500" filter[3]="energy=2500:8000" # RGB colormaps cmap[1]="red" cmap[2]="green" cmap[3]="blue" # load event file echo "loading event file: $file" js9load $file # turn blending off (since default is on) js9 BlendImage false # process each of the event filters for i in {1..3}; do echo "filter: ${filter[$i]}" # generate section using event filter into a separately displayed image js9 DisplaySection '{"filter":"'${filter[$i]}'","separate":true}' # this actually takes a bit of time sleep 4 j=`expr $i + 1` # the new file with have a <n> string appended to the original id id="kes75_evt2.fits.gz[EVENTS]<$j>" # set image scale and assign one of the RGB colormaps js9 SetScale "log" '{"display":"'$id'"}' js9 SetColormap "${cmap[$i]}" '{"display":"'$id'"}' done # blend all the images js9 BlendDisplay true echo "all done!"Note the use of the js9load script to load an image. This auxiliary script uses the Load and GetLoadStatus API calls to load an image and wait for completion before returning. The default wait time is 10 seconds, but is configurable on the command line.
The rules governing whether a js9 script can talk to a JS9 instance are determined by the globalOpts.remoteMsgs property supplied to the back-end helper at start-up. The options are:
If a JS9 instance is connected to a helper on a remote host, you can use the --host or --helper switch to specify the remote host to contact. For example, if the helper is running on js9.cfa.harvard.edu, you can send a command to your instance of JS9 this way:
sh> js9 --host https://js9.si.edu:443 region circle OK(Note that the main JS9 web site uses a reverse proxy to communicate with an internal-facing JS9 helper. You send a message to the main web server port 443, and it is relayed to the helper listening internally on port 2718.)
If more than one instance of JS9 appears on a single web page, the --id switch can differentiate between instances. The value of the id switch is the div id for that JS9 instance. For example, if two instances of JS9 having div ids of "JS9" and "myJS9" are defined on the same page, then js9 can communicate with the latter in this way:
sh> js9 --id myJS9 region circle OK sh> js9 --id myJS9 region ICRS; circle(23:23:26.929, +58:48:50.381, 14.76")or, from the readline loop:
sh> js9 --id myJS9 JS9> region circle(23:23:26.929, +58:48:50.381, 14.76") OK JS9> region ICRS; circle(23:23:26.929, +58:48:50.381, 14.76")
Putting the last two techniques together, you can talk to one of many JS9 instances on a page connected to a remote helper this way:
sh> js9 --host https://js9.si.edu:443 --id myJS9 cmap heat OK
NB: The following options are available with the canonical js9 script, but not with the script that is exported from a pre-built JS9 app using the File->export messaging script menu option. These options require you to have installed the Node.js or Electron.js, since they call js9Msg.js under the hood.
If the -p or --pipe switch is supplied, the script will read commands from stdin. You can send multiple commands to the script's standard input (comments and blank lines are ignored):
sh> cat test.cmds # colormap cmap heat # scale scale log # regions using image coords region circle {"x":588, "y":590, "radius":30, "tags":"source"} region circle {"x":390, "y":430, "radius":50, "tags":"background"} sh> cat test.cmds | js9 -
DS9/Funtools region syntax can also be used for regions:
sh> cat test2.cmds cmap heat scale log wcssys fk5 region box(23:23:35.236,+58:50:00.95,39.352",20.1679",24.0163) region ellipse(23:23:33.323,+58:47:41.50,29.6394",11.0139",25.7599) region polygon(23:23:19.379,+58:49:30.02,23:23:17.270,+58:49:40.93,23:23:14.834,+58:49:38.59,23:23:17.974,+58:49:13.64) {"tags": "background"} sh> cat test2.cmds | js9 -
The -p or --pipe switch also allows you to specify a string on the JS9 command line that will prefix all lines read from stdin. This allows you to send a regions file to JS9:
sh> cat ds9.reg # Region file format: DS9 version 4.1 global color=green dashlist=8 3 width=1 font="helvetica 10 normal roman" select=1 highlite=1 dash=0 fixed=0 edit=1 move=1 delete=1 include=1 source=1 fk5 box(23:23:35.236,+58:50:00.95,39.352",20.1679",24.0163) ellipse(23:23:33.323,+58:47:41.50,29.6394",11.0139",25.7599) polygon(23:23:19.379,+58:49:30.02,23:23:17.270,+58:49:40.93,23:23:14.834,+58:49:38.59,23:23:17.974,+58:49:13.64) # background sh> cat ds9.reg | js9 - regionWithout the - ("dash") argument, standard input will not be read and the "region" command will be executed to return current regions.
Ordinarily, the js9 script talks to a displayed JS9 web page. It also can be used to start the JS9 Desktop app and load an image into the app's web page. The JS9 Desktop app simply requires that you install Electron.js, which is available here:
https://www.electronjs.org/Once this is done, use the -a switch to specify the app startup and the -w or --webpage switch to specify a web page (default is a nice, basic JS9 web page).
sh> js9 -a ~/data/casa.fitswill start the JS9 Desktop app with a basic JS9 web page and load the Cas-A FITS files into the page, while:
sh> js9 -a --webpage ~/js9/js9basics.html ~/data/casa.fitswill display the same image in one of the JS9 demo pages. For more details, see: Desktop JS9.
The js9 script also can be used to start up a new browser, display a JS9 web page, and then load an image into that page. To do this, use the -b or --browser switch to specify the browser (chrome, safari, or firefox) and the -w or --webpage switch to specify a web page (default is a basic JS9 web page). For example:
sh> js9 -b chrome ~/data/casa.fitswill start a Chrome browser with a basic JS9 web page and load the Cas-A FITS files into the page, while:
sh> js9 -b firefox -w ~/js9/js9basics.html ~/data/casa.fitswill use Firefox to display the same image in one of the JS9 demo pages.
Instead of supplying the browser name each time on the command line, you can set the environment variable JS9_BROWSER and just use the -b switch with no argument. (Note that you still must supply the -b switch, which tells the script to start a browser.) Similarly, the default web page can be configured using the JS9_WEBPAGE environment variable:
sh> export JS9_BROWSER=chrome sh> export JS9_WEBPAGE=$HOME/js9/js9basics.html sh> js9 -b ~/data/casa.fits
Care must be taken that no JS9 web page is already being displayed when the -b or --browser switch is utilized, or else the specified image will be loaded into the existing web page (and no new browser will be started). Also, it is important to note that the Google Chrome browser must be started by the js9 script or it must be started by you using the --allow-file-access-from-files switch. Without this switch, Chrome will not permit a local HTML file to read other files. Finally, Mac OSX Safari occasionally experiences delayed data transfers when the js9 messaging script is located in a different Space (desktop) from the browser window, so keep these in the same Space.
If you do not have access to the js9 script, you can still send messages to a JS9 web page using wget or curl. This is possible because the JS9 helper also listens for HTTP connections. The syntax for HTTP-based commands is analogous to the scripting syntax, if somewhat more primitive: you pass a JSON-formatted string to the helper in a GET or POST request, as show below.
export MYHOST="https://js9.si.edu:443" export ID="JS9" export WARGS="-q -O-" # GET request, using public api: wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "GetColormap"}' wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "SetColormap", "args": ["red"]}' wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "RunAnalysis", "args": ["counts"]}' # GET request, using command line api: wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "zoom"}' wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "zoom", "args": [2]}' wget $WARGS $MYHOST'/msg?{"id": "'$ID'", "cmd": "analysis", "args": ["counts"]}' # POST request, using public api: wget $WARGS --post-data='{"id": "'$ID'", "cmd": "GetColormap"}' $MYHOST/msg wget $WARGS --post-data='{"id": "'$ID'", "cmd": "SetColormap", "args": ["red"]}' $MYHOST/msg wget $WARGS --post-data='{"id": "'$ID'", "cmd": "RunAnalysis", "args": ["counts"]}' $MYHOST/msg


We are a group of students from WPI who are desinging and constructing an autonomous boat to compete in the Microtransat challenge in 2020. We hope that by incorportaing new technolgies we can demonstrate the capabilities of these technologies as well as break the mictrotransat speed record.
Talk about our boat here
Using a large array of solar panels and batteries the boat can maintain thrust continually and power the onboard computer and navigation. This allows for long distance travel at a useful speed without the need for fossile fuels.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sit amet nisl dapibus, malesuada odio a, molestie nunc. Aliquam erat volutpat. Aliquam imperdiet, ex vitae congue mollis, dui felis auctor metus, quis dictum magna sem ac neque.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sit amet nisl dapibus, malesuada odio a, molestie nunc. Aliquam erat volutpat. Aliquam imperdiet, ex vitae congue mollis, dui felis auctor metus, quis dictum magna sem ac neque.


Classes
Ballot
BallotDropLocation
BallotDropLocationController
BallotResponse
CampaignIssue
Candidate
CandidateBallot
CandidateController
CandidateStatement
Contest
ContestController
Contrib
CustomBallot
CustomNote
Election
ElectionAdministration
ElectionAdministrationController
ElectionController
ElectionOfficial
ElectionOfficialController
Locality
LocalityController
PollingLocation
PollingLocationController
Precinct
PrecinctController
PrecinctSplit
PrecinctSplitsController
RailsVip::Routing::MapperExtensions
Referendum
Source
SourceController
State
StateController
StreetAddress
StreetSegment
StreetSegmentController
TabulationArea
TabulationAreaController
UnresolvedId
VipHandler
VipParser


Here's a paragraph. Inside it we can have a span. It does nothing really, without CSS. We can go to the other row here but it won't work, though.
Here's another paragraph. Here's a strong tag as well as em tag. We can go to the other row here. And have a oC or log2 displayed for example
This won't have extra spaces
This will have extra spaces
This will be styled by css. This will be styled by css. This will be styled by css. This will be styled by css.
This pre tag should not be enlarged by child rules, but by descendant.
Success consists of going from failure to failure without loss of enthusiasm.
Success consists of going from failure to failure without loss of enthusiasm.
| No. | Title | Name | Surname |
|---|---|---|---|
| 1 | Mr. | Petar | Petrovic |
| 2 | Jovan | Jovanovic | |
| 3 | Mrs. | Marija | Markovic |
| Total students | 3 |


_Magnolia_ (R) **** (out of ****)
A faceless narrator ruminates on the nature of chance and fate by telling of three different inexplicable occurrences through time. The most interesting anecdote is one where a young man's attempt at a suicidal fall is botched mid-plunge--when he ends up the victim of a murder to which he was an accessory. The convoluted mechanics of this strange--make that _freak_--occurrence are analyzed in exhaustive detail, complete with a visual breakdown by telestrator. It's not exactly the most obvious way to open any film about the anguished lives of a cross-section of people in Los Angeles' San Fernando Valley, but in terms of Paul Thomas Anderson's _Magnolia_, it is the perfect curtain- and eyebrow-raiser for three hours of the director's astonishingly powerful and audacious vision.
Anderson follows that bold prologue with an introductory sequence that can only be described as being cinematically alive. As a TV blares the ridiculously macho propaganda of male self-help guru Frank T.J. Mackey (Tom Cruise), one by one we're introduced to the characters, storylines, and relationships that intertwine over one eventful 24-hour period detailed in the film. Cancer-stricken television producer Earl Partridge (Jason Robards) is on his deathbed, being tended to by his nurse, Phil Parma (Philip Seymour Hoffman), as his much younger trophy wife, Linda (Julianne Moore) searches in vain for a way to cope. Elsewhere in the Valley is another terminal cancer victim, Jimmy Gator (Philip Baker Hall), who hasn't yet let his estranged, drug-addicted daughter Claudia (Melora Walters) know about his condition. In the meantime, he continues his long-running hosting duties on the popular kids-versus-adults quiz show _What_Do_Kids_Know?_, whose current champion is child genius Stanley Spector (Jeremy Blackman). Serving as a counterpoint to Stanley's progression is the downward slide of Donnie Smith (William H. Macy), a former champion of the same show back in the '60s. Patrolling the Valley streets while talking to an invisible partner is Officer Jim Kurring (John C. Reilly).
This highly kinetic sequence, fueled by energized editing and camera work, is ultimately held together by the song that plays in the background, a tune that succinctly sums up the main feeling of the characters and the film itself: Aimee Mann's cover of "One"--as in, "one is the loneliest number." Isolation is the primary theme of _Magnolia_, and the overwhelming pain that comes with the state its primary mood; as the characters each seek out connection and comfort, Anderson masterfully uses music to express that which is neither seen nor spoken. For a non-musical film, _Magnolia_ is highly dependent on the music; there is nary a moment where either a song (usually by Mann, contributed seven to the film) or Jon Brion's instrumental score is playing in the background. Sometimes Anderson even has score and songs playing concurrently, and a number of times the music takes the foreground and the dialogue recedes into the background (most notably in the film's final scenes); both are bold moves, and they prove to be highly effective in showing the urgency of emotion that burns beneath the surface.
But no example of Anderson's use of music is as ingenius as in one bound-to-be-discussed scene that occurs about two-thirds into the film. As all the characters appear to be at their lowest, most uncertain point, the action completely stops and each person, regardless of where they are, sings along to Mann's somber "Wise Up." The tune is not playing on anyone's stereo as source music; it simply plays on the film's soundtrack, and everyone relates their pain through the song, whose chorus goes, "It's not going to stop 'til you wise up." The idea sounds ridiculous and almost overly cutesy on paper, but the scene sends chills while watching it unfold onscreen. When the signature line is sung for the final time, with the altered lyric "It's not going to stop, so just _give_up_"--it packs a stunning wallop.
Of course, such an experimental, for lack of a better term, "stunt" would not work if the audience does not care for any of the characters. While _Magnolia_ runs three hours, Anderson still has only so much screen time to divide between its large canvas of players, and it's a testimony to his writing and directing skill and the ability of the actors that everyone comes across as a fully-realized human being. The cast is absolutely flawless, with Cruise undoubtedly set to get the lion's share of attention for his showy, likely-to-be-Oscar-nominated work. The recognition would be well-deserved, but I found myself even more impressed with others in the ensemble. Moore is particularly strong, gradually revealing the tenderness that lies beneath her character's shrewish bitterness; the moment where Linda is finally able to be honest about her feelings to another and to herself is shattering. Walters and Reilly are called on to navigate the film's central romantic thread, and their oddball characters' pairing is at once comically eccentric and genuinely endearing. Then there's the bound-to-be-unsung hero by the name of Philip Seymour Hoffman. The role of loyal and nice nurse Phil is far from the film's flashiest (not surprisingly, that distinction goes to Cruise's), but it's one of those critical parts that, if done completely wrong, could short-circuit the entire film. That Hoffman's work is likely to go unrecognized says everything about the quality of his performance.
The idea of the inexplicable--and Anderson's courageously go-for-broke creative approach--comes to a head during the film's climax, when something indeed beyond reason takes place, serving as a unifying force between all the characters and plotlines. I will not give it away, but the development not quite as out-of-left-field as some people suggest; it is, in fact, very subtly foreshadowed throughout the course of the movie. Nonetheless, it _is_ quite a jarring turn, but by that point I was willing to go anywhere the boundlessly imaginative Anderson was leading. That's the sign of a true film artist at work, and the proof is the moving, magnificent masterwork that is _Magnolia_.
Michael Dequina<EMAIL_ADDRESS>|<EMAIL_ADDRESS>|<EMAIL_ADDRESS>|<EMAIL_ADDRESS>Mr. Brown's Movie Site: http://welcome.to/mrbrown CinemaReview Magazine: http://www.CinemaReview.com on ICQ: #25289934 | on AOL Instant Messenger: MrBrown23
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


Normal to
Surface
Surface
Incident
Angle = 50°
Angle = 50°
Reflected
Angle = 50°
Angle = 50°
(n = refractive index, Θ = angle)
(Because n = n in a reflection...)
(The n's cancel...)
(Leaving Θ(i) = Θ(r))
(Because n = n in a reflection...)
(The n's cancel...)
(Leaving Θ(i) = Θ(r))
n sin Θ(i) = n sin Θ(r)
n sin 50° = n sin Θ(r)
sin 50° = sin Θ(r)
50° = Θ(r)
n sin 50° = n sin Θ(r)
sin 50° = sin Θ(r)
50° = Θ(r)
Loaded: 100%


Home
Posts
Users
Clubs
Reference
Book
Worms
My name's Vince and I like to read.
Vincent Hart
War and Peace
Mountains
Name
Club
Favorite Book
Post Title
Date Posted
Posts
Vincent Hart
Mountains
War and Peace
Leo does it again... wow! Just wow.
February 24th
Posts
Name
Club
Favorite Book
Post Title
Date Posted
Posts
Vincent Hart
Mountains
War and Peace
I just read "The Mezzanine" by Nicholson Baker and thoroughly enjoyed myself.
February 11th
Posts
Name
Club
Favorite Book
Post Title
Date Posted
Posts
Vincent Hart
Mountains
War and Peace
Never again! Dr. Seuss ruins my day for the last time!
January 29th
Posts


White on roll, cube action?
pips White=87 Black=110
(CorrectAnswer= 0/0, ErrorScore= 0)
No redouble Player Winning Chances: 83.374% (G:35.953% B:1.848%) Opponent Winning Chances: 16.626% (G:1.597% B:0.025%) Redouble/Take Player Winning Chances: 83.515% (G:35.238% B:1.796%) Opponent Winning Chances: 16.485% (G:1.461% B:0.026%) Cubeless Equities: No double=+1.0293 Double=+2.0515 Cubeful Equities No redouble: +1.1643 Redouble/Take: +1.9395 (+0.7752) Redouble/Pass: +1.0000 (-0.1643) Best Cube action: Too good to redouble / Pass Percentage of wrong take needed to make the double decision right: 17.5%


FlightSurety
Flight
Submit to Oracles
Airline Management
Airlines
Register Airline
Get registered Airlines
Give fund
Flights Management
Flight number
Register Flight
Flight
Flight Key
Status
Departure
Airline
Insurance Management
Flight Key
Buy Insurance
Passenger Refunding
Withdraw


Discontinued software - DONT USE - only for educational purpose - KomodoPlatform/Agama
Andy05-Jun-19 03:12 PM
hi @Deleted User
Dependency management is very difficult. I mean they use a lot of custom repos, which is actually good if they are the ones maintaining them
And very bad if it's just a random repo
jl777c05-Jun-19 03:13 PM
yes, agama was specifically targeted with an exploit in an upstream module
Andy05-Jun-19 03:14 PM
I've been thinking a lot about how we can make apps more secure and not (or less) vulnerable to those kind of attacks. But it's hard...
There is basically no way of protecting yourself unless you can ensure that your code is run BEFORE ANY OTHER CODE, which is just not the case in most situations...
Deleted User05-Jun-19 03:14 PM
how bout not using 10 different bitcoinjs forks when bitgo one supports most of alts out of box
also two sha256 modules when js does that already
Andy05-Jun-19 03:15 PM
Well yeah that is definitely true ;).
Deleted User05-Jun-19 03:15 PM
but that’s just my opinion
Andy05-Jun-19 03:15 PM
But we'll see where the hack originated
They said it's something specifically targeted at agama, so maybe agama-wallet-lib?
Last week I've gone down the rabbit hole of trying to secure our library and sadly I wasn't satisfied with the options we have. Is anyone else interested in starting a small group where we can discuss best-practices regarding dependency management, specifically in the crypto space?
It happened to bitpay, now to agama. We found a vulnerability that was luckily never exploited, but it affected bitpay, Ark, our wallet. So it's only a matter of time until it happens again.
I don't know who else is here, we have 3 wallets and the app from unko. I know that the maintainer of web3 would also be interested to talk about that.
Deleted User05-Jun-19 04:15 PM
@Andy what vulnerability?
Deleted User05-Jun-19 05:23 PM
can anyone ping me when the CVE is released? am developer of largest tipbot on discord rn and i'd like to know my users are not affected
jl777c05-Jun-19 05:25 PM
unless you used agama code, you are safe
Deleted User05-Jun-19 05:27 PM
oki
Deleted User05-Jun-19 08:10 PM
CVE released yet?
jl777c05-Jun-19 08:11 PM
havent seen it yet
they did remove the offending package
so if your code builds fine now, it means for sure you are not affected
Deleted User05-Jun-19 08:12 PM
@jl777c what was the package?
Andy05-Jun-19 09:13 PM
@Deleted User We found a bug in the native implementation of the ionic-webview plugin. To serve the content, they started an internal server. But this server is accessible to the whole operating system, so if you manage to start your own server before it, then someone could inject any code into your app. Granted, it's not that easy to exploit. But not only crypto-currency related apps were affected, we even found a microsoft app that was affected. Here's a small proof of concept video we made: https://www.youtube.com/watch?v=RR1r323otOQ(edited)
You will have to release an app to the app store, but the webserver keeps running for minutes after the app has been suspended
You can set it in the config, but everyone leaves it on the default
But the webserver is now gone from the plugin, so this is not an issue anymore
And it might seem like it's hard to exploit, but if you release some kind of "companion app" for bitpay, for example a contact book or something that then deeplinks into bitpay (not sure if they enabled it), then it would be very easy and completely invisible to the user.
Deleted User05-Jun-19 09:16 PM
true
Andy05-Jun-19 09:17 PM
But the apps we reported it to did fix it fast, so it was all good
That attack would also have to be planned really well, so I guess it's easier to just inject code into some random npm dependency
Do you manually review (the code) of the dependencies you use?
I have always taken a look at the dependencies we use (author, if it's maintained, etc.), but you would also have to check the compiled code on npm to be completely sure
I'm now thinking about simply copy/pasting the dependencies directly into our app, at least the ones that don't have too many dependencies themselves(edited)
And then you just have to check updates manually
Ideally there would be a way to "recursively" add dependencies directly from github, so it would always pull the source rather than some minified version(edited)
But you would still have to review every sub dependency...
It's like, once you go down that rabbit hole, you'll probably only be doing dependency review the whole day. But especially in our field it is getting more and more important.
Anyway, I'm curious how this attack looked like exactly, then we can think about how we can protect ourselves from it in the future.
1
Deleted User05-Jun-19 09:24 PM
i don't really hhave many dependencies
Andy05-Jun-19 09:25 PM
Have you checked how many you have in total (including sub-dependencies)?
Deleted User05-Jun-19 09:25 PM
i use package lock etc
Andy05-Jun-19 09:25 PM
Can a package on npm not be changed once hit has been released? (a specific version)
Deleted User05-Jun-19 09:26 PM
well a version cannot be overriden i believe
Andy05-Jun-19 09:26 PM
And if then probably the hash would change in the package lock
Deleted User05-Jun-19 09:26 PM
use package lock and you will be stuck with the same versions, even on sub-modules
Andy05-Jun-19 09:26 PM
but then you still have to review the code that is hosted on NPM
Deleted User05-Jun-19 09:27 PM
i only use a custom fork of bitcoinjs-lib and bip32 for crypto operations
Andy05-Jun-19 09:27 PM
the scary part is that any package can just overwrite critical functions, even if you use your own libs for the critical functions
One could simply do crypto.getRandomValues = () => { return 1 } somewhere, and then your libs would probably use that...
Deleted User05-Jun-19 09:28 PM
scoping bro
lol
Andy05-Jun-19 09:28 PM
that doesn't work
Deleted User05-Jun-19 09:28 PM
really
Andy05-Jun-19 09:29 PM
it might be different in node
but in the browser you can overwrite window.crypto.getRandomValues and it is changed EVERYWHERE it is used
The only thing you can do is create a secure copy of that function at the beginning of your code, so in the case of an app in your index.html
Deleted User05-Jun-19 09:29 PM
i generated my seed outside of my app anyway
Andy05-Jun-19 09:30 PM
hopefully there was no code injected there
Deleted User05-Jun-19 09:30 PM
into my node repl?
dont htihnk so
Andy05-Jun-19 09:31 PM
yeah then it's probably pretty safe
(unless you distrust node + dependencies or your hardware RNG), but at some point you just have to trust something/someone...
Deleted User05-Jun-19 09:31 PM
true
Andy05-Jun-19 09:32 PM
There is an interesting TC39 proposal open that would solve this problem by introducing proper scoping, or "realms" into javascript: https://github.com/tc39/proposal-realms
Yesterday, the npm, Inc. security team, in collaboration with Komodo, helped protect over $13 million USD in cryptocurrency assets as we found and responded to a malware threat targeting the users of...


Functions implementing Single Source of Error state space models for purposes of time series analysis and forecasting. The package includes Exponential Smoothing, SARIMA, Complex Exponential Smoothing, Simple Moving Average, Vector Exponential Smoothing in state space forms, several simulation functions and intermittent demand state space models.
| Version: | 2.4.7 |
| Depends: | R (≥ 3.0.2), greybox (≥ 0.3.3) |
| Imports: | Rcpp (≥ 0.12.3), stats, graphics, forecast, nloptr, utils, zoo |
| LinkingTo: | Rcpp, RcppArmadillo (≥ <IP_ADDRESS>.0) |
| Suggests: | Mcomp, numDeriv, testthat, knitr, rmarkdown |
| Published: | 2018-12-02 |
| Author: | Ivan Svetunkov [aut, cre] (Lecturer at Centre for Marketing Analytics and Forecasting, Lancaster University, UK) |
| Maintainer: | Ivan Svetunkov <ivan at svetunkov.ru> |
| BugReports: | https://github.com/config-i1/smooth/issues |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| URL: | https://github.com/config-i1/smooth |
| NeedsCompilation: | yes |
| Language: | en-GB |
| Materials: | README NEWS |
| In views: | TimeSeries |
| CRAN checks: | smooth results |
| Reference manual: | smooth.pdf |
| Vignettes: |
ces() - Complex Exponential Smoothing es() - Exponential Smoothing gum() - Generalised Univariate Model Simulate functions of the package sma() - Simple Moving Average smooth ssarima() - State-Space ARIMA ves() - Vector Exponential Smoothing |
| Package source: | smooth_2.4.7.tar.gz |
| Windows binaries: | r-devel: smooth_2.4.7.zip, r-release: smooth_2.4.7.zip, r-oldrel: smooth_2.4.7.zip |
| OS X binaries: | r-release: smooth_2.4.7.tgz, r-oldrel: smooth_2.4.7.tgz |
| Old sources: | smooth archive |
| Reverse depends: | MAPA |
| Reverse suggests: | greybox |
Please use the canonical form https://CRAN.R-project.org/package=smooth to link to this page.


“we are glad, we were able to help you today and we so appreciate your business.
We would love it if you shared this experience.
Seeing glowing reviews from existing customers makes others more comfortable
knowing they’ll get the support they need should an issue
with our services arise.”


| < Day Day Up > |
Chapter 3. Compiling and InstallingSquid is designed to be portable and should compile on all major Unix systems, including Linux, BSD/OS, FreeBSD, NetBSD, OpenBSD, Solaris, HP-UX, OSF/DUNIX/TRU-64, Mac OS/X, IRIX, and AIX. Squid also runs on Microsoft Windows. Please see Appendix E for instructions on compiling and running Squid on Windows. Compiling Squid is relatively straightforward. If you've installed more than a few open source packages, you're probably already familiar with the procedure. You first use a program called ./configure to probe your system and then a program called make to do the actual compiling. Before getting to that step, however, let's talk about tuning your system in preparation for Squid. Your operating system may have default resource limits that are too low for Squid to run correctly. Most importantly, you need to worry about the number of available file descriptors. |
| < Day Day Up > |


Simple Marker with latlng="[51.505, -0.09]"
Simple Marker with latlng="Brampton, Canada"
Enter Address:
Marker with an event, on-dragend="dragendHandler"
Add/Remove Markers
click on map to add a marker, click on marker to remove it.


To overcome these problems, our new approach is based in Julia.
Julia is a high-level scripting language designed for scientific computing. (
www.julialang.org)
It was specifically motivated to remove the need for multiple-language approach that we had used.
Downside of using Julia: Young and actively developed (current version 0.5) so language core and library APIs are subject to change.


Back to Daily Storage Reports
Cluster
Alert type
Path
Expr
Value
Recipients
Max Send Count
Send Count


While your BMI can be a good indicator of health, please note that if you are someone who is active with a lot of muscle mass, this calculation may not be an accurate measure of your actual well-being.
Based on your BMI, you would be categorized as “underweight”. Depending upon how low your BMI is, this could mean that it might be helpful for you to intake more calories, vitamins, and nutrients to ensure your body has the energy it needs for you to operate effectively.
Based on your BMI, you can be considered a normal weight. This likely means your body is handling calories efficiently, you get some form of consistent exercise, and do not carry a lot of fat mass. It should be noted that, even if your weight is considered normal, there are tremendous benefits to overall health if you eat a healthy diet and get some form of exercise if you are physically capable and are well enough to do so.
Based on your BMI, you can be considered overweight. This likely means that you carry some amount of extra body fat and that you may be at risk for diseases such as diabetes. Eating a healthy diet and getting some form of exercise might be helpful for you to reach a lower BMI. If you are a bodybuilder or someone who lifts weights regularly, it is likely your BMI is not accurate to your actual fitness level or health.
Based on your BMI, you can be considered obese. This likely means you carry a large amount of body fat that could eventually cause health problems such as diabetes, heart disease, or high blood pressure down the road. You would likely significantly benefit from a diet change and getting some form of consistent exercise. If you are a bodybuilder, your BMI designation could be incorrect. If not, a visit to your family physician might be helpful for you to better understand what risks you may have.


{% extends "base.html" %} {% block title %}
Medieval catalogues > UNIVERSITY AND COLLEGE LIBRARIES OF CAMBRIDGE > Corpus Christi College > Inventory, mid 16th cent.
{% endif %}25 identified entries found.
All data was derived from the List of Identifications by Professor Richard Sharpe.
{% if not printing %}
A key to codes used in the List is available (opens in new tab).{% endif %}


We want evaluate nonlinear function f(Q_i, y_i, ar_x, ar_y, c, d), where c and d are constants, and ar_x and ar_y are arrays, both fixed. x_i and y_i vary over each row of matrix. We would like to evaluate this nonlinear function concurrently across \(N\) individuals. The eventual goal is to find the \(i\) specific \(Q\) that solves the nonlinear equations.
This is a continuation of R use Apply, Sapply and dplyr Mutate to Evaluate one Function Across Rows of a Matrix
<IP_ADDRESS> Set up Input Arrays
There is a function that takes \(M=Q+P\) inputs, we want to evaluate this function \(N\) times. Each time, there are \(M\) inputs, where all but \(Q\) of the \(M\) inputs, meaning \(P\) of the \(M\) inputs, are the same. In particular, \(P=Q*N\).
\[M = Q+P = Q + Q*N\]
# it_child_count = N, the number of children
= 5
it_N_child_cnt # it_heter_param = Q, number of parameters that are heterogeneous across children
= 2
it_Q_hetpa_cnt
# P fixed parameters, nN is N dimensional, nP is P dimensional
= seq(-2, 2, length.out = it_N_child_cnt)
ar_nN_A = seq(0.1, 0.9, length.out = it_N_child_cnt)
ar_nN_alpha = c(ar_nN_A, ar_nN_alpha)
ar_nP_A_alpha = seq(1,it_N_child_cnt)/sum(seq(1,it_N_child_cnt))
ar_nN_N_choice
# N by Q varying parameters
= cbind(ar_nN_A, ar_nN_alpha, ar_nN_N_choice)
mt_nN_by_nQ_A_alpha
# Convert Matrix to Tibble
= c('fl_A', 'fl_alpha', 'fl_N')
ar_st_col_names <- as_tibble(mt_nN_by_nQ_A_alpha) %>% rename_all(~c(ar_st_col_names))
tb_nN_by_nQ_A_alpha
# Show
kable(tb_nN_by_nQ_A_alpha) %>%
kable_styling_fc()
| fl_A | fl_alpha | fl_N |
|---|---|---|
| -2 | 0.1 | 0.0666667 |
| -1 | 0.3 | 0.1333333 |
| 0 | 0.5 | 0.2000000 |
| 1 | 0.7 | 0.2666667 |
| 2 | 0.9 | 0.3333333 |
<IP_ADDRESS> Mutate over Simple Function
For this example, use a very simple function with only one type of input, all inputs are scalars.
# Define Implicit Function
<- function(fl_A, fl_alpha){
ffi_nonlinear
<- (fl_A + fl_alpha*fl_A)/(fl_A)^2
fl_out
return(fl_out)
}
Apply the function over the dataframe, note five different ways below, the third way allows for parameters to be strings.
# variable names
<- 'fl_A'
svr_fl_A <- 'fl_alpha'
svr_fl_alpha
# Evaluate
<- tb_nN_by_nQ_A_alpha %>%
tb_nN_by_nQ_A_alpha_mutate_rows mutate(fl_out_m1 = ffi_nonlinear(fl_A=.$fl_A, fl_alpha=.$fl_alpha),
fl_out_m2 = ffi_nonlinear(fl_A=`$`(., 'fl_A'), fl_alpha=`$`(., 'fl_alpha')),
fl_out_m3 = ffi_nonlinear(fl_A=.[[svr_fl_A]], fl_alpha=.[[svr_fl_alpha]]),
fl_out_m4 = ffi_nonlinear(fl_A=fl_A, fl_alpha=fl_alpha),
fl_out_m5 = ffi_nonlinear(fl_A, fl_alpha))
# print
kable(tb_nN_by_nQ_A_alpha_mutate_rows) %>% kable_styling_fc()
| fl_A | fl_alpha | fl_N | fl_out_m1 | fl_out_m2 | fl_out_m3 | fl_out_m4 | fl_out_m5 |
|---|---|---|---|---|---|---|---|
| -2 | 0.1 | 0.0666667 | -0.55 | -0.55 | -0.55 | -0.55 | -0.55 |
| -1 | 0.3 | 0.1333333 | -1.30 | -1.30 | -1.30 | -1.30 | -1.30 |
| 0 | 0.5 | 0.2000000 | NaN | NaN | NaN | NaN | NaN |
| 1 | 0.7 | 0.2666667 | 1.70 | 1.70 | 1.70 | 1.70 | 1.70 |
| 2 | 0.9 | 0.3333333 | 0.95 | 0.95 | 0.95 | 0.95 | 0.95 |
<IP_ADDRESS> Testing Function with Scalar and Arrays
Test non-linear Equation.
# Test Parameters
= 100
fl_N_agg = -1
fl_rho = ar_nN_N_choice[4]*fl_N_agg
fl_N_q = mt_nN_by_nQ_A_alpha[4,]
ar_A_alpha # Apply Function
= exp((ar_A_alpha[1] - ar_nN_A)*fl_rho)
ar_p1_s1 = (ar_A_alpha[2]/ar_nN_alpha)
ar_p1_s2 = (1/(ar_nN_alpha*fl_rho - 1))
ar_p1_s3 = (ar_p1_s1*ar_p1_s2)^ar_p1_s3
ar_p1 = fl_N_q^((ar_A_alpha[2]*fl_rho-1)/(ar_nN_alpha*fl_rho-1))
ar_p2 = ar_p1*ar_p2
ar_overall = fl_N_agg - sum(ar_overall)
fl_overall print(fl_overall)
## [1] -598.2559
Implement the non-linear problem’s evaluation using apply over all \(N\) individuals.
# Define Implicit Function
<- function(fl_A, fl_alpha, fl_N, ar_A, ar_alpha, fl_N_agg, fl_rho){
ffi_nonlin_dplyrdo # ar_A_alpha[1] is A
# ar_A_alpha[2] is alpha
# # Test Parameters
# fl_N = 100
# fl_rho = -1
# fl_N_q = 10
# Apply Function
= exp((fl_A - ar_A)*fl_rho)
ar_p1_s1 = (fl_alpha/ar_alpha)
ar_p1_s2 = (1/(ar_alpha*fl_rho - 1))
ar_p1_s3 = (ar_p1_s1*ar_p1_s2)^ar_p1_s3
ar_p1 = fl_N^((fl_alpha*fl_rho-1)/(ar_alpha*fl_rho-1))
ar_p2 = ar_p1*ar_p2
ar_overall = fl_N_agg - sum(ar_overall)
fl_overall
return(fl_overall)
}
# Parameters
= -1
fl_rho
# Evaluate Function
print(ffi_nonlin_dplyrdo(mt_nN_by_nQ_A_alpha[1,1],
1,2],
mt_nN_by_nQ_A_alpha[1,3]*fl_N_agg,
mt_nN_by_nQ_A_alpha[ ar_nN_A, ar_nN_alpha, fl_N_agg, fl_rho))
## [1] 81.86645
for (i in seq(1,dim(mt_nN_by_nQ_A_alpha)[1])){
= ffi_nonlin_dplyrdo(mt_nN_by_nQ_A_alpha[i,1],
fl_eval 2],
mt_nN_by_nQ_A_alpha[i,3]*fl_N_agg,
mt_nN_by_nQ_A_alpha[i,
ar_nN_A, ar_nN_alpha, fl_N_agg, fl_rho)print(fl_eval)
}
## [1] 81.86645
## [1] 54.48885
## [1] -65.5619
## [1] -598.2559
## [1] -3154.072
<IP_ADDRESS> Evaluate Nonlinear Function using dplyr mutate
# Define Implicit Function
<- function(fl_A, fl_alpha, fl_N, ar_A, ar_alpha, fl_N_agg, fl_rho){
ffi_nonlin_dplyrdo
# Test Parameters
# ar_A = ar_nN_A
# ar_alpha = ar_nN_alpha
# fl_N = 100
# fl_rho = -1
# fl_N_q = 10
# Apply Function
= exp((fl_A - ar_A)*fl_rho)
ar_p1_s1 = (fl_alpha/ar_alpha)
ar_p1_s2 = (1/(ar_alpha*fl_rho - 1))
ar_p1_s3 = (ar_p1_s1*ar_p1_s2)^ar_p1_s3
ar_p1 = (fl_N*fl_N_agg)^((fl_alpha*fl_rho-1)/(ar_alpha*fl_rho-1))
ar_p2 = ar_p1*ar_p2
ar_overall = fl_N_agg - sum(ar_overall)
fl_overall
return(fl_overall)
}
# fl_A, fl_alpha are from columns of tb_nN_by_nQ_A_alpha
= tb_nN_by_nQ_A_alpha %>% rowwise() %>%
tb_nN_by_nQ_A_alpha mutate(dplyr_eval = ffi_nonlin_dplyrdo(fl_A, fl_alpha, fl_N,
ar_nN_A, ar_nN_alpha,
fl_N_agg, fl_rho))# Show
kable(tb_nN_by_nQ_A_alpha) %>%
kable_styling_fc()
| fl_A | fl_alpha | fl_N | dplyr_eval |
|---|---|---|---|
| -2 | 0.1 | 0.0666667 | 81.86645 |
| -1 | 0.3 | 0.1333333 | 54.48885 |
| 0 | 0.5 | 0.2000000 | -65.56190 |
| 1 | 0.7 | 0.2666667 | -598.25595 |
| 2 | 0.9 | 0.3333333 | -3154.07226 |
3.1.2 Evaluate Choices Across States
Go back to fan’s REconTools Package, R Code Examples Repository (bookdown site), or Intro Stats with R Repository (bookdown site).
See the ff_opti_bisect_pmap_multi function from Fan’s REconTools Package, which provides a resuable function based on the algorithm worked out here.
We want evaluate linear function \(0=f(z_{ij}, x_i, y_i, \textbf{X}, \textbf{Y}, c, d)\). There are \(i\) functions that have \(i\) specific \(x\) and \(y\). For each \(i\) function, we evaluate along a grid of feasible values for \(z\), over \(j\in J\) grid points, potentially looking for the \(j\) that is closest to the root. \(\textbf{X}\) and \(\textbf{Y}\) are arrays common across the \(i\) equations, and \(c\) and \(d\) are constants.
The evaluation strategy is the following, given min and max for \(z\) that are specific for each \(j\), and given common number of grid points, generate a matrix of \(z_{ij}\). Suppose there the number of \(i\) is \(I\), and the number of grid points for \(j\) is \(J\).
- Generate a \(J \cdot I\) by \(3\) matrix where the columns are \(z,x,y\) as tibble
- Follow this Mutate to evaluate the \(f(\cdot)\) function.
- Add two categorical columns for grid levels and wich \(i\), \(i\) and \(j\) index. Plot Mutate output evaluated column categorized by \(i\) as color and \(j\) as x-axis.
<IP_ADDRESS> Set up Input Arrays
There is a function that takes \(M=Q+P\) inputs, we want to evaluate this function \(N\) times. Each time, there are \(M\) inputs, where all but \(Q\) of the \(M\) inputs, meaning \(P\) of the \(M\) inputs, are the same. In particular, \(P=Q*N\).
\[M = Q+P = Q + Q*N\]
Now we need to expand this by the number of choice grid. Each row, representing one equation, is expanded by the number of choice grids. We are graphically searching, or rather brute force searching, which means if we have 100 individuals, we want to plot out the nonlinear equation for each of these lines, and show graphically where each line crosses zero. We achieve this, by evaluating the equation for each of the 100 individuals along a grid of feasible choices.
In this problem here, the feasible choices are shared across individuals.
# Parameters
= 0.20
fl_rho = 'INDI_ID'
svr_id_var
# it_child_count = N, the number of children
= 4
it_N_child_cnt # it_heter_param = Q, number of parameters that are heterogeneous across children
= 2
it_Q_hetpa_cnt
# P fixed parameters, nN is N dimensional, nP is P dimensional
= seq(-2, 2, length.out = it_N_child_cnt)
ar_nN_A = seq(0.1, 0.9, length.out = it_N_child_cnt)
ar_nN_alpha = c(ar_nN_A, ar_nN_alpha)
ar_nP_A_alpha
# N by Q varying parameters
= cbind(ar_nN_A, ar_nN_alpha)
mt_nN_by_nQ_A_alpha
# Choice Grid for nutritional feasible choices for each
= 100
fl_N_agg = 0
fl_N_min = 3
it_N_choice_cnt_ttest = 100
it_N_choice_cnt_dense = seq(fl_N_min, fl_N_agg, length.out = it_N_choice_cnt_ttest)
ar_N_choices_ttest = seq(fl_N_min, fl_N_agg, length.out = it_N_choice_cnt_dense)
ar_N_choices_dense
# Mesh Expand
<- as_tibble(mt_nN_by_nQ_A_alpha) %>% rowid_to_column(var=svr_id_var)
tb_states_choices <- tb_states_choices %>% expand_grid(choices = ar_N_choices_ttest)
tb_states_choices_ttest <- tb_states_choices %>% expand_grid(choices = ar_N_choices_dense)
tb_states_choices_dense
# display
summary(tb_states_choices_dense)
## INDI_ID ar_nN_A ar_nN_alpha choices
## Min. :1.00 Min. :-2 Min. :0.1 Min. : 0
## 1st Qu.:1.75 1st Qu.:-1 1st Qu.:0.3 1st Qu.: 25
## Median :2.50 Median : 0 Median :0.5 Median : 50
## Mean :2.50 Mean : 0 Mean :0.5 Mean : 50
## 3rd Qu.:3.25 3rd Qu.: 1 3rd Qu.:0.7 3rd Qu.: 75
## Max. :4.00 Max. : 2 Max. :0.9 Max. :100
kable(tb_states_choices_ttest) %>%
kable_styling_fc()
| INDI_ID | ar_nN_A | ar_nN_alpha | choices |
|---|---|---|---|
| 1 | -2.0000000 | 0.1000000 | 0 |
| 1 | -2.0000000 | 0.1000000 | 50 |
| 1 | -2.0000000 | 0.1000000 | 100 |
| 2 | -0.6666667 | 0.3666667 | 0 |
| 2 | -0.6666667 | 0.3666667 | 50 |
| 2 | -0.6666667 | 0.3666667 | 100 |
| 3 | 0.6666667 | 0.6333333 | 0 |
| 3 | 0.6666667 | 0.6333333 | 50 |
| 3 | 0.6666667 | 0.6333333 | 100 |
| 4 | 2.0000000 | 0.9000000 | 0 |
| 4 | 2.0000000 | 0.9000000 | 50 |
| 4 | 2.0000000 | 0.9000000 | 100 |
3.2 Dataframe Do Anything
3.2.1 (Mx1 by N) to (MxQ by N+1)
Go back to fan’s REconTools Package, R Code Examples Repository (bookdown site), or Intro Stats with R Repository (bookdown site).
Case One: There is a dataframe with \(M\) rows, based on these \(m\) specific information, generate dataframes for each \(m\). Stack these indivdiual dataframes together and merge original \(m\) specific information in as well. The number of rows for each \(m\) is \(Q_m\), each \(m\) could have different number of expansion rows.
Generate a panel with \(M\) individuals, each individual is observed for different spans of times (uncount). Before expanding, generate individual specific normal distribution standard deviation. All individuals share the same mean, but have increasing standard deviations.
<IP_ADDRESS> Generate Dataframe with M Rows.
This is the first step, generate \(M\) rows of data, to be expanded. Each row contains the number of normal draws to make and the mean and the standard deviation for normal daraws that are \(m\) specific.
# Parameter Setups
<- 3
it_M <- 5
it_Q_max <- 1000
fl_rnorm_mu <- seq(0.01, 200, length.out=it_M)
ar_rnorm_sd <- sample.int(it_Q_max, it_M, replace=TRUE)
ar_it_q
# N by Q varying parameters
= cbind(ar_it_q, ar_rnorm_sd)
mt_data <- as_tibble(mt_data) %>% rowid_to_column(var = "ID") %>%
tb_M rename(sd = ar_rnorm_sd, Q = ar_it_q) %>%
mutate(mean = fl_rnorm_mu)
# display
kable(tb_M) %>%
kable_styling_fc()
| ID | Q | sd | mean |
|---|---|---|---|
| 1 | 1 | 0.010 | 1000 |
| 2 | 3 | 100.005 | 1000 |
| 3 | 4 | 200.000 | 1000 |
<IP_ADDRESS> Random Normal Draw Expansion
The steps are:
- do anything
- use “.$” sign to refer to variable names, or [[‘name’]]
- unnest
- left_join expanded and original
Note these all give the same results
Use dot dollar to get variables
# Generate $Q_m$ individual specific incomes, expanded different number of times for each m
<- tb_M %>% group_by(ID) %>%
tb_income do(income = rnorm(.$Q, mean=.$mean, sd=.$sd)) %>%
unnest(c(income))
# Merge back with tb_M
<- tb_income %>%
tb_income_full_dd left_join(tb_M)
# display
kable(tb_income) %>%
kable_styling_fc()
| ID | income |
|---|---|
| 1 | 999.9803 |
| 2 | 1070.1391 |
| 2 | 952.7185 |
| 2 | 893.2123 |
| 3 | 956.4050 |
| 3 | 794.7991 |
| 3 | 854.2218 |
| 3 | 874.9921 |
kable(tb_income_full_dd) %>%
kable_styling_fc()
| ID | income | Q | sd | mean |
|---|---|---|---|---|
| 1 | 999.9803 | 1 | 0.010 | 1000 |
| 2 | 1070.1391 | 3 | 100.005 | 1000 |
| 2 | 952.7185 | 3 | 100.005 | 1000 |
| 2 | 893.2123 | 3 | 100.005 | 1000 |
| 3 | 956.4050 | 4 | 200.000 | 1000 |
| 3 | 794.7991 | 4 | 200.000 | 1000 |
| 3 | 854.2218 | 4 | 200.000 | 1000 |
| 3 | 874.9921 | 4 | 200.000 | 1000 |
3.2.2 (MxP by N) to (Mx1 by 1)
Go back to fan’s REconTools Package, R Code Examples Repository (bookdown site), or Intro Stats with R Repository (bookdown site).
There is a Panel with \(M\) individuals and each individual has \(Q\) records/rows. A function generate an individual specific outcome given the \(Q\) individual specific inputs, along with shared parameters and arrays across the \(M\) individuals.
For example, suppose we have a dataframe of individual wage information from different countries, each row is an individual from one country. We want to generate country specific gini based on the individual data for each country in the dataframe. But additionally, perhaps the gini formula requires not just individual income but some additional parameters or shared dataframes as inputs.
Given the within \(m\) income observations, we can compute gini statistics that are individual specific based on the observed distribution of incomes. For this, we will use the ff_dist_gini_vector_pos.html function from REconTools.
To make this more interesting, we will generate large dataframe with more \(M\) and more \(Q\) each \(m\).
<IP_ADDRESS> Income Rows for Individuals in Many Groups
There are up to ten thousand income observation per person. And there are ten people.
# Parameter Setups
<- 10
it_M <- 10000
it_Q_max <- 1
fl_rnorm_mu <- seq(0.01, 0.2, length.out=it_M)
ar_rnorm_sd <- sample.int(it_Q_max, it_M, replace=TRUE)
ar_it_q
# N by Q varying parameters
= cbind(ar_it_q, ar_rnorm_sd)
mt_data <- as_tibble(mt_data) %>% rowid_to_column(var = "ID") %>%
tb_M rename(sd = ar_rnorm_sd, Q = ar_it_q) %>%
mutate(mean = fl_rnorm_mu)
<IP_ADDRESS> Compute Group Specific Gini
There is only one input for the gini function ar_pos. Note that the gini are not very large even with large SD, because these are normal distributions. By Construction, most peple are in the middle. So with almost zero standard deviation, we have perfect equality, as standard deviation increases, inequality increases, but still pretty equal overall, there is no fat upper tail.
Note that there are three ways of referring to variable names with dot, which are all shown below:
- We can explicitly refer to names
- We can use the dollar dot structure to use string variable names in do anything.
- We can use dot bracket, this is the only option that works with string variable names
First: Generate individual group all incomes:
# A. Normal Draw Expansion, Explicitly Name
set.seed('123')
<- tb_M %>% group_by(ID) %>%
tb_income_norm_dot_dollar do(income = rnorm(.$Q,
mean=.$mean,
sd=.$sd)) %>%
unnest(c(income)) %>%
left_join(tb_M, by="ID")
# Normal Draw Expansion again, dot dollar differently with string variable name
set.seed('123')
<- tb_M %>% group_by(ID) %>%
tb_income_norm_dollar_dot do(income = rnorm(`$`(., 'Q'),
mean = `$`(., 'mean'),
sd = `$`(., 'sd'))) %>%
unnest(c(income)) %>%
left_join(tb_M, by="ID")
# Normal Draw Expansion again, dot double bracket
set.seed('123')
<- 'mean'
svr_mean <- 'sd'
svr_sd <- 'Q'
svr_Q <- tb_M %>% group_by(ID) %>%
tb_income_norm_dot_bracket_db do(income = rnorm(.[[svr_Q]],
mean = .[[svr_mean]],
sd = .[[svr_sd]])) %>%
unnest(c(income)) %>%
left_join(tb_M, by="ID")
# display
print(dim(tb_income_norm_dot_bracket_db))
## [1] 59429 5
kable(head(tb_income_norm_dot_bracket_db, 20)) %>% kable_styling_fc()
| ID | income | Q | sd | mean |
|---|---|---|---|---|
| 1 | 0.9943952 | 3004 | 0.01 | 1 |
| 1 | 0.9976982 | 3004 | 0.01 | 1 |
| 1 | 1.0155871 | 3004 | 0.01 | 1 |
| 1 | 1.0007051 | 3004 | 0.01 | 1 |
| 1 | 1.0012929 | 3004 | 0.01 | 1 |
| 1 | 1.0171506 | 3004 | 0.01 | 1 |
| 1 | 1.0046092 | 3004 | 0.01 | 1 |
| 1 | 0.9873494 | 3004 | 0.01 | 1 |
| 1 | 0.9931315 | 3004 | 0.01 | 1 |
| 1 | 0.9955434 | 3004 | 0.01 | 1 |
| 1 | 1.0122408 | 3004 | 0.01 | 1 |
| 1 | 1.0035981 | 3004 | 0.01 | 1 |
| 1 | 1.0040077 | 3004 | 0.01 | 1 |
| 1 | 1.0011068 | 3004 | 0.01 | 1 |
| 1 | 0.9944416 | 3004 | 0.01 | 1 |
| 1 | 1.0178691 | 3004 | 0.01 | 1 |
| 1 | 1.0049785 | 3004 | 0.01 | 1 |
| 1 | 0.9803338 | 3004 | 0.01 | 1 |
| 1 | 1.0070136 | 3004 | 0.01 | 1 |
| 1 | 0.9952721 | 3004 | 0.01 | 1 |
Second, compute gini:
# Gini by Group
<- tb_income_norm_dot_bracket_db %>% group_by(ID) %>%
tb_gini_norm do(inc_gini_norm = ff_dist_gini_vector_pos(.$income)) %>%
unnest(c(inc_gini_norm)) %>%
left_join(tb_M, by="ID")
# display
kable(tb_gini_norm) %>% kable_styling_fc()
| ID | inc_gini_norm | Q | sd | mean |
|---|---|---|---|---|
| 1 | 0.0056006 | 3004 | 0.0100000 | 1 |
| 2 | 0.0174893 | 3207 | 0.0311111 | 1 |
| 3 | 0.0295527 | 7989 | 0.0522222 | 1 |
| 4 | 0.0412807 | 3995 | 0.0733333 | 1 |
| 5 | 0.0537107 | 8358 | 0.0944444 | 1 |
| 6 | 0.0650354 | 217 | 0.1155556 | 1 |
| 7 | 0.0766718 | 9506 | 0.1366667 | 1 |
| 8 | 0.0891009 | 8157 | 0.1577778 | 1 |
| 9 | 0.1014251 | 6216 | 0.1788889 | 1 |
| 10 | 0.1135054 | 8780 | 0.2000000 | 1 |
3.2.3 (MxP by N) to (MxQ by N+Z)
Go back to fan’s REconTools Package, R Code Examples Repository (bookdown site), or Intro Stats with R Repository (bookdown site).
There is a dataframe composed of M mini-dataframes. Group by a variable that identifies each unique sub-dataframe, and use the sub-dataframes with P rows as inputs to a function.
The function outputs Q by Z rows and columns of results, stack the results. The output file has MxQ rows and the Z columns of additional results should be appended.
<IP_ADDRESS> Generate the MxP by N Dataframe
M Grouping characteristics, P rows for each group, and N Variables.
- M are individuals
- P are dates
- A wage variable for individual wage at each date. And a savings varaible as well.
# Define
<- 3
it_M <- 5
it_P <- 'group_m'
svr_m <- 'info_mp'
svr_mp
# dataframe
set.seed(123)
<- as_tibble(matrix(it_P, nrow=it_M, ncol=1)) %>%
df_panel_skeleton rowid_to_column(var = svr_m) %>%
uncount(V1) %>%
group_by(!!sym(svr_m)) %>% mutate(!!sym(svr_mp) := row_number()) %>%
ungroup() %>%
rowwise() %>% mutate(wage = rnorm(1, 100, 10),
savings = rnorm(1, 200, 30)) %>%
ungroup() %>%
rowid_to_column(var = "id_ji")
# Print
kable(df_panel_skeleton) %>% kable_styling_fc()
| id_ji | group_m | info_mp | wage | savings |
|---|---|---|---|---|
| 1 | 1 | 1 | 94.39524 | 253.6074 |
| 2 | 1 | 2 | 97.69823 | 214.9355 |
| 3 | 1 | 3 | 115.58708 | 141.0015 |
| 4 | 1 | 4 | 100.70508 | 221.0407 |
| 5 | 1 | 5 | 101.29288 | 185.8163 |
| 6 | 2 | 1 | 117.15065 | 167.9653 |
| 7 | 2 | 2 | 104.60916 | 193.4608 |
| 8 | 2 | 3 | 87.34939 | 169.2199 |
| 9 | 2 | 4 | 93.13147 | 178.1333 |
| 10 | 2 | 5 | 95.54338 | 181.2488 |
| 11 | 3 | 1 | 112.24082 | 149.3992 |
| 12 | 3 | 2 | 103.59814 | 225.1336 |
| 13 | 3 | 3 | 104.00771 | 204.6012 |
| 14 | 3 | 4 | 101.10683 | 165.8559 |
| 15 | 3 | 5 | 94.44159 | 237.6144 |
<IP_ADDRESS> Subgroup Compute and Expand
Use the M sub-dataframes, generate Q by Z result for each of the M groups. Stack all results together.
Base on all the wages for each individual, generate individual specific mean and standard deviations. Do this for three things, the wage variable, the savings variable, and the sum of wage and savings:
- Z=2: 2 columns, mean and standard deviation
- Q=3: 3 rows, statistics based on wage, savings, and the sum of both
First, here is the processing function that takes the dataframe as input, with a parameter for rounding:
# define function
<- function(df_sub, it_round=1) {
ffi_subset_mean_sd #' A function that generates mean and sd for several variables
#'
#' @description
#' Assume there are two variables in df_sub wage and savings
#'
#' @param df_sub dataframe where each individual row is a different
#' data point, over which we compute mean and sd, Assum there are two
#' variables, savings and wage
#' @param it_round integer rounding for resulting dataframe
#' @return a dataframe where each row is aggregate for a different type
#' of variablea and each column is a different statistics
= mean(df_sub$wage)
fl_wage_mn = sd(df_sub$wage)
fl_wage_sd
= mean(df_sub$savings)
fl_save_mn = sd(df_sub$savings)
fl_save_sd
= mean(df_sub$wage + df_sub$savings)
fl_wgsv_mn = sd(df_sub$wage + df_sub$savings)
fl_wgsv_sd
<- c(fl_wage_mn, fl_save_mn, fl_wgsv_mn)
ar_mn <- c(fl_wage_sd, fl_save_sd, fl_wgsv_sd)
ar_sd <- c('wage', 'savings', 'wage_and_savings')
ar_st_row_lab
<- cbind(ar_mn, ar_sd)
mt_stats <- round(mt_stats, it_round)
mt_stats
<- c('mean', 'sd', 'variables')
ar_st_varnames <- as_tibble(mt_stats) %>%
df_combine add_column(ar_st_row_lab) %>%
rename_all(~c(ar_st_varnames)) %>%
select(variables, 'mean', 'sd') %>%
rowid_to_column(var = "id_q")
return(df_combine)
}# testing function
ffi_subset_mean_sd(df_panel_skeleton %>% filter(!!sym(svr_m)==1))
Second, call ffi_subset_mean_sd function for each of the groups indexed by j and stack results together with j index:
- group by
- call function
- unnest
# run group stats and stack dataframes
<- df_panel_skeleton %>% group_by(!!sym(svr_m)) %>%
df_outputs do(df_stats = ffi_subset_mean_sd(., it_round=2)) %>%
unnest() %>%
rowid_to_column(var = "id_mq")
# print
kable(df_outputs) %>% kable_styling_fc()
| id_mq | group_m | id_q | variables | mean | sd |
|---|---|---|---|---|---|
| 1 | 1 | 1 | wage | 101.94 | 8.11 |
| 2 | 1 | 2 | savings | 203.28 | 42.33 |
| 3 | 1 | 3 | wage_and_savings | 305.22 | 34.83 |
| 4 | 2 | 1 | wage | 99.56 | 11.63 |
| 5 | 2 | 2 | savings | 178.01 | 10.34 |
| 6 | 2 | 3 | wage_and_savings | 277.56 | 15.48 |
| 7 | 3 | 1 | wage | 103.08 | 6.39 |
| 8 | 3 | 2 | savings | 196.52 | 37.86 |
| 9 | 3 | 3 | wage_and_savings | 299.60 | 33.50 |
In the resulting file, we went from a matrix with MxP rows to a matrix with MxQ Rows.
3.3 Apply and pmap
3.3.1 Apply and Sapply
Go back to fan’s REconTools Package, R Code Examples Repository (bookdown site), or Intro Stats with R Repository (bookdown site).
- r apply matrix to function row by row
- r evaluate function on grid
- Apply a function to every row of a matrix or a data frame
- r apply
- r sapply
- sapply over matrix row by row
- function as parameters using formulas
- do
We want evaluate linear function f(x_i, y_i, ar_x, ar_y, c, d), where c and d are constants, and ar_x and ar_y are arrays, both fixed. x_i and y_i vary over each row of matrix. More specifically, we have a functions, this function takes inputs that are individual specific. We would like to evaluate this function concurrently across \(N\) individuals.
The function is such that across the \(N\) individuals, some of the function parameter inputs are the same, but others are different. If we are looking at demand for a particular product, the prices of all products enter the demand equation for each product, but the product’s own price enters also in a different way.
The objective is either to just evaluate this function across \(N\) individuals, or this is a part of a nonlinear solution system.
What is the relationship between apply, lapply and vectorization? see Is the “*apply” family really not vectorized?.
<IP_ADDRESS> Set up Input Arrays
There is a function that takes \(M=Q+P\) inputs, we want to evaluate this function \(N\) times. Each time, there are \(M\) inputs, where all but \(Q\) of the \(M\) inputs, meaning \(P\) of the \(M\) inputs, are the same. In particular, \(P=Q*N\).
\[M = Q+P = Q + Q*N\]
# it_child_count = N, the number of children
= 5
it_N_child_cnt # it_heter_param = Q, number of parameters that are
# heterogeneous across children
= 2
it_Q_hetpa_cnt
# P fixed parameters, nN is N dimensional, nP is P dimensional
= seq(-2, 2, length.out = it_N_child_cnt)
ar_nN_A = seq(0.1, 0.9, length.out = it_N_child_cnt)
ar_nN_alpha = c(ar_nN_A, ar_nN_alpha)
ar_nP_A_alpha
# N by Q varying parameters
= cbind(ar_nN_A, ar_nN_alpha)
mt_nN_by_nQ_A_alpha
# display
kable(mt_nN_by_nQ_A_alpha) %>%
kable_styling_fc()
| ar_nN_A | ar_nN_alpha |
|---|---|
| -2 | 0.1 |
| -1 | 0.3 |
| 0 | 0.5 |
| 1 | 0.7 |
| 2 | 0.9 |
<IP_ADDRESS> Using apply
<IP_ADDRESS>.1 Named Function
First we use the apply function, we have to hard-code the arrays that are fixed for each of the \(N\) individuals. Then apply allows us to loop over the matrix that is \(N\) by \(Q\), each row one at a time, from \(1\) to \(N\).
# Define Implicit Function
<- function(ar_A_alpha){
ffi_linear_hardcode # ar_A_alpha[1] is A
# ar_A_alpha[2] is alpha
= sum(ar_A_alpha[1]*ar_nN_A +
fl_out 1/(ar_A_alpha[2] + 1/ar_nN_alpha))
return(fl_out)
}
# Evaluate function row by row
= apply(mt_nN_by_nQ_A_alpha, 1, ffi_linear_hardcode) ar_func_apply
<IP_ADDRESS>.2 Anonymous Function
- apply over matrix
Apply with anonymous function generating a list of arrays of different lengths. In the example below, we want to drawn \(N\) sets of random uniform numbers, but for each set the number of draws we want to have is \(Q_i\). Furthermore, we want to rescale the random uniform draws so that they all become proportions that sum u pto one for each \(i\), but then we multply each row’s values by the row specific aggregates.
The anonymous function has hard coded parameters. Using an anonymous function here allows for parameters to be provided inside the function that are shared across each looped evaluation. This is perhaps more convenient than sapply with additional parameters.
set.seed(1039)
# Define the number of draws each row and total amount
<- 4
it_N <- 1
fl_unif_min <- 2
fl_unif_max <- cbind(sample(it_N, it_N, replace=TRUE),
mt_draw_define runif(it_N, min=1, max=10))
<- as_tibble(mt_draw_define) %>%
tb_draw_define rowid_to_column(var = "draw_group")
print(tb_draw_define)
# apply row by row, anonymous function has hard
# coded min and max
=
ls_ar_draws_shares_lvls apply(tb_draw_define,
1,
function(row) {
<- row[2]
it_draw <- row[3]
fl_sum <- runif(it_draw,
ar_unif min=fl_unif_min,
max=fl_unif_max)
<- ar_unif/sum(ar_unif)
ar_share <- ar_share*fl_sum
ar_levels return(list(ar_share=ar_share,
ar_levels=ar_levels))
})
# Show Results
print(ls_ar_draws_shares_lvls)
## [[1]]
## [[1]]$ar_share
## [1] 0.2783638 0.2224140 0.2797840 0.2194381
##
## [[1]]$ar_levels
## [1] 1.492414 1.192446 1.500028 1.176491
##
##
## [[2]]
## [[2]]$ar_share
## [1] 0.5052919 0.4947081
##
## [[2]]$ar_levels
## [1] 3.866528 3.785541
##
##
## [[3]]
## [[3]]$ar_share
## [1] 1
##
## [[3]]$ar_levels
## V2
## 9.572211
##
##
## [[4]]
## [[4]]$ar_share
## [1] 0.4211426 0.2909812 0.2878762
##
## [[4]]$ar_levels
## [1] 4.051971 2.799640 2.769765
We will try to do the same thing as above, but now the output will be a stacked dataframe. Note that within each element of the apply row by row loop, we are generating two variables ar_share and ar_levels. We will not generate a dataframe with multiple columns, storing ar_share, ar_levels as well as information on min, max, number of draws and rescale total sum.
set.seed(1039)
# apply row by row, anonymous function has hard coded min and max
=
ls_mt_draws_shares_lvls apply(tb_draw_define, 1, function(row) {
<- row[1]
it_draw_group <- row[2]
it_draw <- row[3]
fl_sum
<- runif(it_draw,
ar_unif min=fl_unif_min,
max=fl_unif_max)
<- ar_unif/sum(ar_unif)
ar_share <- ar_share*fl_sum
ar_levels
<- cbind(it_draw_group, it_draw, fl_sum,
mt_all_res
ar_unif, ar_share, ar_levels)colnames(mt_all_res) <-
c('draw_group', 'draw_count', 'sum',
'unif_draw', 'share', 'rescale')
rownames(mt_all_res) <- NULL
return(mt_all_res)
})<- do.call(rbind, ls_mt_draws_shares_lvls)
mt_draws_shares_lvls_all # Show Results
kable(mt_draws_shares_lvls_all) %>% kable_styling_fc()
| draw_group | draw_count | sum | unif_draw | share | rescale |
|---|---|---|---|---|---|
| 1 | 4 | 5.361378 | 1.125668 | 0.1988606 | 1.066167 |
| 1 | 4 | 5.361378 | 1.668536 | 0.2947638 | 1.580340 |
| 1 | 4 | 5.361378 | 1.419382 | 0.2507483 | 1.344356 |
| 1 | 4 | 5.361378 | 1.447001 | 0.2556274 | 1.370515 |
| 2 | 2 | 7.652069 | 1.484598 | 0.4605236 | 3.523959 |
| 2 | 2 | 7.652069 | 1.739119 | 0.5394764 | 4.128110 |
| 3 | 1 | 9.572211 | 1.952468 | 1.0000000 | 9.572211 |
| 4 | 3 | 9.621375 | 1.957931 | 0.3609352 | 3.472693 |
| 4 | 3 | 9.621375 | 1.926995 | 0.3552324 | 3.417824 |
| 4 | 3 | 9.621375 | 1.539678 | 0.2838324 | 2.730858 |
<IP_ADDRESS> Using sapply
<IP_ADDRESS>.1 Named Function
- r convert matrix to list
- Convert a matrix to a list of vectors in R
Sapply allows us to not have tohard code in the A and alpha arrays. But Sapply works over List or Vector, not Matrix. So we have to convert the \(N\) by \(Q\) matrix to a N element list Now update the function with sapply.
= as.list(data.frame(t(mt_nN_by_nQ_A_alpha)))
ls_ar_nN_by_nQ_A_alpha
# Define Implicit Function
<- function(ar_A_alpha, ar_A, ar_alpha){
ffi_linear_sapply # ar_A_alpha[1] is A
# ar_A_alpha[2] is alpha
= sum(ar_A_alpha[1]*ar_nN_A +
fl_out 1/(ar_A_alpha[2] + 1/ar_nN_alpha))
return(fl_out)
}
# Evaluate function row by row
= sapply(ls_ar_nN_by_nQ_A_alpha, ffi_linear_sapply,
ar_func_sapply ar_A=ar_nN_A, ar_alpha=ar_nN_alpha)
<IP_ADDRESS>.2 Anonymous Function
- sapply anonymous function
- r anoymous function multiple lines
Sapply with anonymous function generating a list of arrays of different lengths. In the example below, we want to drawn \(N\) sets of random uniform numbers, but for each set the number of draws we want to have is \(Q_i\). Furthermore, we want to rescale the random uniform draws so that they all become proportions that sum u pto one for each \(i\).
<- 4
it_N <- 1
fl_unif_min <- 2
fl_unif_max
# Generate using runif without anonymous function
set.seed(1039)
= sapply(seq(it_N),
ls_ar_draws
runif,min=fl_unif_min, max=fl_unif_max)
print(ls_ar_draws)
## [[1]]
## [1] 1.125668
##
## [[2]]
## [1] 1.668536 1.419382
##
## [[3]]
## [1] 1.447001 1.484598 1.739119
##
## [[4]]
## [1] 1.952468 1.957931 1.926995 1.539678
# Generate Using Anonymous Function
set.seed(1039)
= sapply(seq(it_N),
ls_ar_draws_shares function(n, min, max) {
<- runif(n,min,max)
ar_unif <- ar_unif/sum(ar_unif)
ar_share return(ar_share)
},min=fl_unif_min, max=fl_unif_max)
# Print Share
print(ls_ar_draws_shares)
## [[1]]
## [1] 1
##
## [[2]]
## [1] 0.5403432 0.4596568
##
## [[3]]
## [1] 0.3098027 0.3178522 0.3723451
##
## [[4]]
## [1] 0.2646671 0.2654076 0.2612141 0.2087113
# Sapply with anonymous function to check sums
sapply(seq(it_N), function(x) {sum(ls_ar_draws[[x]])})
## [1] 1.125668 3.087918 4.670717 7.377071
sapply(seq(it_N), function(x) {sum(ls_ar_draws_shares[[x]])})
## [1] 1 1 1 1
<IP_ADDRESS> Compare Results
# Show overall Results
<- cbind(ar_func_apply, ar_func_sapply)
mt_results colnames(mt_results) <- c('eval_lin_apply', 'eval_lin_sapply')
kable(mt_results) %>% kable_styling_fc()
| eval_lin_apply | eval_lin_sapply | |
|---|---|---|
| X1 | 2.346356 | 2.346356 |
| X2 | 2.094273 | 2.094273 |
| X3 | 1.895316 | 1.895316 |
| X4 | 1.733708 | 1.733708 |
| X5 | 1.599477 | 1.599477 |
3.3.2 Mutate Evaluate Functions
Go back to fan’s REconTools Package, R Code Examples Repository (bookdown site), or Intro Stats with R Repository (bookdown site).
Apply a function over rows of a matrix using mutate, rowwise, etc.
<IP_ADDRESS> Set up Input Arrays
There is a function that takes \(M=Q+P\) inputs, we want to evaluate this function \(N\) times. Each time, there are \(M\) inputs, where all but \(Q\) of the \(M\) inputs, meaning \(P\) of the \(M\) inputs, are the same. In particular, \(P=Q*N\).
\[M = Q+P = Q + Q*N\]
# it_child_count = N, the number of children
= 5
it_N_child_cnt # it_heter_param = Q, number of parameters that are
# heterogeneous across children
= 2
it_Q_hetpa_cnt
# P fixed parameters, nN is N dimensional, nP is P dimensional
= seq(-2, 2, length.out = it_N_child_cnt)
ar_nN_A = seq(0.1, 0.9, length.out = it_N_child_cnt)
ar_nN_alpha = c(ar_nN_A, ar_nN_alpha)
ar_nP_A_alpha
# N by Q varying parameters
= cbind(ar_nN_A, ar_nN_alpha)
mt_nN_by_nQ_A_alpha
# display
kable(mt_nN_by_nQ_A_alpha) %>%
kable_styling_fc()
| ar_nN_A | ar_nN_alpha |
|---|---|
| -2 | 0.1 |
| -1 | 0.3 |
| 0 | 0.5 |
| 1 | 0.7 |
| 2 | 0.9 |
# Convert Matrix to Tibble
= c('fl_A', 'fl_alpha')
ar_st_col_names <- as_tibble(mt_nN_by_nQ_A_alpha) %>%
tb_nN_by_nQ_A_alpha rename_all(~c(ar_st_col_names))
# Show
kable(tb_nN_by_nQ_A_alpha) %>%
kable_styling_fc()
| fl_A | fl_alpha |
|---|---|
| -2 | 0.1 |
| -1 | 0.3 |
| 0 | 0.5 |
| 1 | 0.7 |
| 2 | 0.9 |
<IP_ADDRESS> mutate rowwise
- dplyr mutate own function
- dplyr all row function
- dplyr do function
- apply function each row dplyr
- applying a function to every row of a table using dplyr
- dplyr rowwise
# Define Implicit Function
<- function(fl_A, fl_alpha, ar_nN_A, ar_nN_alpha){
ffi_linear_dplyrdo # ar_A_alpha[1] is A
# ar_A_alpha[2] is alpha
print(paste0('cur row, fl_A=', fl_A, ', fl_alpha=', fl_alpha))
= sum(fl_A*ar_nN_A + 1/(fl_alpha + 1/ar_nN_alpha))
fl_out
return(fl_out)
}
# Evaluate function row by row of tibble
# fl_A, fl_alpha are from columns of tb_nN_by_nQ_A_alpha
<- tb_nN_by_nQ_A_alpha %>%
tb_nN_by_nQ_A_alpha_show rowwise() %>%
mutate(dplyr_eval =
ffi_linear_dplyrdo(fl_A, fl_alpha, ar_nN_A, ar_nN_alpha))
## [1] "cur row, fl_A=-2, fl_alpha=0.1"
## [1] "cur row, fl_A=-1, fl_alpha=0.3"
## [1] "cur row, fl_A=0, fl_alpha=0.5"
## [1] "cur row, fl_A=1, fl_alpha=0.7"
## [1] "cur row, fl_A=2, fl_alpha=0.9"
# Show
kable(tb_nN_by_nQ_A_alpha_show) %>%
kable_styling_fc()
| fl_A | fl_alpha | dplyr_eval |
|---|---|---|
| -2 | 0.1 | 2.346356 |
| -1 | 0.3 | 2.094273 |
| 0 | 0.5 | 1.895316 |
| 1 | 0.7 | 1.733708 |
| 2 | 0.9 | 1.599477 |
same as before, still rowwise, but hard code some inputs:
# Define function, fixed inputs are not parameters, but
# defined earlier as a part of the function
# ar_nN_A, ar_nN_alpha are fixed, not parameters
<- function(fl_A, fl_alpha){
ffi_linear_dplyrdo_func <- sum(fl_A*ar_nN_A + 1/(fl_alpha + 1/ar_nN_alpha))
fl_out return(fl_out)
}
# Evaluate function row by row of tibble
= tb_nN_by_nQ_A_alpha %>% rowwise() %>%
tbfunc_A_nN_by_nQ_A_alpha_rowwise mutate(dplyr_eval = ffi_linear_dplyrdo_func(fl_A, fl_alpha))
# Show
kable(tbfunc_A_nN_by_nQ_A_alpha_rowwise) %>%
kable_styling_fc()
| fl_A | fl_alpha | dplyr_eval |
|---|---|---|
| -2 | 0.1 | 2.346356 |
| -1 | 0.3 | 2.094273 |
| 0 | 0.5 | 1.895316 |
| 1 | 0.7 | 1.733708 |
| 2 | 0.9 | 1.599477 |
<IP_ADDRESS> mutate with pmap
Apparantly rowwise() is not a good idea, and pmap should be used, below is the pmap solution to the problem. Which does seem nicer. Crucially, don’t have to define input parameter names, automatically I think they are matching up to the names in the function
- dplyr mutate pass function
- r function quosure string multiple
- r function multiple parameters as one string
- dplyr mutate anonymous function
- quosure style lambda
- pmap tibble rows
- dplyr pwalk
# Define function, fixed inputs are not parameters, but defined
# earlier as a part of the function Rorate fl_alpha and fl_A name
# compared to before to make sure pmap tracks by names
<- function(fl_alpha, fl_A){
ffi_linear_dplyrdo_func <- sum(fl_A*ar_nN_A + 1/(fl_alpha + 1/ar_nN_alpha))
fl_out return(fl_out)
}
# Evaluate a function row by row of dataframe, generate list,
# then to vector
%>% pmap(ffi_linear_dplyrdo_func) %>% unlist() tb_nN_by_nQ_A_alpha
## [1] 2.346356 2.094273 1.895316 1.733708 1.599477
# Same as above, but in line line and save output as new column
# in dataframe note this ONLY works if the tibble only has variables
# that are inputs for the function if tibble contains additional
# variables, those should be droppd, or only the ones needed selected,
# inside the pmap call below.
<- tb_nN_by_nQ_A_alpha %>%
tbfunc_A_nN_by_nQ_A_alpha_pmap mutate(dplyr_eval_pmap =
unlist(
pmap(tb_nN_by_nQ_A_alpha, ffi_linear_dplyrdo_func)
)
)
# Show
kable(tbfunc_A_nN_by_nQ_A_alpha_pmap) %>%
kable_styling_fc()
| fl_A | fl_alpha | dplyr_eval_pmap |
|---|---|---|
| -2 | 0.1 | 2.346356 |
| -1 | 0.3 | 2.094273 |
| 0 | 0.5 | 1.895316 |
| 1 | 0.7 | 1.733708 |
| 2 | 0.9 | 1.599477 |
<IP_ADDRESS> rowwise and do
Now, we have three types of parameters, for something like a bisection type calculation. We will supply the program with a function with some hard-coded value inside, and as parameters, we will have one parameter which is a row in the current matrix, and another parameter which is a sclar values. The three types of parameters are dealt with sparately:
- parameters that are fixed for all bisection iterations, but differ for each row
- these are hard-coded into the function
- parameters that are fixed for all bisection iterations, but are shared across rows
- these are the first parameter of the function, a list
- parameters that differ for each iteration, but differ acoss iterations
second scalar value parameter for the function
dplyr mutate function applow to each row dot notation
note rowwise might be bad according to Hadley, should use pmap?
<- function(ls_row, fl_param){
ffi_linear_dplyrdo_fdot # Type 1 Param = ar_nN_A, ar_nN_alpha
# Type 2 Param = ls_row$fl_A, ls_row$fl_alpha
# Type 3 Param = fl_param
<- (sum(ls_row$fl_A*ar_nN_A +
fl_out 1/(ls_row$fl_alpha + 1/ar_nN_alpha))) + fl_param
return(fl_out)
}
<- ffi_linear_dplyrdo_fdot
cur_func <- 0
fl_param <- tb_nN_by_nQ_A_alpha %>% rowwise() %>%
dplyr_eval_flex do(dplyr_eval_flex = cur_func(., fl_param)) %>%
unnest(dplyr_eval_flex)
<- tb_nN_by_nQ_A_alpha %>% add_column(dplyr_eval_flex)
tbfunc_B_nN_by_nQ_A_alpha # Show
kable(tbfunc_B_nN_by_nQ_A_alpha) %>%
kable_styling_fc()
| fl_A | fl_alpha | dplyr_eval_flex |
|---|---|---|
| -2 | 0.1 | 2.346356 |
| -1 | 0.3 | 2.094273 |
| 0 | 0.5 | 1.895316 |
| 1 | 0.7 | 1.733708 |
| 2 | 0.9 | 1.599477 |
<IP_ADDRESS> Compare Apply and Mutate Results
# Show overall Results
<- cbind(tb_nN_by_nQ_A_alpha_show['dplyr_eval'],
mt_results 'dplyr_eval'],
tbfunc_A_nN_by_nQ_A_alpha_rowwise['dplyr_eval_pmap'],
tbfunc_A_nN_by_nQ_A_alpha_pmap['dplyr_eval_flex'],
tbfunc_B_nN_by_nQ_A_alpha[
mt_nN_by_nQ_A_alpha)colnames(mt_results) <- c('eval_dplyr_mutate',
'eval_dplyr_mutate_hcode',
'eval_dplyr_mutate_pmap',
'eval_dplyr_mutate_flex',
'A_child', 'alpha_child')
kable(mt_results) %>%
kable_styling_fc_wide()
| eval_dplyr_mutate | eval_dplyr_mutate_hcode | eval_dplyr_mutate_pmap | eval_dplyr_mutate_flex | A_child | alpha_child |
|---|---|---|---|---|---|
| 2.346356 | 2.346356 | 2.346356 | 2.346356 | -2 | 0.1 |
| 2.094273 | 2.094273 | 2.094273 | 2.094273 | -1 | 0.3 |
| 1.895316 | 1.895316 | 1.895316 | 1.895316 | 0 | 0.5 |
| 1.733708 | 1.733708 | 1.733708 | 1.733708 | 1 | 0.7 |
| 1.599477 | 1.599477 | 1.599477 | 1.599477 | 2 | 0.9 |


Hello. I am currently a software engineer at Uber. I graduated from the University of British Columbia in 2018.
Work
I definitely stubled across software engineering by mistake. Now I find joy in taking lines of code and crafting them into something beautiful.
Hobbies
I love nature. I enjoy hiking, snowboarding, and traveling. I am also interested in creating music.
Contact Information
You can email me at<EMAIL_ADDRESS>or view my resume.


Godzilla vs. Kong Bumped Eight Months
by Samuel GelmanThose waiting to see two of the greatest monsters go head to head will have to wait a little bit longer.
According to Variety, Warner Bros. and Legendary's Godzilla vs. Kong has been delayed eight months to Nov. 20, 2020. It was initially scheduled to open in theaters on Mar. 13, 2020.
Godzilla vs. Kong will be the fourth film in the Legendary's monster universe. Previous films include Godzilla, Kong: Skull Island and, most recently, Godzilla: King of the Monsters. The crossover film will star Alexander Skarsgard, Millie Bobby Brown, Rebecca Hall and Brian Tyree Henry, and will see the two famous creatures clash in an epic battle. Of the four, only Millie Bobby Brown has appeared in a previous monster movie, having stared in Godzilla: King of the Monsters.
Click the button below to start this article in quick view.
The monster universe has had its ups and downs financially. While Kong: Skull Island ($566 million) and Godzilla ($524 million) were financial success, Godzilla: King of the Monsters only brought in $385 million.
Directed by Adam Wingard, Godzilla vs. Kong stars Alexander Skarsgard, Millie Bobby Brown, Rebecca Hall and Brian Tyree Henry. The film will open in theaters on Nov. 20, 2020.
https://schema.orgBreadcrumbListListItem1Homehttps://www.cbr.com/ListItem2Movieshttps://www.cbr.com/category/movies/ListItem3Movie Newshttps://www.cbr.com/category/movies/news-movies/ListItem4Godzilla vs. Kong Bumped Eight Monthshttps://www.cbr.com/godzilla-vs-kong-eight-months/


Turn on your beacon and check the battery and lights/arrows. The battery should be at least 60% (with lithium batteries)
Before you leave the trailhead:
Make sure everyone has their beacons turned on and they have checked their batteries
Keep one beacon on 'send', and have everyone else turn their's to 'search'
With everyone at least 3 meters apart, have the person with the 'send' beacon move around to each person, ensuring
that each beacon is accurately tracking direction and distance in regard to the beacon that is 'sending'
Switch all of the beacons. Now one is searching and the rest are sending.
Have the person with the 'search' beacon start down the trail and stop at least 30 meters away
One at a time, have each person walk by the 'searcher'.
The 'searcher' makes sure their beacon is getting an accurate signal from each passing person
If everyone has a properly working beacon, double check that everyone in the group is 'sending' and their beacons are
secured to their bodies. Have a great adventure!
**there are many ways to do a beacon check, this is just one that works well with groups.


Keen UI
A collection of essential UI components written with
Vue
and inspired by
Material Design
.
Github
Components
Keen UI
A collection of essential UI components written with
Vue
and inspired by
Material Design
.
Github
Components


| Figure 1 |
Observed and modelled spatial distributions of common ash an ... |
| Figure 2 |
Modelled spatial distributions of Hymenoscyphus fraxineus. M ... |
| Figure 3 |
Expected long-term changes in the spatial distribution of co ... |
| Figure 4 |
Expected future spatial distribution of common ash and its p ... |
| Figure 5 |
Expected future spatial distribution of common ash and its p ... |


johnmulapi
An API for John Mulaney quotes
api.johnmulapi.com
help_outline
refresh
- John Mulaney
How do I use this?
>_
JS
PY
$ curl api.johnmulapi.com
Can I use this in my project?
Please do. Let me know how it goes.


| I know | Results |
|---|---|
| Your operating system is: | |
| You are using this web browser | and another thing |
| You are using this version of the web browser: | |
| Your screen width is: | |
| Your screen height is: | and another thing |
| Your screen resolution is: | and another thing |
| Here is how to be | SMART |
| Here is are some internet safety | RULES |
| Here is are some internet safety | TIPS |


Sign up to get interesting news and updates delivered to your inbox.
Email Address
First Name
Last Name
Select a country
Street
City
Select a state/province
Zip Code
Job Title
Company
Website
By submitting this form, you are granting<EMAIL_ADDRESS>312 N May Street, Suite 6D, Chicago, Illinois, 60607, United States, http://www.solutionpeople.com permission to email you. You may unsubscribe via the link found at the bottom of every email. (See our Email Privacy Policy for details.) Emails are serviced by Constant Contact.


Interrupt based Pulse Counter
Example Arduino sketch for interrupt based pulse counting:
//Number of pulses, used to measure energy. long pulseCount = 0;
//Used to measure power.
unsigned long pulseTime,lastTime;
//power and energy
double power, elapsedkWh;
//Number of pulses per wh - found or set on the meter.
int ppwh = 1; //1000 pulses/kwh = 1 pulse per wh
void setup()
{
Serial.begin(115200);
// KWH interrupt attached to IRQ 1 = pin3
attachInterrupt(1, onPulse, FALLING);
}
void loop()
{
}
// The interrupt routine
void onPulse()
{
//used to measure time between pulses.
lastTime = pulseTime;
pulseTime = micros();
//pulseCounter
pulseCount++;
//Calculate power
power =<PHONE_NUMBER>.0 / (pulseTime - lastTime))/ppwh;
//Find kwh elapsed
elapsedkWh = (1.0*pulseCount/(ppwh*1000)); //multiply by 1000 to convert pulses per wh to kwh
//Print the values.
Serial.print(power,4);
Serial.print(" ");
Serial.println(elapsedkWh,3);
}
Accuracy
Range of 0 to 25kW (typical range for solid state pulse output meters):
1000 pulses per kWh
|
Pulse Gen (kW) |
Pulse Counter (kW) |
Error (W) |
% Error |
Std. Deviation |
| 0.101 | 0.101 | 0.00 | 0.00% | 0 |
| 2.56 | 2.5599 | 0.10 | 0.00% | 0.00017 |
| 3.15 | 3.1496 | 0.40 | 0.00% | 0.00049 |
| 6.89 | 6.888 | 2.00 | 0.00% | 0.001 |
| 9.56 | 9.556 | 4.00 | 0.00% | 0.0019 |
| 10.63 | 10.625 | 5.00 | 0.00% | 0.0024 |
| 19.62 | 19.6 | 20.00 | 0.00% | 0.008 |
| 22.56 | 22.535 | 25.00 | 0.00% | 0.0111 |
| 24.98 | 24.95 | 30.00 | 0.00% | 0.0126 |
Notes
If the Serial monitor displays values rapidly, and at excessive power levels, try connecting a 10k pull down resistor to the digital input.
Re: Interrupt based Pulse Counter
I think the column headings above need adjusting, I was more than a bit confused when I read it the first time... :)


It's Nice To Meet You
selectionnez svp
Send opinion