Extends
Members
-
When commands are executed on a stream the actual execution occurs between renders. Consequently there can be a (possibly considerable) delay before execution occurs. Specifying a cancel level causes any current render to be cancelled so command execution can occur as soon as possible. If set to
0
then rendering is cancelled, and if possible rendering continues without restarting progression. If1
then cancelling will occur faster at the expense of always needing to restart. Any other value will not cancel rendering when executing commands- Default Value:
- -1
-
Controls error handling when an error occurs during command execution. If
true
then commands will continue to be processed, iffalse
processing will end at the first error and any subsequent commands will be aborted and get error resposes. Defaults to true.- Default Value:
- true
-
The pause count for this stream. When evaluated in a truthy manner will be
true
if paused andfalse
if not. -
The name of the render loop this stream is providing images from. Is \c undefined if the stream has not yet been started.
-
Whether this loop is streaming or not.
Methods
-
Executes a single command on this render loop and returns a
Promise
that resolves to an iterable. The iterable will contain up to 2 results- if
want_response
istrue
then the first iterable will be the result of the command or a RS.Command_error. - if
wait_for_render
istrue
then the last iterable will be a RS.Stream~Rendered_result containing the first rendered image that contains the result of the command.
The promise will reject in the following circumstances:
- there is no WebSocket connection.
- the WebSocket connection has not started (IE: RS.Service#connect has not yet resolved).
Name Type Description command
RS.Command The command to execute.
options
Object optional Name Type Default Description want_response
Boolean optional If
true
then the returned promise will not resolve until the command response is available and the response will be in the first iterable.wait_for_render
Boolean optional If
true
, the promise will not resolve until the RS.Service#event:image event that contains the result of this command is about to be emitted. The last iterable in the resolved value will be contain the rendered image.cancel_level
Number this.cancel_level optional If provided then this overrides the streams cancel level.
continue_on_error
Boolean this.continue_on_error optional If provided then this overrides the streams continue on error.
Fires:
Returns:
Type Description Promise A Promise
that resolves to an iterable. - if
-
Pauses emiting RS.Service#event:image events for this stream. Note the images are still transmitted from the server, the callback is just not called. Pause calls are counted so you need to call RS.Stream#resume the same number of times as pause before events are emitted begins again.
Returns:
Type Description Number The pause count, IE: the number of times resume will need to be called to start emitting events again. -
Executes a pick operation on the render loop. The returned promise resolves with an array of pick results. If no objects were under the point then the array will be empty.
Note that stream picking is only supported in RealityServer 6.2 and above.
The returned promise will reject in the following circumstances:
- there is no WebSocket connection.
- the WebSocket connection has not started (IE: RS.Service#connect has not yet resolved).
- this stream is not yet streaming
- no position is provided.
- arguments are the wrong type or \p position has a negative coordinate
- the render loop is no longer available.
- the connected RealityServer does not support picking on a stream.
Name Type Description position
Vector2 The screen space position of the pick.
size
Vector2 optional The screen space rectangular size of the pick. Defaults to a 1x1 pixel area.
cancel_level
Number optional The cancel level override. Defaults to 1.
Returns:
Type Description Promise A Promise
that resolves to an array of pick results. Each element in the pick result array will be an object containing the following properties: world_point (Vector3), picked_object_name (String), path (String[]). -
Executes a pick operation on the render loop. The returned promise resolves with an array of pick results. If no objects were under the point then the array will be empty.
Note that stream picking is only supported in RealityServer 6.2 and above.
The returned promise will reject in the following circumstances:
- there is no WebSocket connection.
- the WebSocket connection has not started (IE: RS.Service#connect has not yet resolved).
- this stream is not yet streaming
- no position is provided.
- arguments are the wrong type or \p position has a negative coordinate
- the render loop is no longer available.
- the connected RealityServer does not support picking on a stream.
Name Type Description pick
Object Object defining what to pick
Name Type Description position
Vector2 The screen space position of the pick.
size
Vector2 optional The screen space rectangular size of the pick. Defaults to a 1x1 pixel area.
max_levels
Number optional Controls the number of rays that may be cast, per ray, during the picking operation. A level of 1 will only trace primary rays. Any other value will continue tracing rays through the scene until nothing was hit or the maximum depth is exhausted, with a value of 0 indicating unconstrained depth. This parameter has no effect when using versions of RealityServer prior to 6.3.
params
Object optional Render loop handler defined parameters used to control the pick operation.
cancel_level
Number optional The cancel level override. Defaults to 1.
Returns:
Type Description Promise A Promise
that resolves to an array of pick results. Each element in the pick result array will be an object containing the following properties: world_point (Vector3), picked_object_name (String), path (String[]). -
queue_commands (options)RS.Command_queue
-
Returns a RS.Command_queue that can be used to queue up a series of commands to be executed on this render loop
Name Type Description options
Object optional Name Type Default Description wait_for_render
Boolean optional If
true
then when this queue is executed it will also generate aPromise
that will resolve when the RS.Service#event:image event that contains the results of the commands is about to be emitted.cancel_level
Number this.cancel_level optional If provided then this overrides the streams cancel level.
continue_on_error
Boolean this.continue_on_error optional If provided then this overrides the streams continue on error.
Returns:
Type Description RS.Command_queue The command queue to add commands to and then execute. -
Resumes emiting RS.Service#event:image events for this stream if the pause count has reduced to
0
.Name Type Default Description force
Boolean false optional If
true
then forces display to resume regardless of the pause count.Returns:
Type Description Number The pause count, IE: the number of times resume will need to be called to start emitting events again. -
Sends a single command to execute on this render loop and returns an
Array
ofPromises
that will resolve with the responses. The array will contain up to 2Promises
.- if
want_response
istrue
then the firstPromise
will resolve to the result of the command or a RS.Command_error. - if
wait_for_render
istrue
then the lastPromise
will resolve to a RS.Stream~Rendered_image when the first rendered image that contains the results of the commands is generated.
Name Type Description command
RS.Command The command to execute.
options
Object optional Name Type Default Description want_response
Boolean optional If
true
then thereponse
promise resolves to the response of the command. Iffalse
then the promise resolves immediately to undefined.wait_for_render
Boolean optional If
true
, then therender
promise resolves to a RS.Stream~Rendered_result just before the RS.Service#event:image event that contains the result of this command is emitted.cancel_level
Number this.cancel_level optional If provided then this overrides the streams cancel level.
continue_on_error
Boolean this.continue_on_error optional If provided then this overrides the streams continue on error.
Fires:
Throws:
-
This call will throw an error in the following circumstances:
- there is no WebSocket connection.
- the WebSocket connection has not started (IE: RS.Service#connect has not yet resolved).
- Type
- RS.Error
Returns:
Type Description Array.<Promise> An Array
ofPromises
. These promises will not reject. - if
-
Sets parameters on a stream. Returns a promise that resolves with the parameters have been set. The returned promise will reject in the following circumstances:
- there is no WebSocket connection.
- the WebSocket connection has not started (IE: RS.Service#connect has not yet resolved).
- this stream is not yet streaming
- updating the parameters failed
Name Type Description parameters
Object The parameter to set. Supported parameters include:
Name Type Description encoder_name
String optional the name of the stream encoder to modify or the default encoder if omitted.
image_format
String optional the streamed image format.
pixel_type
String optional the streamed image pixel type.
quality
String optional the streamed image quality.
encoders
Object optional named encoder parameters.
Returns:
Type Description Promise A promise that resolves with the set parameter response or rejects with the error message. -
Starts streaming images from a render loop on this stream. Note that a stream can only stream images from one render loop at a time. Returns a promise that resolves when the stream has started. The promise will reject in the following circumstances:
- there is no WebSocket connection.
- the WebSocket connection has not started (IE: RS.Service#connect has not yet resolved).
- if the given render loop is already being streamed by this service.
- starting the stream failed, usually this occurs if the render loop cannot be found or invalid streaming data is provided.
Once the stream has started RS.Stream#event:image events will be emitted on both the stream object and the original RS.Service object every time a rendered image is received from the server.
Starting from version 2.0.1 the special
image_format
value ofNONE
can be supplied. This will establish a 'command and control' stream that will not send images to the client but can still be used to edit the RealityServer scene. Note that it is not possible to start or stop streaming images once a stream has started.Name Type Description render_loop
String | Object If a
String
then the name of the render loop to stream. Provide an object to specify additional streaming data.Name Type Description render_loop_name
String the name of the render loop to stream.
image_format
String optional the streamed image format.
pixel_type
String optional the streamed image pixel type.
quality
String optional the streamed image quality.
encoders
Object optional an object containing named stream encoder settings, each defining image_format, pixel_type and quality parameters. Note that all possible named encoders must be specified at start time. It is not possible to add new named encoders using RS.Stream#set_parameters, only modify existing settings.
Fires:
Returns:
Type Description Promise A promise that resolves when the stream has started. -
Stops streaming from a render loop.
Returns:
Type Description Promise A promise that resolves when the stream is stopped or rejects on error. -
Utility function to update the camera on this stream's render loop.
While it is possible to simply use individual commands to update the camera this method is more efficient as changes will be collated on the server and applied as a single update between render calls.
The returned promise will reject in the following circumstances:
- there is no WebSocket connection.
- the WebSocket connection has not started (IE: RS.Service#connect has not yet resolved).
- this stream is not yet streaming
- no data is provided.
- updating the camera information failed
- wait for render is true but the connected RealityServer does not support this with update camera.
Name Type Description data
Object Object specifying the camera to update. Supported format is:
Name Type Description cancel_level
Number optional Cancel level to use when updating.
wait_for_render
Boolean optional If true then the promise will resolve when the new camera data is available in a rendered image.
camera
Object optional Properties to update on the camera
Name Type Description name
String The name of the camera to update
aperture
Number optional The aperture width of the camera.
aspect
Number optional The aspect ratio of the camera.
clip_max
Number optional The yon clipping distance.
clip_min
Number optional The hither clipping distance.
focal
Number optional The focal length to set.
frame_time
Number optional The frame time of the camera, in seconds.
offset_x
Number optional The horizontal plane shift.
offset_y
Number optional The vertical plane shift.
orthographicn
Number optional If the camera is orthographic or not.
resolution_x
Number optional The width of the camera.
resolution_y
Number optional The height of the camera.
window_xh
Number optional The right edge of the render sub-window in raster space.
window_xl
Number optional The left edge of the render sub-window in raster space.
window_yh
Number optional The top edge of the render sub-window in raster space.
window_yl
Number optional The bottom edge of the render sub-window in raster space.
attributes
Object optional Arbitrary attributes to set on the camera. Property names are the attribute names to set. Each property value should be an object containing the following:
Name Type Description value
* The attribute value to set.
type
String The type of the attribute to set.
camera_instance
Object optional Properties to update on the camera instance.
Name Type Description name
String The name of the camera instance to update.
transform
RS.Math.Matrix4x4 optional The camera instance transform to set
attributes
Object optional Arbitrary attributes to set on the camera instance. Property names are the attribute names to set. Each property value should be an object containing the following:
Name Type Description value
* The attribute value to set.
type
String The type of the attribute to set.
Returns:
Type Description Promise A promise that resolves with the result of the camera update or when the camera data is available in a render if \c wait_for_render is c true.
Type Definitions
-
A single image of a render result.
Properties:
Name Type Description width
Number The image width.
height
Number The image height.
image
Uint8Array The rendered image
mime_type
String The mime type of the rendered image.
render_type
String The renderer defined type for the image. Typically 'result'.
-
The result of an image render.
Properties:
Name Type Description render_loop_name
String The name of the render loop this image was rendered by.
result
Number The render result,
0
for success,1
for converged,-1
cancelled render, other negative values indicate errors.images
Array.<RS.Stream~Rendered_image> An array of images that have been rendered.
statistics
Object Rendering statistics.
Events
-
Image event.
Fired whenever a renderer image is available on a stream. This event will be fired on RS.Service for all streams and on each individual RS.Stream
Name Type Description image
RS.Stream~Rendered_result The rendered result


Visual Soar is a development environment for Soar applications. It is written in Java which means in order to run Visual Soar you must have a Java Runtime Environment installed.
Visual Soar contains tools that directly support many Soar related programming tasks. For example, creation of the operator heirarchy, maintence of the source tree, along with support for templates. In addition, upon supplying Visual Soar with information about what you expect to be in working memory, Visual Soar can check to make sure your productions are consistent, and in some cases complete attribute or values for you.
The three key components of Visual Soar are the operator window, rule editor, and data map. The operator window displays the heirarchy of operators you have in your system. The rule editor allows you to edit and manipulate rules for the operators. The data map displays the all possible structures that might exist in working memory when the rules are supposed to fire.
The operator window is where you define the structure of your system. It directly supports subgoaling and a heirarchy of operators. Here is where you directly manipulate the logical structure of your system. Entities that exist in this system are:
The root, the basis of the project, and will be named the same thing as what you called your project. You can add suboperators to the root, and access the top-state view of the data map from the root.
Operators come in three flavors: high-level, low-level, and linked. High-level operators are ones that produce a substate and have suboperators. Low-level operators produce no substate. Linked operators are operators with the same name as another high-level operator in the system, and produce the same substate. Every type of operator has an associated rule file where productions associated with that operator are saved. High-level operators also have an associated view of the data map where the suboperator productions will be checked against.
Files aid organization. Files are where you place things that are to be read into the system, but are not productions, productions that are not assciated with any operator, and productions that relate to state rather than operators (elaborations) among others. The only place where user's can add file entities is under the elaborations folder. An elaborations file is automatically created for you under a high-level operator. If you do not want the file parsed by a Check All Productions Command, start the name of the file with an "_". Note, this will also work for operators.
Folders are also organizational aids. There are always two, elaborations and all. All is a place to put operators that don't belong in any particular place in heirarchy because they can fire in all states. Elaborations is a folder that contain files with productions that relate to the top-state, fire in all possible states, or other productions that do not fit well within the hierarchy.
The rule editor allows you to edit the actual productions associated with operator or file. It provides basic text editing facilities. It also allows for template insertion along with a tab-completion type facility called "soar complete" which will complete some attribute or values for you.
The data map provides a way to enter information about what you expect to be in working memory when a production fires. It is supposed to represent the superset of all things that can be in working memory. Visual Soar uses this information to make sure your productions are consistent with this data map. The data map also uses type information to make sure values have the right type.
The different value types you can create in the data map are:
An identifier is equivalent to a soar identifier and can have a value.
An enumeration is usually an enumeration of strings that represent possible values for that attribute.
An integer is an integer number that is either ranged or not.
A float is a floating point number that is either ranged or not.
A string can be basically anything besides an identifier.
Note on mixed types: sometimes attributes have mixed-type values. You can simulate that by creating more than one attribute-value with the same attribute name but different value types.
To see how these components interact in the creation of a real system, we will be creating a wandering agent for Tank Soar.
The first thing to do to create your agent is select New Project... from the File menu (or hit ctrl n). A new agent dialog will come up; type in the name of your agent. I'm going to call mine Alphonse. Then either browse or type in your agent's path. Since I have tanksoar installed in my c:\temp\tank\TankSoar24\ directory, I chose c:\temp\tank\TankSoar24\agents for my agent's path. Then hit New to create the agent.
The operator window opens with our new agent. By default Visual Soar creates two folders: all, and elaborations. Along with the _firstload file, which will be the first file to load. The all folder is used to create operators that don't fit within the operator hierarchy and the elaboration folder is used to add elaborations that are either associated with the top-state or common to all states.
Next, we will open the data map for our top-state, so right-click on the root node of the operator window, which in my case is Alphonse and select Open DataMap from the context menu.
The DataMap window opens in the right view pane. Now, we will add common attribute-values. Expand the io attribute. You should see input-link and output-link. Right-click on input-link. A context menu will come up asking you what attribute-values you want to add. Select Add Identifier.... In the dialog, type in for the attribute name: blocked and hit Ok. You should now see the attribute blocked hanging off the input-link. You might need to expand the input-link to see it. You now have the basics of adding attribute values to the data map. Something to note, attribute-values can be linked, that is a new attribute is created but it points to the same value as another attribute. Attributes can be linked by ctrl-shift dragging attribute-values to the new desired parent in the data map (this also works across different views/windows of the data map). If a link is made to a primitive WME (anything besides an identifier) it's behavior is the same as making an independent copy. However, if a link is made to an identifier, the name of the link and original node will be independent, but their children will be shared.
When Visual Soar created your project, it created some productions to set up the type of task decomposition that Visual Soar supports. These productions create a top-state link on all states. Name the substate the same thing as the selected superstate operator. The last thing they do is name the top-state the same thing as your project name. New data map views are created assuming these productions exist. So you probably shouldn't modify them. These productions are found in the elaborations folder. They are in the _all and top-state files. When you right-click on _all and select Open Rules You should see a rule editor open with the following productions:
sp {elaborate*state*name
(state <s> ^superstate.operator.name <name>)
-->
(<s> ^name <name>)
}
sp {elaborate*state*top-state
(state <s> ^superstate.top-state <ts>)
-->
(<s> ^top-state <ts>)
}
The elaborate*state*name production copies the operator name from the superstate down to the substate. The elaborate*state*top-state similarly copies down the top-state link. You can now close the rule editor.
You might want to open the top-state file also, in this file you will find the following productions:
sp {elaborate*top-state*name
(state <s> ^superstate nil)
-->
(<s> ^name Alphonse)
}
sp {elaborate*top-state*top-state
(state <s> ^name Alphonse)
-->
(<s> ^top-state <s>)
}
The elaborate*top-state*name names the top-state the same as our project name. The elaborate*top-state*top-state production makes the initial link from the top-state to itself so that the elaborate*state*top-state will work.
Re-open the _all rule file. Our tank will be using a general io mechanism. In order for this to work we need to enter the following productions in the _all rule window.
sp {apply*operator*create-action-command
(state <s> ^operator <o>
^top-state.io.output-link <ol>)
(<o> ^actions <act>)
(<act> ^<att> <value>)
-->
(<ol> ^<att> <value>)
}
sp {apply*operator*remove-command
(state <s> ^operator <o>
^top-state.io.output-link <ol>)
(<ol> ^<att> <value>)
(<value> ^status complete)
-->
(<ol> ^<att> <value> -)
}
The apply*operator*create-action-command production copies the actions off an operator and places them on the output-link through the top-state. (Note that the tutorial does this by copying a link to io to all substates and copying items to that. I feel that going through the top-state is a more general way of dealing with the problem and only slightly more verbose. But the big advantage is that it is the way that Visual Soar directly supports so it saves you some work manipulating the data map.) The apply*operator*remove-command checks the output-link for any completed commands and frees up their memory.
Now that we have some ground rules set, we are ready to start specifying behavior for our tank. For this example, we will just build a wandering tank. So first thing we need to do is create a operator, so we right-click on Alphonse in the operator window and select Add a Suboperator... from the context menu, for the operator name type in wander.
Now wander is in our operator hierarchy, so right click on wander and select Open Rules.
Since all our tank is going to do is wander, we will make that the only proposal.
Note: only proposals for operator wander go into the wander operator file. These rules must match against the top-state.
sp {propose*wander
(state <s> ^name Alphonse)
-->
(<s> ^operator <o>)
(<o> ^name wander)
}
You can check this production against the data map to see if there are any mistakes.
Since wander is a high-level goal, we need to decide exactly what is wandering. I decided on the following behavior:
Each one of these will be its own operator:
So right click on wander and select Add a Suboperator... from the context menu, and type in powerdown. Now do the same for move, turn and turn-around.
Next, we need to set up the DataMap for wander, since wander has suboperators it also has a DataMap, so right-click on wander and select Open DataMap and tile it with the top-state DataMap named Alphonse.
Since these are low-level operators, and they will perform actions using our generalized application rules. We will need to create an actions attribute underneath each operator in the wander data map. To do this, expand top-state and io, ctrl-shift drag the output-link to one of the operator attributes in the wander DataMap. Now, operator has an attribute named output-link, right-click on output-link, select Rename... from the context menu and type actions into the input dialog box. Link this attribute value (ctlr-shift drag) to the rest of the operators.
Our concern in wandering is that we don't want to use any power. Visual Soar created an elaborations file, because wander is a subgoal. So open this elaborations file, and type in the following production
sp {wander*elaborate*using-power
(state <s> ^name wander
^top-state.io.input-link <il>)
(<il> ^<< radar-status shield-status >> on)
-->
(<s> ^using-power true)
}
Now, add ^using-power true to the wander DataMap.
Now we know if we are using power, so close elaborations, open powerdown and type in the following production:
sp {wander*propse*powerdown
(state <s> ^name wander
^using-power)
-->
(<s> ^operator <o>)
(<o> ^name powerdown)
(<o> ^actions <a>)
(<a> ^radar.switch off
^shields.switch off)
}
open move's rule file and type in
sp {wander*propose*move
(state <s> ^name wander
-^using-power
^top-state.io.input-link.blocked.forward no)
-->
(<s> ^operator <o>)
(<o> ^name move)
(<o> ^actions <a>)
(<a> ^move.direction forward)
}
similarly, for turn type in
sp {wander*propose*turn
(state <s> ^name wander
-^using-power
^top-state.io.input-link.blocked <b>)
(<b> ^forward yes
^{ << left right >> <dir> } no)
-->
(<s> ^operator <o> + =)
(<o> ^name turn
^actions.rotate.direction <dir>)
}
Finally, for turn-around type in
sp {wander*propose*turn-around
(state <s> ^name wander
-^using-power
^top-state.io.input-link.blocked <b>)
(<b> ^forward yes ^left yes ^right yes)
-->
(<s> ^operator <o>)
(<o> ^name turn-around
^actions.rotate.direction left)
}
Now we have finished our wandering Tank Agent. To be able to load our agent into TankSoar you must save it at least once. Alphonse is now able to be loaded into Tank Soar environment at Alphonse.soar.


Elliptic curves with prescribed good reduction#
Construction of elliptic curves with good reduction outside a finite set of primes
A theorem of Shafarevich states that, over a number field \(K\), given any finite set \(S\) of primes of \(K\), there are (up to isomorphism) only a finite set of elliptic curves defined over \(K\) with good reduction at all primes outside \(S\). An explicit form of the theorem with an algorithm for finding this finite set was given in “Finding all elliptic curves with good reduction outside a given set of primes” by John Cremona and Mark Lingham, Experimental Mathematics 16 No.3 (2007), 303-312. The method requires computation of the class and unit groups of \(K\) as well as all the \(S\)-integral points on a collection of auxiliary elliptic curves defined over \(K\).
This implementation (April 2009) is only for the case \(K=\QQ\), where in
many cases the determination of the necessary sets of \(S\)-integral
points is possible. The main user-level function is
EllipticCurves_with_good_reduction_outside_S()
, defined in
constructor.py. Users should note carefully the following points:
(1) the number of auxiliary curves to be considered is exponential in the size of \(S\) (specifically, \(2.6^s\) where \(s=|S|\)).
(2) For some of the auxiliary curves it is impossible at present to
provably find all the \(S\)-integral points using the current
algorithms, which rely on first finding a basis for their Mordell-Weil
groups using 2-descent. A warning is output in cases where the set of
points (and hence the final output) is not guaranteed to be complete.
Using the proof=False
flag suppresses these warnings.
EXAMPLES: We find all elliptic curves with good reduction outside 2, listing the label of each:
sage: [e.label() for e in EllipticCurves_with_good_reduction_outside_S([2])] # long time (5s on sage.math, 2013)
['32a1',
'32a2',
'32a3',
'32a4',
'64a1',
'64a2',
'64a3',
'64a4',
'128a1',
'128a2',
'128b1',
'128b2',
'128c1',
'128c2',
'128d1',
'128d2',
'256a1',
'256a2',
'256b1',
'256b2',
'256c1',
'256c2',
'256d1',
'256d2']
Secondly we try the same with \(S={11}\); note that warning messages are
printed without proof=False
(unless the optional database is
installed: two of the auxiliary curves whose Mordell-Weil bases are
required have conductors 13068 and 52272 so are in the database):
sage: [e.label() for e in EllipticCurves_with_good_reduction_outside_S([11], proof=False)] # long time (13s on sage.math, 2011)
['11a1', '11a2', '11a3', '121a1', '121a2', '121b1', '121b2', '121c1', '121c2', '121d1', '121d2', '121d3']
AUTHORS:
John Cremona (6 April 2009): initial version (over \(\QQ\) only).
- sage.schemes.elliptic_curves.ell_egros.curve_key(E1)#
Comparison key for elliptic curves over \(\QQ\).
The key is a tuple:
if the curve is in the database: (conductor, 0, label, number)
otherwise: (conductor, 1, a_invariants)
EXAMPLES:
sage: from sage.schemes.elliptic_curves.ell_egros import curve_key sage: E = EllipticCurve_from_j(1728) sage: curve_key(E) (32, 0, 0, 2) sage: E = EllipticCurve_from_j(1729) sage: curve_key(E) (2989441, 1, (1, 0, 0, -36, -1))
- sage.schemes.elliptic_curves.ell_egros.egros_from_j(j, S=[])#
Given a rational j and a list of primes S, returns a list of elliptic curves over \(\QQ\) with j-invariant j and good reduction outside S, by checking all relevant quadratic twists.
INPUT:
j – a rational number.
S – list of primes (default: empty list).
Note
Primality of elements of S is not checked, and the output is undefined if S is not a list or contains non-primes.
OUTPUT:
A sorted list of all elliptic curves defined over \(\QQ\) with \(j\)-invariant equal to \(j\) and with good reduction at all primes outside the list
S
.EXAMPLES:
sage: from sage.schemes.elliptic_curves.ell_egros import egros_from_j sage: [e.label() for e in egros_from_j(0,[3])] ['27a1', '27a3', '243a1', '243a2', '243b1', '243b2'] sage: [e.label() for e in egros_from_j(1728,[2])] ['32a1', '32a2', '64a1', '64a4', '256b1', '256b2', '256c1', '256c2'] sage: elist=egros_from_j(-4096/11,[11]) sage: [e.label() for e in elist] ['11a3', '121d1']
- sage.schemes.elliptic_curves.ell_egros.egros_from_j_0(S=[])#
Given a list of primes S, returns a list of elliptic curves over \(\QQ\) with j-invariant 0 and good reduction outside S, by checking all relevant sextic twists.
INPUT:
S – list of primes (default: empty list).
Note
Primality of elements of S is not checked, and the output is undefined if S is not a list or contains non-primes.
OUTPUT:
A sorted list of all elliptic curves defined over \(\QQ\) with \(j\)-invariant equal to \(0\) and with good reduction at all primes outside the list
S
.EXAMPLES:
sage: from sage.schemes.elliptic_curves.ell_egros import egros_from_j_0 sage: egros_from_j_0([]) [] sage: egros_from_j_0([2]) [] sage: [e.label() for e in egros_from_j_0([3])] ['27a1', '27a3', '243a1', '243a2', '243b1', '243b2'] sage: len(egros_from_j_0([2,3,5])) # long time (8s on sage.math, 2013) 432
- sage.schemes.elliptic_curves.ell_egros.egros_from_j_1728(S=[])#
Given a list of primes S, returns a list of elliptic curves over \(\QQ\) with j-invariant 1728 and good reduction outside S, by checking all relevant quartic twists.
INPUT:
S – list of primes (default: empty list).
Note
Primality of elements of S is not checked, and the output is undefined if S is not a list or contains non-primes.
OUTPUT:
A sorted list of all elliptic curves defined over \(\QQ\) with \(j\)-invariant equal to \(1728\) and with good reduction at all primes outside the list
S
.EXAMPLES:
sage: from sage.schemes.elliptic_curves.ell_egros import egros_from_j_1728 sage: egros_from_j_1728([]) [] sage: egros_from_j_1728([3]) [] sage: [e.cremona_label() for e in egros_from_j_1728([2])] ['32a1', '32a2', '64a1', '64a4', '256b1', '256b2', '256c1', '256c2']
- sage.schemes.elliptic_curves.ell_egros.egros_from_jlist(jlist, S=[])#
Given a list of rational j and a list of primes S, returns a list of elliptic curves over \(\QQ\) with j-invariant in the list and good reduction outside S.
INPUT:
j – list of rational numbers.
S – list of primes (default: empty list).
Note
Primality of elements of S is not checked, and the output is undefined if S is not a list or contains non-primes.
OUTPUT:
A sorted list of all elliptic curves defined over \(\QQ\) with \(j\)-invariant in the list
jlist
and with good reduction at all primes outside the listS
.EXAMPLES:
sage: from sage.schemes.elliptic_curves.ell_egros import egros_get_j, egros_from_jlist sage: jlist=egros_get_j([3]) sage: elist=egros_from_jlist(jlist,[3]) sage: [e.label() for e in elist] ['27a1', '27a2', '27a3', '27a4', '243a1', '243a2', '243b1', '243b2'] sage: [e.ainvs() for e in elist] [(0, 0, 1, 0, -7), (0, 0, 1, -270, -1708), (0, 0, 1, 0, 0), (0, 0, 1, -30, 63), (0, 0, 1, 0, -1), (0, 0, 1, 0, 20), (0, 0, 1, 0, 2), (0, 0, 1, 0, -61)]
- sage.schemes.elliptic_curves.ell_egros.egros_get_j(S=[], proof=None, verbose=False)#
Returns a list of rational \(j\) such that all elliptic curves defined over \(\QQ\) with good reduction outside \(S\) have \(j\)-invariant in the list, sorted by height.
INPUT:
S
– list of primes (default: empty list).proof
–True
/False
(defaultTrue
): the MW basis for auxiliary curves will be computed with this proof flag.verbose
–True
/False
(defaultFalse``
): ifTrue
, some details of the computation will be output.
Note
Proof flag: The algorithm used requires determining all S-integral points on several auxiliary curves, which in turn requires the computation of their generators. This is not always possible (even in theory) using current knowledge.
The value of this flag is passed to the function which computes generators of various auxiliary elliptic curves, in order to find their S-integral points. Set to
False
if the default (True
) causes warning messages, but note that you can then not rely on the set of invariants returned being complete.EXAMPLES:
sage: from sage.schemes.elliptic_curves.ell_egros import egros_get_j sage: egros_get_j([]) [1728] sage: egros_get_j([2]) # long time (3s on sage.math, 2013) [128, 432, -864, 1728, 3375/2, -3456, 6912, 8000, 10976, -35937/4, 287496, -784446336, -189613868625/128] sage: egros_get_j([3]) # long time (3s on sage.math, 2013) [0, -576, 1536, 1728, -5184, -13824, 21952/9, -41472, 140608/3, -12288000] sage: jlist=egros_get_j([2,3]); len(jlist) # long time (30s) 83
- sage.schemes.elliptic_curves.ell_egros.is_possible_j(j, S=[])#
Tests if the rational \(j\) is a possible \(j\)-invariant of an elliptic curve with good reduction outside \(S\).
Note
The condition used is necessary but not sufficient unless S contains both 2 and 3.
EXAMPLES:
sage: from sage.schemes.elliptic_curves.ell_egros import is_possible_j sage: is_possible_j(0,[]) False sage: is_possible_j(1728,[]) True sage: is_possible_j(-4096/11,[11]) True


My love of languages led me to obtain a degree in English Literature
from the University of Wyoming in 1995. After college
I became a medical laboratory technician to satisfy my other love, science.
I attended Clover Park Technical College where I recieved an Associates Degree
in Medical Laboratory Science. After doing that
for a number of years, I decided to return to the languages and enrolled in
Epicodus to become a computer programmer.
My Intersts and Hobbies Are:
- I enjoy gardening; I like to grow a variety of flowers such as Sweet
Peas, Roses, Lobelias and Morning Glories.
- Traveling: I love to visit London and other European cities.
- Music-listening.
- Writing: I am currently writing a memoir.
Projects I have worked on so far:
- Hello-World: Telling the world "hello" in seven different languages.
You will find this at:Git Hub
- Cookie Recipe: A recipe for baking delicious chocolate chip cookies!
You will find this at:Git Hub
- Vacation Site: A website featuring Paris, France and many of its most popular sites to see.
You will find this at:Git Hub
- My First Webpage2: My first website ever created by myself and a fellow student.
You will find this at:Git Hub
- Wikipedia Rebuild: A website in which another student and I attempted to recreate a Wikipedia website.
You will find this at:Git Hub


About
Partner With Us
Get Involved
Donate
Get Started
Browse the Library
Teach with Oppia
<EMAIL_ADDRESS>© {{currentYear}} The Oppia Foundation
Terms of Service
Privacy Policy


Write code in C/C++, Java, Python, Fortran, Perl...
You do not need parallel programming experience
Requires no knowledge of graphics APIs
Access to native instructions and memory
Get started - CUDA Toolkit
Driver
Compiler nvcc
Development, profiling and debugging tools
Various libraries
Programming guides, and API reference
Example codes
Get started
CUDA C Programming Guide
The advent of multicore CPUs and many-core GPUs means that mainstream processor chips are now
parallel
systems. Furthermore, their parallelism continues to scale with Moore’s law. The challenge is to
develop
application software that transparently scales its parallelism to leverage the increasing
number
of
processor cores...
At its core are three key abstractions – a hierarchy of thread groups, shared memories, and
barrier
synchronization...
...data parallelism...
CUDA terminology
Heterogeneous programming
Serial code → Host
Parallel code → Device
Kernels
C functions, that when called, are executed N times in parallel by N different threads on the device.
As
opposed to only once, like a regular C functions.
Thread hierarchy
A kernel is executed by thousands of threads in parallel, organized as a hierarchy.
dim3 is a structure with three properties, x, y and z.
How to determine unique thread IDs?
With this execution configuration
dim3 dimGrid(3); // 3 blocks in 1D
dim3 dimBlock (5); // 5 threads per block in 1D
How are kernels executed?
The GPU core is the stream processor (SP)
Able to run a single sequential thread
SPs are grouped into streaming multiprocessors (SMs)
Can execute hundreds of threads concurrently
SMs is basically a SIMD processor
There are multiple SMs per GPU
NVIDIA's consumer graphics cards
How are kernels executed - Grid
Grid → GPU
An entire grid is handled by a single GPU chip
The GPU is responsible for allocating blocks to SMs that has available capacity
How are kernels executed - Block
Block → Streaming multiprocessor
A block is never divided across multiple streaming multiprocessors
How are kernels executed - Thread
Thread → Stream processor
Each stream processor handles one or more threads in a block
Synchronization
Point in the program where threads stop and wait
When all threads have reached the barrier, they can proceed
Inside kernel
__syncthreads() // Synchronize threads within a block
Memory hierarchy
Memory management
Inside kernel
float variable; // Local memory (registers)
__shared__ float variable; // Shared memory
__device__ float variable; // Global memory
Memory management
Allocate GPU memory:
cudaMalloc(......)
Copy data to/from GPU:
cudaMemcpy(......, cudaMemcpyHostToDevice)
cudaMemcpy(......, cudaMemcpyDeviceToHost)
Free GPU memory:
cudaFree(......)
CUDA C Programming Guide...
At its core are three key abstractions – a hierarchy of thread groups, shared memories, and
barrier
synchronization...
CUDA example - Vector addition
Typical program execution
Allocate memory and initialize data on CPU
Allocate memory on GPU
Transfer data from CPU to GPU
A slow operation, aim to minimize this!
Lunch kernel
Transfer results back from GPU to CPU
Free CPU and GPU memory
The problem to solve
C = A + B
Vector addition on CPU
for(int i=0; i<N-1; i++) {
C[i] = A[i] + B[i];
}
Only one thread of execution
No explicit parallelism
Allocate memory on CPU
int main() {
// Size of vectors
int n = 50000;
// Size, in bytes, of each vector
size_t bytes = n * sizeof(float);
// Allocate memory for the host vectors
float *h_A = (float *) malloc(bytes);
float *h_B = (float *) malloc(bytes);
float *h_C = (float *) malloc(bytes);
// Copy the host vectors to the device
cudaMemcpy(d_A, h_A, bytes, cudaMemcpyHostToDevice);
cudaMemcpy(d_B, h_B, bytes, cudaMemcpyHostToDevice);
Lunch kernel
// Execution configuration
int threadsPerBlock = 256;
int blocksPerGrid =(n + threadsPerBlock - 1) / threadsPerBlock;
// Launch kernel
vectorAdd<<<blocksPerGrid, threadsPerBlock>>>(d_A, d_B,
d_C, n);
printf("Kernel launch with %d blocks of %d threads\n",
blocksPerGrid, threadsPerBlock);
Transfer results back from GPU to CPU
// Copy the result back to the host result vector
cudaMemcpy(h_C, d_C, bytes, cudaMemcpyDeviceToHost);
Show the result
// Sum up host result vector and print result divided by n,
// this should equal 4
float sum = 0;
for(int i=0; i<n; i++) {
sum += h_C[i];
}
sum = sum / n;
printf("Final result: %f\n", sum);
#include <stdio.h>
#include <cuda_runtime.h>
__global__ void vectorAdd(float *d_A, float *d_B, float *d_C, int n) {
// Calculate the thread ID
int i = blockIdx.x * blockDim.x + threadIdx.x;
// Make sure we do not go out of bounds
if (i < n) {
d_C[i] = d_A[i] + d_B[i];
}
}
Visualized
Example: Vector addition on GPU
$ Kernel launch with 196 blocks of 256 threads
$ Final result: 4.000000
Execution time CPU vs. GPU - Assume we do 64 additions
CPU uses 2 ns for 1 addition. CPU execution time = number of additions * time it takes for 1 addition = 64 * 2 ns = 128 ns
GPU uses 10 ns for 1 addition. GPU execution time = the time it takes for 1 addition (we assume we have enough resources to do the
all additions in parallel) = 10 ns
Final comments
Performance guidelines
High arithmetic intensity: Math (maximize) / memory (minimize)
High number of threads: Keep the GPU busy. Need enough threads to hide memory latency
Avoid thread divergence (caused by if, switch, do, for, while statements): Different execution
paths -> serialisation (SIMT)
Large data sets: Plenty to operate on in parallel
Minimize CPU-GPU memory transfers: Slow operation
Use single precision if possible
...
Why use GPUs?
Computing power. It is powerful
Number crunching: 1 GPU ~= 4 TFLOPS ~= Small cluster
It is a cheap commodity hardware
FLOPS per NOK
It is everywhere
Sold hundreds of millions programmable GPUs
Power
FLOPS per Watt
NVIDIA - Tesla cards
No graphic output! What?
Aimed at scientific computing rather than gaming
Tested and burned-in for long-running calculations
GPGPU - Areas
Graphics
Multimedia
Ultrasound Imaging
Molecular Dynamics
Seismic Imaging
Astrophysic
Data Mining
Finance
Physics
Chemistry
...
More Responsibility
GPU programming puts more responsibility on the programmer than "regular" programming
For example the programmer must decide and explicitly code:
How to partition the computation into a grid, blocks, and threads
Where (in what kind of memory) to put each piece of data for best performance
The end!
CPU + GPU = combination of flexibility and performance
GPUs can make your simulations go faster. So that you can not slack off....
Getting started with GPU programming is easy, being able to fully utilize GPU hardware is
hard...


This inspection checks that Velocity file references (in #include and #parse directives) are resolved correctly


ARTICLE II [OLD]
INTESTATE SUCCESSION AND WILLS
§§560:2-101 to 560:2-902 REPEALED. L 1996, c 288, pt of §6.
ARTICLE II
INTESTATE SUCCESSION AND WILLS
PART 1. INTESTATE SUCCESSION
Cross References
Applies only to the estates of decedents dying after January 1, 1997; for other effect and transition provisions, see §560:8-201.
§560:2-101 Intestate estate. (a) Any part of a decedent's estate not effectively disposed of by will passes by intestate succession to the decedent's heirs as prescribed in this chapter, except as modified by the decedent's will.
(b) A decedent by will may expressly exclude or limit the right of an individual or class to succeed to property of the decedent passing by intestate succession. If that individual or a member of that class survives the decedent, the share of the decedent's intestate estate to which that individual or class would have succeeded passes as if that individual or each member of that class had disclaimed the intestate share. [L 1996, c 288, pt of §1]


iTunes 4.7 freeze w/Synergy 1.5b.
-
anonymous
Since I've updated to Syergy 1.5b, iTunes 4.7 has been showing some strange behavior. For instance, with iTunes launched, but no music playing, there have been many instances when it simply will not respond. If I click on it, it say "not responding" and I have to Force Quit. If I put the cursor over Synergy, it shows the spinning beach ball. For the last couple of days, I've not launched Synergy in an attempt to see if iTunes would freeze, and it hasn't at all. When I upgraded to 1.5b, I uninstalled the previous installation, and then installed 1.5b. I've checked permissions, run Disk Utilities, and Diskwarrior to make sure that there are no issues with the drive itself. I miss using Synergy. Can you offer any suggestions?
Thanks!
Jeff
-
Greg Hurrell
Have a look at the bug tracking database, and in particular, this report:
http://wincent.com/a/support/bugs/show_bug.cgi?id=39
I personally am not sure if this is specific to 1.5b and/or 4.7. I haven't seen the issue myself. There may be something else triggering it, or it may just be random. But if you can contribute some details to the report it would be useful in trying to narrow down the causes.
Reply
This topic is now closed.


Gateway
BOT
08-Feb-19 06:46 PM
[dscrdeql] <SwimedDragon> Just a question, but when the reward contracts are activated, are you still thinking of some way to let staking pools use EQLI on their sites to ''stake'' coins or do you want to keep away from that?
[dscrdeql] <SwimedDragon> I do get there's trust issues and it's also people's own decision to store coins somewhere, but if reward contracts are able to be hosted per 100k coins on a staking website, it would definitily mean a good advertising spot for EQLI so people get to know more about EQLI's existance
[dscrdeql] <SwimedDragon> Or can these staking sites do whatever they want and list coins without the teams wanting them to do so?
[dscrdeql] <CowboyCrypto- Founder> they dont need permission to do it.
[dscrdeql] <CowboyCrypto- Founder> they can do it on their own free will, I have actually been talking to the developers at Utrum who have implemented a similar feature called Proof-of-Lock, where it all acts teh same but its done on an API instead of contractually based.
[dscrdeql] <CowboyCrypto- Founder> example you have 100k coins sitting in your wallet for 90 days. You get rewarded at 90 days, etc etc
[dscrdeql] <SwimedDragon> Do you know if some of the staking sites around use fee's to get coins listed like an exchange does? I've seen some staking sites doing it, but I'm not sure if all are doing it
[dscrdeql] <CowboyCrypto- Founder> I have no idea honestly.
[dscrdeql] <CowboyCrypto- Founder> back when i was promoting masternodes we used sites like Masternodes.pro
[dscrdeql] <SwimedDragon> If some of them are free and they are around for quiete some time, it could provide a chance for free advertising about EQLI and I'm sure people would look up on EQLI if they see it getting listed and announced on a staking website
[dscrdeql] <SwimedDragon> I mean, I have some shitcoins on some staking pools and most staking pools often have tons of shitcoins on it, but if they list a new coin, I'm alway's checking it out
[dscrdeql] <SwimedDragon> I know some coins have their own staking service hosted by someone from their own team, which is probably the best you could putt trust in if you're going to buy and stake their coin if you haven't got enough to stake good amounts yourself. But could something similiar be done if there's demand for that in the future?


{% extends 'base.html' %} {% block title %}About - Geomancer{% endblock %} {% block content %}
Geomancer is a project with a simple goal: to create a prototype tool that will help journalists easily mash up data based on shared geography.
It’s such a common task for data-savvy journalists that it’s easy to underestimate the difficulty. But on deadline, it can become daunting. It requires locating the right data set to provide context, getting it into shape and into place to join it with the data in hand and then merging the two data sets — all before the reporter can even get started with the analysis.
We aim to take some of that complexity out of the way by providing an intuitive interface to discover available data sets for a given geography and supplement the data in hand with the relevant values. We’ll know it’s working when it appears too easy.
Read more on the Geomancer blog >
Uploading your data to our server is necessary for Geomancer to work. We do not, however, store any of it permenantly. All processing is done in memory, so when you end your session, your uploaded data will automatically be deleted.
Please note: Do not upload any sensitive data to this site! If you have sensitive data that you want to use with Geomancer, look in to setting up your own instance.
If you want to access Geomancer programatically, we have an API for you! The Geomancer API can be used to list the geographic types and data sources we support and geomance posted spreadsheets.
A few things to know:
HTTP GET
or HTTP POST
http://geomancer.io/api/SOME-ENDPOINT
/api/data-sources/
list all available data sources
This returns all available data sources and tables in Geomancer.
Query Parameters
All query parameters are optional.
| Parameter | Default value | Description |
|---|---|---|
geo_type |
none | Filter the data sources by a specific geography type. See /api/geo-types/ for the full list of options. |
Response
| Parameter | Description | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
machine_name |
Name of data source | ||||||||||||||||||
description |
Data source description | ||||||||||||||||||
info_url |
Link to more information on data source | ||||||||||||||||||
base_url |
API url root | ||||||||||||||||||
data_types |
|
Example
http://geomancer.io/api/data-sources/
Returns a list of data sources and tables in Geomancer
/api/geo-types/
list all supported geographic types
This returns all supported geographic types and related data sources in Geomancer.
Query Parameters
All query parameters are optional.
| Parameter | Default value | Description |
|---|---|---|
geo_type |
none | Geography type. Used to fetch a single geographic type and related data sources. |
Response
| Parameter | Description | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
machine_name |
Name of geographic type | ||||||||||||
human_name |
Friendly name of geographic type | ||||||||||||
formatting_notes |
Instructions on expected format for this geographic type | ||||||||||||
formatting_example |
Example of properly formatted geographic type | ||||||||||||
tables |
|
Example
http://geomancer.io/api/geo-types/
Returns a list of all supported geographic types and related data sources in Geomancer
/api/geomance/
run geomancer on a posted file
Once you've figured out what geographic types and data sources you want to use, you can geomance a spreadsheet via an API call by posting a file and a JSON configuration as a multipart POST
.
Once a task is started, geomancer will start processing the request and give you back a link to your file with the additional columns by polling the /api/geomance-results/<session_key>/
endpoint.
Post Parameters
| Parameter | Default value | Description |
|---|---|---|
file |
none | Must be in CSV, XLS or XLSX format. See more on spreadsheet formatting |
form |
none |
Field definitions in a string encoded JSON blob like so:
{ 10: { 'type': 'city_state', 'append_columns': ['total_population', 'median_age'] } } The key is the zero-indexed position of the columns within the posted spreadsheet. The value is a dict containing the geographic type and the columns to append. The values in that list can be fetched from You can also match on two columns. To do so, separate the column indexes and geotypes with a semicolon like so: { 10;2: { 'type': 'city;state', 'append_columns': ['total_population', 'median_age'] } } In this example, column 10 contains the |
Response
Responds with a key that can be used to poll for results.
| Parameter | Description |
|---|---|
session_key |
Unique identifier of a task. Poll the /api/geomance-results/<session_key>/ endpoint to get your result and see when the task finishes |
/api/geomance-results/<session_key>/
query the status of a geomancer task
Query Parameters
| Parameter | Default value | Description |
|---|---|---|
session_key |
none | Unique identifier of a task. Returned after posting to the /api/geomance/ endpoint |
Response
Responds with a key that can be used to poll for results.
| Parameter | Description |
|---|---|
ready |
Returns true if the task is completed, false otherwise. |
result |
Link to download your completed file. Only available if ready is true |
status |
Success or failure of task. Only available if ready is true |
All of the code for this project is open source. You can find, view and fork it on GitHub.
Technologies used:
We built this as an open & extensible platform, so that others can adapt this tool to their data needs. If you know how to program in Python, you can contribute new data to Geomancer (otherwise, post your request to our Google Group).
See documentation for contributing data >Geomancer is a project of Associated Press and was implemented by DataMade, a civic technology company. We are:
Have a question for us or having trouble using Geomancer? Join our Google Group.
Notice a bug or want to contribute to this project? Get involved on GitHub.


Google Vision is a very powerful tool used by many companies big and small, it works by uploading an image or taking a new picture, sending this to the API and returning the information requested, in our situation we use this technology to display information about a landmark


We think that this demonstration will be useful for chant and musical scholars, so we have made it available online. Our current interface provides the following methods of content search:
* Neume names: Search by sequences of neume names, e.g., "torculus torculus punctum scandicus"
* Strict pitch sequence: Untransposed pitch sequences, e.g., "edcdeee", "fgagfde", "cbcbcbc".
* Transposed pitch sequence: Same as strict, but will match pitch sequences diatonically.
* Contour: The "Parsons code": u(p), d(own), and r(epeat), e.g., "uuddrrd".
* Intervals: Number of semitones +/-, e.g., "+2 +2 +3 -1 -1 +2".
* Text: OCR'ed text results, e.g., "alleluia", "pastor". Note: The OCR results are very poor.
Search results will be highlighted on the original page images alongside the search results. You can use the "next" and "previous" buttons to step through the results.
The current search supports sequences up to a length of 10 for all musical queries. Note that this means that for the pitch sequences this is a length of 10, but for the contour and intervals it is a maximum length of 9.
The Liber Usualis is a valuable resource for musical scholars. As a compendium of the most common chants used by the Catholic Church, it is useful for identifying the origins of chants used in polyphonic compositions.
Using Optical Music Recognition and Optical Text Recognition, we have processed a scanned version of the Liber and made its contents searchable. This is a proof-of-concept demonstration for the larger task of providing search capabilities for all digitized musical works.
This work was done as part of the SIMSSA project.
Hosted by the Distributed Digital Music Archives & Libraries Lab of McGill University.
Contact us with questions or comments.


Automatic Eye Dropper
About 3 million Americans have glaucoma and a significant portion of them are the elderly who need help to take their eye drop medication. We design an automated eye-dropper that detects the patients eye, adminsters the eye drop and registers if the adminstration was successful. We modify a head-mounted display for this purpose and add an onboard computer that deals with the control processes.
Eye Region Detection
To detect the patient’s eye record a clip of the patient moving their eye. Because of the controlled nature of our setup we can compute the variance of the sequence of images and segment out the eye region. The variance can be color thresholded to give us a segmentation of the eye region. An example of the mean and variance is shown in the figure below.
Blink Detection
We want to detect eye blinks of the patient so that we can plan when to administer the eye drop and know if it was successfully delivered. To detect blinks we collect videos from 25 patients with three different eye colors at three different illumination conditions. We have a total of 75 videos each 200 frames long. We automatically annotate the frames(as open/close) by asking the participants to actively open or close their eyes and synchronizing the commands with the realtime video sequence. We crop out the eye region and train a classifier to classify each frame as open or close. We train this classifier using the annotated videos we collected and successfully detect blinks.
Eye drop tracker
To control when and how much eye drops will be dispensed we design a motorized setup that can be controlled by the on-board computer. We 3D print the device and fix it on the head mounded device. We position the illumination such that the light from the LEDs gets total internally reflected and enters the camera. This illuminates the drop making it look as a bright white streak in the image. If we fit a line to this image using Hough Transform we get the trajectory of the water drop as shown in the figure below.