Human Capital Software Firm CDP Holdings Begins U.S. IPO Process
by Donovan JonesSummary
- CDP Holdings has filed to raise $125 million in a U.S. IPO, although the final figure may differ.
- The firm provides human capital management software [SaaS] to organizations throughout Asia.
- CDP has grown impressively but its trajectory is flattening and the firm is producing increasing losses and cash burn.
Quick Take
CDP Holdings (CDP) has filed to raise gross proceeds of $125 million from a U.S. IPO, according to an F-1 registration statement.
The firm provides human capital management software solutions in China.
CDP has grown quickly but that growth is decelerating while the firm produces increasing operating losses and cash burn.
Company & Technology
Shanghai, China-based CDP was founded in 2004 as ‘CDP Information Technology’ to develop and provide human capital management software solutions in China through its ‘CDP EcoSaaS’ integrated software platform.
Management is headed by Founder, Chairman and CEO Wei (Wayne) Wang, who was previously Chief Information Officer at Schneider Electric Greater China.
CDP Holdings has developed the cloud-based ‘CDP EcoSaaS’ human capital management platform that covers payroll, tax and social security management, benefits programs, workforce management, and other HR applications, which provides services through Shanghai Caishuo Talent Information in China.
Management says that, according to a 2019 market research report by Frost & Sullivan (which frequently sells its services to IPO firms), the firm was the #1 company in China to provide complete and localized human capital management solutions, with a track record of providing services for over 3,600 organizations, of which more than 1,000 were group customers, as of September 30, 2019.
Additionally, the firm is one of the top three cloud-based workforce management service providers in China in terms of revenue in the first half of 2019.
Management says CDP has built subsidiaries in Hong Kong, Singapore, Australia and India, through which it anticipates to expand its operational coverage.
Investors in CDP included Investor AB, CBC Capital, Morgan Sanley (MS), Sumitomo Corporation, and Eight Road Ventures, among others.. Source: Crunchbase
Customer Acquisition
The firm holds an annual industry conference, named the CDP EcoSaaS Partners Summit, and markets its offerings through other channels, such as online search engine marketing, other user conferences, executive events, trade shows, industry events, regional user group meetings and online customer community, as well as participation and sponsorship in third-party marketing events.
Additionally, CDP has a dedicated sales team tasked with converting possible customers to paying ones.
The firm has one large customer, Best Inc., which accounted for 38.9% of its total revenue for the nine months ended September 30, 2019.
Sales and marketing expenses as a percentage of revenue have been rising, per the table below:
| Selling & Marketing | Expenses vs. Revenue |
| Period | Percentage |
| Nine Mos. Ended Sept. 30, 2019 | 6.1% |
| 2018 | 5.5% |
| 2017 | 5.1% |
Source: Company registration statement
The sales & marketing efficiency rate, defined as how many dollars of additional new revenue generated by each dollar of sales & marketing spend, was 3.1x in the most recent nine-month period, as shown in the table below:
| Selling & Marketing | Efficiency Rate |
| Period | Multiple |
| Nine Mos. Ended Sept. 30, 2019 | 3.1 |
| 2018 | 5.6 |
Source: Company registration statement
Average Revenue per Customer/User has been uneven, per the table below:
| Average Revenue Per | Customer | |
| Period | ARPC | Variance |
| Nine Mos. Ended Sept. 30, 2019 | $30,158 | -26.8% |
| 2018 | $41,218 | 17.9% |
| 2017 | $34,957 |
Source: Company registration statement
Per management, its revenue retention rate in 2018 was 120.2% for its 2016 cohort of customers.
A number above 100% is considered good as it indicates the firm is increasing its revenue from a given cohort of customers over time.
Market & Competition
According to a 2019 market research report by Fortune Business Insights, the global human capital management market was valued at $15 billion in 2018 and expected to reach more than $30 billion by 2026.
This represents a forecast CAGR of 9.4% from 2018 to 2016, as the chart below illustrates:
The main factors driving forecast market growth are the increasing need for workforce management and core HR for strategic decisions taking while planning talent acquisition and recruitment, and a growing emphasis on digitization.
The North America region accounted for $7.27 billion of the global market in 2018 and is expected to maintain its dominance through the forecast years due to increasing adoption of workforce analytics and employee experience platforms.
Major competitors that provide or are developing human capital management solutions include:
- Automatic Data Processing (ADP)
- Accenture (ACN)
- IBM (IBM)
- Infor
- NetSuite (ORCL)
- Oracle (ORCL)
- SAP (SAP)
- Ultimate Software
- Workday (WDAY)
Source: Sentieo
Financial Performance
CDP’s recent financial results can be summarized as follows:
- Growing topline revenue, but at a decelerating rate
- Increasing gross profit and uneven margin
- Growing operating losses and negative operating margin
- Increasing use of cash in operations
Below are relevant financial metrics derived from the firm’s registration statement:
| Total Revenue | ||
| Period | Total Revenue | % Variance vs. Prior |
| Nine Mos. Ended Sept. 30, 2019 | $ 95,328,000 | 23.1% |
| 2018 | $ 104,198,000 | 45.3% |
| 2017 | $ 71,731,176 | |
| Gross Profit (Loss) | ||
| Period | Gross Profit (Loss) | % Variance vs. Prior |
| Nine Mos. Ended Sept. 30, 2019 | $ 9,956,000 | 26.4% |
| 2018 | $ 10,428,000 | 33.0% |
| 2017 | $ 7,840,147 | |
| Gross Margin | ||
| Period | Gross Margin | |
| Nine Mos. Ended Sept. 30, 2019 | 10.44% | |
| 2018 | 10.01% | |
| 2017 | 10.93% | |
| Operating Profit (Loss) | ||
| Period | Operating Profit (Loss) | Operating Margin |
| Nine Mos. Ended Sept. 30, 2019 | $ (23,857,000) | -25.0% |
| 2018 | $ (8,367,000) | -8.0% |
| 2017 | $ (6,012,206) | -8.4% |
| Net Income (Loss) | ||
| Period | Net Income (Loss) | |
| Nine Mos. Ended Sept. 30, 2019 | $ (22,036,000) | |
| 2018 | $ (4,363,000) | |
| 2017 | $ (1,068,235) | |
| Cash Flow From Operations | ||
| Period | Cash Flow From Operations | |
| Nine Mos. Ended Sept. 30, 2019 | $ (7,612,000) | |
| 2018 | $ (590,000) | |
| 2017 | $ (4,414,853) |
Source: Company registration statement
As of September 30, 2019, the company had $20.7 million in cash and $42.7 million in total liabilities. (Unaudited, interim)
Free cash flow during the twelve months ended September 30, 2019, was a negative ($7.8 million).
IPO Details
CDP has filed to raise $125 million in gross proceeds from an IPO of ADSs representing Class A shares.
Class A shareholders will be entitled to one vote per share and Class B shareholders, who include existing shareholders, will have ten votes per share.
The S&P 500 Index no longer admits firms with multiple classes of stock into its index.
Per the firm’s latest filing, the firm plans to use the net proceeds from the IPO as follows:
to invest in research and development to enhance our CDP EcoSaaS platform; to enhance our sales and marketing efforts to expand our service coverage in China and overseas; and to satisfy general corporate purposes.
Management’s presentation of the company roadshow is not currently available.
Listed underwriters of the IPO are BofA Securities, Citigroup, and Haitong International.
Commentary
CDP is a Chinese enterprise SaaS firm attempting to access U.S. public capital markets for its expansion plans.
There haven’t been many enterprise SaaS firms coming from China to U.S. markets in recent years.
The firm’s financials indicate it is growing revenue and gross profit smartly but growth is decelerating as the company has passed through $100 million in annual revenue.
Furthermore, operating losses and operating cash burn are mounting.
Sales and marketing expenses as a percentage of revenue have been rising.
The firm’s dollar retention rate was 120.2% for 2018, which is an impressive figure and indicates management’s efforts are generating negative net churn.
The market opportunity for human capital management software is large and expected to grow at an enviable rate, so the firm has quite positive industry trends in its favor.
Like many Chinese firms seeking to tap U.S. markets, the firm operates within a VIE structure or Variable Interest Entity. U.S. investors would only have an interest in an offshore firm with contractual rights to the firm’s operational results but would not own the underlying assets.
This is a legal gray area that brings the risk of management changing the terms of the contractual agreement or the Chinese government altering the legality of such arrangements. Prospective investors in the IPO would need to factor in this important structural uncertainty.
CDP’s IPO will be an interesting test for the U.S. IPO market, as the firm is showing strong but decelerating growth while producing increasing losses and cash burn.
I’ll provide an update when we learn more IPO details from management.
Expected IPO Pricing Date: To be announced.
Gain Insight and actionable information on U.S. IPOs with IPO Edge research.
Members of IPO Edge get the latest IPO research, news, and industry analysis. Get started with a free trial!
Disclosure: I/we have no positions in any stocks mentioned, and no plans to initiate any positions within the next 72 hours. I wrote this article myself, and it expresses my own opinions. I am not receiving compensation for it (other than from Seeking Alpha). I have no business relationship with any company whose stock is mentioned in this article.


|
Online FIR |
         |
Simpliest way to file a FIR in India. |
                     |
Shruti Verma DGP,Team leader |
Shefali Goyal DSP |
Surabhi Pal DSP |
Shubhangi Tiwari ACP |
Anshi Sharma ACP |
Vaishnavi Trivedi |
Garima Tiwari |
Nidhi Mishra |
Mansi Saxena |
Ayushi Srivastav |
Mahima Srivastav |


Delicious
THE BEST FOOD BLOG ON THE WEB
For the fig-swirl: Melt butter over medium heat in a saucepan. Add brown sugar and stir to dissolve. Halve all of the figs and toss in the saucepan with water and lemon juice. Cook over medium hear, stirring frequently, until you have a chunky-jammy mixture. Add salt with one or two stirs, set aside and let cool completely.
Ice cream: In a small pot over medium heat, combine milk, and granulated sugar until sugar is completely dissolved and the milk is just barely lukewarm. Whisk in the egg yolks. Set mixture in the fridge and wait until the fig mixture is cooled. Using an ice cream machine pour liquids into the frozen basin and process according to the manufacture instructions, i.e., let spin and thicken for 20 minutes before adding mascarpone, fig jam mixture,and the nuts. Continue to process for +/- 10 minutes. Pour semi-frozen mixture into a pyrex dish or glass tupperware. Freeze for at least two hours before serving.


The Muse ***1/2
rated PG-13 October/USA Films 97 minutes starring Albert Brooks, Sharon Stone, Andie MacDowell, Jeff Bridges written by Albert Brooks and Monica Johnson directed by Albert Brooks
I love L.A. Despite the traffic, L.A. is the best place to live if you're looking for a casual lifestyle. Los Angeles has been a major player in films from "Chinatown" to "Short Cuts", perhaps because all the major players in film reside there; the city translated as "city of angels"(how ironic; I guess all they all moved away). An overlooked aspect of Albert Brooks' terrific comedy "The Muse" will be the way Brooks' presents L.A., as a paradise-like city where you could sit home during the day, write a bit of your new action screenplay, and make enough so that your family could live in a Palisades estate.
"The Muse" is Woody Allen territory, both in the way the film business is presented and in the slightly supernatural mystical storyline. However, what "The Muse" will gain its notoriety for is for being Sharon Stone's return to comedy(her last one was "Irrenconcilable Differences", her first major film role) after years of forgettable dramatic performances("Casino" being an exception). Although her role as the title character won't recieve an Oscar, her natural charm shines through and she is surprisingly likable.
"The Muse" is the story of Steven Phillips(Albert Brooks), an Oscar-nominated screenwriter who is told by his boss that he has lost his edge. He is subsequently fired and turns to his more successful friend(Jeff Bridges) for he advice. He tells him about Sarah(Sharon Stone), who is a real Muse, the daughter of Zeus, who can inspire creativity.
Steven decides to give this Muse thing a try, when he realizes that the Muse has absolutely no concept of money. Sarah will inspire you, but in return you must give her everything she wants. So Sarah ends up moving in to Steven's home, and as well as subtly inspiring Steven, she inspires Steven's wife(Andie MacDowell) into becoming the next "Mrs. Fields".
A lot of the fun in "The Muse" comes from watching different celebrities admit to using the Muse. Rob Reiner thanks her for "The American President", James Cameron thanks her for "Titanic", Martin Scorsese thanks her for inspiring his remake of "Raging Bull"(hopefully a joke), and Sarah claims that she did "The Truman Show".
The only real flaw in "The Muse" is a slightly unsatisfying ending which doesn't live up to the comic genius which preceeded it. But Albert Brooks has created a very funny comedy that entertains at Hollywood's expense. What could be better?
"The Muse" also proves that real inspiration can only be found within yourself, which is something that writers of all kinds need to learn. I, myself, have started work on a few screenplays, only to give up after 5 or so pages. Creativity is certainly not an easy trait. Well, at least Albert Brooks is in top form, proving that he won't be needing a muse for a very long time.
a review by Akiva Gottlieb, The Teenage Movie Critic<EMAIL_ADDRESS>teenagemoviecritic.8m.com
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Country:
USA
Great Britain
Germany
France
Japan
China
Russia
Category:
All
Business
Health
Science
Sport


T
rip
Home
Profile
Logout
Welcome commuterName!
Find a ride now.
Or
Book a ride in advance
Find a ride now
Book a ride in advance.
Or
Get a ride now.
Choose a date and time.
Date:
2019
Time:
Find a ride.
Finding a rider
Please wait...
Loading...
Ongoing trip
Name:
George
Vehicle-type:
Toyota Hiace
Number-Plate:
UAB 123F
Price est:
10000
UGX
Pickup:
Soliz House
Dropoff:
Tuskys Ntinda
Phone Number:
0772123456
Text interface
Hello
Hello there


A fast, 100-LOC partial implementation of
weekli
in domvm
Click cells to toggle
Click col/row headers to toggle
Click and drag cells to "paint"


Home
About Our Team
Public Feed Page
Maps Page
FAQ
Ran Fang
CodeU Student
Summer Feelz: Excited and pumped
Aspirational Hobby: To be able to write and express myself.


Class Example
CodeIgniter Rest Controller
A fully RESTful server implementation for CodeIgniter using one library, one config file and one controller.
- CI_Controller
- REST_Controller
- Example
Package: CodeIgniter\Libraries
Category: Libraries
License: MIT
Author: Phil Sturgeon, Chris Kacerguis
Version: 3.0.0-pre
Link: https://github.com/chriskacerguis/codeigniter-restserver
Located at application/controllers/api/example.php
Category: Libraries
License: MIT
Author: Phil Sturgeon, Chris Kacerguis
Version: 3.0.0-pre
Link: https://github.com/chriskacerguis/codeigniter-restserver
Located at application/controllers/api/example.php
public
|
|
public
|
|
public
|
|
public
|
|
public
|
|
public
|
|
public
|
$_allow,
$_apiuser,
$_args,
$_delete_args,
$_end_rtime,
$_get_args,
$_head_args,
$_insert_id,
$_options_args,
$_patch_args,
$_post_args,
$_put_args,
$_start_rtime,
$_supported_formats,
$_user_ldap_dn,
$_zlib_oc,
$allowed_http_methods,
$methods,
$request,
$response,
$rest,
$rest_format
|


--- layout: archive title: Zulip Chat Archive permalink: /stream/113489-new-members/topic/Understanding.20assume.html ---
New to functional languages. Want to understand how assume
works in Lean. Why is it OK to have theorem ex1 : ¬(p ∧ ¬q) → (p → q) := begin assume h : ¬(p ∧ ¬q), assume hp : p
but not for example theorem ex2 : (p → r ∨ s) → ((p → r) ∨ (p → s)) := begin assume rs : r ∨ s
?
Because -> is right associative. The first argument of theorem ex2
is a function from p
to r or s
.
Also note that in theorem ex1
, your h
is of type (p and not q) -> false
, that is, a function type. You're then left with p -> s
, where associativity plays no part. You can therefore further assume p
. Note that the parentheses around (p -> q)
are redundant.
Surely the analogue of what works in ex1 is assume prs : (p → r ∨ s)
? That's the left hand side of the implication. Both goals are of the form P -> Q
and you want to start with assume hP : P
.
So is there any assumption that can be made to help in theorem ex2
? I wanted to get started like assume hp : p
, like @Kevin Buzzard suggests, but it just doesn't work. I get an error message.
You can't prove that theorem in constructive logic, meaning that the straightforward "follow your nose" approach doesn't work
You can prove it by cases on whether p
is true or false
How to get started in that case?
begin by_cases p,
if it complains about decidable something then write this at the top of your file:
local attribute [instance] classical.prop_decidable
Right, it does say by_cases tactic failed, type of given expression is not decidable
.
I said P
not p
. You have some super-complex goals with lots and lots of p's and q's and and's and r's, but ultimately it is of the form P -> Q with P and Q slightly less complicated expressions. Your job is to figure out what P and Q are, and then assume hP of type P.
@Kevin Buzzard Sorry, I noticed that too late. That is actually something I can already get from intro
, right?
oh sure
if it complains about decidable something then write this at the top of your file:
local attribute [instance] classical.prop_decidable
Isn't something like
local attribute [instance, priority 10] classical.prop_decidable
better? But isn't open_locale classical
even better?
Yes, but I don't know if daniel is using mathlib
@Moses Schönfinkel Your response is too high-level for a newbie like me. Is there any way to elaborate a bit? For another example, I can do theorem T3L : ¬p ∧ ¬q → ¬(p ∨ q) := assume right: p ∨ q
but can't do assume right : ((p → r) ∨ (p → s))
in that ex2
.
Are you really sure you can do assume right: p ∨ q
?
¬p ∧ ¬q → ¬(p ∨ q)
is of the form X -> Y
with X=¬p ∧ ¬q
and Y=¬(p ∨ q)
. Do you understand that?
So the only possible thing you can assume is a proof of X
ex2 is also of the form X -> Y and you have to figure out what X and Y are, and then assume you have a proof of X, and your goal will be to prove Y. But first you need to figure out what X and Y are.
@Kevin Buzzard I sure can. I have that working.
theorem T3L : ¬p ∧ ¬q → ¬(p ∨ q) := begin intros notP_and_notQ, assume rhs : p ∨ q, { cases rhs with hp hq, { exact notP_and_notQ.left hp }, { exact notP_and_notQ.right hq } } end #check T3L p q
sure it works after the intros!
After the intros, the goal is (p ∨ q) -> false
so you can assume a proof of (p ∨ q)
If your goal is X -> Y then you can assume a proof of X. That's the rule.
@Daniel Keys
You want to prove ((p → r) ∨ (p → s))
in ex2
, so it just doesn't make any sense to assume it. Else there would be nothing left to prove.
I'm not sure why you find this confusing...
@Joe You're right, that part is not confusing. What I struggle with is something around these lines: to prove a statement, sometimes you need to go several routes. For example, you can have cases that split in "if p is true, this follows" and "if p is not true, this follows". So in my mind it seems like I should be able to "assume p" and reach a conclusion, then "assume not p" and reach the other. That is kind of where I struggle now.
Yes you can do that
Do you have mathlib installed? What happens if you type import tactic.linarith
at the beginning of your file?
What does that do? Why install mathlib?
fellow newbie so take this with a grain of salt: mathlib is the accompanying library that defines a bunch of common mathematical concepts for use in other proofs
e.g. i'm using it for data.set.basic
which just defines sets and their properties
Mathlib offers more tactic tools for you to be able to argue like a mathematician would, for example here's a proof of Q given that P -> Q
and ¬ P → Q
, but using a tactic from mathlib:
import tactic variables (P Q : Prop) open_locale classical example (hP : P → Q) (hnP : ¬ P → Q) : Q := begin by_cases h : P, { apply hP, assumption }, { apply hnP, assumption } end
Without mathlib you have to write some more intimidating stuff like Mario's local attribute [instance] classical.prop_decidable
above.
Your underlying problem with assume
is that you're assuming it means a vague all-purpose "assume" which we use in normal English. In Lean assume
has one, extremely precise, meaning -- it can only be used on goals of the form X -> Y
and it can only be used to assume that X
is true.
I proved Q
above by saying "Assume P
is true -- then use hP
; now assume it's false and use hnP
instead". But the Lean translation of that kind of "assume" is by_cases
, at least if you have mathlib. If you only have core Lean then it will look uglier.
variables (P Q : Prop) example (hP : P → Q) (hnP : ¬ P → Q) : Q := begin have H : P ∨ ¬ P := classical.em P, cases H, { apply hP, assumption }, { apply hnP, assumption } end
classical.em
is the classical law of the excluded middle.
@Kevin Buzzard OK then, so the way to introduce other assumptions (is it goals?) is by have
? But what was confusing was that I could still use assume hp:p
in the very first example I posted. It seems like an extra.
I can only repeat what I've said before about exactly what assume does
That's fine, thank you! I need more homework.
Try the exercises in Theorem Proving In Lean
Or the natural number game
Well, I did all of those in chapter 3 except for the classical stuff (7 problems) where I got totally stuck.
Well maybe you could ask some very precise questions about things you were stuck on
A precise question in the form of some working lean code which people can just cut and paste without having to figure out variables or whatever is usually what goes down best here
@Kevin Buzzard I can. Here is this, I need help! theorem T1 : (p → r ∨ s) → ((p → r) ∨ (p → s)) := sorry
. The first one in the classical problems in ch.3
@Daniel Keys
theorem T1 {p q r s : Prop} : (p → r ∨ s) → ((p → r) ∨ (p → s)) := λ h, classical.by_cases (λ hp : p, or.elim (h hp) (λ hr, or.inl $ λ hp, hr) $ λ hs, or.inr $ λ hp, hs) (λ hp : ¬p, or.inl $ λ hp', absurd hp' hp)
@Joe @Kevin Buzzard So that brings me exactly to what I fail to understand in these proofs. All of a sudden you have hr
and hs
, or the even more cryptic $ λ hp'
coming up in your lambda
terms. How can you produce these and work with them if the only hypothesis is (p → r ∨ s)
? Where from does LEAN know what hp'
is? Maybe it is my unwillingness to work with lambda
. While I'll be looking into it, can one get what you wrote in a framework like this:
theorem T1 : (p → r ∨ s) → ((p → r) ∨ (p → s)) := begin intros prs, cases (em p) with hp hnp, { ... }, { ... } end
which is easier to read, to help my understanding?
lambda is a binder, meaning that it introduces a new name. So when you see λ hp'
, you should expect that the name hp'
has not been previously used
The tactic version of lambda is intros
The dollar sign is just a trick for reducing parentheses. f $ g x y
is the same as f (g x y)
So how do you write it with begin...end
? I probably just need to see that once.
variables p q r s : Prop open classical theorem T1 : (p → r ∨ s) → ((p → r) ∨ (p → s)) := begin intros prs, cases (em p) with hp hnp, { cases prs hp with hr hs, { left, intro, exact hr }, { right, intro, exact hs } }, { left, intro, contradiction } end
Thanks a lot! This will get me going.
protip: use ```lean ... ```
to fence lean code
I can see what the left
and right
terms do in the above, but I don't remember having seen that in the manual. Is it there somewhere?
They're explained in the natural number game
https://leanprover.github.io/theorem_proving_in_lean/tactics.html?highlight=left#more-tactics
OK, I see. I only got to the end of chapter 3.
{% endraw %}Last updated: Apr 24 2020 at 19:02 UTC


* Name:
* E-Mail:
* Phone Number:
* Birthday:
* Password (6 digits, upper, lower, number, and symbol):
* Verify Password:


Used to send a text sms message. More...
Public Member Functions | |
| TextMessage () | |
| TextMessage (long recipient, string messageContent) | |
| TextMessage (long[] recipientAddressList, string messageContent) | |
| string | GetTargetUrl () |
| Public Member Functions inherited from Websms.Data.TextSmsSendRequest | |
| TextSmsSendRequest () | |
Additional Inherited Members | |
| Properties inherited from Websms.Data.TextSmsSendRequest | |
| string | messageContent [get, set] |
| Message content. More... | |
| uint | maxSmsPerMessage [get, set] |
| Max number of messages to be send. More... | |
| bool | test [get, set] |
| Test message? More... | |
| long [] | recipientAddressList [get, set] |
| List of recipients. More... | |
| string | senderAddress [get, set] |
| Address of sender. More... | |
| string | senderAddressType [get, set] |
| Type of sender address. More... | |
| bool | sendAsFlashSms [get, set] |
| Send as flash sms? More... | |
| string | notificationCallbackUrl [get, set] |
| Notification url. More... | |
| string | clientMessageId [get, set] |
| User-defined message id. More... | |
| uint | priority [get, set] |
| Priority. More... | |
| string | authToken [get, set] |
| Authentification information. More... | |
| string | apiKey [get, set] |
| API Key. More... | |
Used to send a text sms message.
Definition at line 17 of file TextMessage.cs.
| Websms.TextMessage.TextMessage | ( | ) |
Definition at line 19 of file TextMessage.cs.
| Websms.TextMessage.TextMessage | ( | long | recipient, |
| string | messageContent | ||
| ) |
Constructor
| [in] | recipient | Recipient |
| [in] | messageContent | Message content |
Definition at line 28 of file TextMessage.cs.
| Websms.TextMessage.TextMessage | ( | long [] | recipientAddressList, |
| string | messageContent | ||
| ) |
Constructor
| [in] | recipientAddressList | List of recipients |
| [in] | messageContent | Message content |
Definition at line 40 of file TextMessage.cs.
| string Websms.TextMessage.GetTargetUrl | ( | ) |
Definition at line 46 of file TextMessage.cs.


Introduction¶
Pymatgen (Python Materials Genomics) is a robust, open-source Python library for materials analysis. These are some of the main features:
- Highly flexible classes for the representation of Element, Site, Molecule, Structure objects.
- Extensive input/output support, including support for VASP (http://cms.mpi.univie.ac.at/vasp/), ABINIT (http://www.abinit.org/), CIF, Gaussian, XYZ, and many other file formats.
- Powerful analysis tools, including generation of phase diagrams, Pourbaix diagrams, diffusion analyses, reactions, etc.
- Electronic structure analyses, such as density of states and band structure.
- Integration with the Materials Project REST API, Crystallography Open Database.
Pymatgen is free to use. However, we also welcome your help to improve this library by making your own contributions. These contributions can be in the form of additional tools or modules you develop, or feature requests and bug reports. The following are resources for pymatgen:
Please report any bugs and issues at pymatgen’s Github Issues page.
For help with any pymatgen issue, please use the pymatgen Discourse page. Please note that the pymatgen Google group has been deprecated in favor of Discourse.
Twitter. Follow to get news and tips.
matgenb. For example notebooks.
The code is mightier than the pen.
Offline docs¶
If you would like to have an offline version of the docs for reference, there are two options:
Development News¶
Py3k-only with effect from 2019.1.1¶
Pymatgen has supported both Python 2.7 as well as Python 3.x from version 3.0. With increasing support by most standard libraries for Py3k, it no longer makes sense to maintain this dual support going forward. Dual support imposes costs in terms of developmental effort, and also forces compromises in code quality and efficiency. Though some legacy clusters may only come with Py2k installed by default, the recommended approach in any case is to create an isolated Py3k environment.
The pymatgen development team will phase out Py2k support over the course of 2018. From v2018.1.1, new features implemented in pymatgen no longer need to support Py2k (i.e., unittests do not need to pass Py2k testing), though existing features will still be Py2k compatible. From v2019.1.1, pymatgen will be Py3k only.
Matgenie & Examples¶
The Materials Virtual Lab has developed a matgenie web app which demonstrates some of the basic functionality of pymatgen, as well as a matgenb repository of Jupyter notebooks for common and advanced use cases. We have deprecated the pymatgen examples page in favor of this more sustainable approach going forward. One of the ways you can contribute is to fork the matgenb repo and add your own examples.
Below are a quick look at some of the graphical output possible.
Why use pymatgen?¶
There are many materials analysis codes out there, both commercial and free. So you might ask - why should I use pymatgen over others? Pymatgen offer several advantages over other codes out there:
- It is (fairly) robust. Pymatgen is used by thousands of researchers, and is the analysis code powering the Materials Project. The analysis it produces survives rigorous scrutiny every single day. Bugs tend to be found and corrected quickly. Pymatgen also uses CircleCI and Appveyor for continuous integration on the Linux and Windows platforms, respectively, which ensures that every commit passes a comprehensive suite of unittests. The coverage of the unittests can be seen on coveralls.io.
- It is well documented. A fairly comprehensive documentation has been written to help you get to grips with it quickly.
- It is open. You are free to use and contribute to pymatgen. It also means that pymatgen is continuously being improved. We will attribute any code you contribute to any publication you specify. Contributing to pymatgen means your research becomes more visible, which translates to greater impact.
- It is fast. Many of the core numerical methods in pymatgen have been optimized by vectorizing in numpy/scipy. This means that coordinate manipulations are extremely fast and are in fact comparable to codes written in other languages. Pymatgen also comes with a complete system for handling periodic boundary conditions.
- It will be around. Pymatgen is not a pet research project. It is used in the well-established Materials Project. It is also actively being developed and maintained by the Materials Virtual Lab, the ABINIT group and many other research groups.
Please review the coding guidelines.
Change log¶
- Streamlined Site, PeriodicSite, Molecule and Structure code by abandoning immutability for Site and PeriodicSite.
- VaspInput class now supports a run_vasp method, which can be used to code runnable python scripts for running simple calculations (custodian still recommended for more complex calculations.). For example, the following is a kpoint convergence script that can be submitted in a queue
from pymatgen import MPRester
from pymatgen.io.vasp.sets import MPRelaxSet
VASP_CMD = ["mpirun", "-machinefile", "$PBS_NODEFILE", "-np", "16", "vasp"]
def main():
mpr = MPRester()
structure = mpr.get_structures("Li2O")[0]
for k_dens in [100, 200, 400, 800]:
vis = MPRelaxSet(structure,
user_kpoints_settings={"reciprocal_density": k_dens})
vi = vis.get_vasp_input()
kpoints = vi["KPOINTS"].kpts[0][0]
d = "Li2O_kpoints_%d" % kpoints
# Directly run vasp.
vi.run_vasp(d, vasp_cmd=VASP_CMD)
# Use the final structure as the new initial structure to speed up calculations.
structure = Vasprun("%s/vasprun.xml" % d).final_structure
if __name__ == "__main__":
main()
- Many pymatgen from_file methods now support pathlib.Path as well as strings.
- Misc bug fixes.
Getting pymatgen¶
Via conda (recommended)¶
If you are absolutely new to Python and/or are using Windows, the easiest installation process is using conda. The Materials Virtual Lab has started materials.sh, a community initiative to build a comprehensive collection of materials science software, where pymatgen is available. If you already have conda installed, pymatgen can be installed from the matsci channel on Anaconda cloud using the following one line command:
conda install --channel matsci pymatgen
Pymatgen is under active development, and new features are added regularly. To upgrade pymatgen to the latest version, use the following command:
conda upgrade pymatgen
Step-by-step instructions for all platforms are available at the installation page.
Via pip¶
Note
Preparation
Before installing pymatgen, you may need to first install a few critical dependencies manually.
- It is highly recommended that you use Python>=2.7.9 or latest 3.x. In fact, unless you are very sure you have dependencies that require Python 2, it is highly recommended that you use latest Python 3.x.
- Installation has been tested to be most successful with gcc. Use gcc where possible and do “export CC=gcc” prior to installation.
- Numpy’s distutils is needed to compile the spglib and pyhull dependencies. Numpy should be the first thing you install.
- One of the best things you can do is to use conda to manage all this. The instructions for Shared cluster installation pretty much applies to any machine as well.
The version at the Python Package Index (PyPI) is always the latest stable release that is relatively bug-free. The easiest way to install pymatgen on any system is to use pip:
pip install pymatgen
Wheels for Mac and Windows have been built for convenience. To upgrade pymatgen via pip:
pip install --upgrade pymatgen
The bleeding edge developmental version is at the pymatgen Github repo. The developmental version is likely to be more buggy, but may contain new features. The Github version include complete test files. After cloning the source, you can type in the root of the repo:
pip install .
or to install the package in developmental mode:
pip install -e .
Detailed installation instructions, including installation of option dependencies, set up for POTCAR generation, Materials Project REST interface usage, setup for developers, etc.are given on this page.
For some extras, you can also install the optional dependencies using:
pip install pymatgen[extra]
For an always up-to-date list of extras, consult the setup.py’s extras_require.
Usage¶
The figure above provides an overview of the functionality in pymatgen. A typical workflow would involve a user converting data (structure, calculations, etc.) from various sources (first principles calculations, crystallographic and molecule input files, Materials Project, etc.) into Python objects using pymatgen’s io packages, which are then used to perform further structure manipulation or analyses.
Quick start¶
Useful aliases for commonly used objects are now provided. Supported objects include Element, Composition, Structure, Molecule, Spin and Orbital. Here are some quick examples of the core capabilities and objects:
>>> import pymatgen as mg
>>>
>>> si = mg.Element("Si")
>>> si.atomic_mass
28.0855
>>> print(si.melting_point)
1687.0 K
>>>
>>> comp = mg.Composition("Fe2O3")
>>> comp.weight
159.6882
>>> # Note that Composition conveniently allows strings to be treated just
>>> # like an Element object.
>>> comp["Fe"]
2.0
>>> comp.get_atomic_fraction("Fe")
0.4
>>> lattice = mg.Lattice.cubic(4.2)
>>> structure = mg.Structure(lattice, ["Cs", "Cl"],
... [[0, 0, 0], [0.5, 0.5, 0.5]])
>>> structure.volume
74.088000000000008
>>> structure[0]
PeriodicSite: Cs (0.0000, 0.0000, 0.0000) [0.0000, 0.0000, 0.0000]
>>>
>>> # You can create a Structure using spacegroup symmetry as well.
>>> li2o = mg.Structure.from_spacegroup("Fm-3m", mg.Lattice.cubic(3),
["Li", "O"],
[[0.25, 0.25, 0.25], [0, 0, 0]])
>>>
>>> # Integrated symmetry analysis tools from spglib.
>>> from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
>>> finder = SpacegroupAnalyzer(structure)
>>> finder.get_spacegroup_symbol()
'Pm-3m'
>>>
>>> # Convenient IO to various formats. You can specify various formats.
>>> # Without a filename, a string is returned. Otherwise,
>>> # the output is written to the file. If only the filenmae is provided,
>>> # the format is intelligently determined from a file.
>>> structure.to(fmt="poscar")
>>> structure.to(filename="POSCAR")
>>> structure.to(filename="CsCl.cif")
>>>
>>> # Reading a structure is similarly easy.
>>> structure = mg.Structure.from_str(open("CsCl.cif").read(), fmt="cif")
>>> structure = mg.Structure.from_file("CsCl.cif")
>>>
>>> # Reading and writing a molecule from a file. Supports XYZ and
>>> # Gaussian input and output by default. Support for many other
>>> # formats via the optional openbabel dependency (if installed).
>>> methane = mg.Molecule.from_file("methane.xyz")
>>> mol.to("methane.gjf")
>>>
>>> # Pythonic API for editing Structures and Molecules (v2.9.1 onwards)
>>> # Changing the specie of a site.
>>> structure[1] = "F"
>>> print(structure)
Structure Summary (Cs1 F1)
Reduced Formula: CsF
abc : 4.200000 4.200000 4.200000
angles: 90.000000 90.000000 90.000000
Sites (2)
1 Cs 0.000000 0.000000 0.000000
2 F 0.500000 0.500000 0.500000
>>>
>>> # Changes species and coordinates (fractional assumed for structures)
>>> structure[1] = "Cl", [0.51, 0.51, 0.51]
>>> print(structure)
Structure Summary (Cs1 Cl1)
Reduced Formula: CsCl
abc : 4.200000 4.200000 4.200000
angles: 90.000000 90.000000 90.000000
Sites (2)
1 Cs 0.000000 0.000000 0.000000
2 Cl 0.510000 0.510000 0.510000
>>>
>>> # Replaces all Cs in the structure with K
>>> structure["Cs"] = "K"
>>> print(structure)
Structure Summary (K1 Cl1)
Reduced Formula: KCl
abc : 4.200000 4.200000 4.200000
angles: 90.000000 90.000000 90.000000
Sites (2)
1 K 0.000000 0.000000 0.000000
2 Cl 0.510000 0.510000 0.510000
>>>
>>> # Replaces all K in the structure with K: 0.5, Na: 0.5, i.e.,
>>> # a disordered structure is created.
>>> structure["K"] = "K0.5Na0.5"
>>> print(structure)
Full Formula (K0.5 Na0.5 Cl1)
Reduced Formula: K0.5Na0.5Cl1
abc : 4.209000 4.209000 4.209000
angles: 90.000000 90.000000 90.000000
Sites (2)
# SP a b c
--- ----------------- --- --- ---
0 K:0.500, Na:0.500 0 0 0
1 Cl 0.5 0.5 0.5
>>>
>>> # Because structure is like a list, it supports most list-like methods
>>> # such as sort, reverse, etc.
>>> structure.reverse()
>>> print(structure)
Structure Summary (Cs1 Cl1)
Reduced Formula: CsCl
abc : 4.200000 4.200000 4.200000
angles: 90.000000 90.000000 90.000000
Sites (2)
1 Cl 0.510000 0.510000 0.510000
2 Cs 0.000000 0.000000 0.000000
>>>
>>> # Molecules function similarly, but with Site and cartesian coords.
>>> # The following changes the C in CH4 to an N and displaces it by 0.01A
>>> # in the x-direction.
>>> methane[0] = "N", [0.01, 0, 0]
>>>
>>> # If you set up your .pmgrc.yaml with your Materials Project API key
>>> # You can now easily grab structures from the Materials Project.
>>> lifepo4 = mg.get_structure_from_mp("LiFePO4")
The above illustrates only the most basic capabilities of pymatgen. Users are strongly encouraged to explore the usage pages (toc given below).
API documentation¶
For detailed documentation of all modules and classes, please refer to the API docs.
More resources¶
The founder and maintainer of pymatgen, Shyue Ping Ong, has conducted several workshops (together with Anubhav Jain) on how to effectively use pymatgen (as well as the extremely useful custodian error management and FireWorks workflow software. The slides for these workshops are available on the Materials Virtual Lab.
pmg - Command line tool¶
To demonstrate the capabilities of pymatgen and to make it easy for users to quickly use the functionality, pymatgen comes with a set of useful scripts that utilize the library to perform all kinds of analyses. These are installed to your path by default when you install pymatgen through the typical installation routes.
Here, we will discuss the most versatile of these scripts, known as pmg. The typical usage of pmg is:
pmg {setup, config, analyze, plotdos, plotchgint, convert, symm, view, compare} additional_arguments
At any time, you can use "pmg --help"
or "pmg subcommand
--help"
to bring up a useful help message on how to use these subcommands.
With effect from v4.6.0, pmg
also supports bash completion using
argcomplete, which is useful given the many options available in the cli tool.
To enable argcomplete, pip install argcomplete
and either follow
argcomplete’s instructions for enabling global completion, or add the following
line to your .bash_profile
(this method usually works more reliably):
eval "$(register-python-argcomplete pmg)"
Here are a few examples of typical usages:
# Parses all vasp runs in a directory and display the basic energy
# information. Saves the data in a file called vasp_data.gz for subsequent
# reuse.
pmg analyze .
# Plot the dos from the vasprun.xml file.
pmg plot --dos vasprun.xml
# Convert between file formats. The script attempts to intelligently
# determine the file type. Input file types supported include CIF,
# vasprun.xml, POSCAR, CSSR. You can force the script to assume certain file
# types by specifying additional arguments. See pmg convert -h.
pmg structure --convert --filenames input_filename output_filename.
# Obtain spacegroup information using a tolerance of 0.1 angstroms.
pmg structure --symmetry 0.1 --filenames filename1 filename2
# Visualize a structure. Requires VTK to be installed.
pmg view filename
# Compare two structures for similarity
pmg structure --group element --filenames filename1 filename2
# Generate a POTCAR with symbols Li_sv O and the PBE functional
pmg potcar --symbols Li_sv O --functional PBE
Add-ons¶
Some add-ons are available for pymatgen today:
- The pymatgen-db add-on provides tools to create databases of calculated run data using pymatgen.
- The custodian package provides a JIT job management and error correction for calculations.
- The pymatgen-diffusion by the Materials Virtual Lab provides additional useful analyses for diffusion in materials.
Contributing¶
Pymatgen is developed by a team of volunteers. It is started by a team comprising of MIT and Lawrence Berkeley National Laboratory staff to be a robust toolkit for materials researchers to perform advanced manipulations of structures and analyses.
For pymatgen to continue to grow in functionality and robustness, we rely on other volunteers to develop new analyses and report and fix bugs. We welcome anyone to use our code as-is, but if you could take a few moment to give back to pymatgen in some small way, it would be greatly appreciated. A benefit of contributing is that your code will now be used by other researchers who use pymatgen, and we will include an acknowledgement to you (and any related publications) in pymatgen.
A simple way that anyone can contribute is simply to report bugs and issues to the developing team. Please report any bugs and issues at pymatgen’s Github Issues page. For help with any pymatgen issue, consult Stack Overflow and if you cannot find an answer, please post a question with the tag pymatgen.
Another way to contribute is to submit new code/bugfixes to pymatgen. The best way for anyone to develop pymatgen is by adopting the collaborative Github workflow (see contributing page).
How to cite pymatgen¶
If you use pymatgen in your research, please consider citing the following work:
Shyue Ping Ong, William Davidson Richards, Anubhav Jain, Geoffroy Hautier, Michael Kocher, Shreyas Cholia, Dan Gunter, Vincent Chevrier, Kristin A. Persson, Gerbrand Ceder. Python Materials Genomics (pymatgen) : A Robust, Open-Source Python Library for Materials Analysis. Computational Materials Science, 2013, 68, 314–319. doi:10.1016/j.commatsci.2012.10.028
In addition, some of pymatgen’s functionality is based on scientific advances / principles developed by various scientists. Please refer to the references page for citation info.
License¶
Pymatgen is released under the MIT License. The terms of the license are as follows:
The MIT License (MIT)
Copyright (c) 2011-2012 MIT & LBNL
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
 IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
About the Team¶
Shyue Ping Ong of the Materials Virtual Lab started Pymatgen in 2011, and is still the project lead.
The Pymatgen Development Team is the set of all contributors to the pymatgen project, including all subprojects.
The full list of contributors are listed in the team page.
Copyright Policy¶
Pymatgen uses a shared copyright model. Each contributor maintains copyright over their contributions to pymatgen. But, it is important to note that these contributions are typically only changes to the repositories. Thus, the pymatgen source code, in its entirety is not the copyright of any single person or institution. Instead, it is the collective copyright of the entire pymatgen Development Team. If individual contributors want to maintain a record of what changes/contributions they have specific copyright on, they should indicate their copyright in the commit message of the change, when they commit the change to one of the pymatgen repositories.
With this in mind, the following banner should be used in any source code file to indicate the copyright and license terms:
# Copyright (c) Pymatgen Development Team.
# Distributed under the terms of the MIT License.


data infection simplicial points complexes co-infection single algorithm bacterial sets values time immune Fig. number mapper response groups viral [], using metric used IAV analysis neighbour set distance Dist. Projection vertices []. different group lenses topological generated {border-style correlation features lens intervals px;} #ffffff;} IL- complex dimensional early hpc cytokines percentage point value overlap post high infection. neighbours parameter projection yellow Euclidean IFN-γ Lens TNF-α dimensionality function results shape space MCP- load lung reduction behaviour burden changes co-infections information later metric. original specific study clusters compared disease mathematical points. use (e.g. Table choice co-infection. connected cosine cytokine data. dimension distances example, experimental hours i.e. illustrated infections influenza late matrix pathogens projections px; stages tested transition {font-family Kepler Neighbour belong concentration correspond course data, dot following font-size mice potential product regions represent representative stage (IAV (the .Lens However, Python algorithms based belonging biological calculated chose cluster clustering create dotted double; group. higher library looping make non-linear obtained pathogen persistent pneumococcal possible representation research sampled scenarios. secondary shapes shows significantly words, (i.e. (in -dimensional Finally, Mapper TDA Topological according average border-color border-width choosing close closest clusters. color common complex, component concentrations contain corresponding detailed edges effects epsilon exclusively feature form generate geometric host important indicate infected investigate known lenses, linear local measurements methods metrics models multiple normalised observations onset order phase point. points, previous range reveal revealed set. sets. solid; space. specifically, times {font-style {font-weight (and COVID- DBSCAN EP. Elsevier Nonlinear Projections Section Specifically, Therefore, able algebraic algorithms. applied approaches bold called case, centre clearly closely clusterer co-infection, co-infections, colored complexes. considered consists construct correlated courier; described divided does draw dynamics em; eps exactly functions global hpc) implement increased increasing individual infection, infectious intervals, kinetics largely maximum mechanisms method missing observed orange overlap. pairs parameters particular primary pt;} purple regarding region resource role row rows second seeks semi-unsupervised simplices statistical steps structure studies subsets susceptibility together, various virus work


bg
Resumes jobs that have been suspended (e.g. using `Ctrl + Z`), and keeps them running in the background.
More information: home page
- Resume the most recently suspended job and run it in the background:
bg
- Resume a specific job (use `jobs -l` to get its ID) and run it in the background:
bg %job_id


SHELL PETROLEUM DEVELOPMENT COMPANY 44 MARINA, LAGOS NIGERIA.   WE HAVE DECIDED TO CONTACT YOU BY E-MAIL DUE TO THE URGENCY OF THIS TRANSACTION.  I AM MR DANJUMA WILLIAMS M, THE AUDITOR OF THE SHELL PETROLEUM DEVELOPMENT COMPANY (SPDC). I CAME TO KNOW OF YOU IN MY PRIVATE SEARCH FOR A RELIABLE AND REPUTABLE PERSON TO HANDLE THIS CONFIDENTIALTRANSACTION WHICH INVOLVES THE TRANSFER OF THE SUM OF NINE-FIVE MILLION UNITED STATES DOLLARS WITH SECURITY COMPANY IN EUROPE. THIS AMOUNT WAS SECURED FROM EXCESS OIL SALES FROM NIGERIA CRUDE OIL. THE SUM OF $1.2 BILLION OIL WINDFALL WAS RELIEZED BY THE SHELL PETROLEUM DEVELOPMENT COMPANY FOR THE MONTH OF AUGUST 2003.ORGANISATION OF PETROLEUM EXPORTING COUNTRIES (OPEC) CRUDE OIL PRICE WAS PEG AT $22.00 PER BARREL AND FORTUNATELY FOR OIL PRODUCING COUNTRIES LIKE NIGERIA, THERE WAS RISES IN OIL PRICE TO ABOUT $27.00 AND $28.00 PER BARREL AND AS A RESULT THERE WAS EXCESS OIL SALES AND I BELIEVE YOU WOULD BE AWARE OF THIS RISE IN OIL PRICE THIS YEAR. OUT OF THESE $1.2 BILLION EXCESS OIL FUNDS, MY COLLEAQUES AND MYSELF DECIDED TO CONTACT YOU, BECAUSE OF OUR POSITION IN THE ACCOUNT DEPARTMENT OF THE SHELL PETROLEUM DEVELOPMENT COMPANY DIVERTED THE SUM OF NINE-FIVE MILLION UNITED STATE DOLLARS, WE AGREED TO TRANSFER THIS SUM INTO YOUR NOMINATED ACCOUNT, THE EXCESS CRUDE OIL SALES IS BEING KEPT WITH SECURITY COMPANY IN EUROPE.     YOURS FAITHFULLY, MR DANJUMA WILLIAMS M, THE AUDITOR OF SHELL PETROLEUM DEVELOPMENT COMPANY


PROFILE
About Us
Edit Profile
Post Jobs
My Jobs
Notifications
Log Out
Edit Profile
Post Jobs
My Jobs
Notifications


{% import 'headers.html' as headers %} {% import 'footers.html' as footers %} {% import 'algo.html' as algo %}
This article describes techniques of finding some discrete logarithm - integer \(x\) satisfying \(a^x \equiv b \pmod m\) for given \(a,b,m\).
Suppose You are given numbers \(1 \le a, b, m \le 10^{12}\), where \(gcd(a, m)=1\), and thine aim is to find such \(x\) that \(a^x \equiv b \pmod m\).
Input format: values \(a, b, m\), for which \(x: a^x \equiv b \pmod m\) has to be calculated. \(gcd(a, m)=1\) or expect the unexpected.
\(a, b, m\)
Notice, that for particular \(a\) not \(\phi(m)-1\), but \(ord_m(a)-1\) can be upper bound on range, where minimal discrete logarithm solving \(a^x \equiv b \pmod m\) can be found. Passing maximal possible exponent may drastically speed up computation time. Using this information within algorithm will be crucial for one algorithm shown later.
Instead of using sort and binary search, one can use hash table with, say, \(s\) bins for storing values \(a^q\). On average, in each bin there will be exactly one value - if values of \(a^q\) come from some uniform random distribution. Also, on average, each bin will be accessed once if values of \(a^{-ps}\) come from some uniform random distribution. Both statements will be false if \(ord_m(a)\) is lower than maximal exponent, for which the search is executed. Otherwise, values of \(a^q\) or \(a^{-ps}\) are quite problematic to predict; empirically, there is a good reason to believe, that it usually should run much faster than standard version.
Suppose You are given numbers \(1 \le a, b, m \le 10^{12}\), and thine aim is to find such \(x\) that \(a^x \equiv b \pmod m\).
Solving this problem relies on changing values \(a, b, m\) in such way, that if one can make \(gcd(a, m)=1\) anew, then one can pass problem to any other algorithm solving discrete logarithm problem.
Suppose You are given numbers \(1 \le a, b, m \le 10^{18}\), where \(gcd(a, m)=1\), factorization of \(m\) can be represented as \(m=g_1^{e_1}g_2^{e_2} \dots g_r^{e_r}\) where \( \forall_i g_i \le 10^9\), and thine aim is to find such \(x\) that \(a^x \equiv b \pmod m\).
To sum up all that has been stated (or implicitly assumed):
Summing all up, complexity will look like \(O(fac(m)+\sum_{i=0}^{s} q_i(\sqrt{p_i} \log(p_i)+\log(m)))\). As \(\sum_{i=0}^{s} q_i \le \log_2(m)\), then complexity can be formulated as: $$O(fac(m)+\log(m)\sqrt{p} \log(p))$$ For \(p=\max(p_i)\), though this estimation is extremely rough. Using some refined factorization method one can solve this problem in reasonable time.


This is a test of mylog's content search capability.  This is a large word. Another
large word is pulchritudinous. Damn, that's weird. Plus Vinayak is cool.


-
ftp Library Package 2.1 for Tcl/Tk Manual Pages
- COMMAND
- ftp::Pwd handle
-
-
The ftp::Pwd command gets the complete path of the current
working directory on the ftp server or an empty string if an
error occurs.
- EXAMPLE
-
# get directory path
set current_path [ftp::Pwd $conn]
[Contents]
[Previous: ftp::Cd]
[Next: ftp::Type]
© 1999 Steffen Traeger


--- layout: post title: "Redirect legacy URLs" description: "Evolving REST API URLs when cool URIs don't change." date: 2020-11-16 6:47 UTC tags: [REST, ASP.NET Web API, Services] image: "/content/binary/reverse-proxy-based-redirect.png" image_alt: "Sequence diagram showing a reverse proxy returning a redirect response to a request for a legacy URL." --- {% include JB/setup %}
{{ page.description }}
More than one reader reacted to my article on fit URLs by asking about bookmarks and original URLs. Daniel Sklenitzka's question is a good example:
While I answered the question on the same page, I think that it's worthwhile to expand it."I see how signing the URLs prevents clients from retro-engineering the URL templates, but how does it help preventing breaking changes? If the client stores the whole URL instead of just the ID and later the URL changes because a restaurant ID is added, the original URL is still broken, isn't it?"
I agree with the implicit assumption that clients are allowed to bookmark links. It seems, then, like a breaking change if you later change your internal URL scheme. That seems to imply that the bookmarked URL is gone, breaking a tenet of the HTTP protocol: Cool URIs don't change.
REST APIs are supposed to play by the rules of HTTP, so it'd seem that once you've published a URL, you can never retire it. You can, on the other hand, change its behaviour.
Let's call such URLs legacy URLs. Keep them around, but change them to return 301 Moved Permanently
responses.
The rules of REST go both ways. The API is expected to play by the rules of HTTP, and so are the clients. Clients are not only expected to follow links, but also redirects. If a legacy URL starts returning a 301 Moved Permanently
response, a well-behaved client doesn't break.
As I've previously described, one of the many benefits of HTTP-based services is that you can put a reverse proxy in front of your application servers. I've no idea how to configure or operate NGINX or Varnish, but from talking to people who do know, I get the impression that they're quite scriptable.
Since the above ideas are independent of actual service implementation or behaviour, it's a generic problem that you should seek to address with general-purpose software.
Imagine that a reverse proxy is configured with a set of rules that detects legacy URLs and knows how to forward them. Clearly, the reverse proxy must know of the REST API's current URL scheme to be able to do that. You might think that this would entail leaking an implementation detail, but just as I consider any database used by the API as part of the overall system, I'd consider the reverse proxy as just another part.
If you don't have a reverse proxy, you can also implement redirects in code. It'd be better to use something like a reverse proxy, because that would mean that you get to delete code from your code base, but sometimes that's not possible.
The code shown here is part of the sample code base that accompanies my book Code That Fits in Your Head.
In ASP.NET, you can return 301 Moved Permanently
responses just like any other kind of HTTP response:
[Obsolete("Use Get method with restaurant ID.")] [HttpGet("calendar/{year}/{month}")] public ActionResult LegacyGet(int year, int month) { return new RedirectToActionResult( nameof(Get), null, new { restaurantId = Grandfather.Id, year, month }, permanent: true); }
This LegacyGet
method redirects to the current Controller action called Get
by supplying the arguments that the new method requires. The Get
method has this signature:
[HttpGet("restaurants/{restaurantId}/calendar/{year}/{month}")] public async Task<ActionResult> Get(int restaurantId, int year, int month)
When I expanded the API from a single restaurant to a multi-tenant system, I had to grandfather in the original restaurant. I gave it a restaurantId
, but in order to not put magic constants in the code, I defined it as the named constant Grandfather.Id
.
Notice that I also adorned the LegacyGet
method with an [Obsolete]
attribute to make it clear to maintenance programmers that this is legacy code. You might argue that the Legacy prefix already does that, but the [Obsolete]
attribute will make the compiler emit a warning, which is even better feedback.
While legacy URLs may be just that: legacy, that doesn't mean that it doesn't matter whether or not they work. You may want to add regression tests.
If you implement redirects in code (as opposed to a reverse proxy), you should also add automated tests that verify that the redirects work:
[Theory] [InlineData("http://localhost/calendar/2020?sig=ePBoUg5gDw2RKMVWz8KIVzF%2Fgq74RL6ynECiPpDwVks%3D")] [InlineData("http://localhost/calendar/2020/9?sig=ZgxaZqg5ubDp0Z7IUx4dkqTzS%2Fyjv6veDUc2swdysDU%3D")] public async Task BookmarksStillWork(string bookmarkedAddress) { using var api = new LegacyApi(); var actual = await api.CreateDefaultClient().GetAsync(new Uri(bookmarkedAddress)); Assert.Equal(HttpStatusCode.MovedPermanently, actual.StatusCode); var follow = await api.CreateClient().GetAsync(actual.Headers.Location); follow.EnsureSuccessStatusCode(); }
This test interacts with a self-hosted service at the HTTP level. LegacyApi
is a test-specific helper class that derives from WebApplicationFactory<Startup>.
The test uses URLs that I 'bookmarked' before I evolved the URLs to a multi-tenant system. As you can tell from the host name (localhost
), these are bookmarks against the self-hosted service. The test first verifies that the response is 301 Moved Permanently
. It then requests the new address and uses EnsureSuccessStatusCode as an assertion.
When you evolve fit URLs, it could break clients that may have bookmarked legacy URLs. Consider leaving 301 Moved Permanently
responses at those addresses.


NAFlex provides a friendly environment to analyse your own generated molecular dynamics trajectories of nucleic acid structures.
Please note that in this version of NAFlex, only double-stranded, standard nucleic acids can be analysed. Mispaired nucleotides, single-stranded nucleic acids, triplexes and quadruplexes are not currently supported in NAFlex flexibility analysis. Modified nucleotides are only allowed in some of the flexibility analysis operations.
User should follow three necessary steps before being able to analyse his/her own trajectory. These steps are registration, starting project, and uploading a trajectory. A short tutorial about these steps can be found in Uploading a Trajectory help section.


A One-Minute Book Review of Leo Tolstoy's 'War and Peace' « One ...
Jan 9, 2008 . War and Peace. By Leo Tolstoy. Translated by Constance Garnett. Modern Library, 1,386 pages, $24.95. By Janice Harayda. Reading War and .
http://oneminutebookreviews.wordpress.com/2008/01/09/a-one-minute-book-review-of-leo-tolstoys-war-and-peace/
Treatment for Herniated or Bulging Discs
War and Peace - War and Peace - best translation (showing 1-42 of ...
Mar 28, 2011 . Gordon said: I've decided to finally tackle Tolstoy's epic and I was wondering . I plan to read War and Peace and I will get the P & V translations, as I . their somewhat inflated prices, considering e-copy relative to paperback.
http://www.goodreads.com/topic/show/522084-war-and-peace---best-translation
War and Peace Wikipedia | Reception | GradeSaver
Slavophiles declared Tolstoy their 'bogatyr' and pronounced War and Peace "the . translating into Danish War and Peace, adding: "This is positively what might .
http://www.gradesaver.com/war-and-peace/wikipedia/reception/
tolstoy relative translated war and peace Herniated or Bulging Discs
The Original War and Peace - Caxton Club of Chicago
Jul 14, 2012 . War and Peace by Count Leo Tolstoy is . volunteered that it had never been translated . and discovered they were distant relatives.
http://www.caxtonclub.org/reading/2012/jul12.pdf
Ernest Hilbert's Introduction to the Maude Translation of Leo ...
Aug 11, 2011 . That's not the way, that's not the way, Sonya! cried Natasha turning her head and clutching with both hands at her hair which the maid who was .
http://www.everseradio.com/ernest-hilberts-introduction-to-the-maude-translation-of-leo-tolstoys-war-and-peace-issued-as-part-of-the-canterbury-classics-series/
Tolstoy's Mathematics in War and Peace
Tolstoy's views on the matter are set forth at great length in 'War and Peace', . We base our treatment on Rosemary Edmonds 1957 translation into English . of equations, shall we be able to compare the relative values of the unknown factor; .
http://libelli.narod.ru/tolstoy/wap_math.html
Official Impairment Listing for Spinal Disorders
Leo Tolstoy - Wikipedia, the free encyclopedia
Gustave Flaubert, on reading a translation of War and Peace, exclaimed, "What an artist and what a psychologist!" Anton Chekhov, who often visited Tolstoy at .
http://en.wikipedia.org/wiki/Leo_Tolstoy
- flag navy ww i (narrowing of the spine)
Amazon.com: War and Peace (Signet Classics)<PHONE_NUMBER>266 ...
War and Peace (Signet Classics) [Leo Tolstoy, Ann Dunnigan, John Bayley] on . s" than the Garnett, Maude, or Edmonds translations, leaving readers free to enjoy . Tolstoy put into the book thinly veiled versions of his parents and relatives .
http://www.amazon.com/War-Peace-Signet-Classics-Tolstoy/dp/0451523261leo tolstoy - AbeBooks
Results 1 - 30 . War and Peace (First Edition, complete in six [6] volumes) by Tolstoy, . Three volumes in six, translated from the French by Clara Bell. . As a matter of fact, contemporarymusician and guitarist David Crosby is a distant relative.
http://www.abebooks.com/book-search/author/leo-tolstoy/sortby/1/page-1/
War and Peace Project
Apr 22, 2012 . I'm going to take a leap here and try apply Tolstoy's thoughts to our project. . Pevear/Volokhonsky translation page 1214-1215 . For months now I've been mulling over what would be a fitting final post for the War and Peace Project blog. . I have had the great fortune of living in a period of relative peace.
http://warpeaceproject.blogspot.com/
War and Peace Quotes | GradeSaver
One exception to this occurs at the beginning of War and Peace, when Pierre and . the Modernist movement, fifty years after Tolstoy published War and Peace. . For Pierre, these qualities are easier to find in relative poverty than they are in . Analysis of Epilogue · Translation Wars: English Versions of 'War and Peace' .
http://www.gradesaver.com/war-and-peace/study-guide/quotes/
Medical-Vocational Allowance for Herniated Disc
Leo Tolstoy: Biography from Answers.com
The brilliant rhetoric of those passages in War and Peace in which Tolstoy argued . A Translation and Unification of the Gospels (1881), What I Believe ( 1884), and . when he was young, so he and his siblings were brought up by relatives.
http://www.answers.com/topic/leo-tolstoy
Leo Tolstoy-Death-War and Peace-Anna Karenina-Death of Ivan ...
Leo Tolstoy, War and Peace, 1869 . Translated by Richard Pevear & Larissa Volokhonsky . No one but you gives me the same soft peace
the same light. I want to . There was nothing violent or terrible in this relatively slow awakening.
http://www.deathdyinggriefandmourning.com/Death-Dying-Grief-Mourning/60-Leo-Tolstoy-Death-War-and-Peace-Anna-Karenina-Death-of-Ivan-Ilych-Prince-Andrey-Anna-Karenina.htm
Appealing a Denial of Benefits
War and Peace Background | GradeSaver
GradeSaver (TM) ClassicNotes: War and Peace . by Leo Tolstoy . For more on this, see the 'Translation Wars' section of this ClassicNote. . names characters that other novelists would usually leave unnamed (like servants, distant relatives, .
http://www.gradesaver.com/war-and-peace/study-guide/about/
War and Peace
By Leo Tolstoy (1828-1910) . Most English translations of War and Peace are easy to read and understand. . Also staying with the Rostovs is Sonya, a poor teenage relative who lives as a ward of the Rostovs and enjoys their affection.
http://www.cummingsstudyguides.net/Guides3/WarandPeace.html


Home
Projects
Resume
About
More
Hello, World!
This is some filler text to make it look like I did a thing to my website.
Test REST API
Ping
Another Heading
A Third Header


- getAmount() - Method in class group5.trackerexpress.Expense
-
Gets the amount.
- getApproverEmail() - Method in class group5.trackerexpress.Claim
-
Sets the approvers email.
- getApproverName() - Method in class group5.trackerexpress.Claim
-
Gets the user name.
- getBitmap() - Method in class group5.trackerexpress.Receipt
-
Gets bitmap from byte array is not null.
- getCategory() - Method in class group5.trackerexpress.Expense
-
Gets the Category
- getClaim(UUID) - Method in class group5.trackerexpress.ClaimList
-
Gets the claim.
- getClaim(Context, UUID) - Static method in class group5.trackerexpress.Controller
-
Gets the claim based on the claim id
- getClaim(Context, UUID) - Method in class group5.trackerexpress.ElasticSearchEngineClaims
-
Get claim from Elastic Search server
- getClaim(UUID) - Method in class group5.trackerexpress.ElasticSearchEngineUnthreadedClaims
-
Gets a claim
- getClaimList(Context) - Static method in class group5.trackerexpress.Controller
-
Gets the static claim list, newing it if necessary
- getClaimName() - Method in class group5.trackerexpress.Claim
-
Gets the name the user set on the claim
- getClaims(Context) - Method in class group5.trackerexpress.ElasticSearchEngineClaims
-
Gets all claims from elastic search server
- getClaims() - Method in class group5.trackerexpress.ElasticSearchEngineUnthreadedClaims
-
Gets claims from es server
- getClaimsForGlobalClaimList(Context) - Method in class group5.trackerexpress.ElasticSearchEngineClaims
-
Gets the claims that user can approve, i.e.
- getComments() - Method in class group5.trackerexpress.Claim
-
Gets the comments from the approver
- getContext() - Static method in class group5.trackerexpress.Controller
-
- getCount() - Method in class group5.trackerexpress.PlaceAutocompleteAdapter
-
Returns the number of results received in the last autocomplete query.
- getCount() - Method in class group5.trackerexpress.SectionsPagerAdapter
-
- getCurrency() - Method in class group5.trackerexpress.Expense
-
Gets the currency.
- getDate() - Method in class group5.trackerexpress.Expense
-
Gets the year.
- getDescription() - Method in class group5.trackerexpress.Claim
-
Gets the description.
- getDescription() - Method in class group5.trackerexpress.Destination
-
gets the description of the destination
- getDestinationList() - Method in class group5.trackerexpress.Claim
-
Gets the destination list.
- getDistanceBetween(Destination, Destination) - Static method in class group5.trackerexpress.Destination
-
gets the distance between two destinations
- getDrawable() - Method in class group5.trackerexpress.Receipt
-
Deprecated.
- getEmail() - Method in class group5.trackerexpress.User
-
Gets the email.
- getEndDate() - Method in class group5.trackerexpress.Claim
-
Gets the end date.
- getExpense(Context, UUID, UUID) - Static method in class group5.trackerexpress.Controller
-
Gets the expense base on the claim id and the expense id
- getExpense(UUID) - Method in class group5.trackerexpress.ExpenseList
-
Gets the expense.
- getExpenseList() - Method in class group5.trackerexpress.Claim
-
Gets the expense list.
- getFilter() - Method in class group5.trackerexpress.PlaceAutocompleteAdapter
-
Returns the filter for the current set of autocomplete results.
- getFilteredClaims(Context) - Static method in class group5.trackerexpress.ClaimList
-
Returns a list of filtered Claims based on selected tags.
- getHits() - Method in class group5.trackerexpress.ElasticSearchEngineUnthreadedClaims.Hits
-
- getHits() - Method in class group5.trackerexpress.ElasticSearchEngineUnthreadedUser.Hits
-
- getItem(int) - Method in class group5.trackerexpress.PlaceAutocompleteAdapter
-
Returns an item from the last autocomplete query.
- getItem(int) - Method in class group5.trackerexpress.SectionsPagerAdapter
-
- getLatitude() - Method in class group5.trackerexpress.Destination
-
gets the latitude of destination
- getLatitude() - Method in class group5.trackerexpress.Expense
-
gets the latitude of destination
- getLocation() - Method in class group5.trackerexpress.Destination
-
gets the location object of the destination
- getLocation() - Method in class group5.trackerexpress.Expense
-
gets the location object of the destination
- getLocation() - Method in class group5.trackerexpress.User
-
- getLongitude() - Method in class group5.trackerexpress.Destination
-
gets the longitude of destination
- getLongitude() - Method in class group5.trackerexpress.Expense
-
gets the longitude of destination
- getName() - Method in class group5.trackerexpress.Destination
-
gets the name of the destination
- getName() - Method in class group5.trackerexpress.User
-
Gets the name.
- getPassword() - Method in class group5.trackerexpress.User
-
Gets the password.
- getPath() - Method in class group5.trackerexpress.Receipt
-
Path to the file, if stored locally.
- getReceipt() - Method in class group5.trackerexpress.Expense
-
gets the receipt
- getStartDate() - Method in class group5.trackerexpress.Claim
-
Gets the start date.
- getStatus() - Method in class group5.trackerexpress.Claim
-
Gets the status of the claim.
- getSubmitterEmail() - Method in class group5.trackerexpress.Claim
-
Gets the submitters name
This function does not need context
since it will not be updating views.
- getSubmitterName() - Method in class group5.trackerexpress.Claim
-
Gets the submitters username.
- getTag(UUID) - Method in class group5.trackerexpress.TagMap
-
Gets the tag.
- getTagMap(Context) - Static method in class group5.trackerexpress.Controller
-
Gets the static tag map, newing it if necessary
- getTagsIds(Context) - Method in class group5.trackerexpress.Claim
-
Gets the list of TagIds.
- getTagStrings(ArrayList<Tag>) - Method in class group5.trackerexpress.TagMap
-
- getTitle() - Method in class group5.trackerexpress.Expense
-
Gets the title.
- getUser(Context) - Static method in class group5.trackerexpress.Controller
-
Gets the User data object.
- getUsers() - Method in class group5.trackerexpress.ElasticSearchEngineUnthreadedUser
-
Gets all registerd users from server
- getUsers(Context) - Method in class group5.trackerexpress.ElasticSearchEngineUser
-
Gets all users from server
- getUuid() - Method in class group5.trackerexpress.Claim
-
Gets the uuid.
- getUuid() - Method in class group5.trackerexpress.Expense
-
Gets the uuid.
- getUuid() - Method in class group5.trackerexpress.Tag
-
Gets the tag id.
- getUuid() - Method in class group5.trackerexpress.User
-
- getView(int, View, ViewGroup) - Method in class group5.trackerexpress.ExpenseListAdapter
-
- getView(int, View, ViewGroup) - Method in class group5.trackerexpress.GlobalClaimsListAdapter
-
Updates the respective listview item in the custom listview
- getView(int, View, ViewGroup) - Method in class group5.trackerexpress.MainClaimListAdapter
-
Updates the respective listview item in the custom listview
- getView(int, View, ViewGroup) - Method in class group5.trackerexpress.MainTagListAdapter
-
Updates the respective listview item in the custom listview
- getVisibleFragment() - Method in class group5.trackerexpress.MainActivity
-
Returns the fragment currently on screen
- global_claims_popup - Static variable in class group5.trackerexpress.R.menu
-
- GlobalClaimsFragment - Class in group5.trackerexpress
-
Fragment that deals with the global claim list, claims submitted by other
users.
- GlobalClaimsFragment() - Constructor for class group5.trackerexpress.GlobalClaimsFragment
-
Instantiates a new global claims fragment.
- GlobalClaimsListAdapter - Class in group5.trackerexpress
-
Displays the list of global claims.
- GlobalClaimsListAdapter(Context, Claim[]) - Constructor for class group5.trackerexpress.GlobalClaimsListAdapter
-
Instantiates a new main claim list adapter.
- google_play_services_version - Static variable in class com.google.android.gms.R.integer
-
- google_play_services_version - Static variable in class group5.trackerexpress.R.integer
-
- goToLocation(LatLng, Integer) - Method in class group5.trackerexpress.BasicMapActivity
-
- goToLocation(LatLng, Integer) - Method in class group5.trackerexpress.InteractiveMapActivity
-
Moves the map to a specified location.
- goToMarker(Marker, Integer) - Method in class group5.trackerexpress.BasicMapActivity
-
- grayscale - Static variable in class com.google.android.gms.R.id
-
- grayscale - Static variable in class group5.trackerexpress.R.id
-
- group5.trackerexpress - package group5.trackerexpress
-
- gtm_analytics - Static variable in class com.google.android.gms.R.raw
-
- gtm_analytics - Static variable in class group5.trackerexpress.R.raw
-


---
layout: slides
title: "On representing space."
category: hidden
type: course
semester: Fall 2018
college: Wellesley College
permalink: /cognition/space/
---
# On representing space.
???
The first stop on our tour of the mind is space. Every person exists somewhere in space, and a tremendous amount of our daily experience deals with making sure that we move ourselves and the objects under our control from one place to the next.
---
# Administrivia.
1. Attendance sheet.
2. Assignment 3 is due on Friday at 5 p.m.
3. Office hours. https://doodle.com/poll/3p5tms8yhnc9ew7w
---
class: center, middle, statement, dark
< recap >
---
class: center, middle, statement, dark
This course is on cognition.
---
class: center, middle, statement, dark
The QALMRI method can be used to analyze an experiment by considering the (Q)uestion, (A)lternataive hypotheses, (L)ogic and design, (M)ethods, (R)esults, and (I)nferences.
---
class: center, middle, statement, dark
We applied the QALMRI method to "The sting of intentional pain" as an example.
---
class: center, middle, statement, dark
Being curious pays off. Everyday experience can be mined for interesting cognitive phenomena.
---
class: center, middle, statement, dark
We asked whether there are locations where you consistently get lost.
---
class: center, middle, statement, dark
We asked how fast your hair grows in mph and why that's absurd.
---
class: center, middle, statement, dark
We asked if you believe in parapsychological abilities like ESP, mind-reading, forture telling, or mental levitation?
---
class: center, middle, statement, dark
We asked about the smartest thing you've seen a (non-human) animal do.
---
class: center, middle, statement, dark
We asked whether you have ever seen a child try to count objects.
---
class: center, middle, statement, dark
We asked for concepts for which English has no word, but another language does.
---
class: center, middle, statement, dark
We asked whether we can define "chair" and "salad".
---
class: center, middle, statement, dark
The mind faces many maddeningly hard engineering problems. Pinker's Robot Challenge reveals some. You came up with many others.
---
class: center, middle, statement, dark
To approximately solve them, the mind uses an arsenal of {mental organs, faculties, subsystems, modules, neural networks, machinery, gizmos, widgets}.
---
class: center, middle, statement, dark
Once identified, the trick is to then reverse engineer the mind's approximate solution to that problem.
---
class: center, middle, statement, dark
Each problem/solution can be analyzed using Marr's levels-of-analysis framework: computational, representational/algorithmic, implementation.
---
class: center, middle, statement, dark
What exactly is a "representation"? Consider Gallistel's isomorphisms, Playfair's maps, and Victor's visualization tools.
---
class: center, middle, statement, dark
---
class: center, middle, statement, dark
recap >
---
# The backstory that cognition tells itself.
- Until 1900s, introspective studies of consciousness
- Early 1900s, behaviorism
- Then the cognitive revolution.
???
---
# Psychology as the behaviorist views it.
“The behaviourist views psychology as a purely directive experimental branch of natural science. Its theoretical goal is the prediction and control of behavior. So far, human psychology has been unsuccessful due to the mistaken notion that introspection is the only method available to psychology, and that it is the study of consciousness. Actually, psychology is the study of behavior and therefore need not take recourse to conscious phenomena. Hence, animal psychology is as valid a field of study as human psychology. The laws of behavior of animals must be determined and evaluated in and for themselves, regardless of their generalizability to other animals or humans. This suggested elimination of states of consciousness as the objects of investigation will remove the barrier that exists between psychology and other natural sciences, without neglecting the essential problems of introspective psychology.” — John Watson
---
# Skinner
---
class: center, middle
---
# Chomsky on Skinner
“What is so surprising is the particular limitations he has imposed on the way in which the observables of behavior are to be studied, and, above all, the particularly simple nature of the function which, he claims, describes the causation of behavior. One would naturally expect that prediction of the behavior of a complex organism (or machine) would require, in addition to information about external stimulation, knowledge of the internal structure of the organism, the ways in which it processes input information and organizes its own behavior.” — Noam Chomsky
---
# Tolman
---
class: center, middle
???
Two conditions:
- Place learning (always go to F1)
- Response learning (always go right)
---
class: center, middle
---
class: center, middle
---
class: center, middle
???
Axes.
Three conditions:
- HNR: never found food
- HR: found it throughout
- HNR-R: found food only after day 10
Latent learning. When they are freely roaming the maze, they are still learning something about the layout of the maze.
---
class: center, middle
---
class: center, middle
---
class: center, middle
---
# Path integration and dead reckoning
???
What is dead reckoning? Dead reckoning is navigation by knowing where you start and then updating your location based on a vector representation of where you have moved in the interval since you last updated.
Show a vector on an axis: it has a magnitude and direction. (Highschool physics.)
Wang and Spelke point out possible representations by which path integration could be acheieved: egocentric and geocentric.
Displacement of homeward-bound ants, what do they do?
Problems: errors can accumulate, and requires memory.
---
# Viewpoint dependent representations of landmarks
---
# Reorientation
???
- C is the correct location
- R is the rotationally equivalent location
- E is elsewhere
Left is disoriented rats, right is disoriented humans.
Major point is that, when disoriented, the major landmarks don't help all that much!
---
class: middle
“Animals with cognitive systems as simple as insects
navigate by continuously updating the vectors
specifying their relation to significant environmental
locations such as the nest. As they do so, animals store
egocentric representations of significant places for
recognition, and they use these representations on
trips through familiar territory, falling back on their
path integration system when they wander into novel
terrain. Finally, a variety of animals among fish, birds
and mammals reorient themselves primarily by the
geometry of the surrounding surface layout.” — Wang & Spelke
---
class: middle, center
---
# Place cells and grid cells
???
Place cells in the hippocampus
Grid cells in the medial entorhinal cortex
---
class: center, middle
# Fin.


Quotes are a must, so we created a tone of variations, each easily customizable with colors, font sizes, images or icons.
The code is always great with any Enabled template, but its the customer support that wins me over all the time. So responsive and helpful!
Eminat99 - Envato BuyerThe code is always great with any Enabled template, but its the customer support that wins me over all the time.
Wonderful support and design! Had some questions and got fast support and answers. Highly recommend.
btimsah - Envato BuyerThe code is always great with any Enabled template, but its the customer support that wins me over all the time. So responsive and helpful!
Brilliant Template and Amazing Support Response Times! John Doe - Envato Buyer
The code is always great with any Enabled template, but its the customer support that wins me over all the time.
Everything about this theme is brilliant. I bought this as my main site was too heavy for phones and to be honest I actually prefer the mobile version to the desktop one I spent months on!
John Doe - Envato Buyer


Often configuration properties are stored in files on the user's hard disk, e.g. in .properties files or as XML documents. Configuration classes that deal with such properties need to provide typical operations like loading or saving files. The files to be processed can be specified in several different flavors like java.io.File objects, relative or absolute path names, or URLs.
To provide a consistent way of dealing with configuration files in Commons Configuration the FileConfiguration interface exists. FileConfiguration defines a standard API for accessing files and is implemented by many configuration implementations, including PropertiesConfiguration and XMLConfiguration.
In the following sections we take a closer look at the methods of the FileConfiguration interface and how they are used.
The FileConfiguration interface contains several methods for specifying the file to be loaded. The following variants are supported:
While a File or a URL uniquely identify a file, the situation is a bit ambigous when only a base path and a file name are set. These can be arbitrary strings (even full URLs) whose exact meaning must be detected when the file is loaded. For this purpose file-based configurations perform the following checks (in this order):
After the file name has been defined using one of the methods mentioned above, the load() method can be called. This method tries to locate the file and open it. If this fails, a ConfigurationException is thrown.
The FileConfiguration interface defines multiple overloaded load() methods. The one that takes no argument will always operate on the file name that has been set earlier. All other methods allow to specify the source to be loaded. This can be done as java.io.File, java.net.URL, string (containing either an absolute or relative path), input stream, or reader. When using these variants of the load() method be aware of two things:
File-based configurations typically define a set of constructors that correspond to the various setter methods for defining the data file. These constructors will set the file and then invoke the load() method. So creating a file-based configuration object and loading its content can be done in a single step.
Saving is implemented analogously to loading: There is a no argument save() method that will use the internal file name. Then for each load() method a corresponding save() method exists that will write the data contained in the configuration to different targets.
An example for loading, manipulating, and saving a configuration (based on a PropertiesConfiguration) could look as follows:
PropertiesConfiguration config = new PropertiesConfiguration("usergui.properties"); config.setProperty("colors.background", "#000000"); config.save();
You can also save a copy of the configuration to another file:
PropertiesConfiguration config = new PropertiesConfiguration("usergui.properties"); config.setProperty("colors.background", "#000000"); config.save("usergui.backup.properties);
If you want to ensure that every modification of a configuration object is immideately written to disk, you can enable the automatic saving mode. This is done through the setAutoSave() method as shown in the following example:
PropertiesConfiguration config = new PropertiesConfiguration("usergui.properties"); config.setAutoSave(true); config.setProperty("colors.background", "#000000"); // the configuration is saved after this call
Be careful with this mode when you have many updates on your configuration. This will lead to many I/O operations, too.
A common issue with file-based configurations is to handle the reloading of the data file when it changes. This is especially important if you have long running applications and do not want to restart them when a configuration file was updated. Commons Configuration has the concept of so called reloading strategies that can be associated with a file-based configuration. Such a strategy monitors a configuration file and is able to detect changes. A default reloading strategy is FileChangedReloadingStrategy. It can be set on a file-based configuration as follows:
PropertiesConfiguration config = new PropertiesConfiguration("usergui.properties"); config.setReloadingStrategy(new FileChangedReloadingStrategy());
FileChangedReloadingStrategy works as follows: On every property access the configuration checks its associated reloading strategy. FileChangedReloadingStrategy will then obtain the last modification date of the configuration file and check whether it has changed since the last access. If this is the case, a reload is triggered. To avoid often disk access when multiple properties are queried from the configuration, a refresh delay can be set on the reloading strategy. This is a time in milli seconds with the meaning that the reloading strategy will only once check the file's last modification time in the period specified here.
ManagedReloadingStrategy is an alternative to automatic reloading. It allows to hot-reload properties on a running application but only when requested by admin. The refresh() method will force a reload of the configuration source.
A typical use of this feature is to setup ManagedReloadingStrategy as a JMX MBean. The following code sample uses Springframework MBeanExporter to expose the ManagedReloadingStrategy to the JMX console :
<!-- A file based configuration bean --> <bean id="configuration" class="(...).PropertiesConfiguration"> <constructor-arg type="java.net.URL" value="file:${user.home}/custom.properties"/> <property name="reloadingStrategy" ref="reloadingStrategy"/> </bean> <!-- The managed reloading strategy for the configuration bean --> <bean id="reloadingStrategy" class="...ManagedReloadingStrategy"/> <!-- The MBeanExporter that exposes reloadingStrategy to the JMX console --> <bean id="mbeanMetadataExporter" class="org.springframework.jmx.export.MBeanExporter"> <property name="server" ref="mbeanServer"/> <property name="beans"> <map> <entry key="myApp:bean=configuration" value-ref="reloadingStrategy"/> </map> </property> </bean>


This tutorial focuses on the boto interface to AWS’ SimpleDB. This tutorial assumes that you have boto already downloaded and installed.
Note
If you’re starting a new application, you might want to consider using DynamoDB2 instead, as it has a more comprehensive feature set & has guaranteed performance throughput levels.
The first step in accessing SimpleDB is to create a connection to the service. To do so, the most straight forward way is the following:
>>> import boto.sdb
>>> conn = boto.sdb.connect_to_region(
... 'us-west-2',
... aws_access_key_id='<YOUR_AWS_KEY_ID>',
... aws_secret_access_key='<YOUR_AWS_SECRET_KEY>')
>>> conn
SDBConnection:sdb.amazonaws.com
>>>
Bear in mind that if you have your credentials in boto config in your home directory, the two keyword arguments in the call above are not needed. Also important to note is that just as any other AWS service, SimpleDB is region-specific and as such you might want to specify which region to connect to, by default, it’ll connect to the US-EAST-1 region.
Arguably, once you have your connection established, you’ll want to create one or more dmains. Creating new domains is a fairly straight forward operation. To do so, you can proceed as follows:
>>> conn.create_domain('test-domain')
Domain:test-domain
>>>
>>> conn.create_domain('test-domain-2')
Domain:test-domain
>>>
Please note that SimpleDB, unlike its newest sibling DynamoDB, is truly and completely schema-less. Thus, there’s no need specify domain keys or ranges.
Unlike DynamoDB or other database systems, SimpleDB uses the concept of ‘domains’ instead of tables. So, to list all your domains for your account in a region, you can simply do as follows:
>>> domains = conn.get_all_domains()
>>> domains
[Domain:test-domain, Domain:test-domain-2]
>>>
The get_all_domains() method returns a boto.resultset.ResultSet containing all boto.sdb.domain.Domain objects associated with this connection’s Access Key ID for that region.
If you wish to retrieve a specific domain whose name is known, you can do so as follows:
>>> dom = conn.get_domain('test-domain')
>>> dom
Domain:test-domain
>>>
The get_domain call has an optional validate parameter, which defaults to True. This will make sure to raise an exception if the domain you are looking for doesn’t exist. If you set it to false, it will return a Domain object blindly regardless of its existence.
There are times when you might want to know your domains’ machine usage, aprox. item count and other such data. To this end, boto offers a simple and convenient way to do so as shown below:
>>> domain_meta = conn.domain_metadata(dom)
>>> domain_meta
<boto.sdb.domain.DomainMetaData instance at 0x23cd440>
>>> dir(domain_meta)
['BoxUsage', 'DomainMetadataResponse', 'DomainMetadataResult', 'RequestId', 'ResponseMetadata',
'__doc__', '__init__', '__module__', 'attr_name_count', 'attr_names_size', 'attr_value_count', 'attr_values_size',
'domain', 'endElement', 'item_count', 'item_names_size', 'startElement', 'timestamp']
>>> domain_meta.item_count
0
>>>
Please bear in mind that while in the example above we used a previously retrieved domain object as the parameter, you can retrieve the domain metadata via its name (string).
Once you have your domain setup, presumably, you’ll want to start adding items to it. In its most straight forward form, you need to provide a name for the item – think of it as a record id – and a collection of the attributes you want to store in the item (often a Dictionary-like object). So, adding an item to a domain looks as follows:
>>> item_name = 'ABC_123'
>>> item_attrs = {'Artist': 'The Jackson 5', 'Genera':'Pop'}
>>> dom.put_attributes(item_name, item_attrs)
True
>>>
Now let’s check if it worked:
>>> domain_meta = conn.domain_metadata(dom)
>>> domain_meta.item_count
1
>>>
You can also add a number of items at the same time in a similar fashion. All you have to provide to the batch_put_attributes() method is a Dictionary-like object with your items and their respective attributes, as follows:
>>> items = {'item1':{'attr1':'val1'},'item2':{'attr2':'val2'}}
>>> dom.batch_put_attributes(items)
True
>>>
Now, let’s check the item count once again:
>>> domain_meta = conn.domain_metadata(dom)
>>> domain_meta.item_count
3
>>>
A few words of warning: both batch_put_attributes() and put_item(), by default, will overwrite the values of the attributes if both the item and attribute already exist. If the item exists, but not the attributes, it will append the new attributes to the attribute list of that item. If you do not wish these methods to behave in that manner, simply supply them with a ‘replace=False’ parameter.
To retrieve an item along with its attributes is a fairly straight forward operation and can be accomplished as follows:
>>> dom.get_item('item1')
{u'attr1': u'val1'}
>>>
Since SimpleDB works in an “eventual consistency” manner, we can also request a forced consistent read (though this will invariably adversely affect read performance). The way to accomplish that is as shown below:
>>> dom.get_item('item1', consistent_read=True)
{u'attr1': u'val1'}
>>>
Another way to retrieve items is through boto’s select() method. This method, at the bare minimum, requires a standard SQL select query string and you would do something along the lines of:
>>> query = 'select * from `test-domain` where attr1="val1"'
>>> rs = dom.select(query)
>>> for j in rs:
... print 'o hai'
...
o hai
>>>
This method returns a ResultSet collection you can iterate over.
The easiest way to modify an item’s attributes is by manipulating the item’s attributes and then saving those changes. For example:
>>> item = dom.get_item('item1')
>>> item['attr1'] = 'val_changed'
>>> item.save()
Deleting an item is a very simple operation. All you are required to provide is either the name of the item or an item object to the delete_item() method, boto will take care of the rest:
>>>dom.delete_item(item)
>>>True
To delete a domain and all items under it (i.e. be very careful), you can do it as follows:
>>> conn.delete_domain('test-domain')
True
>>>


© N/C 2016. All Rights Reserved.
Leafy: Holographic Guide for First Time Gardeners
Leafy is a service that expresses plants' needs to their carers using augmented reality. It helps first time gardeners be more empathetic towards their environment by gently informing them what they need to do to take care of their plants better.
Duration: 2 weeks
Team Members: Shruti Aditya Chowdhury, Jiyoung Ko, Calvin Ryu
Project Brief: To investigate the future of user interface and generate a rapid prototype to propose an ideal or disruptive user experience using emerging technologies.
My Role: Ideation, Concept Development, Interviews, UI Development, Prototyping
Initial Research:
Interviews with Novice Gardeners
People who have less experience in gardening often find out that something is wrong with their plants only after they die. This is because most of the information about plants are invisible.
To find out the reasons for unsuccessful plant growing experience, our team conducted interviews with novice gardeners to share their difficulties in maintaining healthy plants. From the interviews, we found two main causes of failure: forgetfulness and lack of knowledge.
Synthesizing our Findings:
What are the core features a novice might need?
From the findings from our research, we identified the core information a novice gardener might need. The information included the basic needs of the plants - such as amount of sunlight, water, and fertilizer. We also saw an opportunity for the system to become an interesting educational tool for the gardeners. It could visualize the plants' growth (temporal aspect) as well as provide a microscopic view into them.
Introducing Leafy:
Communicator for Your Plants' Needs
1. Plant needs water
When the plant needs water or sunlight a simple animated alarm appears. This reminds the person to water the plant or put it in a sunny spot. When the water or sunlight is received enough, the raindrops/sunlight reduce and a further confirmation is when the animated avatar (a personification of the plant) turns into a happy face. Our intention was to keep this alarm as non-intrusive as possible, rather than a constant cry for help or admonishment that disrupt the surroundings.
2. Plant needs fertilizer
There is a graphical indication when something is wrong but the detailed information is displayed only when there is a direct invocation. This too responds to physical actions taken by the person and read by the data collector.
Delivering Information Visually:
What is the best way to communicate the plant's needs?
The main design goal of Leafy was to present information to users in easy-to-understand visualizations at the right moment.
We decided that the best way to do so would be to have the interface in the same spatial-context as the plant (hologram) to provide a seamless and immersive interaction between the plant and the user. We also used metaphors and personification to convey the plant as a living organism (a pet) with emotions to help the users become more empathetic.
Designing Plant-Person Interaction:
Use of Proximity Sensor and Speech Interaction
Presenting the right information at the right moment is important - but we did not want the experience to be obstructive. So only the most urgent needs of plants are visualized when the user is in proximity, the other information are invoked only when the user speaks to the plant.
Simulating the Experience:
Prototyping using Pepper's Ghost Effect
We used used Pepper's Ghost Effect to Wizard-of-Oz the holographic experience. To achieve the effect, we designed and built a hologram simulator with a pane of mirror and acrylic sheets that would float a projection of the mobile device screen in midair. If you haven't watched our demo video - please check it out at the top of the page.