text:
# function¶

The function module defines the Evaluable class and derived objects, commonly referred to as nutils functions. They represent mappings from a nutils.topology onto Python space. The notabe class of Array objects map onto the space of Numpy arrays of predefined dimension and shape. Most functions used in nutils applicatons are of this latter type, including the geometry and function bases for analysis.

Nutils functions are essentially postponed python functions, stored in a tree structure of input/output dependencies. Many Array objects have directly recognizable numpy equivalents, such as Sin or Inverse. By not evaluating directly but merely stacking operations, complex operations can be defined prior to entering a quadrature loop, allowing for a higher level style programming. It also allows for automatic differentiation and code optimization.

It is important to realize that nutils functions do not map for a physical xy-domain but from a topology, where a point is characterized by the combination of an element and its local coordinate. This is a natural fit for typical finite element operations such as quadrature. Evaluation from physical coordinates is possible only via inverting of the geometry function, which is a fundamentally expensive and currently unsupported operation.

class nutils.function.Evaluable(args)

Bases: nutils.types.Singleton

Base class

dependencies

collection of all function arguments

ordereddeps

collection of all function arguments such that the arguments to dependencies[i] can be found in dependencies[:i]

dependencytree

lookup table of function arguments into ordereddeps, such that ordereddeps[i].__args[j] == ordereddeps[dependencytree[i][j]], and self.__args[j] == ordereddeps[dependencytree[-1][j]]

asciitree(self, richoutput=False)

string representation

graphviz(self, dotpath='dot', imgtype='png')

create function graph

stackstr(self, nlines=- 1)

print stack

prepare_eval(self, /, **kwargs)

Return a function tree suitable for evaluation.

exception nutils.function.EvaluationError(etype, evalue, evaluable, values)

Bases: Exception

evaluation error

__init__(self, etype, evalue, evaluable, values)

constructor

__str__(self)

string representation

__weakref__

list of weak references to the object (if defined)

class nutils.function.EvaluableConstant(value)

Evaluate to the given constant value.

Parameters

value – The return value of eval.

class nutils.function.TransformChain(args, todims=None)

Chain of affine transformations.

Evaluates to a tuple of nutils.transform.TransformItem objects.

nutils.function.dot(a, b, axes=None)

Contract a and b along axes.

class nutils.function.Array(args, shape, dtype)

Base class for array valued functions.

shape

The shape of this array function.

Type

tuple of ints

ndim

The number of dimensions of this array array function. Equal to len(shape).

Type

int

dtype

The dtype of the array elements.

Type
dot(a, b, axes=None)

Contract a and b along axes.

Bases: nutils.function.Array

normal

class nutils.function.Inverse(func)

Bases: nutils.function.Array

Matrix inverse of func over the last two axes. All other axes are treated element-wise.

class nutils.function.Interpolate(x, xp, fp, left=None, right=None)

Bases: nutils.function.Array

interpolate uniformly spaced data; stepwise for now

class nutils.function.Pointwise(*args)

Bases: nutils.function.Array

Abstract base class for pointwise array functions.

class nutils.function.Cos(*args)

Cosine, element-wise.

evalf = <ufunc 'cos'>
class nutils.function.Sin(*args)

Sine, element-wise.

evalf = <ufunc 'sin'>
class nutils.function.Tan(*args)

Tangent, element-wise.

evalf = <ufunc 'tan'>
class nutils.function.ArcSin(*args)

Inverse sine, element-wise.

evalf = <ufunc 'arcsin'>
class nutils.function.ArcCos(*args)

Inverse cosine, element-wise.

evalf = <ufunc 'arccos'>
class nutils.function.ArcTan(*args)

Inverse tangent, element-wise.

evalf = <ufunc 'arctan'>
class nutils.function.Sampled(points, expect)

Bases: nutils.function.Array

Basis-like identity operator.

Basis-like function that for every point in a predefined set evaluates to the unit vector corresponding to its index.

Parameters
• points (1d Array) – Present point coordinates.

• expect (2d Array) – Elementwise constant that evaluates to the predefined point coordinates; used for error checking and to inherit the shape.

class nutils.function.Zeros(shape, dtype)

Bases: nutils.function.Array

zero

class nutils.function.Guard(fun)

Bases: nutils.function.Array

bar all simplifications

class nutils.function.TrigNormal(angle)

Bases: nutils.function.Array

cos, sin

class nutils.function.TrigTangent(angle)

Bases: nutils.function.Array

-sin, cos

class nutils.function.Find(where)

Bases: nutils.function.Array

indices of boolean index vector

class nutils.function.DerivativeTargetBase(args, shape, dtype)

Bases: nutils.function.Array

base class for derivative targets

class nutils.function.Argument(name, shape, nderiv=0)

Array argument, to be substituted before evaluation.

The Argument is an Array with a known shape, but whose values are to be defined later, before evaluation, e.g. using replace_arguments().

It is possible to take the derivative of an Array to an Argument:

>>> from nutils import function
>>> a = function.Argument('x', [])
>>> b = function.Argument('y', [])
>>> f = a**3 + b**2
>>> function.derivative(f, a).simplified == (3.*a**2).simplified
True

Furthermore, derivatives to the local cooardinates are remembered and applied to the replacement when using replace_arguments():

>>> from nutils import mesh
>>> domain, x = mesh.rectilinear([2,2])
>>> basis = domain.basis('spline', degree=2)
>>> c = function.Argument('c', basis.shape)
True
Parameters
• name (str) – The Identifier of this argument.

• shape (tuple of ints) – The shape of this argument.

• nderiv (int, non-negative) – Number of times a derivative to the local coordinates is taken. Default: 0.

class nutils.function.LocalCoords(ndims)

local coords derivative target

class nutils.function.DelayedJacobian(geom, *derivativestack)

Bases: nutils.function.Array

Placeholder for jacobian() until the dimension of the nutils.topology.Topology where this functions is being evaluated is known. The replacing is carried out by Evaluable.prepare_eval().

Bases: nutils.function.Array

Computes the $$k$$-dimensional array

$\begin{split}j_0,\dots,j_{k-1} \mapsto \sum_{\substack{i_0,\dots,i_{n-1}\in\mathbb{N}\\i_0+\cdots+i_{n-1}\le d}} p_0^{i_0} \cdots p_{n-1}^{i_{n-1}} c_{j_0,\dots,j_{k-1},i_0,\dots,i_{n-1}},\end{split}$

where $$p$$ are the $$n$$-dimensional local coordinates and $$c$$ is the argument coeffs and $$d$$ is the degree of the polynomial, where $$d$$ is the length of the last $$n$$ axes of coeffs.

Warning

All coefficients with a (combined) degree larger than $$d$$ should be zero. Failing to do so won’t raise an Exception, but might give incorrect results.

class nutils.function.RevolutionAngle

Bases: nutils.function.Array

Pseudo coordinates of a nutils.topology.RevolutionTopology.

class nutils.function.Custom(args, shape, dtype)

Bases: nutils.function.Array

Backport for forward compatibility with version 7.

Parameters
• args (iterable of Array objects or immutable and hashable objects) – The arguments of this array function.

• shape (tuple of int or Array) – The shape of the array function.

• dtype (bool, int or float) – The dtype of the array elements.

Example

The following class implements multiply using Custom without broadcasting and for float arrays only.

>>> class Multiply(Custom):
...
...   def __init__(self, left, right):
...     left, right = broadcast_arrays(left, right)
...     # Dtype coercion is beyond the scope of this example.
...     if left.dtype != right.dtype:
...       raise ValueError('left and right arguments should have the same dtype')
...     super().__init__(args=(left, right), shape=left.shape, dtype=left.dtype)
...
...   @staticmethod
...   def evalf(left, right):
...     return left * right
...
...   @staticmethod
...   def partial_derivative(iarg, left, right):
...     if iarg == 0:
...       return functools.reduce(diagonalize, range(left.ndim), right)
...     elif iarg == 1:
...       return functools.reduce(diagonalize, range(right.ndim), left)
...     else:
...       raise NotImplementedError
...
>>> Multiply(asarray([1., 2.]), asarray([3., 4.])).eval()
array([[ 3.,  8.]])
>>> a = Argument('a', (2,))
>>> derivative(Multiply(a, asarray([3., 4.])), a).eval(a=numpy.array([1., 2.]))
array([[[ 3.,  0.],
[ 0.,  4.]]])
partial_derivative(self, iarg, *args)

Return the partial derivative of this function to Custom constructor argument number iarg.

This method is only called for those arguments that are instances of Array with dtype float and have the derivative target as a dependency. It is therefor allowed to omit an implementation for some or all arguments if the above conditions are not met.

Parameters
• iarg (int) – The index of the argument to compute the derivative for.

• *args – The arguments as passed to the constructor of Custom.

Returns

The partial derivative of this function to the given argument.

Return type

Array or similar

class nutils.function.Basis(ndofs, transforms, trans=<nutils.function.SelectChain object at 0x7fe418db1b90>)

Bases: nutils.function.Array

Abstract base class for bases.

A basis is a sequence of elementwise polynomial functions.

Parameters

Notes

Subclasses must implement get_dofs() and get_coefficients() and if possible should redefine get_support().

get_support(self, dof)

Return the support of basis function dof.

If dof is an int, return the indices of elements that form the support of dof. If dof is an array, return the union of supports of the selected dofs as a unique array. The returned array is always unique, i.e. strict monotonic increasing.

Parameters

dof (int or array of int or bool) – Index or indices of basis function or a mask.

Returns

support – The elements (as indices) where function dof has support.

Return type

sorted and unique numpy.ndarray

abstract get_dofs(self, ielem)

Return an array of indices of basis functions with support on element ielem.

If ielem is an int, return the dofs on element ielem matching the coefficients array as returned by get_coefficients(). If ielem is an array, return the union of dofs on the selected elements as a unique array, i.e. a strict monotonic increasing array.

Parameters

ielem (int or array of int or bool) – Element number(s) or mask.

Returns

dofs – A 1D Array of indices.

Return type

numpy.ndarray

get_ndofs(self, ielem)

Return the number of basis functions with support on element ielem.

abstract get_coefficients(self, ielem)

Return an array of coefficients for all basis functions with support on element ielem.

Parameters

ielem (int) – Element number.

Returns

coefficients – Array of coefficients with shape (nlocaldofs,)+(degree,)*ndims, where the first axis corresponds to the dofs returned by get_dofs().

Return type

nutils.types.frozenarray

get_coeffshape(self, ielem)

Return the shape of the array of coefficients for basis functions with support on element ielem.

class nutils.function.PlainBasis(coefficients, dofs, ndofs, transforms, trans=<nutils.function.SelectChain object at 0x7fe418db1b90>)

Bases: nutils.function.Basis

A general purpose implementation of a Basis.

Use this class only if there exists no specific implementation of Basis for the basis at hand.

Parameters
class nutils.function.DiscontBasis(coefficients, transforms, trans=<nutils.function.SelectChain object at 0x7fe418db1b90>)

Bases: nutils.function.Basis

A discontinuous basis with monotonic increasing dofs.

Parameters
class nutils.function.MaskedBasis(parent, indices, trans=<nutils.function.SelectChain object at 0x7fe418db1b90>)

Bases: nutils.function.Basis

An order preserving subset of another Basis.

Parameters
• parent (Basis) – The basis to mask.

• indices (array of ints) – The strict monotonic increasing indices of parent basis functions to keep.

• trans (TransformChain) –

class nutils.function.StructuredBasis(coeffs, start_dofs, stop_dofs, dofs_shape, transforms, transforms_shape, trans=<nutils.function.SelectChain object at 0x7fe418db1b90>)

Bases: nutils.function.Basis

A basis for class:nutils.transformseq.StructuredTransforms.

Parameters
• coeffs (tuple of tuples of arrays) – Per dimension the coefficients of the basis functions per transform.

• start_dofs (tuple of arrays of ints) – Per dimension the dof of the first entry in coeffs per transform.

• stop_dofs (tuple of arrays of ints) – Per dimension one plus the dof of the last entry in coeffs per transform.

• dofs_shape (tuple of ints) – The tensor shape of the dofs.

• transforms (nutils.transformseq.Transforms) – The transforms on which this basis is defined.

• transforms_shape (tuple of ints) – The tensor shape of the transforms.

• trans (TransformChain) –

class nutils.function.PrunedBasis(parent, transmap, trans=<nutils.function.SelectChain object at 0x7fe418db1b90>)

Bases: nutils.function.Basis

A subset of another Basis.

Parameters
• parent (Basis) – The basis to prune.

• transmap (one-dimensional array of ints) – The indices of transforms in parent that form this subset.

nutils.function.replace(func)

decorator for deep object replacement

Generates a deep replacement method for Immutable objects based on a callable that is applied (recursively) on individual constructor arguments.

Parameters

func – callable which maps (obj, …) onto replaced_obj

Returns

The method that searches the object to perform the replacements.

Return type

callable

nutils.function.partition(f, *levels)

Create a partition of unity for a scalar function f.

When n levels are specified, n+1 indicator functions are formed that evaluate to one if and only if the following condition holds:

indicator 0: f < levels[0]
indicator 1: levels[0] < f < levels[1]
...
indicator n-1: levels[n-2] < f < levels[n-1]
indicator n: f > levels[n-1]

At the interval boundaries the indicators evaluate to one half, in the remainder of the domain they evaluate to zero such that the whole forms a partition of unity. The partitions can be used to create a piecewise continuous function by means of multiplication and addition.

The following example creates a topology consiting of three elements, and a function f that is zero in the first element, parabolic in the second, and zero again in the third element.

>>> from nutils import mesh
>>> domain, x = mesh.rectilinear([3])
>>> left, center, right = partition(x[0], 1, 2)
>>> f = (1 - (2*x[0]-3)**2) * center
Parameters
• f (Array) – Scalar-valued function

• levels (scalar constants or Arrays) – The interval endpoints.

Returns

The indicator functions.

Return type

list of scalar Arrays

Parameters

*arrays (Array or similar) –

Returns

Return type

Broadcast the given shapes into a single shape.

Parameters

*shapes (tuple or int) –

Returns

Return type

tuple of int

Broadcast an array to a new shape.

Parameters
• array (Array or similar) – The array to broadcast.

• shape (tuple of int) – The desired shape.

Returns

Return type

Array

nutils.function.chain(funcs)
nutils.function.vectorize(args)

Combine scalar-valued bases into a vector-valued basis.

Parameters

args (iterable of 1-dimensional nutils.function.Array objects) –

Returns

Return type

Array

nutils.function.jacobian(geom, ndims)

Return $$\sqrt{|J^T J|}$$ with $$J$$ the gradient of geom to the local coordinate system with ndims dimensions (localgradient(geom, ndims)).

nutils.function.matmat(arg0, *args)

helper function, contracts last axis of arg0 with first axis of arg1, etc

nutils.function.derivative(func, var, seen=None)

local derivative

nutils.function.outer(arg1, arg2=None, axis=0)

outer product

nutils.function.find(arg)
nutils.function.J(geometry, ndims=None)

Return $$\sqrt{|J^T J|}$$ with $$J$$ the gradient of geometry to the local coordinate system with ndims dimensions (localgradient(geom, ndims)).

nutils.function.replace_arguments(value, arguments)

Replace Argument objects in value.

Replace Argument objects in value according to the arguments map, taking into account derivatives to the local coordinates.

Parameters
Returns

The edited value.

Return type

Array

class nutils.function.Namespace(*, default_geometry_name='x', fallback_length=None, **kwargs)

Bases: object

Namespace for Array objects supporting assignments with tensor expressions.

The Namespace object is used to store Array objects.

>>> from nutils import function
>>> ns = function.Namespace()
>>> ns.A = function.zeros([3, 3])
>>> ns.x = function.zeros([3])
>>> ns.c = 2

In addition to the assignment of Array objects, it is also possible to specify an array using a tensor expression string — see nutils.expression.parse() for the syntax. All attributes defined in this namespace are available as variables in the expression. If the array defined by the expression has one or more dimensions the indices of the axes should be appended to the attribute name. Examples:

>>> ns.cAx_i = 'c A_ij x_j'
>>> ns.xAx = 'x_i A_ij x_j'

It is also possible to simply evaluate an expression without storing its value in the namespace by passing the expression to the method eval_ suffixed with appropriate indices:

>>> ns.eval_('2 c')
Array<>
>>> ns.eval_i('c A_ij x_j')
Array<3>
>>> ns.eval_ij('A_ij + A_ji')
Array<3,3>

For zero and one dimensional expressions the following shorthand can be used:

>>> '2 c' @ ns
Array<>
>>> 'A_ij x_j' @ ns
Array<3>

Sometimes the dimension of an expression cannot be determined, e.g. when evaluating the identity array:

>>> ns.eval_ij('δ_ij')
Traceback (most recent call last):
...
nutils.expression.ExpressionSyntaxError: Length of axis cannot be determined from the expression.
δ_ij
^

There are two ways to inform the namespace of the correct lengths. The first is to assign fixed lengths to certain indices via keyword argument length_<indices>:

>>> ns_fixed = function.Namespace(length_ij=2)
>>> ns_fixed.eval_ij('δ_ij')
Array<2,2>

Note that evaluating an expression with an incompatible length raises an exception:

>>> ns = function.Namespace(length_i=2)
>>> ns.a = numpy.array([1,2,3])
>>> 'a_i' @ ns
Traceback (most recent call last):
...
nutils.expression.ExpressionSyntaxError: Length of index i is fixed at 2 but the expression has length 3.
a_i
^

The second is to define a fallback length via the fallback_length argument:

>>> ns_fallback = function.Namespace(fallback_length=2)
>>> ns_fallback.eval_ij('δ_ij')
Array<2,2>

When evaluating an expression through this namespace the following functions are available: opposite, sin, cos, tan, sinh, cosh, tanh, arcsin, arccos, arctan2, arctanh, exp, abs, ln, log, log2, log10, sqrt and sign.

Parameters
• default_geometry_name (str) – The name of the default geometry. This argument is passed to nutils.expression.parse(). Default: 'x'.

• fallback_length (int, optional) – The fallback length of an axis if the length cannot be determined from the expression.

• length_<indices> (int) – The fixed length of <indices>. All axes in the expression marked with one of the <indices> are asserted to have the specified length.

arg_shapes

A readonly map of argument names and shapes.

Type

dict

default_geometry_name

The name of the default geometry. See argument with the same name.

Type

str

__getstate__(self)

Pickle instructions

__setstate__(self, d)

Unpickle instructions

property default_geometry

The default geometry, shorthand for getattr(ns, ns.default_geometry_name).

Type

nutils.function.Array

__call__(*args, **subs)

Return a copy with arguments replaced by subs.

Return a copy of this namespace with Argument objects replaced according to subs.

Parameters

**subs (dict of str and nutils.function.Array objects) – Replacements of the Argument objects, identified by their names.

Returns

ns – The copy of this namespace with replaced Argument objects.

Return type

Namespace

copy_(self, *, default_geometry_name=None)

Return a copy of this namespace.

__getattr__(self, name)

Get attribute name.

__setattr__(self, name, value)

Set attribute name to value.

__delattr__(self, name)

Delete attribute name.

__rmatmul__(self, expr)

Evaluate zero or one dimensional expr or a list of expressions.


text:
# ggRandomForests: Exploring randomForestSRC Regression

john.ehrlinger@gmail.com

# Abtract

Random Forests (Leo Breiman 2001) (RF) are a non-parametric statistical method requiring no distributional assumptions on covariate relation to the response. RF are a robust, nonlinear technique that optimizes predictive accuracy by fitting an ensemble of trees to stabilize model estimates. The package (Ishwaran and Kogalur 2014) is a unified treatment of Breiman’s random forests for survival, regression and classification problems.

Predictive accuracy make RF an attractive alternative to parametric models, though complexity and interpretability of the forest hinder wider application of the method. We introduce the package, tools for visually understand random forest models grown in R ( Core Team 2014) with the package. The package is structured to extract intermediate data objects from objects and generates figures using the (Wickham 2009) graphics package

This document is structured as a tutorial for building random forests for regression with the package and using the package for investigating how the forest is constructed. We investigate the Boston Housing data Belsley, Kuh, and Welsch (1980). We demonstrate random forest variable selection using Variable Importance (VIMP) (Leo Breiman 2001) and Minimal Depth (Ishwaran et al. 2010), a property derived from the construction of each tree within the forest. We will also demonstrate the use of variable dependence plots (Friedman 2000) to aid interpretation RF results. We then examine variable interactions between covariates using a minimal depth interactions, and conditional variable dependence plots. The goal of the exercise is to demonstrate the strength of using Random Forest methods for both prediction and information retrieval in regression settings.

This document is a package vignette for the package for “Visually Exploring Random Forests” (https://cran.r-project.org/package=ggRandomForests). The package is designed for use with the package (https://cran.r-project.org/package=randomForestSRC) (Ishwaran and Kogalur 2014) for growing random forests for survival (time to event response), regression (continuous response) and classification (categorical response) settings and uses the package (https://cran.r-project.org/package=ggplot2) (Wickham 2009) for plotting diagnostic and variable association results. is structured to extract data objects from objects and provides functions for printing and plotting these objects.

The vignette is a tutorial for using the package with the package for building and post-processing random forests for regression settings. In this tutorial, we explore a random forest for regression model constructed for the Boston housing data set Belsley, Kuh, and Welsch (1980), available in the MASS package (Venables and Ripley 2002). We grow a random forest and demonstrate how can be used when determining how the response depends on predictive variables within the model. The tutorial demonstrates the design and usage of many of functions and features and also how to modify and customize the resulting ggplot graphic objects along the way.

The vignette is written in using the knitr package (https://cran.r-project.org/package=knitr]Xie (2013), which facilitates weaving R ( Core Team 2014) code, results and figures into document text. Throughout this document, R code will be displayed in code blocks as shown below. This code block loads the R packages required to run the source code listed in code blocks throughout the remainder of this document.

> ################## Load packages ##################
> library("ggplot2")         # Graphics engine
> library("RColorBrewer")    # Nice color palettes
> library("plot3D")          # for 3d surfaces.
> library("dplyr")           # Better data manipulations
> library("tidyr")           # gather variables into long format
> library("parallel")        # mclapply for multicore processing
>
> # Analysis packages.
> library("randomForestSRC") # random forests for survival, regression and
> # classification
> library("ggRandomForests") # ggplot2 random forest figures (This!)
>
> ################ Default Settings ##################
> theme_set(theme_bw())     # A ggplot2 theme with white background
>
> ## Set open circle for censored, and x for events
> event.marks <- c(1, 4)
> event.labels <- c(FALSE, TRUE)
>
> ## We want red for death events, so reorder this set.
> strCol <- brewer.pal(3, "Set1")[c(2,1,3)]

This vignette is available within the package on the Comprehensive R Archive Network (CRAN) (https://www.r-project.org) ( Core Team 2014). Once the package has been installed, the vignette can be viewed directly from within R with the following command:

> vignette("randomForestSRC-Regression", package = "ggRFVignette")

A development version of the package is also available on GitHub (https://github.com). We invite comments, feature requests and bug reports for this package at (https://github.com/ehrlinger/ggRandomForests).

# Introduction

Random Forests (Leo Breiman 2001) (RF) are a fully non-parametric statistical method which requires no distributional or functional assumptions on covariate relation to the response. RF is a robust, nonlinear technique that optimizes predictive accuracy by fitting an ensemble of trees to stabilize model estimates. Random Survival Forests (RSF) Ishwaran et al. (2008) are an extension of Breiman’s RF techniques to survival settings, allowing efficient non-parametric analysis of time to event data. The package (Ishwaran and Kogalur 2014) is a unified treatment of Breiman’s random forests for survival (time to event response), regression (continuous response) and classification (categorical response) problems.

Predictive accuracy make RF an attractive alternative to parametric models, though complexity and interpretability of the forest hinder wider application of the method. We introduce the package for visually exploring random forest models. The package is structured to extract intermediate data objects from objects and generate figures using the graphics package (Wickham 2009).

Many of the figures created by the package are also available directly from within the package. However offers the following advantages:

• Separation of data and figures: contains functions that operate on either the randomForestSRC::rfsrc forest object directly, or on the output from post processing functions (i.e. plot.variable, var.select, find.interaction) to generate intermediate data objects. Functions are provide to further process these objects and plot results using the graphics package. Alternatively, users can use these data objects for their own custom plotting or analysis operations.

• Each data object/figure is a single, self contained object. This allows simple modification and manipulation of the data or objects to meet users specific needs and requirements.

• The use of for plotting. We chose to use the package for our figures to allow users flexibility in modifying the figures to their liking. Each plot function returns either a single ggplot object, or a list of ggplot objects, allowing users to use additional functions or themes to modify and customize the figures to their liking.

This document is formatted as a tutorial for using the package for building and post-processing random forest models with the package for investigating how the forest is constructed. In this tutorial, we use the Boston Housing Data (), available in the MASS package (Venables and Ripley 2002), to build a random forest for regression () and demonstrate the tools in the package for examining the forest construction.

Random forests are not parsimonious, but use all variables available in the construction of a response predictor. We demonstrate a random forest variable selection () process using the Variable Importance () measure (VIMP) (Leo Breiman 2001) as well as Minimal Depth () (Ishwaran et al. 2010), a property derived from the construction of each tree within the forest, to assess the impact of variables on forest prediction.

Once we have an idea of which variables we are want to investigate further, we will use variable dependence plots (Friedman 2000) to understand how a variable is related to the response. Marginal variable dependence () plots give us an idea of the overall trend of a variable/response relation, while partial dependence () plots show us a risk adjusted relation. These figures may show strongly non-linear variable/response relations that are not easily obtained through a parametric approach. We are also interested in examining variable interactions () within the forest model. Using a minimal depth approach, we can quantify how closely variables are related within the forest, and generate marginal dependence coplots() and partial dependence coplots () (risk adjusted) conditioning plots (coplots) Cleveland (1993) to examine these interactions graphically.

# Data: Boston Housing Values

The Boston Housing data is a standard benchmark data set for regression models. It contains data for 506 census tracts of Boston from the 1970 census Belsley, Kuh, and Welsch (1980). The data is available in multiple R packages, but to keep the installation dependencies for the package down, we will use the data contained in the MASS package (https://cran.r-project.org/package=MASS) (Venables and Ripley 2002), available with the base install of R. The following code block loads the data into the environment. We include a table of the Boston data set variable names, types and descriptions for reference when we interpret the model results.

> # Load the Boston Housing data
> data(Boston, package="MASS")
>
> # Set modes correctly. For binary variables: transform to logical
> Boston$chas <- as.logical(Boston$chas)
Table 1: Boston housing data dictionary.
Variable Description type
crim Crime rate by town. numeric
zn Proportion of residential land zoned for lots over 25,000 sq.ft. numeric
indus Proportion of non-retail business acres per town. numeric
chas Charles River (tract bounds river). logical
nox Nitrogen oxides concentration (10 ppm). numeric
rm Number of rooms per dwelling. numeric
age Proportion of units built prior to 1940. numeric
dis Distances to Boston employment center. numeric
tax Property tax rate per $10,000. numeric ptratio Pupil teacher ratio by town. numeric black Proportion of blacks by town. numeric lstat Lower status of the population (percent). numeric medv Median value of homes ($1000s). numeric

The main objective of the Boston Housing data is to investigate variables associated with predicting the median value of homes (continuous medv response) within 506 suburban areas of Boston.

## Exploratory Data Analysis

It is good practice to view your data before beginning an analysis, what(Tukey 1977) refers to as Exploratory Data Analysis (EDA). To facilitate this, we use figures with the ggplot2::facet_wrap command to create two sets of panel plots, one for categorical variables with boxplots at each level, and one of scatter plots for continuous variables. Each variable is plotted along a selected continuous variable on the X-axis. These figures help to find outliers, missing values and other data anomalies in each variable before getting deep into the analysis. We have also created a separate shiny app (https://shiny.rstudio.com) (Chang et al. 2015), available at (https://ehrlinger.shinyapps.io/xportEDA), for creating similar figures with an arbitrary data set, to make the EDA process easier for users.

The Boston housing data consists almost entirely of continuous variables, with the exception of the “Charles river” logical variable. A simple EDA visualization to use for this data is a single panel plot of the continuous variables, with observation points colored by the logical variable. Missing values in our continuous variable plots are indicated by the rug marks along the x-axis, of which there are none in this data. We used the Boston housing response variable, the median value of homes (medv), for X variable.

This figure is loosely related to a pairs scatter plot (Becker, Chambers, and Wilks 1988), but in this case we only examine the relation between the response variable against the remainder. Plotting the data against the response also gives us a “sanity check” when viewing our model results. It’s pretty obvious from this figure that we should find a strong relation between median home values and the lstat and rm variables.

# Random Forest - Regression

A Random Forest is grown by bagging (L. Breiman 1996a) a collection of classification and regression trees (CART) (L. Breiman et al. 1984). The method uses a set of $$B$$ bootstrap (Efron and Tibshirani 1994) samples, growing an independent tree model on each sub-sample of the population. Each tree is grown by recursively partitioning the population based on optimization of a split rule over the $$p$$-dimensional covariate space. At each split, a subset of $$m \le p$$ candidate variables are tested for the split rule optimization, dividing each node into two daughter nodes. Each daughter node is then split again until the process reaches the stopping criteria of either node purity or node member size, which defines the set of terminal (unsplit) nodes for the tree. In regression trees, the split rule is based on minimizing the mean squared error, whereas in classification problems, the Gini index is used (Friedman 2000).

Random Forests sort each training set observation into one unique terminal node per tree. Tree estimates for each observation are constructed at each terminal node, among the terminal node members. The Random Forest estimate for each observation is then calculated by aggregating, averaging (regression) or votes (classification), the terminal node results across the collection of $$B$$ trees.

For this tutorial, we grow the random forest for regression using the rfsrc command to predict the median home value (medv variable) using the remaining 13 independent predictor variables. For this example we will use the default set of $$B=1000$$ trees (ntree argument), $$m=5$$ candidate variables (mtry) for each split with a stopping criteria of at most nodesize=5 observations within each terminal node.

Because growing random forests are computationally expensive, and the package is targeted at the visualization of random forest objects, we will use cached copies of the objects throughout this document. We include the cached objects as data sets in the package. The actual rfsrc calls are included in comments within code blocks.

> # Load the data, from the call:
> rfsrc_Boston <- rfsrc(medv~., data=Boston,
+                       importance = TRUE, err.block = 5)
>
> # print the forest summary
> rfsrc_Boston

The randomForestSRC::print.rfsrc summary details the parameters used for the rfsrc call described above, and returns variance and generalization error estimate from the forest training set. The forest is built from 506 observations and 13 independent variables. It was constructed for the continuous medv variable using ntree=1000 regression (regr) trees, randomly selecting 5 candidate variables at each node split, and terminating nodes with no fewer than 5 observations.

## Generalization error estimates

One advantage of Random Forests is a built in generalization error estimate. Each bootstrap sample selects approximately 63.2% of the population on average. The remaining 36.8% of observations, the Out-of-Bag (OOB) (L. Breiman 1996b) sample, can be used as a hold out test set for each of the trees in the forest. An OOB prediction error estimate can be calculated for each observation by predicting the response over the set of trees which were NOT trained with that particular observation. The Out-of-Bag prediction error estimates have been shown to be nearly identical to n–fold cross validation estimates (Hastie, Tibshirani, and Friedman 2009). This feature of Random Forests allows us to obtain both model fit and validation in one pass of the algorithm.

The gg_error function operates on the randomForestSRC::rfsrc object to extract the error estimates as the forest is grown. The code block demonstrates part the design philosophy, to create separate data objects and provide functions to operate on the data objects. The following code block first creates a gg_error object, then uses the plot.gg_error function to create a ggplot object for display.

> # Plot the OOB errors against the growth of the forest.
> gg_e <- gg_error(rfsrc_Boston)
> gg_e <- gg_e %>% filter(!is.na(error))
> class(gg_e) <- c("gg_error",class(gg_e))
> plot(gg_e)

This figure demonstrates that it does not take a large number of trees to stabilize the forest prediction error estimate. However, to ensure that each variable has enough of a chance to be included in the forest prediction process, we do want to create a rather large random forest of trees.

## Random Forest Prediction

The gg_rfsrc function extracts the OOB prediction estimates from the random forest. This code block executes the the data extraction and plotting in one line, since we are not interested in holding the prediction estimates for later reuse. Also note that we add in the additional command (coord_cartesian) to modify the plot object. Each of the plot commands return ggplot objects, which we can also store for modification or reuse later in the analysis.

> # Plot predicted median home values.
> plot(gg_rfsrc(rfsrc_Boston), alpha=.5)+
+   coord_cartesian(ylim=c(5,49))

The gg_rfsrc plot shows the predicted median home value, one point for each observation in the training set. The points are jittered around a single point on the x-axis, since we are only looking at predicted values from the forest. These estimates are Out of Bag, which are analogous to test set estimates. The boxplot is shown to give an indication of the distribution of the prediction estimates. For this analysis the figure is another model sanity check, as we are more interested in exploring the why questions for these predictions.

# Variable Selection

Random forests are not parsimonious, but use all variables available in the construction of a response predictor. Also, unlike parametric models, Random Forests do not require the explicit specification of the functional form of covariates to the response. Therefore there is no explicit p-value/significance test for variable selection with a random forest model. Instead, RF ascertain which variables contribute to the prediction through the split rule optimization, optimally choosing variables which separate observations. We use two separate approaches to explore the RF selection process, Variable Importance (\autoref{variable-importance) and Minimal Depth (\autoref{minimal-depth).

## Variable Importance

Variable importance (VIMP) was originally defined for CART using a measure involving surrogate variables (see Chapter 5 of (L. Breiman et al. 1984)). The most popular VIMP method uses a prediction error approach involving “noising-up” each variable in turn. VIMP for a variable $$x_v$$ is the difference between prediction error when $$x_v$$ is noised up by randomly permuting its values, compared to prediction error under the observed values Ishwaran et al. (2008).

Since VIMP is the difference between OOB prediction error before and after permutation, a large VIMP value indicates that misspecification detracts from the variable predictive accuracy in the forest. VIMP close to zero indicates the variable contributes nothing to predictive accuracy, and negative values indicate the predictive accuracy improves when the variable is misspecified. In the later case, we assume noise is more informative than the true variable. As such, we ignore variables with negative and near zero values of VIMP, relying on large positive values to indicate that the predictive power of the forest is dependent on those variables.

The gg_vimp function extracts VIMP measures for each of the variables used to grow the forest. The plot.gg_vimp function shows the variables, in VIMP rank order, from the largest (Lower Status) at the top, to smallest (Charles River) at the bottom. VIMP measures are shown using bars to compare the scale of the error increase under permutation.

> # Plot the VIMP rankings of independent variables.
> plot(gg_vimp(rfsrc_Boston), lbls=st.labs)

For our random forest, the top two variables (lstat and rm) have the largest VIMP, with a sizable difference to the remaining variables, which mostly have similar VIMP measure. This indicates we should focus attention on these two variables, at least, over the others.

In this example, all VIMP measures are positive, though some are small. When there are both negative and positive VIMP values, the plot.gg_vimp function will color VIMP by the sign of the measure. We use the lbls argument to pass a named vector of meaningful text descriptions to the plot.gg_vimp function, replacing the often terse variable names used by default.

## Minimal Depth

In VIMP, prognostic risk factors are determined by testing the forest prediction under alternative data settings, ranking the most important variables according to their impact on predictive ability of the forest. An alternative method uses inspection of the forest construction to rank variables. Minimal depth assumes that variables with high impact on the prediction are those that most frequently split nodes nearest to the trunks of the trees (i.e. at the root node) where they partition large samples of the population.

Within a tree, node levels are numbered based on their relative distance to the trunk of the tree (with the root at 0). Minimal depth measures the important risk factors by averaging the depth of the first split for each variable over all trees within the forest. Lower values of this measure indicate variables important in splitting large groups of patients.

The maximal subtree for a variable $$x$$ is the largest subtree whose root node splits on $$x$$. All parent nodes of $$x$$’s maximal subtree have nodes that split on variables other than $$x$$. The largest maximal subtree possible is at the root node. If a variable does not split the root node, it can have more than one maximal subtree, or a maximal subtree may also not exist if there are no splits on the variable. The minimal depth of a variables is a surrogate measure of predictiveness of the variable. The smaller the minimal depth, the more impact the variable has sorting observations, and therefore on the forest prediction.

The gg_minimal_depth function is analogous to the gg_vimp function for minimal depth. Variables are ranked from most important at the top (minimal depth measure), to least at the bottom (maximal minimal depth). The vertical dashed line indicates the minimal depth threshold where smaller minimal depth values indicate higher importance and larger indicate lower importance.

The randomForestSRC::var.select call is again a computationally intensive function, as it traverses the forest finding the maximal subtree within each tree for each variable before averaging the results we use in the gg_minimal_depth call. We again use the cached object strategy here to save computational time. The var.select call is included in the comment of this code block.

> # Load the data, from the call:
> varsel_Boston <- var.select(rfsrc_Boston)
>
> # Save the gg_minimal_depth object for later use.
> gg_md <- gg_minimal_depth(varsel_Boston)
>
> # plot the object
> plot(gg_md, lbls=st.labs)

In general, the selection of variables according to VIMP is to rather arbitrarily examine the values, looking for some point along the ranking where there is a large difference in VIMP measures. The minimal depth threshold method has a more quantitative approach to determine a selection threshold. Given minimal depth is a quantitative property of the forest construction, (Ishwaran et al. 2010) also construct an analytic threshold for evidence of variable impact. A simple optimistic threshold rule uses the mean of the minimal depth distribution, classifying variables with minimal depth lower than this threshold as important in forest prediction. The minimal depth plot for our model indicates there are ten variables which have a higher impact (minimal depth below the mean value threshold) than the remaining three.

Since the VIMP and Minimal Depth measures use different criteria, we expect the variable ranking to be somewhat different. We use gg_minimal_vimp function to compare rankings between minimal depth and VIMP. In this call, we plot the stored gg_minimal_depth object (gg_md), which would be equivalent to calling plot.gg_minimal_vimp(varsel_Boston) or plot(gg_minimal_vimp(varsel_Boston)).

> # gg_minimal_depth objects contain information about
> # both minimal depth and VIMP.
> plot(gg_minimal_vimp(gg_md))

The points along the red dashed line indicates where the measures are in agreement. Points above the red dashed line are ranked higher by VIMP than by minimal depth, indicating the variables are sensitive to misspecification. Those below the line have a higher minimal depth ranking, indicating they are better at dividing large portions of the population. The further the points are from the line, the more the discrepancy between measures. The construction of this figure is skewed towards a minimal depth approach, by ranking variables along the y-axis, though points are colored by the sign of VIMP.

In our example, both minimal depth and VIMP indicate the strong relation of lstat and rm variables to the forest prediction, which agrees with our expectation from the Data: Boston Housing Values () done at the beginning of this document. We now turn to investigating how these, and other variables, are related to the predicted response.

# Response/Variable Dependence

As random forests are not a parsimonious methodology, we can use the minimal depth and VIMP measures to reduce the number of variables we need to examine to a manageable subset. We would like to know how the forest response depends on some specific variables of interest. We often choose to examine variables of interest based on the study question, or other previous knowledge. In the absence of this, we will look at variables that contribute most to the predictive accuracy of the forest.

Although often characterized as a “black box” method, it is possible to express a random forest in functional form. In the end the forest predictor is some function, although complex, of the predictor variables $\hat{f}_{rf} = f(x).$ We use graphical methods to examine the forest predicted response dependency on covariates. We again have two options, Variable Dependence () plots are quick and easy to generate, and Partial Dependence (\autoref{partial-dependence) plots are computationally intensive but give us a risk adjusted look at the dependence.

## Variable Dependence

Variable dependence plots show the predicted response as a function of a covariate of interest, where each observation is represented by a point on the plot. Each predicted point is an individual observations, dependent on the full combination of all other covariates, not only on the covariate of interest. Interpretation of variable dependence plots can only be in general terms, as point predictions are a function of all covariates in that particular observation. However, variable dependence is straight forward to calculate, only requiring the predicted response for each observation.

We use the gg_variable function call to extract the training set variables and the predicted OOB response from randomForestSRC::rfsrc and randomForestSRC::predict objects. In the following code block, we will store the gg_variable data object for later use, as all remaining variable dependence plots can be constructed from this (gg_v) object. We will also use the minimal depth selected variables (minimal depth lower than the threshold value) from the previously stored gg_minimal_depth object (gg_md\$topvars) to filter the variables of interest.

The plot.gg_variable function call operates in the gg_variable object. We pass it the list of variables of interest (xvar) and request a single panel (panel=TRUE) to display the figures. By default, the plot.gg_variable function returns a list of ggplot objects, one figure for each variable named in xvar argument. The next three arguments are passed to internal ggplot plotting routines. The se and span arguments are used to modify the internal call to ggplot2::geom_smooth for fitting smooth lines to the data. The alpha argument lightens the coloring points in the ggplot2::geom_point call, making it easier to see point over plotting. We also demonstrate modification of the plot labels using the ggplot2::labs function.

This figure looks very similar to the Data: Boston Housing Values (\autoref{data-boston-housing-values) figure, although with transposed axis as we plot the response variable on the y-axis. The closer the panels match, the better the RF prediction. The panels are sorted to match the order of variables in the xvar argument and include a smooth loess line Cleveland and Devlin (1988), with 95% shaded confidence band, to indicates the trend of the prediction dependence over the covariate values.

There is not a convenient method to panel scatter plots and boxplots together, so we recommend creating panel plots for each variable type separately. The Boston housing data does contain a single categorical variable, the Charles river logical variable. Variable dependence plots for categorical variables are constructed using boxplots to show the distribution of the predictions within each category. Although the Charles river variable has the lowest importance scores in both VIMP and minimal depth measures, we include the variable dependence plot as an example of categorical variable dependence.

> plot(gg_v, xvar="chas", alpha=.4)+
+   labs(y=st.labs["medv"])
>
> # , points=FALSE, se=FALSE, notch=TRUE

The figure shows that most housing tracts do not border the Charles river (chas=FALSE), and comparing the distributions of the predicted median housing values indicates no significant difference in home values. This reinforces the findings in both VIMP and Minimal depth, the Charles river variable has very little impact on the forest prediction of median home values.

## Partial Dependence

Partial variable dependence plots are a risk adjusted alternative to variable dependence. Partial plots are generated by integrating out the effects of all variables beside the covariate of interest. Partial dependence data are constructed by selecting points evenly spaced along the distribution of the $$X$$ variable of interest. For each value ($$X = x$$), we calculate the average RF prediction over all other covariates in $$X$$ by $\tilde{f}(x) = \frac{1}{n} \sum_{i = 1}^n \hat{f}(x, x_{i, o}),$ where $$\hat{f}$$ is the predicted response from the random forest and $$x_{i, o}$$ is the value for all other covariates other than $$X = x$$ for the observation $$i$$ (Friedman 2000). Essentially, we average a set of predictions for each observation in the training set at the value of $$X=x$$. We repeating the process for a sequence of $$X=x$$ values to generate the estimated points to create a partial dependence plot.

Partial plots are another computationally intensive analysis, especially when there are a large number of observations. We again turn to our data caching strategy here. The default parameters for the randomForestSRC::plot.variable function generate partial dependence estimates at npts=25 points (the default value) along the variable of interest. For each point of interest, the plot.variable function averages n response predictions. This is repeated for each of the variables of interest and the results are returned for later analysis.

We again order the panels by minimal depth ranking. We see again how the lstat and rm variables are strongly related to the median value response, making the partial dependence of the remaining variables look flat. We also see strong nonlinearity of these two variables. The lstat variable looks rather quadratic, while the rm shape is more complex.

We could stop here, indicating that the RF analysis has found these ten variables to be important in predicting the median home values. That increasing lstat (percentage population of lower status) values are associated with decreasing median home values (medv) and increasing rm > 6 (number of rooms $$> 6$$) are associated with increasing median home values. However, we may also be interested in investigating how these variables work together to help improve the random forest prediction of median home values.

# Variable Interactions

Using the different variable dependence measures, it is also possible to calculate measures of pairwise interactions among variables. Recall that minimal depth measure is defined by averaging the tree depth of variable $$i$$ relative to the root node. To detect interactions, this calculation can be modified to measure the minimal depth of a variable $$j$$ with respect to the maximal subtree for variable $$i$$ Ishwaran et al. (2011).

The randomForestSRC::find.interaction function traverses the forest, calculating all pairwise minimal depth interactions, and returns a $$p \times p$$ matrix of interaction measures. For each row, the diagonal terms are are related to the minimal depth relative to the root node, though normalized to minimize scaling issues. Each off diagonal minimal depth term is relative to the diagonal term on that row. Small values indicate that an off diagonal term typically splits close to the diagonal term, indicating an forest split proximity of the two variables.

The gg_interaction function wraps the find.interaction matrix for use with the provided plot and print functions. The xvar argument indicates which variables we’re interested in looking at. We again use the cache strategy, and collect the figures together using the panel=TRUE option.

plots the interactions for the target variable (shown in the red cross) with interaction scores for all remaining variables. We expect the covariate with lowest minimal depth (lstat) to be associated with almost all other variables, as it typically splits close to the root node, so viewed alone it may not be as informative as looking at a collection of interactive depth plots. Scanning across the panels, we see each successive target depth increasing, as expected. We also see the interactive variables increasing with increasing target depth. Of interest here is the interaction of lstat with the rm variable shown in the rm panel. Aside from these being the strongest variables by both measures, this interactive measure indicates the strongest connection between variables.

# Coplots

Conditioning plots (coplots) Cleveland (1993) are a powerful visualization tool to efficiently study how a response depends on two or more variables (Cleveland 1993). The method allows us to view data by grouping observations on some conditional membership. The simplest example involves a categorical variable, where we plot our data conditional on class membership, for instance on the Charles river logical variable. We can view a coplot as a stratified variable dependence plot, indicating trends in the RF prediction results within panels of group membership.

Conditional membership with a continuous variable requires stratification at some level. Often we can make these stratification along some feature of the variable, for instance a variable with integer values, or 5 or 10 year age group cohorts. However in the variables of interest in our Boston housing example, we have no “logical” stratification indications. Therefore we will arbitrarily stratify our variables into 6 groups of roughly equal population size using the quantile_pts function. We pass the break points located by quantile_pts to the cut function to create grouping intervals, which we can then add to the gg_variable object before plotting with the plot.gg_variable function. The simple modification to convert variable dependence plots into condition variable dependence plots is to use the ggplot2::facet_wrap command to generate a panel for each grouping interval.

We start by examining the predicted median home value as a function of lstat conditional on membership within 6 groups of rm “intervals”.

format: plain


text:
# [tex-eplain] eplain and XeTeX

Dorai Sitaram ds26gte at yahoo.com
Fri Apr 17 18:08:51 CEST 2009

```I was wondering if there are any experiences here using eplain with the XeTeX engine.  I'd like to use a Unicode font with eplain-on-XeTeX.  I don't need to be able to enter Unicode characters "as is" in the source, and it is fine (even preferable) to have ``, '', --, --- convert to the corresponding ligatures as in usual TeX.  However, I'd like to be able to specify Unicode characters using \char, i.e., \char"XYZW should typeset as U+XYZW.

While there is a wealth of info on using LaTeX with XeTeX, I can't seem to find c(l)ues on how to it with (e)plain.

Thanks for any advice/thoughts,

--d

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://tug.org/pipermail/tex-eplain/attachments/20090417/1327de3d/attachment.html
```


text:
# Difference between revisions of "Quest:Uberwald quests"

WARNING: This page contains Quest spoilers. ~ Solutions ~ Table ~ List ~ All ~ Category ~

Highlight to view quest spoilers.

## Escrow quests

#### "Sentimentalist", in which you demonstrated a little control over expression. (Quest level 1)

Find Pireria in the Escrow town hall.

She will instruct you to huggle her warmly, wuffle her gently, and hug her tightly.

## Magpyr Castle quests

#### "Hatched Out", in which you conquered the evil within to release the flame of goodness into the world. (Quest level 3)

#### "Maestro", in which you traded key for key and made beautiful music. (Quest level 5)

#### "Scraps Mender", in which you risked life, limb and bad hair to save a beloved pet. (Quest level 4)

#### "Superior Sportsman", in which you traveled long and far and vanquished a terrible menace. (Quest level 7)

Note that the vampires you need to kill to get the quest are as difficult as you'd expect them to be (which is EXTREMELY difficult - bring friends or be very large.

Travel through Uberwald to Magpyr Castle, find your way into the castle dungeons, and kill Count Magpyr. Attempts at skipping part of the route with a portal or passage may lead to you not getting the quest - it's most unsportsmanlike behaviour!

To get to the castle, follow the road east out of Escrow, and follow the signs. The trail will end at a river, with a sign warning that the bridge is out. Make your way across the river, approach the castle from the east, and make your way through to the point where a cliff path leads off to the east.

Now to get into the castle itself, follow the cliff path until you can climb the wall and enter the window. Once inside, search the frame of the painting to find the key of the door to the south. Explore this floor until you get to the garderobe.

Climb into the garderobe and you'll fall into a cesspit. Search the floor for a small key, then move the piles of filth to expose a door to the west. You are now outside the castle again, so will have to climb the walls again.

You now have access to the great hall, so once inside, find your way there and then do the Maestro quest to get access to Igor's room on the ground floor of the castle.

In Igor's room, search the mattress to find the dungeon key. Also search the stuffing to find a keyring for all the keys!

Go west into the dungeon. Continue on into the dungeon until you can see a gem in the carvings on the wall. If you try to get this gem, then Vlad will appear. Kill him and take his key. Go to the next room and do the same with Lacrimosa. Go north twice (if you have the keys you can just unlock the doors otherwise you'll have to pick the locks). In the room with the sarcophagus, open it and kill the count to get the quest.

Note:  you must be alone when you open the sarcophagus and kill the Count - if anyone else is in the same room (including clouds, balls of light, fruitbats, etc), he will disappear and the quest will fail. You'll need to come back and restart it some other time, once it resets. You do not need to repeat every other part of the quest, only the final part.

## Pictsie Barrows quests

#### "Intoxicating Linguist", in which you loosened a Feegle's tongue with strong drink. (Quest level 2)

Skills: Some ad.mo.swimming or the ability to cast Finneblaugh's Thaumic Float
Items: Scumble (a bottle with a pint of scumble can be found by searching Nanny Ogg's drink cabinet in nearby Lancre Town)
Follow the road from Creel Springs to Blackglass until you see an island on the map, and enter the barrows from the east (this requires either swimming across or floating across one room of the lake around the barrows). Find Fione mac Feegle and say "help". Then give her scumble. She seems to want about a pint (the amount of scumble that's in a bottle when you buy it) although it doesn't seem to have to be all at once. It doesn't matter if the scumble in the container is mixed with something else. Then "enroll", and Fione will ask you to repeat some phrases. There are four lessons, and you have to wait a bit before enrolling again. You can try enrolling before you hand over the scumble to check whether you've waited long enough. After the final lesson, you'll get some skills in Uberwaldean (and in Lancrastian culture) and the quest.


text:
# How does Nyquist bit rate formula relate Bandwidth, Signal Rate, and Bit Rate?

I know what each of Bandwidth, Signal rate, and Bit rate mean. But I am having trouble in their mathematical relationship with each other. I will use the notation of the textbook I am reading from (which I think is the cause of this confusion, and I don't know if I can name it here or not). Specifically, I am trying to understand how to derive the BW for a certain line code. The book defines $$\r = \frac{number~of~data~elements}{number~of~signal~elements}\$$ and relates the bit rate $$\(N)\$$ with the signal rate $$\(S)\$$ as follows:

$$\S = c \times \frac{N}{r}\$$ . . . . .(1)

Where $$\c\$$ is some constant. When calculating the bandwidth $$\(BW)\$$ of a line code the book uses formula (1) above and seems to substitute $$\c\$$ with $$\\frac{1}{2}\$$. My sources of confusion are:

1) $$\S\$$ is defined as the signal rate not bandwidth

2) Why always $$\c=\frac{1}{2}\$$?

3) In the plots the X axis units are $$\f/N\$$ (is this Hz/bps?)

I searched a lot and I think the answer is in Nyquit's bit rate formula which says:

$$\N=2\times BW \times \log_2(L) \$$

where $$\L\$$ is the number of signal levels which is equal to $$\2^r\$$. This means that:

$$\BW = N/2r\$$ . . . . . (2)

But this suggests that $$\BW = S\$$ (from (1) and (2)). This is where I get stuck. How should I understand this?

So if we go back to Nyquit's formula $$\N = 2 \times BW \times log_2L\$$ and take a look at the units we see that the units for $$\2 \times log_2L\$$ or equivalently $$\2 \times log_22^r = 2r\$$ should be bits/cyc, i.e.:

$$\\frac{bits}{sec} = \frac{cyc}{sec} \times \frac{bits}{cyc}\$$

We know that $$\r\$$ units are bits/sym. So for everything to line up correctly the units for the $$\2\$$ should be sym/cyc, i.e.:

$$\N(\frac{bits}{sec}) = 2(\frac{sym}{cyc}) \times BW (\frac{cyc}{sec}) \times r(\frac{bits}{sym})\$$

This is easy to see for the case with highest frequency for patterns of 101010... or 0101010... in NRZ line coding where we have 2 symbols (one 1 and one 0) per cycle of a pure sine wave. But what if the line coding was polar RZ? In this case a pure sine will not line up with the transmitted bits. So how can we know the symbols/cycle factor for any line code?

• Oops in addition to my response, you ask about the "plots" but there is no source or reference, so I'm not able to comment on the plots at all. – Mr. Snrub Mar 21 '19 at 19:41
• I don't know if I am allowed to include plots from a textbook. If this does not violate any rules I can include a figure. – osmak Mar 21 '19 at 19:42
• It's probably safer not to include it. – Mr. Snrub Mar 21 '19 at 19:51
• OK, I think I am starting to figure it out. To answer my question above, in polar RZ the pattern with highest change would be 111111... or 00000.... which lines up with a pure sine wave. Thus, we can take the sym/cyc to be 2 again. But here we have $r=1/2$ bits/sym which makes $BW = N$. Is the key always to find the pattern that matches with a sine wave? – osmak Mar 22 '19 at 7:51

You mention that you are getting stuck on they Nyquist bit rate formula. I think the sticking point for you is that the Nyquist formula only gives the upper bound for bit rate, for a given bandwidth. In other words, the Nyquist formula doesn't state that $$\BW=S\$$, but it could be interpreted to mean that $$\BW \geq S\$$.

A few other (hopefully) helpful bits:

• Signal rate $$\S\$$ is not necessarily equal to bandwidth. There are a number of different modulation schemes or even line level codings which could all have the same symbol rate but have different bandwidth (i.e. occupy a wider or narrower range of frequencies).

• Similarly a symbol (related to signal rate) can encode any number of individual bits (even a non-integer number in some fancier schemes), so signal rate is not necessarily equal to bit rate either.

• Honestly I'm not sure where $$\c\$$ comes from; I haven't seen that particular formula before. What's the source? If you look at this calculator you will see that their formula only cares about data rate, bits per symbol, and forward error correction (which we're not using here so presume that FEC=1), so there is no $$\c\$$ factor to be found.

UPDATE

A better treatment of the relationship between symbol rate (signal rate) and bandwidth can be found in this paper. Relevant excerpt:

The maximum feasible symbol rate and the bandwidth of the communication medium are directly proportional,
Symbol rate = α · Bandwidth
with a constant of proportionality α ≤ 2 (in practice, α ≈ 1.8).

• One of the problems is that the units of BW and S are different although the formulas are the same. So I think it is a problem saying that $BW \geq S$. The reference is Forouzan's Data Communications and Networks book. – osmak Mar 21 '19 at 19:46
• Sorry, I'm not familiar with this textbook. So $c$ is likely a conversion factor from (symbols/sec) to (Hz). – Mr. Snrub Mar 21 '19 at 19:52
• How can we convert cycles/second to symbols/second? – osmak Mar 21 '19 at 20:10
• By accounting for how we have physically encoded the signal. For a modulated signal, you could encode a single symbol as 16 carrier cycles, or 100 carrier cycles, or whatever, so the conversion between (symbols/second) and (cycles/second) is pretty intuitive. Even for a non-modulated signal, you can have the "raw" bits which have perfect vertical transitions between HIGH and LOW states, and then filtered signal (pulse shaping) which take less bandwidth. For example see eye pattern. – Mr. Snrub Mar 21 '19 at 20:21
• Actually here is a far better example of filtering line-encoded data to lower the bandwidth (i.e. fewer Hz for the same symbols/second): techbriefs.com/component/content/article/tb/techbriefs/… – Mr. Snrub Mar 21 '19 at 20:23


text:
# How to get the angle and speed to reach a movable point

This topic is 4218 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi all, I'm been trying to find a solution for this but my math skills are not very high and I haven't found anything yet. I hope you guys may give me some ideas. The problem is the following: - We have a 2D scenario. - There are two points in there, A and B. For each point we know its position (x,y), speed (V), and the current direction (0º to 360º) - We know the maximum speed that A can reach. (Vmax) - B may change its direction and speed at any moment. We don't know the maximum speed that B may reach. Problem: We need to know what angle and speed A should follow to reach B in the shortest amount of time possible. The algorithm will be called every second, since B may be changing its position and angle at any time. Any ideas? I really appreciate your help. Thanks

##### Share on other sites
Any reason why there is a maximum speed your 'chaser' can travel at?
Are these like cars, or like spaceships?
Inertia? Newtonian Physics?

How drastically can B change its position and direction? does it have simulated angular momentum and torque and acceleration? or is it totally an arcade object that can do crazy things with no prediction at all?

##### Share on other sites

Quote:
 Original post by haphazardlynamedAny reason why there is a maximum speed your 'chaser' can travel at?

Yes, because we are going to have different types of chasers at the same time
on the screen. Each chaser will have its own properties such as maximum speed.
(some chasers may be slower that others)
Quote:
 Are these like cars, or like spaceships?

Yes, like cars.
Quote:
 Inertia? Newtonian Physics?

No, we don't have to worry about that.

Quote:
 How drastically can B change its position and direction?

Just imagine you are driving a car. Do you remember the game 'Supersprint'?
Something like that.

Quote:
 does it have simulated angular momentum and torque and acceleration?

Simpler than that. No acceleration either.

Quote:
 or is it totally an arcade object that can do crazy things with no prediction at all?

Not too crazy. Usually the direction and speed are constant, but it may change
at any moment.

##### Share on other sites
Quote:
 Original post by JBourrieCraig W Reynolds has all the answers

Could you be more concrete? I checked that website but there are tons of articles.

Thanks

##### Share on other sites
If we assume B's direction and speed to remain constant, then I think the following algorithms will give you decent results. I don't guarantee anything, though. [wink]

Here's the pseudo-code:

Vec2 predictPosition(float dt, B b) {     // Assuming b.heading is in radians,     // b.velocity = b.speed * (cos(b.heading), sin(b.heading))     return b.position + b.velocity * dt;}float resolveImpactTime(A a, B b, int accuracy) {     float newEstimate = 0;     Vec2 projectedPosition = b.position;     for (int i = 0; i < accuracy; ++i) {          newEstimate = getCurrTime() + mag(projectedPosition - a.position) / a.maxSpeed;          projectedPosition = predictPosition(newEstimate - getCurrTime(), b);     }     return newEstimate;}Vec2 computeMovementDestination(A a, B b, int accuracy) {     return predictPosition(resolveImpactTime(a, b, accuracy) - getCurrTime(), b);}// To have A move towards B, simply make A move toward the point returned by computeMovementDestination().

A few notes on the method:

1) It assumes B is travelling with constant speed and heading. It should be straightforward to modify the predictPosition() function to take into account angular velocity. To be honest, though, I don't forsee this causing too many problems as long as you call computeMovementDestination() often enough.

2) I have actually used the iterative algorithm contained in resolveImpactTime() in practice before, so I know it works (provided I didn't make any typos). It's not the most efficient algorithm, and I'm sure there's an analytical solution, but it works. You shouldn't need to set accuracy to anything more than 10, at least not in my experience.

3) The code assumes A is just going to move at its maximum speed.

##### Share on other sites
Quote:
Original post by Staryon
Quote:
 Original post by JBourrieCraig W Reynolds has all the answers

Could you be more concrete? I checked that website but there are tons of articles.

Thanks

Steering behaviors

##### Share on other sites
OK
so you dont have intertia and stuff like that to worry about
and its a car

this makes it simpler, since you can basically assumme that you move where youre pointed, with no delay or inertia to compensate the angle for or whatever

First of all, if B is moving away from A, then A Must have a max speed greater than B or you Can't ever reach it.
So do this check first, or you'll get NULL solutions.

Id go with:
start by assuming that B won't change direction for now. If we take its current direction and speed, we can parametarize a formula for B's future position as a function of Time.
next assume that A can travel in any direction it wants, at its max speed from current location. Since we haevn't chosen the direction of A Yet, the possible future postion of A is a circle who's radius can be parametarized as a function of Time as well.

So we have two functions of Time now, PositionB(T) and RadiusA(T)
using pythagorean therorm on PositionB, we can convert to a formula of the distance from A to B.
getting: DistB(T)
DistB(T) and RadiusA(T) can now be combined as a system of equations to find the exact time T, which is the earliest possible point that A could reach B. (find the T condition where they match)

if we then plug T back into PositionB(T), we can get the location of this possible interception point. Aim A to steer towards this location at max speed.

Details of the math are left as an exercise... based on the number of variables, this should be solvable.

since your objects will change their paths over time(dont move straight as assumed), the above will need to be recalculated each update
It should converge though.

##### Share on other sites
haphazardlynamed,

Thanks for your reply. I'm trying to follow your algorithm and I think I got it, but I still have some problems with the functions.

The max speed should be included there, right?

nilkn, I'm still studying your algorithm. I'll get back to you later.

Thanks you guys!

##### Share on other sites
nilkn

Sorry about these questions, because I know they are too basic, but as I said I'm very new with all this.

1. Is Vec2 something like this?

struct{  float x;  float y;  float heading;}

2. In the predictPosition function, when you do
return b.position + b.velocity * dt;

Should I calculate that for x and y ? I'm not sure how to make that operation if 'position' has 2 coordinates (x,y)

3. Is mag(A) = sqrt (x*x + y*y ) ?

Sorry about these stupid questions :(

I think if I got an answer to these questions it will be easier for me to understand your algorithm.

##### Share on other sites
Quote:
 Original post by StaryonCould you give me more details about how to calculate RadiusA(T)?The max speed should be included there, right?

Radius is just the possible distance A can travel, with no information about the direction it is pointed.

In reality, since this is a car, and cars cannot make sharp turns instantly, rather than a circle of possible locations A can reach, it is probably really a irregular shape like a Cardiod (heart shape) or some kind of oval.
But since this calculation is going to be repeated each gameloop, the approximation should be good enough. If you want to be safer about it, you can Under-Estimate the radius of A's interception circle... and multiply it by .9 or something to give a saftey margin.

Regarding Vectors
generally, a Vector does not include a 'heading' value, but if you want to save that information too, it shouldn't hurt. Just make sure the heading really matches up with the x,y information when they change.

##### Share on other sites
haphazardlynamed, thanks for the explanation. I think I'm getting closer.

PositionB(T) = Vb * T
DistB(T) = sqrt ( (Xa-Xb)^2 + (Ya-Yb)^2 )

Now I need to combine RadiusA(T) and DistB(T) but I cannot find the way of getting T from DistB(T)
Do you know what I'm missing?

Thanks. I really really appreciate all your help.

##### Share on other sites
You need to break up the PositionB function into X and Y components and plug its parts into your Distance forumula (subsititute Xb and Yb), then Distance will have a T variable.

From there, if you equate DistB and RadiusA... you should be able to simplfy it to Quadratic Forumla.

*Edited*

See next post.

##### Share on other sites
Is this correct?

PositionB(T) = ( Xb+V*T , Yb+V*T )

So

DistB(T) = sqrt ( (Xa-(Xb+V*T))^2 + (Ya-(Yb+V*T) )^2 )

##### Share on other sites
Quote:
 Original post by StaryonIs this correct?PositionB(T) = ( Xb+V*T , Yb+V*T )SoDistB(T) = sqrt ( (Xa-(Xb+V*T))^2 + (Ya-(Yb+V*T) )^2 )

Assuming that 'V' is a vector like the one you asked about earlier.
what you want is the individual x and y coord pieces, not the entire vector in that formula

so
PositionB(t)= (Xb+V.x*t , Yb+V.y*t)

DistB(T) = sqrt ( (Xa-(Xb+V.x*T))^2 + (Ya-(Yb+V.y*T) )^2 )

equate:
RadiusA(T)=DistB(T)maxSpdA*T=sqrt ( (Xa-(Xb+V.x*T))^2 + (Ya-(Yb+V.y*T) )^2 )maxSpdA^2*T^2 = (Xa-(Xb+V.x*T))^2 + (Ya-(Yb+V.y*T) )^2 maxSpdA^2*T^2 = Xa^2 -2(Xb+V.x*T) + (Xb+V.x*T)^2 + Ya^2 -2(Yb+V.y*T) +(Yb+V.y*T)^2maxSpdA^2*T^2 = -2V.x*T + (Xb+V.x*T)^2 -2V.y*T +(Yb+V.y*T)^2 + Xa^2 -2Xb + Ya^2 -2Yb maxSpdA^2*T^2 = -2V.x*T + Xb^2 + 2(V.x*T) + V.x^2*T^2 -2V.y*T + Yb^2 +2V.y*T +V.y^2*T^2 + Xa^2 -2Xb + Ya^2 -2Yb maxSpdA^2*T^2 = + V.x^2*T^2 +V.y^2*T^2 -2V.x*T  + 2(V.x*T)  -2V.y*T  +2V.y*T  + Xa^2 -2Xb + Ya^2 -2Yb + Xb^2 + Yb^20 = +V.x^2*T^2 +V.y^2*T^2 -maxSpdA^2*T^2 +Xa^2 +Ya^2 +Xb^2 +Yb^2 -2Xb -2Yb This is Quadratic, solve using Quadratic Formula

You might want to work all that out separatly to doublecheck, since I Probably made mistakes...

##### Share on other sites
oh... what I meant with ´V´ is velocity and V.x and V.y should both be the same, right?

##### Share on other sites
Quote:
 Original post by Staryonoh... what I meant with ´V´ is velocity and V.x and V.y should both be the same, right?

Yes

##### Share on other sites
Quote:
 Orignal post by Staryonnilkn, I'm still studying your algorithm. I'll get back to you later.

My algorithm is similar to what is being illustrated in this image from the article JBourrie linked you to:

We are, of course, interested in the Pursuit path, not the Evade path. My method is to move A not towards B's current position, but towards where we predict B will be if it continues moving in a straight line until we hit it.

This is a difficult problem to solve analytically. Although I'm sure it's possible, I instead opted to use a simple numerical algorithm to compute how far forward in time we should project B's position. We then use this time value to actually compute the projected future position of B, and move A towards this point.

Quote:
 Orignal post by Staryon1. Is Vec2 something like this?

Yes, Vec2 simply referred to any valid class representing a 2-dimensional vector. In most cases, however, it would not contain a heading member. I also assumed the class had overloaded operators appropriate for a vector.

Quote:
 2. In the predictPosition function, when you doreturn b.position + b.velocity * dt;Should I calculate that for x and y ? I'm not sure how to make that operation if 'position' has 2 coordinates (x,y)

Yes. b.position and b.velocity are vectors, so that code could be expanded into:

Vec2 predictedPosition;
predictedPosition.x = b.position.x + b.velocity.x * dt;
predictedPosition.y = b.position.y + b.velocity.y * dt;

return predictedPosition;

The value dt represents how far forward in time to project B's position.

Quote:
 3. Is mag(A) = sqrt (x*x + y*y ) ?

Yes.

Keep in mind that the code snippet I posted was pseudo-code. It was intended to illustrate the concepts using code, not as a piece of code ready to copy-and-paste into your project.

##### Share on other sites
The simplest chase algorithm that looks good and works most of the time is:

for each frame    move towards where the target is now

That looks like this:

-me

##### Share on other sites
Your link points to a simulation which predicts the interception point, as described above.

##### Share on other sites
haphazardlynamed,
Thanks a lot for you effort and taking the time for doing those calculations. I am going to try to do the same thing by myself.
I think I finally understand how to do it! I will let you know how was everything tomorrow.

nilkn,

Quote:
 Keep in mind that the code snippet I posted was pseudo-code. It was intended to illustrate the concepts using code, not as a piece of code ready to copy-and-paste into your project.

Yes, It's just I want to understand the whole algorithm before trying to code anything.

Just one more thing, when you say

##### Share on other sites
Quote:
vector2 direction;direction.x = cos(b.heading);direction.y = sin(b.heading);b.velocity = b.speed * direction;

Thanks jyk!

##### Share on other sites
I'm back.

nilkn,

Today I'm trying your method. I think at this moment I understand both of them *THANKS A LOT TO YOU AND TO haphazardlynamed* , but I still have a couple of questions about yours.

1. I'm not sure about the getCurrTime() function. What should it return?
Should it return the number of seconds elapsed since you started the process?

2. Just for testing, I have implemented your pseudocode in C++.
This is how looks like.

struct stVelocity{  float x;  float y;};struct stPosition{  float x;  float y;};struct Car{  stPosition position;  float speed;  float heading;  float MaxSpeed;};Car a;Car b;int T;int accuracy;stPosition predictPosition ( float dt, Car b ){  stVelocity temp;  temp.x = b.speed * cos(b.heading);  temp.y = b.speed * sin(b.heading);  stPosition predictedPosition;  predictedPosition.x = b.position.x + temp.x * dt;  predictedPosition.y = b.position.y + temp.y * dt;  return predictedPosition;}float resolveImpactTime ( Car a, Car b, int accuracy ){  float newEstimate = 0;  stPosition projectedPosition;  projectedPosition.x = b.position.x;  projectedPosition.y = b.position.y;  stPosition Aux;  for ( int i=0; i< accuracy; ++ i )  {    Aux.x = projectedPosition.x - a.position.x;    Aux.y = projectedPosition.y - a.position.y;    newEstimate = T + sqrt( Aux.x*Aux.x + Aux.y*Aux.y ) / a.MaxSpeed ;    projectedPosition = predictPosition( newEstimate - T, b);  }  return newEstimate;}stPosition computeMovementDestination( Car a, Car b, int accuracy ){  return predictPosition( resolveImpactTime( a, b, accuracy) - T, b );}

And I have added some test data like this:

  accuracy = 5;  b.position.x = 0;  b.position.y = 1000;  b.speed = 40;  a.position.x = 0;  a.position.y = 0;  a.MaxSpeed = 40;  // 1 degree = 0.0174532925 radians  b.heading = 270 * 0.0174532925;  stPosition res;  res = computeMovementDestination( a, b, accuracy );

In that example, B is going South (270º) and A and B are going at the same speed. If A is located in (0,0) and B is located in (0,1000)
Shouldn´t they meet at (0,500)?
For some reason, the results that I get are (1.192488E-05,0)
I think Y shouldn´t be zero... because that´s the starting point of A

I think there is a problem when both have the same speed or A's maximum speed is slower that B's current speed.
Do you think there is something wrong with the algorithm?

Thanks

[Edited by - Staryon on May 25, 2006 1:56:51 PM]

##### Share on other sites

This topic is 4218 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628722
• Total Posts
2984396

• 25
• 11
• 10
• 16
• 14


text:
# Basics of Chemistry (G.O.B.) Homework Pack

Lead Author(s): Norbert Pienta

Student Price: Contact us to learn more

Homework and Practice Questions from Basics of Chemistry: General, Organic and Biological text.

# Chapter 1: Homework Questions

Homework Question 1.01

True or False: An element is defined by its number of electrons or number of protons.

A

True

B

False

Homework Question 1.02

How many electrons and protons are in these elements? Match the correct answer.

Premise
Response
1

Potassium

A

23

2

Magnesium

B

33

3

Vanadium

C

20

4

Nickel

D

79

5

Gold

E

19

6

Arsenic

F

13

7

Selenium

G

34

8

Bromine

H

12

I

28

J

35

Homework Question 1.03

How many electrons, protons and neutrons are in these elements? Match the correct response.

Premise
Response
1

Sodium

A

27; 27; 32

2

Barium

B

56; 56; 81

3

Cobalt

C

14; 14; 14

4

Tin

D

9; 9; 10

5

Boron

E

56; 56; 57

6

Silicon

F

7; 7; 7

7

Nitrogen

G

50; 50; 69

8

Fluorine

H

11; 11; 12

I

5; 5; 5

J

5; 5; 6

This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
Homework Question 1.08

List each set of isotopes in order of increasing number of neutrons (least to most).

A

At-218

B

Po-218

C

Rn-222

Homework Question 1.09

List each set of isotopes in order of increasing number of neutrons (least to most).

A

C-13

B

N-15

C

O-14

Homework Question 1.10

List each set of isotopes in order of increasing number of neutrons (least to most).

A

Li-7

B

B-8

C

Be-6

Homework Question 1.11

List each set of isotopes in order of increasing number of neutrons (least to most).

A

Pa-234

B

Th-234

C

U-234

This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
Homework Question 1.13

Use the atomic mass in the periodic table to determine which of the stable isotopes in each set is the predominant one in nature. Match the correct answer.

Premise
Response
1

Li-6; Li-7

A

N-15

2

C-12; C-13

B

L-6

3

N-14; N-15

C

C-13

D

C-12

E

Li-7

F

N-14

Homework Question 1.14

Which of these values for the mass of a neutron is the most precise?

A

1.0087 amu

B

1.009 amu

C

1.008 amu

D

1.01 amu

E

Can’t answer this without knowing the actual experimental value

Homework Question 1.15

How many significant figures are in each of these numbers? Match the correct answer.

Premise
Response
1

0.00142

A

5

2

0.1021

B

7

3

5.02

C

3

4

33.020

D

3

5

100.02

E

3

6

10.00

F

1

7

500

G

4

8

73600

H

5

9

173600.1

I

4

10

802000

J

3

This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
Homework Question 1.20

Identify and match the appropriate number in the requested unit.

Premise
Response
1

1.078 g in units of mg

A

727

2

1.078 g in units of μg

B

2.54 x 10$^{-5}$

3

1.078 g in units of kg

C

0.727

4

428 nm in units of m

D

1078

5

7.27 x 10$^{-10}$ m in units of nm

E

0.001078

6

2.54 x 10$^7$cm in units of km

F

1.078 x 10$^6$

G

4.28 x 10$^{-9}$

H

4.28 x 10$^{-7}$

I

254

Homework Question 1.21

Which sample is larger? Match the number that represents the larger of the two values.

Premise
Response
1

1) 1.0 mg or 2) 0.01 g

A

1

2

1) 1.0 μg or 2) 0.01 mg

B

1

3

1) 12 mg or 2) 0.12 g

C

2

4

1) 12 mg or 2) 1200 μg

D

1

E

2

F

2

Homework Question 1.22

Which answer is equivalent to 0.014 g?

A

14 mg

B

1400 μg

C

1.4 x 10$^{-6}$ kg

D

14‚000 μg

E

None of the above

Homework Question 1.23

Which answer is equivalent to 0.016 g?

A

160 x 10$^{-6}$ kg

B

1‚600 μg

C

1.61 x 10$^{-6}$ kg

D

16‚000 μg

E

16.1 mg

Homework Question 1.24

Which relationship is correct?

A

4.1 g > 4200 mg

B

4.2 mg > 4100 μg

C

4.2 ng > 4100 μg

D

All of the above

Homework Question 1.25

True or False: One mole of an element has the same number of atoms as one mole of any other element.

A

True

B

False

This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
Homework Question 1.28

Which set of elements does not have elements from the same group?

A

Na, K, Li

B

Ar, Ne, He

C

Mg, Cu, Ba

D

Ca, Sr, Mg

E

Kr, Ar, Ne

Homework Question 1.29

Which option best represents the orbitals in which electrons may be found for elements on the third row of the periodic chart?

A

1s, 2s, 2p, 3s, 3p

B

1s, 2s, 2p, 3s

C

1s, 2s, 2p

D

1s, 2s

E

1s

Homework Question 1.30

True or False: The halogens (Group 7A) have one more electron than the previous complete shell.

A

True

B

False

This Content is Locked
Only a limited preview of this text is available. You'll need to sign up to Top Hat, and be a verified professor to have full access to view and teach with the content.
Homework Question 1.32

Determine the percent value for each case, and match the correct answer.

Premise
Response
1

38 out of 82 points on exam 1

A

68%

2

17 out of 25 points on quiz 1

B

46%

3

57 out of 90 points on exam 2

C

65.5%

4

127 out of 175 points on the final

D

72.6%

E

63%

F

56%

G

48.4%

Homework Question 1.33

The air pollutant nitrogen dioxide NO$_2$ has been measured at 107 ppm in Pleasantville. What is the equivalent level in percent?

A

107

B

10.7

C

1.07

D

0.107

E

0.0107

Homework Question 1.34

Which answer has the forms of radiation listed in order of increasing energy (lowest to highest)?

A

Gamma < ultraviolet < infrared

B

X-ray < microwave < visible

C

Visible < infrared < gamma

D

Microwave < ultraviolet < gamma

E

Infrared < radiowave < gamma


text:
I think they are radicals anyway >_> heres some probs from my HW that i didnt get.
Code:
11. *figured it out*

31. *figured out*

41.

Find LCD

9                   3
---    and     ---
8x              2x+4

59.

9         (blank)
---   =    -----
x+3       2(x+3)

and

63.

x                        (blank)
-----             =        -----
x^2+6x+8         (X+4)(X+2)(X+1)
Hopefully those will format correctly..

anyway.

My book does a horrible job of showing how to do these.. -__-.. and purple math doesnt help me much either.

Thanks so much
~Cait

2. Originally Posted by Cait
bump? plz! this shouldnt be that hard!
you are right for 41.

3. ..I know those answers are right i got em out of the book!

What i need is how they GOT those answers lol.

4. 59.

9/(x+3) = 9/(x+3) * (2/2) = 2*9/2(x+3) = 18/2(x+3)

so the blank is 18

notice that we had a fraction where the denominator increased by a factor of 2. to maintain equality, that is, to keep the fraction at the same value it was before, the numerator also had to increase by factor of 2

5. Originally Posted by Cait
..I know those answers are right i got em out of the book!

What i need is how they GOT those answers lol.
o ok, sorry, i thought you came up with that. ok here's how:

6. Here's 63


text:
# The atria are separated from the ventricle by what type of valve?

There are actually 2 atrioventricular valves, namely, the $\textcolor{m a \ge n t a}{\text{mitral valve}}$, also called the $\textcolor{m a \ge n t a}{\text{bicuspid valve}}$, and the $\textcolor{g r e e n}{\text{tricuspid valve}}$.