├── .gitignore ├── Makefile ├── README.md ├── core.cc ├── core.h ├── include ├── v8-debug.h ├── v8-preparser.h ├── v8-profiler.h ├── v8-testing.h ├── v8.h └── v8stdint.h ├── libv8.a ├── main.cc ├── numeric-1.2.6.min.js ├── options.cc ├── options.h ├── quantjs.js ├── run.sh ├── temp.cc └── underscore-min.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | quantjs 31 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Define the compiler options 2 | CXXFLAGS = -pipe -O2 3 | CXXFLAGS += -pthread -Iinclude -I/opt/local/include/ -I/usr/include/eigen3/ 4 | 5 | # Define what to do when make is executed without arguments. 6 | all: quantjs 7 | clang++ -o quantjs -pthread main.o options.o core.o -lv8 -Iinclude -I/usr/include/eigen3/ -I/opt/local/include/ -L/opt/local/lib/ -lQuantLib -lboost_thread -lboost_date_time -lboost_system -lglut -lGL -lGLU -lGLEW -lX11 -llapack -lblas 8 | quantjs: options.o core.o main.o 9 | 10 | # Define the rules for the object files. 11 | main.o: main.cc 12 | clang++ -c $(CXXFLAGS) main.cc -std=c++11 13 | 14 | options.o: options.cc 15 | clang++ -c $(CXXFLAGS) options.cc -std=c++11 16 | 17 | core.o: core.cc 18 | clang++ -c $(CXXFLAGS) core.cc -std=c++11 19 | 20 | clean: 21 | rm -rf *o quantjs 22 | 23 | run: 24 | ./quantjs quantjs.js 25 | 26 | runa: 27 | ./quantjs quantjs.js 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # About Quant-JS # 2 | 3 | ## What is Quant-JS ## 4 | 5 | Quant-JS is an easy to use quantitative finance workbench for JavaScript, combining Google V8 and QuantLib. 6 | 7 | Will price options (European, Bermudan and American) using the following methods, where they apply: 8 | - Black-Scholes 9 | - Heston semi-analytic 10 | - Bates semi-analytic 11 | - Barone-Adesi/Whaley 12 | - Bjerksund/Stensland 13 | - Integral 14 | - Finite differences 15 | - Binomial Jarrow-Rudd 16 | - Binomial Cox-Ross-Rubinstein 17 | - Additive equiprobabilities 18 | - Binomial Trigeorgis 19 | - Binomial Tian 20 | - Binomial Leisen-Reimer 21 | - Binomial Joshi 22 | - MC (crude) 23 | - QMC (Sobol) 24 | - MC (Longstaff Schwartz) 25 | 26 | ## Getting started ## 27 | 28 | You need the following to be able to compile quant-js (yum package names): 29 | - QuantLib (QuantLib-devel) 30 | - Boost libraries (boost-devel) 31 | - Google V8 (v8-devel) 32 | - Optional: rlwrap (wrapper for readline) 33 | 34 | Build binary: 35 | 36 | $ make 37 | 38 | Run quantjs: 39 | 40 | $ rlwrap -p'1;33' -m ./quantjs --infiles quantjs.js 41 | 42 | Example features: 43 | 44 | qjs> var pricingEngine = new PricingEngine(0) // BS 45 | qjs> var europeanOption = new EuropeanOption() 46 | qjs> europeanOption.setParams(new OptionParams('PUT', 36, 40, 0.5, 0.00, 0.06, 0.20)) 47 | qjs> var t = pricingEngine.calculateNPV(europeanOption) 48 | qjs> t 49 | 3.8094 50 | 51 | qjs> var m1 = ident(5) 52 | qjs> m1 53 | [0] 1 0 0 0 0 54 | [1] 0 1 0 0 0 55 | [2] 0 0 1 0 0 56 | [3] 0 0 0 1 0 57 | [4] 0 0 0 0 1 58 | qjs> numeric.det(m1) 59 | 1.0000 60 | 61 | qjs> var v = _.range(10).map(function(n) { return n; }); 62 | qjs> v 63 | [0] 0 64 | [1] 1 65 | [2] 2 66 | [3] 3 67 | [4] 4 68 | [5] 5 69 | [6] 6 70 | [7] 7 71 | [8] 8 72 | [9] 9 73 | 74 | 75 | The file quantjs.js is a JavaScript library to hide some implementation details and open for use of other JavaScript libraries as well. 76 | 77 | Here's a fully-functional example of how to valuate three different put options using Quant-JS: 78 | 79 | // Calculation date is today's date 80 | var pricingEngine = new PricingEngine(2); // Binomial Trigeorgis 81 | 82 | // Params: optionType, underlyingPrice, strikePrice, timeToMaturity, dividendYield, riskFreeRate, volatility 83 | 84 | var europeanOption = new EuropeanOption(); 85 | europeanOption.setParams(new OptionParams('PUT', 36, 40, 0.5, 0.00, 0.06, 0.20)); 86 | pricingEngine.calculateNPV(europeanOption); // 3.843556981971868 87 | 88 | var americanOption = new AmericanOption(); 89 | americanOption.setParams(new OptionParams('PUT', 36, 40, 0.5, 0.00, 0.06, 0.20)); 90 | pricingEngine.calculateNPV(americanOption); // 4.486461065154719 91 | 92 | var bermudanOption = new BermudanOption(); 93 | bermudanOption.setParams(new OptionParams('PUT', 36, 40, 0.5, 0.00, 0.06, 0.20)); 94 | pricingEngine.calculateNPV(bermudanOption); // 4.360909275428335 95 | 96 | 97 | ## Project status ## 98 | The project is still in early Alpha stage, so there is a lot of missing functionality. 99 | 100 | ## License and copyright ## 101 | 102 | Quant-JS is copyrighted free software made available under the terms 103 | of either the GNU General Public Licence (GPL). 104 | 105 | Copyright: (C) 2012-13 by Johan Astborg. All Rights Reserved. 106 | -------------------------------------------------------------------------------- /core.cc: -------------------------------------------------------------------------------- 1 | #include "core.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | // ----------------------------------------------------------------------------------------- 20 | // --- POINT -------------------------------------------------------------------------------------- 21 | 22 | class Point { 23 | public: 24 | Point(int x, int y) : x_(x), y_(y) { } 25 | int x_, y_; 26 | }; 27 | 28 | v8::Handle GetPointX(v8::Local property, 29 | const v8::AccessorInfo &info) { 30 | v8::Local self = info.Holder(); 31 | v8::Local wrap = v8::Local::Cast(self->GetInternalField(0)); 32 | void* ptr = wrap->Value(); 33 | int value = static_cast(ptr)->x_; 34 | return v8::Number::New(value); 35 | } 36 | 37 | void SetPointX(v8::Local property, v8::Local value, 38 | const v8::AccessorInfo& info) { 39 | v8::Local self = info.Holder(); 40 | v8::Local wrap = v8::Local::Cast(self->GetInternalField(0)); 41 | void* ptr = wrap->Value(); 42 | static_cast(ptr)->x_ = value->Int32Value(); 43 | } 44 | 45 | v8::Handle GetPointY(v8::Local property, 46 | const v8::AccessorInfo &info) { 47 | v8::Local self = info.Holder(); 48 | v8::Local wrap = v8::Local::Cast(self->GetInternalField(0)); 49 | void* ptr = wrap->Value(); 50 | int value = static_cast(ptr)->y_; 51 | return v8::Number::New(value); 52 | } 53 | 54 | void SetPointY(v8::Local property, v8::Local value, 55 | const v8::AccessorInfo& info) { 56 | v8::Local self = info.Holder(); 57 | v8::Local wrap = v8::Local::Cast(self->GetInternalField(0)); 58 | void* ptr = wrap->Value(); 59 | static_cast(ptr)->y_ = value->Int32Value(); 60 | } 61 | 62 | // ----------------------------------------------------------------------------------------- 63 | // --- Person -------------------------------------------------------------------------------------- 64 | 65 | class Person { 66 | public: 67 | Person(std::string name, int age) : name_(name), age_(age) { } 68 | std::string name_; 69 | int age_; 70 | }; 71 | 72 | v8::Handle GetPersonAge(v8::Local property, 73 | const v8::AccessorInfo &info) { 74 | v8::Local self = info.Holder(); 75 | v8::Local wrap = v8::Local::Cast(self->GetInternalField(0)); 76 | void* ptr = wrap->Value(); 77 | int value = static_cast(ptr)->age_; 78 | return v8::Number::New(value); 79 | } 80 | 81 | void SetPersonAge(v8::Local property, v8::Local value, 82 | const v8::AccessorInfo& info) { 83 | v8::Local self = info.Holder(); 84 | v8::Local wrap = v8::Local::Cast(self->GetInternalField(0)); 85 | void* ptr = wrap->Value(); 86 | static_cast(ptr)->age_ = value->Int32Value(); 87 | } 88 | 89 | v8::Handle GetPersonName(v8::Local property, 90 | const v8::AccessorInfo &info) { 91 | v8::Local self = info.Holder(); 92 | v8::Local wrap = v8::Local::Cast(self->GetInternalField(0)); 93 | void* ptr = wrap->Value(); 94 | std::string value = static_cast(ptr)->name_; 95 | return v8::String::New(value.c_str()); 96 | } 97 | 98 | void SetPersonName(v8::Local property, v8::Local value, 99 | const v8::AccessorInfo& info) { 100 | v8::Local self = info.Holder(); 101 | v8::Local wrap = v8::Local::Cast(self->GetInternalField(0)); 102 | void* ptr = wrap->Value(); 103 | static_cast(ptr)->name_ = "johan"; 104 | } 105 | 106 | // ----------------------------------------------------------------------------------------- 107 | 108 | void replaceAll(std::string& str, const std::string& from, const std::string& to) { 109 | if(from.empty()) 110 | return; 111 | size_t start_pos = 0; 112 | while((start_pos = str.find(from, start_pos)) != std::string::npos) { 113 | str.replace(start_pos, from.length(), to); 114 | start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' 115 | } 116 | } 117 | 118 | class Line { 119 | std::string data; 120 | public: 121 | friend std::istream &operator>>(std::istream &is, Line &l) { 122 | std::getline(is, l.data); 123 | //replaceAll(l.data, "\\", ";"); 124 | //replaceAll(l.data, ";;", ";"); 125 | return is; 126 | } 127 | operator std::string() const { return data; } 128 | }; 129 | 130 | struct LineReader: std::ctype { 131 | LineReader(): std::ctype(get_table()) {} 132 | static std::ctype_base::mask const* get_table() { 133 | static std::vector 134 | rc(table_size, std::ctype_base::mask()); 135 | rc['\n'] = std::ctype_base::space; 136 | return &rc[0]; 137 | } 138 | }; 139 | 140 | const char* ToCString(const v8::String::Utf8Value& value) 141 | { 142 | return *value ? *value : ""; 143 | } 144 | 145 | 146 | void Core::execute(const std::string& str) { 147 | 148 | v8::Handle global = context->Global(); 149 | v8::HandleScope handle_scope; 150 | v8::TryCatch try_catch; 151 | 152 | bool print_result = true; 153 | 154 | v8::Handle script = v8::Script::Compile(v8::String::New(str.c_str()), v8::String::New("quantjs")); 155 | 156 | if (!script.IsEmpty()) { 157 | 158 | v8::Handle result = script->Run(); 159 | 160 | v8::String::Utf8Value exception(try_catch.Exception()); 161 | const char* exception_string = ToCString(exception); 162 | v8::Handle message = try_catch.Message(); 163 | 164 | if (!message.IsEmpty()) { 165 | fprintf(stderr, "\e[0;31mOut[1]: %s\n\e[0m", exception_string); 166 | } 167 | 168 | if (!result.IsEmpty() && print_result && !result->IsUndefined()) { 169 | 170 | if (result->IsArray()) { 171 | 172 | v8::Local array = v8::Local::Cast(result->ToObject()); 173 | for (unsigned int i = 0; i < array->Length(); ++i) { 174 | v8::Local v8_value = array->Get(i); 175 | 176 | if (v8_value->IsArray()) { 177 | v8::Local arrayInside = v8::Local::Cast(v8_value->ToObject()); 178 | printf("\t[%u]\t", i); 179 | for (unsigned int j = 0; j < arrayInside->Length(); ++j) { 180 | v8::Local v8_valueInside = arrayInside->Get(j); 181 | v8::String::Utf8Value valueInside(v8_valueInside->ToDetailString()); 182 | printf("\t%s ", *valueInside); 183 | } 184 | printf("\n"); 185 | } 186 | else { 187 | v8::String::Utf8Value value(v8_value->ToDetailString()); 188 | printf("\t[%u]\t%s\n", i, *value); 189 | } 190 | } 191 | 192 | } else if (result->IsNumber()) { 193 | v8::Local number = result->ToNumber(); 194 | 195 | printf("\t%4.4f\n", number->NumberValue()); 196 | 197 | } else if (result->IsObject()) { 198 | v8::Local object = result->ToObject(); 199 | v8::Local properties = object->GetOwnPropertyNames(); 200 | for (unsigned int i = 0; i < properties->Length(); ++i) { 201 | v8::Local v8_value = object->Get(properties->Get(i)); 202 | v8::String::Utf8Value value(v8_value->ToString()); 203 | v8::String::Utf8Value key(properties->Get(i)->ToString()); 204 | printf("\t[%s]\t%s\n", *key, *value); 205 | } 206 | } else { 207 | v8::String::Utf8Value value(result->ToDetailString()); 208 | printf("\t%s\n", *value); 209 | } 210 | } 211 | } 212 | } 213 | 214 | std::string Core::promptString() { 215 | std::stringstream ss; 216 | 217 | ss << "qjs["; 218 | ss << ++promptLine; 219 | ss << "]>: "; 220 | 221 | return ss.str(); 222 | } 223 | 224 | void Core::RunShell() { 225 | 226 | using namespace v8; 227 | 228 | // Init and start V8 229 | HandleScope handle_scope; 230 | 231 | v8::Handle global = ObjectTemplate::New(); 232 | context = Context::New(NULL, global); 233 | Context::Scope context_scope(context); 234 | 235 | Handle engine_templ = FunctionTemplate::New(); 236 | engine_templ->SetClassName(String::New("QuantJS API")); 237 | 238 | Handle engine_proto = engine_templ->PrototypeTemplate(); 239 | 240 | Handle engine_inst = engine_templ->InstanceTemplate(); 241 | engine_inst->SetInternalFieldCount(1); 242 | 243 | 244 | // Point 245 | Local point_templ = ObjectTemplate::New(); 246 | point_templ->SetInternalFieldCount(1); 247 | point_templ->SetAccessor(String::New("x"), GetPointX, SetPointX); 248 | point_templ->SetAccessor(String::New("y"), GetPointY, SetPointY); 249 | Point* p = new Point(10,11); 250 | Local obj = point_templ->NewInstance(); 251 | obj->SetInternalField(0, External::New(p)); 252 | context->Global()->Set(String::New("p"), obj); 253 | 254 | 255 | // Person 256 | Local person_templ = ObjectTemplate::New(); 257 | person_templ->SetInternalFieldCount(1); 258 | person_templ->SetAccessor(String::New("age"), GetPersonAge, SetPersonAge); 259 | person_templ->SetAccessor(String::New("name"), GetPersonName, SetPersonName); 260 | Person* pp = new Person("johan", 29); 261 | Local pobj = person_templ->NewInstance(); 262 | pobj->SetInternalField(0, External::New(pp)); 263 | context->Global()->Set(String::New("person"), pobj); 264 | 265 | 266 | // Run REPL 267 | std::cin.imbue(std::locale(std::locale(), new LineReader())); 268 | 269 | std::cout << promptString(); 270 | 271 | std::for_each(std::istream_iterator(std::cin), 272 | std::istream_iterator(), 273 | [=](const std::string& s) { 274 | // TODO: wrap this pointer 275 | this->execute(s); 276 | std::cout << std::endl << promptString(); 277 | }); 278 | } 279 | 280 | void Core::run() { 281 | 282 | // just for experiementation 283 | using namespace boost::numeric::ublas; 284 | scalar_vector v (3); 285 | std::cout << v << std::endl; 286 | 287 | matrix m (3, 3); 288 | for (unsigned i = 0; i < m.size1 (); ++ i) 289 | for (unsigned j = 0; j < m.size2 (); ++ j) 290 | m (i, j) = 3 * i + j; 291 | std::cout << m << std::endl; 292 | 293 | // TODO: Map ublas to JavaScript 294 | 295 | // Check options 296 | if (!options.validate()) return; 297 | std::cout << options << std::endl; 298 | 299 | RunShell(); 300 | } 301 | -------------------------------------------------------------------------------- /core.h: -------------------------------------------------------------------------------- 1 | #ifndef CORE_H 2 | #define CORE_H 3 | 4 | #include 5 | #include 6 | #include "options.h" 7 | 8 | class Core { 9 | public: 10 | Core(Options options) : options(options), promptLine(0) {} 11 | void run(); 12 | void execute(const std::string& str); 13 | void RunShell(); 14 | 15 | std::string promptString(); 16 | 17 | private: 18 | const Options& options; 19 | v8::Persistent context; 20 | int promptLine; 21 | }; 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /include/v8-debug.h: -------------------------------------------------------------------------------- 1 | // Copyright 2008 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef V8_V8_DEBUG_H_ 29 | #define V8_V8_DEBUG_H_ 30 | 31 | #include "v8.h" 32 | 33 | #ifdef _WIN32 34 | typedef int int32_t; 35 | typedef unsigned int uint32_t; 36 | typedef unsigned short uint16_t; // NOLINT 37 | typedef long long int64_t; // NOLINT 38 | 39 | // Setup for Windows DLL export/import. See v8.h in this directory for 40 | // information on how to build/use V8 as a DLL. 41 | #if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED) 42 | #error both BUILDING_V8_SHARED and USING_V8_SHARED are set - please check the\ 43 | build configuration to ensure that at most one of these is set 44 | #endif 45 | 46 | #ifdef BUILDING_V8_SHARED 47 | #define EXPORT __declspec(dllexport) 48 | #elif USING_V8_SHARED 49 | #define EXPORT __declspec(dllimport) 50 | #else 51 | #define EXPORT 52 | #endif 53 | 54 | #else // _WIN32 55 | 56 | // Setup for Linux shared library export. See v8.h in this directory for 57 | // information on how to build/use V8 as shared library. 58 | #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(V8_SHARED) 59 | #define EXPORT __attribute__ ((visibility("default"))) 60 | #else // defined(__GNUC__) && (__GNUC__ >= 4) 61 | #define EXPORT 62 | #endif // defined(__GNUC__) && (__GNUC__ >= 4) 63 | 64 | #endif // _WIN32 65 | 66 | 67 | /** 68 | * Debugger support for the V8 JavaScript engine. 69 | */ 70 | namespace v8 { 71 | 72 | // Debug events which can occur in the V8 JavaScript engine. 73 | enum DebugEvent { 74 | Break = 1, 75 | Exception = 2, 76 | NewFunction = 3, 77 | BeforeCompile = 4, 78 | AfterCompile = 5, 79 | ScriptCollected = 6, 80 | BreakForCommand = 7 81 | }; 82 | 83 | 84 | class EXPORT Debug { 85 | public: 86 | /** 87 | * A client object passed to the v8 debugger whose ownership will be taken by 88 | * it. v8 is always responsible for deleting the object. 89 | */ 90 | class ClientData { 91 | public: 92 | virtual ~ClientData() {} 93 | }; 94 | 95 | 96 | /** 97 | * A message object passed to the debug message handler. 98 | */ 99 | class Message { 100 | public: 101 | /** 102 | * Check type of message. 103 | */ 104 | virtual bool IsEvent() const = 0; 105 | virtual bool IsResponse() const = 0; 106 | virtual DebugEvent GetEvent() const = 0; 107 | 108 | /** 109 | * Indicate whether this is a response to a continue command which will 110 | * start the VM running after this is processed. 111 | */ 112 | virtual bool WillStartRunning() const = 0; 113 | 114 | /** 115 | * Access to execution state and event data. Don't store these cross 116 | * callbacks as their content becomes invalid. These objects are from the 117 | * debugger event that started the debug message loop. 118 | */ 119 | virtual Handle GetExecutionState() const = 0; 120 | virtual Handle GetEventData() const = 0; 121 | 122 | /** 123 | * Get the debugger protocol JSON. 124 | */ 125 | virtual Handle GetJSON() const = 0; 126 | 127 | /** 128 | * Get the context active when the debug event happened. Note this is not 129 | * the current active context as the JavaScript part of the debugger is 130 | * running in its own context which is entered at this point. 131 | */ 132 | virtual Handle GetEventContext() const = 0; 133 | 134 | /** 135 | * Client data passed with the corresponding request if any. This is the 136 | * client_data data value passed into Debug::SendCommand along with the 137 | * request that led to the message or NULL if the message is an event. The 138 | * debugger takes ownership of the data and will delete it even if there is 139 | * no message handler. 140 | */ 141 | virtual ClientData* GetClientData() const = 0; 142 | 143 | virtual ~Message() {} 144 | }; 145 | 146 | 147 | /** 148 | * An event details object passed to the debug event listener. 149 | */ 150 | class EventDetails { 151 | public: 152 | /** 153 | * Event type. 154 | */ 155 | virtual DebugEvent GetEvent() const = 0; 156 | 157 | /** 158 | * Access to execution state and event data of the debug event. Don't store 159 | * these cross callbacks as their content becomes invalid. 160 | */ 161 | virtual Handle GetExecutionState() const = 0; 162 | virtual Handle GetEventData() const = 0; 163 | 164 | /** 165 | * Get the context active when the debug event happened. Note this is not 166 | * the current active context as the JavaScript part of the debugger is 167 | * running in its own context which is entered at this point. 168 | */ 169 | virtual Handle GetEventContext() const = 0; 170 | 171 | /** 172 | * Client data passed with the corresponding callback when it was 173 | * registered. 174 | */ 175 | virtual Handle GetCallbackData() const = 0; 176 | 177 | /** 178 | * Client data passed to DebugBreakForCommand function. The 179 | * debugger takes ownership of the data and will delete it even if 180 | * there is no message handler. 181 | */ 182 | virtual ClientData* GetClientData() const = 0; 183 | 184 | virtual ~EventDetails() {} 185 | }; 186 | 187 | 188 | /** 189 | * Debug event callback function. 190 | * 191 | * \param event the type of the debug event that triggered the callback 192 | * (enum DebugEvent) 193 | * \param exec_state execution state (JavaScript object) 194 | * \param event_data event specific data (JavaScript object) 195 | * \param data value passed by the user to SetDebugEventListener 196 | */ 197 | typedef void (*EventCallback)(DebugEvent event, 198 | Handle exec_state, 199 | Handle event_data, 200 | Handle data); 201 | 202 | /** 203 | * Debug event callback function. 204 | * 205 | * \param event_details object providing information about the debug event 206 | * 207 | * A EventCallback2 does not take possession of the event data, 208 | * and must not rely on the data persisting after the handler returns. 209 | */ 210 | typedef void (*EventCallback2)(const EventDetails& event_details); 211 | 212 | /** 213 | * Debug message callback function. 214 | * 215 | * \param message the debug message handler message object 216 | * \param length length of the message 217 | * \param client_data the data value passed when registering the message handler 218 | 219 | * A MessageHandler does not take possession of the message string, 220 | * and must not rely on the data persisting after the handler returns. 221 | * 222 | * This message handler is deprecated. Use MessageHandler2 instead. 223 | */ 224 | typedef void (*MessageHandler)(const uint16_t* message, int length, 225 | ClientData* client_data); 226 | 227 | /** 228 | * Debug message callback function. 229 | * 230 | * \param message the debug message handler message object 231 | * 232 | * A MessageHandler does not take possession of the message data, 233 | * and must not rely on the data persisting after the handler returns. 234 | */ 235 | typedef void (*MessageHandler2)(const Message& message); 236 | 237 | /** 238 | * Debug host dispatch callback function. 239 | */ 240 | typedef void (*HostDispatchHandler)(); 241 | 242 | /** 243 | * Callback function for the host to ensure debug messages are processed. 244 | */ 245 | typedef void (*DebugMessageDispatchHandler)(); 246 | 247 | // Set a C debug event listener. 248 | static bool SetDebugEventListener(EventCallback that, 249 | Handle data = Handle()); 250 | static bool SetDebugEventListener2(EventCallback2 that, 251 | Handle data = Handle()); 252 | 253 | // Set a JavaScript debug event listener. 254 | static bool SetDebugEventListener(v8::Handle that, 255 | Handle data = Handle()); 256 | 257 | // Schedule a debugger break to happen when JavaScript code is run 258 | // in the given isolate. If no isolate is provided the default 259 | // isolate is used. 260 | static void DebugBreak(Isolate* isolate = NULL); 261 | 262 | // Remove scheduled debugger break in given isolate if it has not 263 | // happened yet. If no isolate is provided the default isolate is 264 | // used. 265 | static void CancelDebugBreak(Isolate* isolate = NULL); 266 | 267 | // Break execution of JavaScript in the given isolate (this method 268 | // can be invoked from a non-VM thread) for further client command 269 | // execution on a VM thread. Client data is then passed in 270 | // EventDetails to EventCallback at the moment when the VM actually 271 | // stops. If no isolate is provided the default isolate is used. 272 | static void DebugBreakForCommand(ClientData* data = NULL, 273 | Isolate* isolate = NULL); 274 | 275 | // Message based interface. The message protocol is JSON. NOTE the message 276 | // handler thread is not supported any more parameter must be false. 277 | static void SetMessageHandler(MessageHandler handler, 278 | bool message_handler_thread = false); 279 | static void SetMessageHandler2(MessageHandler2 handler); 280 | 281 | // If no isolate is provided the default isolate is 282 | // used. 283 | static void SendCommand(const uint16_t* command, int length, 284 | ClientData* client_data = NULL, 285 | Isolate* isolate = NULL); 286 | 287 | // Dispatch interface. 288 | static void SetHostDispatchHandler(HostDispatchHandler handler, 289 | int period = 100); 290 | 291 | /** 292 | * Register a callback function to be called when a debug message has been 293 | * received and is ready to be processed. For the debug messages to be 294 | * processed V8 needs to be entered, and in certain embedding scenarios this 295 | * callback can be used to make sure V8 is entered for the debug message to 296 | * be processed. Note that debug messages will only be processed if there is 297 | * a V8 break. This can happen automatically by using the option 298 | * --debugger-auto-break. 299 | * \param provide_locker requires that V8 acquires v8::Locker for you before 300 | * calling handler 301 | */ 302 | static void SetDebugMessageDispatchHandler( 303 | DebugMessageDispatchHandler handler, bool provide_locker = false); 304 | 305 | /** 306 | * Run a JavaScript function in the debugger. 307 | * \param fun the function to call 308 | * \param data passed as second argument to the function 309 | * With this call the debugger is entered and the function specified is called 310 | * with the execution state as the first argument. This makes it possible to 311 | * get access to information otherwise not available during normal JavaScript 312 | * execution e.g. details on stack frames. Receiver of the function call will 313 | * be the debugger context global object, however this is a subject to change. 314 | * The following example shows a JavaScript function which when passed to 315 | * v8::Debug::Call will return the current line of JavaScript execution. 316 | * 317 | * \code 318 | * function frame_source_line(exec_state) { 319 | * return exec_state.frame(0).sourceLine(); 320 | * } 321 | * \endcode 322 | */ 323 | static Local Call(v8::Handle fun, 324 | Handle data = Handle()); 325 | 326 | /** 327 | * Returns a mirror object for the given object. 328 | */ 329 | static Local GetMirror(v8::Handle obj); 330 | 331 | /** 332 | * Enable the V8 builtin debug agent. The debugger agent will listen on the 333 | * supplied TCP/IP port for remote debugger connection. 334 | * \param name the name of the embedding application 335 | * \param port the TCP/IP port to listen on 336 | * \param wait_for_connection whether V8 should pause on a first statement 337 | * allowing remote debugger to connect before anything interesting happened 338 | */ 339 | static bool EnableAgent(const char* name, int port, 340 | bool wait_for_connection = false); 341 | 342 | /** 343 | * Disable the V8 builtin debug agent. The TCP/IP connection will be closed. 344 | */ 345 | static void DisableAgent(); 346 | 347 | /** 348 | * Makes V8 process all pending debug messages. 349 | * 350 | * From V8 point of view all debug messages come asynchronously (e.g. from 351 | * remote debugger) but they all must be handled synchronously: V8 cannot 352 | * do 2 things at one time so normal script execution must be interrupted 353 | * for a while. 354 | * 355 | * Generally when message arrives V8 may be in one of 3 states: 356 | * 1. V8 is running script; V8 will automatically interrupt and process all 357 | * pending messages (however auto_break flag should be enabled); 358 | * 2. V8 is suspended on debug breakpoint; in this state V8 is dedicated 359 | * to reading and processing debug messages; 360 | * 3. V8 is not running at all or has called some long-working C++ function; 361 | * by default it means that processing of all debug messages will be deferred 362 | * until V8 gets control again; however, embedding application may improve 363 | * this by manually calling this method. 364 | * 365 | * It makes sense to call this method whenever a new debug message arrived and 366 | * V8 is not already running. Method v8::Debug::SetDebugMessageDispatchHandler 367 | * should help with the former condition. 368 | * 369 | * Technically this method in many senses is equivalent to executing empty 370 | * script: 371 | * 1. It does nothing except for processing all pending debug messages. 372 | * 2. It should be invoked with the same precautions and from the same context 373 | * as V8 script would be invoked from, because: 374 | * a. with "evaluate" command it can do whatever normal script can do, 375 | * including all native calls; 376 | * b. no other thread should call V8 while this method is running 377 | * (v8::Locker may be used here). 378 | * 379 | * "Evaluate" debug command behavior currently is not specified in scope 380 | * of this method. 381 | */ 382 | static void ProcessDebugMessages(); 383 | 384 | /** 385 | * Debugger is running in its own context which is entered while debugger 386 | * messages are being dispatched. This is an explicit getter for this 387 | * debugger context. Note that the content of the debugger context is subject 388 | * to change. 389 | */ 390 | static Local GetDebugContext(); 391 | 392 | 393 | /** 394 | * Enable/disable LiveEdit functionality for the given Isolate 395 | * (default Isolate if not provided). V8 will abort if LiveEdit is 396 | * unexpectedly used. LiveEdit is enabled by default. 397 | */ 398 | static void SetLiveEditEnabled(bool enable, Isolate* isolate = NULL); 399 | }; 400 | 401 | 402 | } // namespace v8 403 | 404 | 405 | #undef EXPORT 406 | 407 | 408 | #endif // V8_V8_DEBUG_H_ 409 | -------------------------------------------------------------------------------- /include/v8-preparser.h: -------------------------------------------------------------------------------- 1 | // Copyright 2011 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef PREPARSER_H 29 | #define PREPARSER_H 30 | 31 | #include "v8stdint.h" 32 | 33 | #ifdef _WIN32 34 | 35 | // Setup for Windows DLL export/import. When building the V8 DLL the 36 | // BUILDING_V8_SHARED needs to be defined. When building a program which uses 37 | // the V8 DLL USING_V8_SHARED needs to be defined. When either building the V8 38 | // static library or building a program which uses the V8 static library neither 39 | // BUILDING_V8_SHARED nor USING_V8_SHARED should be defined. 40 | #if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED) 41 | #error both BUILDING_V8_SHARED and USING_V8_SHARED are set - please check the\ 42 | build configuration to ensure that at most one of these is set 43 | #endif 44 | 45 | #ifdef BUILDING_V8_SHARED 46 | #define V8EXPORT __declspec(dllexport) 47 | #elif USING_V8_SHARED 48 | #define V8EXPORT __declspec(dllimport) 49 | #else 50 | #define V8EXPORT 51 | #endif // BUILDING_V8_SHARED 52 | 53 | #else // _WIN32 54 | 55 | // Setup for Linux shared library export. There is no need to distinguish 56 | // between building or using the V8 shared library, but we should not 57 | // export symbols when we are building a static library. 58 | #if defined(__GNUC__) && ((__GNUC__ >= 4) || \ 59 | (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(V8_SHARED) 60 | #define V8EXPORT __attribute__ ((visibility("default"))) 61 | #else 62 | #define V8EXPORT 63 | #endif 64 | 65 | #endif // _WIN32 66 | 67 | 68 | namespace v8 { 69 | 70 | // The result of preparsing is either a stack overflow error, or an opaque 71 | // blob of data that can be passed back into the parser. 72 | class V8EXPORT PreParserData { 73 | public: 74 | PreParserData(size_t size, const uint8_t* data) 75 | : data_(data), size_(size) { } 76 | 77 | // Create a PreParserData value where stack_overflow reports true. 78 | static PreParserData StackOverflow() { return PreParserData(0, NULL); } 79 | 80 | // Whether the pre-parser stopped due to a stack overflow. 81 | // If this is the case, size() and data() should not be used. 82 | bool stack_overflow() { return size_ == 0u; } 83 | 84 | // The size of the data in bytes. 85 | size_t size() const { return size_; } 86 | 87 | // Pointer to the data. 88 | const uint8_t* data() const { return data_; } 89 | 90 | private: 91 | const uint8_t* const data_; 92 | const size_t size_; 93 | }; 94 | 95 | 96 | // Interface for a stream of Unicode characters. 97 | class V8EXPORT UnicodeInputStream { // NOLINT - Thinks V8EXPORT is class name. 98 | public: 99 | virtual ~UnicodeInputStream(); 100 | 101 | // Returns the next Unicode code-point in the input, or a negative value when 102 | // there is no more input in the stream. 103 | virtual int32_t Next() = 0; 104 | }; 105 | 106 | 107 | // Preparse a JavaScript program. The source code is provided as a 108 | // UnicodeInputStream. The max_stack_size limits the amount of stack 109 | // space that the preparser is allowed to use. If the preparser uses 110 | // more stack space than the limit provided, the result's stack_overflow() 111 | // method will return true. Otherwise the result contains preparser 112 | // data that can be used by the V8 parser to speed up parsing. 113 | PreParserData V8EXPORT Preparse(UnicodeInputStream* input, 114 | size_t max_stack_size); 115 | 116 | } // namespace v8. 117 | 118 | #endif // PREPARSER_H 119 | -------------------------------------------------------------------------------- /include/v8-profiler.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef V8_V8_PROFILER_H_ 29 | #define V8_V8_PROFILER_H_ 30 | 31 | #include "v8.h" 32 | 33 | #ifdef _WIN32 34 | // Setup for Windows DLL export/import. See v8.h in this directory for 35 | // information on how to build/use V8 as a DLL. 36 | #if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED) 37 | #error both BUILDING_V8_SHARED and USING_V8_SHARED are set - please check the\ 38 | build configuration to ensure that at most one of these is set 39 | #endif 40 | 41 | #ifdef BUILDING_V8_SHARED 42 | #define V8EXPORT __declspec(dllexport) 43 | #elif USING_V8_SHARED 44 | #define V8EXPORT __declspec(dllimport) 45 | #else 46 | #define V8EXPORT 47 | #endif 48 | 49 | #else // _WIN32 50 | 51 | // Setup for Linux shared library export. See v8.h in this directory for 52 | // information on how to build/use V8 as shared library. 53 | #if defined(__GNUC__) && ((__GNUC__ >= 4) || \ 54 | (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(V8_SHARED) 55 | #define V8EXPORT __attribute__ ((visibility("default"))) 56 | #else 57 | #define V8EXPORT 58 | #endif 59 | 60 | #endif // _WIN32 61 | 62 | 63 | /** 64 | * Profiler support for the V8 JavaScript engine. 65 | */ 66 | namespace v8 { 67 | 68 | typedef uint32_t SnapshotObjectId; 69 | 70 | /** 71 | * CpuProfileNode represents a node in a call graph. 72 | */ 73 | class V8EXPORT CpuProfileNode { 74 | public: 75 | /** Returns function name (empty string for anonymous functions.) */ 76 | Handle GetFunctionName() const; 77 | 78 | /** Returns resource name for script from where the function originates. */ 79 | Handle GetScriptResourceName() const; 80 | 81 | /** 82 | * Returns the number, 1-based, of the line where the function originates. 83 | * kNoLineNumberInfo if no line number information is available. 84 | */ 85 | int GetLineNumber() const; 86 | 87 | /** 88 | * Returns total (self + children) execution time of the function, 89 | * in milliseconds, estimated by samples count. 90 | */ 91 | double GetTotalTime() const; 92 | 93 | /** 94 | * Returns self execution time of the function, in milliseconds, 95 | * estimated by samples count. 96 | */ 97 | double GetSelfTime() const; 98 | 99 | /** Returns the count of samples where function exists. */ 100 | double GetTotalSamplesCount() const; 101 | 102 | /** Returns the count of samples where function was currently executing. */ 103 | double GetSelfSamplesCount() const; 104 | 105 | /** Returns function entry UID. */ 106 | unsigned GetCallUid() const; 107 | 108 | /** Returns child nodes count of the node. */ 109 | int GetChildrenCount() const; 110 | 111 | /** Retrieves a child node by index. */ 112 | const CpuProfileNode* GetChild(int index) const; 113 | 114 | static const int kNoLineNumberInfo = Message::kNoLineNumberInfo; 115 | }; 116 | 117 | 118 | /** 119 | * CpuProfile contains a CPU profile in a form of two call trees: 120 | * - top-down (from main() down to functions that do all the work); 121 | * - bottom-up call graph (in backward direction). 122 | */ 123 | class V8EXPORT CpuProfile { 124 | public: 125 | /** Returns CPU profile UID (assigned by the profiler.) */ 126 | unsigned GetUid() const; 127 | 128 | /** Returns CPU profile title. */ 129 | Handle GetTitle() const; 130 | 131 | /** Returns the root node of the bottom up call tree. */ 132 | const CpuProfileNode* GetBottomUpRoot() const; 133 | 134 | /** Returns the root node of the top down call tree. */ 135 | const CpuProfileNode* GetTopDownRoot() const; 136 | 137 | /** 138 | * Deletes the profile and removes it from CpuProfiler's list. 139 | * All pointers to nodes previously returned become invalid. 140 | * Profiles with the same uid but obtained using different 141 | * security token are not deleted, but become inaccessible 142 | * using FindProfile method. It is embedder's responsibility 143 | * to call Delete on these profiles. 144 | */ 145 | void Delete(); 146 | }; 147 | 148 | 149 | /** 150 | * Interface for controlling CPU profiling. 151 | */ 152 | class V8EXPORT CpuProfiler { 153 | public: 154 | /** 155 | * A note on security tokens usage. As scripts from different 156 | * origins can run inside a single V8 instance, it is possible to 157 | * have functions from different security contexts intermixed in a 158 | * single CPU profile. To avoid exposing function names belonging to 159 | * other contexts, filtering by security token is performed while 160 | * obtaining profiling results. 161 | */ 162 | 163 | /** 164 | * Returns the number of profiles collected (doesn't include 165 | * profiles that are being collected at the moment of call.) 166 | */ 167 | static int GetProfilesCount(); 168 | 169 | /** Returns a profile by index. */ 170 | static const CpuProfile* GetProfile( 171 | int index, 172 | Handle security_token = Handle()); 173 | 174 | /** Returns a profile by uid. */ 175 | static const CpuProfile* FindProfile( 176 | unsigned uid, 177 | Handle security_token = Handle()); 178 | 179 | /** 180 | * Starts collecting CPU profile. Title may be an empty string. It 181 | * is allowed to have several profiles being collected at 182 | * once. Attempts to start collecting several profiles with the same 183 | * title are silently ignored. While collecting a profile, functions 184 | * from all security contexts are included in it. The token-based 185 | * filtering is only performed when querying for a profile. 186 | */ 187 | static void StartProfiling(Handle title); 188 | 189 | /** 190 | * Stops collecting CPU profile with a given title and returns it. 191 | * If the title given is empty, finishes the last profile started. 192 | */ 193 | static const CpuProfile* StopProfiling( 194 | Handle title, 195 | Handle security_token = Handle()); 196 | 197 | /** 198 | * Deletes all existing profiles, also cancelling all profiling 199 | * activity. All previously returned pointers to profiles and their 200 | * contents become invalid after this call. 201 | */ 202 | static void DeleteAllProfiles(); 203 | }; 204 | 205 | 206 | class HeapGraphNode; 207 | 208 | 209 | /** 210 | * HeapSnapshotEdge represents a directed connection between heap 211 | * graph nodes: from retainers to retained nodes. 212 | */ 213 | class V8EXPORT HeapGraphEdge { 214 | public: 215 | enum Type { 216 | kContextVariable = 0, // A variable from a function context. 217 | kElement = 1, // An element of an array. 218 | kProperty = 2, // A named object property. 219 | kInternal = 3, // A link that can't be accessed from JS, 220 | // thus, its name isn't a real property name 221 | // (e.g. parts of a ConsString). 222 | kHidden = 4, // A link that is needed for proper sizes 223 | // calculation, but may be hidden from user. 224 | kShortcut = 5, // A link that must not be followed during 225 | // sizes calculation. 226 | kWeak = 6 // A weak reference (ignored by the GC). 227 | }; 228 | 229 | /** Returns edge type (see HeapGraphEdge::Type). */ 230 | Type GetType() const; 231 | 232 | /** 233 | * Returns edge name. This can be a variable name, an element index, or 234 | * a property name. 235 | */ 236 | Handle GetName() const; 237 | 238 | /** Returns origin node. */ 239 | const HeapGraphNode* GetFromNode() const; 240 | 241 | /** Returns destination node. */ 242 | const HeapGraphNode* GetToNode() const; 243 | }; 244 | 245 | 246 | /** 247 | * HeapGraphNode represents a node in a heap graph. 248 | */ 249 | class V8EXPORT HeapGraphNode { 250 | public: 251 | enum Type { 252 | kHidden = 0, // Hidden node, may be filtered when shown to user. 253 | kArray = 1, // An array of elements. 254 | kString = 2, // A string. 255 | kObject = 3, // A JS object (except for arrays and strings). 256 | kCode = 4, // Compiled code. 257 | kClosure = 5, // Function closure. 258 | kRegExp = 6, // RegExp. 259 | kHeapNumber = 7, // Number stored in the heap. 260 | kNative = 8, // Native object (not from V8 heap). 261 | kSynthetic = 9 // Synthetic object, usualy used for grouping 262 | // snapshot items together. 263 | }; 264 | 265 | /** Returns node type (see HeapGraphNode::Type). */ 266 | Type GetType() const; 267 | 268 | /** 269 | * Returns node name. Depending on node's type this can be the name 270 | * of the constructor (for objects), the name of the function (for 271 | * closures), string value, or an empty string (for compiled code). 272 | */ 273 | Handle GetName() const; 274 | 275 | /** 276 | * Returns node id. For the same heap object, the id remains the same 277 | * across all snapshots. 278 | */ 279 | SnapshotObjectId GetId() const; 280 | 281 | /** Returns node's own size, in bytes. */ 282 | int GetSelfSize() const; 283 | 284 | /** Returns child nodes count of the node. */ 285 | int GetChildrenCount() const; 286 | 287 | /** Retrieves a child by index. */ 288 | const HeapGraphEdge* GetChild(int index) const; 289 | 290 | /** 291 | * Finds and returns a value from the heap corresponding to this node, 292 | * if the value is still reachable. 293 | */ 294 | Handle GetHeapValue() const; 295 | }; 296 | 297 | 298 | /** 299 | * HeapSnapshots record the state of the JS heap at some moment. 300 | */ 301 | class V8EXPORT HeapSnapshot { 302 | public: 303 | enum Type { 304 | kFull = 0 // Heap snapshot with all instances and references. 305 | }; 306 | enum SerializationFormat { 307 | kJSON = 0 // See format description near 'Serialize' method. 308 | }; 309 | 310 | /** Returns heap snapshot type. */ 311 | Type GetType() const; 312 | 313 | /** Returns heap snapshot UID (assigned by the profiler.) */ 314 | unsigned GetUid() const; 315 | 316 | /** Returns heap snapshot title. */ 317 | Handle GetTitle() const; 318 | 319 | /** Returns the root node of the heap graph. */ 320 | const HeapGraphNode* GetRoot() const; 321 | 322 | /** Returns a node by its id. */ 323 | const HeapGraphNode* GetNodeById(SnapshotObjectId id) const; 324 | 325 | /** Returns total nodes count in the snapshot. */ 326 | int GetNodesCount() const; 327 | 328 | /** Returns a node by index. */ 329 | const HeapGraphNode* GetNode(int index) const; 330 | 331 | /** Returns a max seen JS object Id. */ 332 | SnapshotObjectId GetMaxSnapshotJSObjectId() const; 333 | 334 | /** 335 | * Deletes the snapshot and removes it from HeapProfiler's list. 336 | * All pointers to nodes, edges and paths previously returned become 337 | * invalid. 338 | */ 339 | void Delete(); 340 | 341 | /** 342 | * Prepare a serialized representation of the snapshot. The result 343 | * is written into the stream provided in chunks of specified size. 344 | * The total length of the serialized snapshot is unknown in 345 | * advance, it can be roughly equal to JS heap size (that means, 346 | * it can be really big - tens of megabytes). 347 | * 348 | * For the JSON format, heap contents are represented as an object 349 | * with the following structure: 350 | * 351 | * { 352 | * snapshot: { 353 | * title: "...", 354 | * uid: nnn, 355 | * meta: { meta-info }, 356 | * node_count: nnn, 357 | * edge_count: nnn 358 | * }, 359 | * nodes: [nodes array], 360 | * edges: [edges array], 361 | * strings: [strings array] 362 | * } 363 | * 364 | * Nodes reference strings, other nodes, and edges by their indexes 365 | * in corresponding arrays. 366 | */ 367 | void Serialize(OutputStream* stream, SerializationFormat format) const; 368 | }; 369 | 370 | 371 | class RetainedObjectInfo; 372 | 373 | /** 374 | * Interface for controlling heap profiling. 375 | */ 376 | class V8EXPORT HeapProfiler { 377 | public: 378 | /** 379 | * Callback function invoked for obtaining RetainedObjectInfo for 380 | * the given JavaScript wrapper object. It is prohibited to enter V8 381 | * while the callback is running: only getters on the handle and 382 | * GetPointerFromInternalField on the objects are allowed. 383 | */ 384 | typedef RetainedObjectInfo* (*WrapperInfoCallback) 385 | (uint16_t class_id, Handle wrapper); 386 | 387 | /** Returns the number of snapshots taken. */ 388 | static int GetSnapshotsCount(); 389 | 390 | /** Returns a snapshot by index. */ 391 | static const HeapSnapshot* GetSnapshot(int index); 392 | 393 | /** Returns a profile by uid. */ 394 | static const HeapSnapshot* FindSnapshot(unsigned uid); 395 | 396 | /** 397 | * Returns SnapshotObjectId for a heap object referenced by |value| if 398 | * it has been seen by the heap profiler, kUnknownObjectId otherwise. 399 | */ 400 | static SnapshotObjectId GetSnapshotObjectId(Handle value); 401 | 402 | /** 403 | * A constant for invalid SnapshotObjectId. GetSnapshotObjectId will return 404 | * it in case heap profiler cannot find id for the object passed as 405 | * parameter. HeapSnapshot::GetNodeById will always return NULL for such id. 406 | */ 407 | static const SnapshotObjectId kUnknownObjectId = 0; 408 | 409 | /** 410 | * Takes a heap snapshot and returns it. Title may be an empty string. 411 | * See HeapSnapshot::Type for types description. 412 | */ 413 | static const HeapSnapshot* TakeSnapshot( 414 | Handle title, 415 | HeapSnapshot::Type type = HeapSnapshot::kFull, 416 | ActivityControl* control = NULL); 417 | 418 | /** 419 | * Starts tracking of heap objects population statistics. After calling 420 | * this method, all heap objects relocations done by the garbage collector 421 | * are being registered. 422 | */ 423 | static void StartHeapObjectsTracking(); 424 | 425 | /** 426 | * Adds a new time interval entry to the aggregated statistics array. The 427 | * time interval entry contains information on the current heap objects 428 | * population size. The method also updates aggregated statistics and 429 | * reports updates for all previous time intervals via the OutputStream 430 | * object. Updates on each time interval are provided as a stream of the 431 | * HeapStatsUpdate structure instances. 432 | * The return value of the function is the last seen heap object Id. 433 | * 434 | * StartHeapObjectsTracking must be called before the first call to this 435 | * method. 436 | */ 437 | static SnapshotObjectId PushHeapObjectsStats(OutputStream* stream); 438 | 439 | /** 440 | * Stops tracking of heap objects population statistics, cleans up all 441 | * collected data. StartHeapObjectsTracking must be called again prior to 442 | * calling PushHeapObjectsStats next time. 443 | */ 444 | static void StopHeapObjectsTracking(); 445 | 446 | /** 447 | * Deletes all snapshots taken. All previously returned pointers to 448 | * snapshots and their contents become invalid after this call. 449 | */ 450 | static void DeleteAllSnapshots(); 451 | 452 | /** Binds a callback to embedder's class ID. */ 453 | static void DefineWrapperClass( 454 | uint16_t class_id, 455 | WrapperInfoCallback callback); 456 | 457 | /** 458 | * Default value of persistent handle class ID. Must not be used to 459 | * define a class. Can be used to reset a class of a persistent 460 | * handle. 461 | */ 462 | static const uint16_t kPersistentHandleNoClassId = 0; 463 | 464 | /** Returns the number of currently existing persistent handles. */ 465 | static int GetPersistentHandleCount(); 466 | 467 | /** Returns memory used for profiler internal data and snapshots. */ 468 | static size_t GetMemorySizeUsedByProfiler(); 469 | }; 470 | 471 | 472 | /** 473 | * Interface for providing information about embedder's objects 474 | * held by global handles. This information is reported in two ways: 475 | * 476 | * 1. When calling AddObjectGroup, an embedder may pass 477 | * RetainedObjectInfo instance describing the group. To collect 478 | * this information while taking a heap snapshot, V8 calls GC 479 | * prologue and epilogue callbacks. 480 | * 481 | * 2. When a heap snapshot is collected, V8 additionally 482 | * requests RetainedObjectInfos for persistent handles that 483 | * were not previously reported via AddObjectGroup. 484 | * 485 | * Thus, if an embedder wants to provide information about native 486 | * objects for heap snapshots, he can do it in a GC prologue 487 | * handler, and / or by assigning wrapper class ids in the following way: 488 | * 489 | * 1. Bind a callback to class id by calling DefineWrapperClass. 490 | * 2. Call SetWrapperClassId on certain persistent handles. 491 | * 492 | * V8 takes ownership of RetainedObjectInfo instances passed to it and 493 | * keeps them alive only during snapshot collection. Afterwards, they 494 | * are freed by calling the Dispose class function. 495 | */ 496 | class V8EXPORT RetainedObjectInfo { // NOLINT 497 | public: 498 | /** Called by V8 when it no longer needs an instance. */ 499 | virtual void Dispose() = 0; 500 | 501 | /** Returns whether two instances are equivalent. */ 502 | virtual bool IsEquivalent(RetainedObjectInfo* other) = 0; 503 | 504 | /** 505 | * Returns hash value for the instance. Equivalent instances 506 | * must have the same hash value. 507 | */ 508 | virtual intptr_t GetHash() = 0; 509 | 510 | /** 511 | * Returns human-readable label. It must be a null-terminated UTF-8 512 | * encoded string. V8 copies its contents during a call to GetLabel. 513 | */ 514 | virtual const char* GetLabel() = 0; 515 | 516 | /** 517 | * Returns human-readable group label. It must be a null-terminated UTF-8 518 | * encoded string. V8 copies its contents during a call to GetGroupLabel. 519 | * Heap snapshot generator will collect all the group names, create 520 | * top level entries with these names and attach the objects to the 521 | * corresponding top level group objects. There is a default 522 | * implementation which is required because embedders don't have their 523 | * own implementation yet. 524 | */ 525 | virtual const char* GetGroupLabel() { return GetLabel(); } 526 | 527 | /** 528 | * Returns element count in case if a global handle retains 529 | * a subgraph by holding one of its nodes. 530 | */ 531 | virtual intptr_t GetElementCount() { return -1; } 532 | 533 | /** Returns embedder's object size in bytes. */ 534 | virtual intptr_t GetSizeInBytes() { return -1; } 535 | 536 | protected: 537 | RetainedObjectInfo() {} 538 | virtual ~RetainedObjectInfo() {} 539 | 540 | private: 541 | RetainedObjectInfo(const RetainedObjectInfo&); 542 | RetainedObjectInfo& operator=(const RetainedObjectInfo&); 543 | }; 544 | 545 | 546 | /** 547 | * A struct for exporting HeapStats data from V8, using "push" model. 548 | * See HeapProfiler::PushHeapObjectsStats. 549 | */ 550 | struct HeapStatsUpdate { 551 | HeapStatsUpdate(uint32_t index, uint32_t count, uint32_t size) 552 | : index(index), count(count), size(size) { } 553 | uint32_t index; // Index of the time interval that was changed. 554 | uint32_t count; // New value of count field for the interval with this index. 555 | uint32_t size; // New value of size field for the interval with this index. 556 | }; 557 | 558 | 559 | } // namespace v8 560 | 561 | 562 | #undef V8EXPORT 563 | 564 | 565 | #endif // V8_V8_PROFILER_H_ 566 | -------------------------------------------------------------------------------- /include/v8-testing.h: -------------------------------------------------------------------------------- 1 | // Copyright 2010 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | #ifndef V8_V8_TEST_H_ 29 | #define V8_V8_TEST_H_ 30 | 31 | #include "v8.h" 32 | 33 | #ifdef _WIN32 34 | // Setup for Windows DLL export/import. See v8.h in this directory for 35 | // information on how to build/use V8 as a DLL. 36 | #if defined(BUILDING_V8_SHARED) && defined(USING_V8_SHARED) 37 | #error both BUILDING_V8_SHARED and USING_V8_SHARED are set - please check the\ 38 | build configuration to ensure that at most one of these is set 39 | #endif 40 | 41 | #ifdef BUILDING_V8_SHARED 42 | #define V8EXPORT __declspec(dllexport) 43 | #elif USING_V8_SHARED 44 | #define V8EXPORT __declspec(dllimport) 45 | #else 46 | #define V8EXPORT 47 | #endif 48 | 49 | #else // _WIN32 50 | 51 | // Setup for Linux shared library export. See v8.h in this directory for 52 | // information on how to build/use V8 as shared library. 53 | #if defined(__GNUC__) && ((__GNUC__ >= 4) || \ 54 | (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && defined(V8_SHARED) 55 | #define V8EXPORT __attribute__ ((visibility("default"))) 56 | #else 57 | #define V8EXPORT 58 | #endif 59 | 60 | #endif // _WIN32 61 | 62 | 63 | /** 64 | * Testing support for the V8 JavaScript engine. 65 | */ 66 | namespace v8 { 67 | 68 | class V8EXPORT Testing { 69 | public: 70 | enum StressType { 71 | kStressTypeOpt, 72 | kStressTypeDeopt 73 | }; 74 | 75 | /** 76 | * Set the type of stressing to do. The default if not set is kStressTypeOpt. 77 | */ 78 | static void SetStressRunType(StressType type); 79 | 80 | /** 81 | * Get the number of runs of a given test that is required to get the full 82 | * stress coverage. 83 | */ 84 | static int GetStressRuns(); 85 | 86 | /** 87 | * Indicate the number of the run which is about to start. The value of run 88 | * should be between 0 and one less than the result from GetStressRuns() 89 | */ 90 | static void PrepareStressRun(int run); 91 | 92 | /** 93 | * Force deoptimization of all functions. 94 | */ 95 | static void DeoptimizeAll(); 96 | }; 97 | 98 | 99 | } // namespace v8 100 | 101 | 102 | #undef V8EXPORT 103 | 104 | 105 | #endif // V8_V8_TEST_H_ 106 | -------------------------------------------------------------------------------- /include/v8stdint.h: -------------------------------------------------------------------------------- 1 | // Copyright 2012 the V8 project authors. All rights reserved. 2 | // Redistribution and use in source and binary forms, with or without 3 | // modification, are permitted provided that the following conditions are 4 | // met: 5 | // 6 | // * Redistributions of source code must retain the above copyright 7 | // notice, this list of conditions and the following disclaimer. 8 | // * Redistributions in binary form must reproduce the above 9 | // copyright notice, this list of conditions and the following 10 | // disclaimer in the documentation and/or other materials provided 11 | // with the distribution. 12 | // * Neither the name of Google Inc. nor the names of its 13 | // contributors may be used to endorse or promote products derived 14 | // from this software without specific prior written permission. 15 | // 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | 28 | // Load definitions of standard types. 29 | 30 | #ifndef V8STDINT_H_ 31 | #define V8STDINT_H_ 32 | 33 | #include 34 | #include 35 | 36 | #if defined(_WIN32) && !defined(__MINGW32__) 37 | 38 | typedef signed char int8_t; 39 | typedef unsigned char uint8_t; 40 | typedef short int16_t; // NOLINT 41 | typedef unsigned short uint16_t; // NOLINT 42 | typedef int int32_t; 43 | typedef unsigned int uint32_t; 44 | typedef __int64 int64_t; 45 | typedef unsigned __int64 uint64_t; 46 | // intptr_t and friends are defined in crtdefs.h through stdio.h. 47 | 48 | #else 49 | 50 | #include 51 | 52 | #endif 53 | 54 | #endif // V8STDINT_H_ 55 | -------------------------------------------------------------------------------- /libv8.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joastbg/quant-js/3dff5f399bc1ce69e8035c9db54146265b063c3f/libv8.a -------------------------------------------------------------------------------- /main.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "core.h" 17 | 18 | #define QJS_VERSION "0.0.4" 19 | 20 | void banner() { 21 | std::cout << "quantjs v" << QJS_VERSION << std::endl; 22 | std::cout << "Copyright 2013-2014 Johan Astborg" << std::endl; 23 | } 24 | 25 | void usage() { 26 | std::cout << "usage: quantjs [--infiles filename(s)...] [--help]" << std::endl; 27 | } 28 | 29 | #include 30 | #include 31 | 32 | int main(int argc, char* argv[]) { 33 | 34 | /* 35 | using namespace boost::numeric::ublas; 36 | hermitian_matrix, lower> ml (3, 3); 37 | for (unsigned i = 0; i < ml.size1 (); ++ i) { 38 | for (unsigned j = 0; j < i; ++ j) 39 | ml (i, j) = std::complex (3 * i + j, 3 * i + j); 40 | ml (i, i) = std::complex (4 * i, 0); 41 | } 42 | std::cout << ml << std::endl; 43 | hermitian_matrix, upper> mu (3, 3); 44 | for (unsigned i = 0; i < mu.size1 (); ++ i) { 45 | mu (i, i) = std::complex (4 * i, 0); 46 | for (unsigned j = i + 1; j < mu.size2 (); ++ j) 47 | mu (i, j) = std::complex (3 * i + j, 3 * i + j); 48 | } 49 | std::cout << mu << std::endl; 50 | 51 | vector v (3); 52 | for (unsigned i = 0; i < v.size (); ++ i) 53 | v (i) = i; 54 | std::cout << v << std::endl; 55 | std::cout << v*10.0 << std::endl; 56 | 57 | matrix m (3, 3); 58 | for (unsigned i = 0; i < m.size1 (); ++ i) 59 | for (unsigned j = 0; j < m.size2 (); ++ j) 60 | m (i, j) = 3 * i + j; 61 | std::cout << m << std::endl; 62 | */ 63 | 64 | Options options; 65 | if (argc == 1) usage(); 66 | for (int i = 1; i < argc; ++i) { 67 | if (!strncmp(argv[i], "--infiles", 8)) options.infile = argv[++i]; 68 | if (!strncmp(argv[i], "--help", 6) || !strncmp(argv[i], "-h", 2)) usage(); 69 | if (!strncmp(argv[i], "--debug", 7) || !strncmp(argv[i], "-d", 2)) options.debug=true; 70 | } 71 | 72 | banner(); 73 | 74 | if(!options.validate()) { 75 | usage(); 76 | return 0; 77 | } 78 | 79 | Core Core(options); 80 | Core.run(); 81 | 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /numeric-1.2.6.min.js: -------------------------------------------------------------------------------- 1 | "use strict";var numeric=typeof exports=="undefined"?function(){}:exports;typeof global!="undefined"&&(global.numeric=numeric),numeric.version="1.2.6",numeric.bench=function(t,n){var r,i,s,o;typeof n=="undefined"&&(n=15),s=.5,r=new Date;for(;;){s*=2;for(o=s;o>3;o-=4)t(),t(),t(),t();while(o>0)t(),o--;i=new Date;if(i-r>n)break}for(o=s;o>3;o-=4)t(),t(),t(),t();while(o>0)t(),o--;return i=new Date,1e3*(3*s-1)/(i-r)},numeric._myIndexOf=function(t){var n=this.length,r;for(r=0;rnumeric.largeArray)return r.push("...Large Array..."),!0;var f=!1;r.push("[");for(t=0;t0&&(r.push(","),f&&r.push("\n ")),f=i(e[t]);return r.push("]"),!0}r.push("{");var f=!1;for(t in e)e.hasOwnProperty(t)&&(f&&r.push(",\n"),f=!0,r.push(t),r.push(": \n"),i(e[t]));return r.push("}"),!0}var r=[];return i(t),r.join("")},numeric.parseDate=function(t){function n(e){if(typeof e=="string")return Date.parse(e.replace(/-/g,"/"));if(e instanceof Array){var t=[],r;for(r=0;r0){s[f]=[];for(r=0;r>2,u=((r&3)<<4)+(i>>4),a=((i&15)<<2)+(s>>6),f=s&63,n+1>=t?a=f=64:n+2>=t&&(f=64),c+=l.charAt(o)+l.charAt(u)+l.charAt(a)+l.charAt(f);return c}function r(e,t,n){typeof t=="undefined"&&(t=0),typeof n=="undefined"&&(n=e.length);var r=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117],i=-1,s=0,o=e.length,u;for(u=t;u>>8^r[s];return i^-1}var i=t[0].length,s=t[0][0].length,o,u,a,f,l,c,h,p,d,v,m,g=[137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,s>>24&255,s>>16&255,s>>8&255,s&255,i>>24&255,i>>16&255,i>>8&255,i&255,8,2,0,0,0,-1,-2,-3,-4,-5,-6,-7,-8,73,68,65,84,8,29];m=r(g,12,29),g[29]=m>>24&255,g[30]=m>>16&255,g[31]=m>>8&255,g[32]=m&255,o=1,u=0;for(p=0;p>8&255,g.push(c),g.push(h),g.push(~c&255),g.push(~h&255),p===0&&g.push(0);for(d=0;d255?c=255:c<0?c=0:c=Math.round(c),o=(o+c)%65521,u=(u+o)%65521,g.push(c);g.push(0)}return v=(u<<16)+o,g.push(v>>24&255),g.push(v>>16&255),g.push(v>>8&255),g.push(v&255),l=g.length-41,g[33]=l>>24&255,g[34]=l>>16&255,g[35]=l>>8&255,g[36]=l&255,m=r(g,37),g.push(m>>24&255),g.push(m>>16&255),g.push(m>>8&255),g.push(m&255),g.push(0),g.push(0),g.push(0),g.push(0),g.push(73),g.push(69),g.push(78),g.push(68),g.push(174),g.push(66),g.push(96),g.push(130),"data:image/png;base64,"+n(g)},numeric._dim=function(t){var n=[];while(typeof t=="object")n.push(t.length),t=t[0];return n},numeric.dim=function(t){var n,r;if(typeof t=="object")return n=t[0],typeof n=="object"?(r=n[0],typeof r=="object"?numeric._dim(t):[t.length,n.length]):[t.length];return[]},numeric.mapreduce=function(t,n){return Function("x","accum","_s","_k",'if(typeof accum === "undefined") accum = '+n+";\n"+'if(typeof x === "number") { var xi = x; '+t+"; return accum; }\n"+'if(typeof _s === "undefined") _s = numeric.dim(x);\n'+'if(typeof _k === "undefined") _k = 0;\n'+"var _n = _s[_k];\n"+"var i,xi;\n"+"if(_k < _s.length-1) {\n"+" for(i=_n-1;i>=0;i--) {\n"+" accum = arguments.callee(x[i],accum,_s,_k+1);\n"+" }"+" return accum;\n"+"}\n"+"for(i=_n-1;i>=1;i-=2) { \n"+" xi = x[i];\n"+" "+t+";\n"+" xi = x[i-1];\n"+" "+t+";\n"+"}\n"+"if(i === 0) {\n"+" xi = x[i];\n"+" "+t+"\n"+"}\n"+"return accum;")},numeric.mapreduce2=function(t,n){return Function("x","var n = x.length;\nvar i,xi;\n"+n+";\n"+"for(i=n-1;i!==-1;--i) { \n"+" xi = x[i];\n"+" "+t+";\n"+"}\n"+"return accum;")},numeric.same=function same(e,t){var n,r;if(e instanceof Array&&t instanceof Array){r=e.length;if(r!==t.length)return!1;for(n=0;n=0;o-=2)s[o+1]=n,s[o]=n;return o===-1&&(s[0]=n),s}for(o=i-1;o>=0;o--)s[o]=numeric.rep(t,n,r+1);return s},numeric.dotMMsmall=function(t,n){var r,i,s,o,u,a,f,l,c,h,p,d,v,m;o=t.length,u=n.length,a=n[0].length,f=Array(o);for(r=o-1;r>=0;r--){l=Array(a),c=t[r];for(s=a-1;s>=0;s--){h=c[u-1]*n[u-1][s];for(i=u-2;i>=1;i-=2)p=i-1,h+=c[i]*n[i][s]+c[p]*n[p][s];i===0&&(h+=c[0]*n[0][s]),l[s]=h}f[r]=l}return f},numeric._getCol=function(t,n,r){var i=t.length,s;for(s=i-1;s>0;--s)r[s]=t[s][n],--s,r[s]=t[s][n];s===0&&(r[0]=t[0][n])},numeric.dotMMbig=function(t,n){var r=numeric._getCol,i=n.length,s=Array(i),o=t.length,u=n[0].length,a=new Array(o),f,l=numeric.dotVV,c,h,p,d;--i,--o;for(c=o;c!==-1;--c)a[c]=Array(u);--u;for(c=u;c!==-1;--c){r(n,c,s);for(h=o;h!==-1;--h)d=0,f=t[h],a[h][c]=l(f,s)}return a},numeric.dotMV=function(t,n){var r=t.length,i=n.length,s,o=Array(r),u=numeric.dotVV;for(s=r-1;s>=0;s--)o[s]=u(t[s],n);return o},numeric.dotVM=function(t,n){var r,i,s,o,u,a,f,l,c,h,p,d,v,m,g,y,b,w,E;o=t.length,u=n[0].length,f=Array(u);for(s=u-1;s>=0;s--){h=t[o-1]*n[o-1][s];for(i=o-2;i>=1;i-=2)p=i-1,h+=t[i]*n[i][s]+t[p]*n[p][s];i===0&&(h+=t[0]*n[0][s]),f[s]=h}return f},numeric.dotVV=function(t,n){var r,i=t.length,s,o=t[i-1]*n[i-1];for(r=i-2;r>=1;r-=2)s=r-1,o+=t[r]*n[r]+t[s]*n[s];return r===0&&(o+=t[0]*n[0]),o},numeric.dot=function(t,n){var r=numeric.dim;switch(r(t).length*1e3+r(n).length){case 2002:return n.length<10?numeric.dotMMsmall(t,n):numeric.dotMMbig(t,n);case 2001:return numeric.dotMV(t,n);case 1002:return numeric.dotVM(t,n);case 1001:return numeric.dotVV(t,n);case 1e3:return numeric.mulVS(t,n);case 1:return numeric.mulSV(t,n);case 0:return t*n;default:throw new Error("numeric.dot only works on vectors and matrices")}},numeric.diag=function(t){var n,r,i,s=t.length,o=Array(s),u;for(n=s-1;n>=0;n--){u=Array(s),r=n+2;for(i=s-1;i>=r;i-=2)u[i]=0,u[i-1]=0;i>n&&(u[i]=0),u[n]=t[n];for(i=n-1;i>=1;i-=2)u[i]=0,u[i-1]=0;i===0&&(u[0]=0),o[n]=u}return o},numeric.getDiag=function(e){var t=Math.min(e.length,e[0].length),n,r=Array(t);for(n=t-1;n>=1;--n)r[n]=e[n][n],--n,r[n]=e[n][n];return n===0&&(r[0]=e[0][0]),r},numeric.identity=function(t){return numeric.diag(numeric.rep([t],1))},numeric.pointwise=function(t,n,r){typeof r=="undefined"&&(r="");var i=[],s,o=/\[i\]$/,u,a="",f=!1;for(s=0;s=0;i--) ret[i] = arguments.callee("+t.join(",")+",_s,_k+1);\n"+" return ret;\n"+"}\n"+r+"\n"+"for(i=_n-1;i!==-1;--i) {\n"+" "+n+"\n"+"}\n"+"return ret;",Function.apply(null,i)},numeric.pointwise2=function(t,n,r){typeof r=="undefined"&&(r="");var i=[],s,o=/\[i\]$/,u,a="",f=!1;for(s=0;s=0;s--)_biforeach(typeof e=="object"?e[s]:e,typeof t=="object"?t[s]:t,n,r+1,i)},numeric._biforeach2=function _biforeach2(e,t,n,r,i){if(r===n.length-1)return i(e,t);var s,o=n[r],u=Array(o);for(s=o-1;s>=0;--s)u[s]=_biforeach2(typeof e=="object"?e[s]:e,typeof t=="object"?t[s]:t,n,r+1,i);return u},numeric._foreach=function _foreach(e,t,n,r){if(n===t.length-1){r(e);return}var i,s=t[n];for(i=s-1;i>=0;i--)_foreach(e[i],t,n+1,r)},numeric._foreach2=function _foreach2(e,t,n,r){if(n===t.length-1)return r(e);var i,s=t[n],o=Array(s);for(i=s-1;i>=0;i--)o[i]=_foreach2(e[i],t,n+1,r);return o},numeric.ops2={add:"+",sub:"-",mul:"*",div:"/",mod:"%",and:"&&",or:"||",eq:"===",neq:"!==",lt:"<",gt:">",leq:"<=",geq:">=",band:"&",bor:"|",bxor:"^",lshift:"<<",rshift:">>",rrshift:">>>"},numeric.opseq={addeq:"+=",subeq:"-=",muleq:"*=",diveq:"/=",modeq:"%=",lshifteq:"<<=",rshifteq:">>=",rrshifteq:">>>=",bandeq:"&=",boreq:"|=",bxoreq:"^="},numeric.mathfuns=["abs","acos","asin","atan","ceil","cos","exp","floor","log","round","sin","sqrt","tan","isNaN","isFinite"],numeric.mathfuns2=["atan2","pow","max","min"],numeric.ops1={neg:"-",not:"!",bnot:"~",clone:""},numeric.mapreducers={any:["if(xi) return true;","var accum = false;"],all:["if(!xi) return false;","var accum = true;"],sum:["accum += xi;","var accum = 0;"],prod:["accum *= xi;","var accum = 1;"],norm2Squared:["accum += xi*xi;","var accum = 0;"],norminf:["accum = max(accum,abs(xi));","var accum = 0, max = Math.max, abs = Math.abs;"],norm1:["accum += abs(xi)","var accum = 0, abs = Math.abs;"],sup:["accum = max(accum,xi);","var accum = -Infinity, max = Math.max;"],inf:["accum = min(accum,xi);","var accum = Infinity, min = Math.min;"]},function(){var e,t;for(e=0;em&&(v=h,m=d);a=o[v],o[v]=o[p],o[p]=a,c=f[v],f[v]=f[p],f[p]=c,t=a[p];for(d=p;d!==s;++d)a[d]/=t;for(d=s-1;d!==-1;--d)c[d]/=t;for(h=i-1;h!==-1;--h)if(h!==p){u=o[h],l=f[h],t=u[p];for(d=p+1;d!==s;++d)u[d]-=a[d]*t;for(d=s-1;d>0;--d)l[d]-=c[d]*t,--d,l[d]-=c[d]*t;d===0&&(l[0]-=c[0]*t)}}return f},numeric.det=function(t){var n=numeric.dim(t);if(n.length!==2||n[0]!==n[1])throw new Error("numeric: det() only works on square matrices");var r=n[0],i=1,s,o,u,a=numeric.clone(t),f,l,c,h,p,d,v;for(o=0;oMath.abs(a[u][o])&&(u=s);u!==o&&(h=a[u],a[u]=a[o],a[o]=h,i*=-1),f=a[o];for(s=o+1;s=1;n-=2){a=t[n],u=t[n-1];for(r=s-1;r>=1;--r)f=o[r],f[n]=a[r],f[n-1]=u[r],--r,f=o[r],f[n]=a[r],f[n-1]=u[r];r===0&&(f=o[0],f[n]=a[0],f[n-1]=u[0])}if(n===0){u=t[0];for(r=s-1;r>=1;--r)o[r][0]=u[r],--r,o[r][0]=u[r];r===0&&(o[0][0]=u[0])}return o},numeric.negtranspose=function(t){var n,r,i=t.length,s=t[0].length,o=Array(s),u,a,f;for(r=0;r=1;n-=2){a=t[n],u=t[n-1];for(r=s-1;r>=1;--r)f=o[r],f[n]=-a[r],f[n-1]=-u[r],--r,f=o[r],f[n]=-a[r],f[n-1]=-u[r];r===0&&(f=o[0],f[n]=-a[0],f[n-1]=-u[0])}if(n===0){u=t[0];for(r=s-1;r>=1;--r)o[r][0]=-u[r],--r,o[r][0]=-u[r];r===0&&(o[0][0]=-u[0])}return o},numeric._random=function _random(e,t){var n,r=e[t],i=Array(r),s;if(t===e.length-1){s=Math.random;for(n=r-1;n>=1;n-=2)i[n]=s(),i[n-1]=s();return n===0&&(i[0]=s()),i}for(n=r-1;n>=0;n--)i[n]=_random(e,t+1);return i},numeric.random=function(t){return numeric._random(t,0)},numeric.norm2=function(t){return Math.sqrt(numeric.norm2Squared(t))},numeric.linspace=function(t,n,r){typeof r=="undefined"&&(r=Math.max(Math.round(n-t)+1,1));if(r<2)return r===1?[t]:[];var i,s=Array(r);r--;for(i=r;i>=0;i--)s[i]=(i*n+(r-i)*t)/r;return s},numeric.getBlock=function(t,n,r){function s(e,t){var o,u=n[t],a=r[t]-u,f=Array(a);if(t===i.length-1){for(o=a;o>=0;o--)f[o]=e[o+u];return f}for(o=a;o>=0;o--)f[o]=s(e[o+u],t+1);return f}var i=numeric.dim(t);return s(t,0)},numeric.setBlock=function(t,n,r,i){function o(e,t,i){var u,a=n[i],f=r[i]-a;if(i===s.length-1)for(u=f;u>=0;u--)e[u+a]=t[u];for(u=f;u>=0;u--)o(e[u+a],t[u],i+1)}var s=numeric.dim(t);return o(t,i,0),t},numeric.getRange=function(t,n,r){var i=n.length,s=r.length,o,u,a=Array(i),f,l;for(o=i-1;o!==-1;--o){a[o]=Array(s),f=a[o],l=t[n[o]];for(u=s-1;u!==-1;--u)f[u]=l[r[u]]}return a},numeric.blockMatrix=function(t){var n=numeric.dim(t);if(n.length<4)return numeric.blockMatrix([t]);var r=n[0],i=n[1],s,o,u,a,f;s=0,o=0;for(u=0;u=0;f--){a=Array(o),c=t[f];for(l=o-1;l>=3;--l)a[l]=c*n[l],--l,a[l]=c*n[l],--l,a[l]=c*n[l],--l,a[l]=c*n[l];while(l>=0)a[l]=c*n[l],--l;u[f]=a}return u},numeric.T=function(t,n){this.x=t,this.y=n},numeric.t=function(t,n){return new numeric.T(t,n)},numeric.Tbinop=function(t,n,r,i,s){var o=numeric.indexOf;if(typeof s!="string"){var u;s="";for(u in numeric)numeric.hasOwnProperty(u)&&(t.indexOf(u)>=0||n.indexOf(u)>=0||r.indexOf(u)>=0||i.indexOf(u)>=0)&&u.length>1&&(s+="var "+u+" = numeric."+u+";\n")}return Function(["y"],"var x = this;\nif(!(y instanceof numeric.T)) { y = new numeric.T(y); }\n"+s+"\n"+"if(x.y) {"+" if(y.y) {"+" return new numeric.T("+i+");\n"+" }\n"+" return new numeric.T("+r+");\n"+"}\n"+"if(y.y) {\n"+" return new numeric.T("+n+");\n"+"}\n"+"return new numeric.T("+t+");\n")},numeric.T.prototype.add=numeric.Tbinop("add(x.x,y.x)","add(x.x,y.x),y.y","add(x.x,y.x),x.y","add(x.x,y.x),add(x.y,y.y)"),numeric.T.prototype.sub=numeric.Tbinop("sub(x.x,y.x)","sub(x.x,y.x),neg(y.y)","sub(x.x,y.x),x.y","sub(x.x,y.x),sub(x.y,y.y)"),numeric.T.prototype.mul=numeric.Tbinop("mul(x.x,y.x)","mul(x.x,y.x),mul(x.x,y.y)","mul(x.x,y.x),mul(x.y,y.x)","sub(mul(x.x,y.x),mul(x.y,y.y)),add(mul(x.x,y.y),mul(x.y,y.x))"),numeric.T.prototype.reciprocal=function(){var t=numeric.mul,n=numeric.div;if(this.y){var r=numeric.add(t(this.x,this.x),t(this.y,this.y));return new numeric.T(n(this.x,r),n(numeric.neg(this.y),r))}return new T(n(1,this.x))},numeric.T.prototype.div=function div(e){e instanceof numeric.T||(e=new numeric.T(e));if(e.y)return this.mul(e.reciprocal());var div=numeric.div;return this.y?new numeric.T(div(this.x,e.x),div(this.y,e.x)):new numeric.T(div(this.x,e.x))},numeric.T.prototype.dot=numeric.Tbinop("dot(x.x,y.x)","dot(x.x,y.x),dot(x.x,y.y)","dot(x.x,y.x),dot(x.y,y.x)","sub(dot(x.x,y.x),dot(x.y,y.y)),add(dot(x.x,y.y),dot(x.y,y.x))"),numeric.T.prototype.transpose=function(){var t=numeric.transpose,n=this.x,r=this.y;return r?new numeric.T(t(n),t(r)):new numeric.T(t(n))},numeric.T.prototype.transjugate=function(){var t=numeric.transpose,n=this.x,r=this.y;return r?new numeric.T(t(n),numeric.negtranspose(r)):new numeric.T(t(n))},numeric.Tunop=function(t,n,r){return typeof r!="string"&&(r=""),Function("var x = this;\n"+r+"\n"+"if(x.y) {"+" "+n+";\n"+"}\n"+t+";\n")},numeric.T.prototype.exp=numeric.Tunop("return new numeric.T(ex)","return new numeric.T(mul(cos(x.y),ex),mul(sin(x.y),ex))","var ex = numeric.exp(x.x), cos = numeric.cos, sin = numeric.sin, mul = numeric.mul;"),numeric.T.prototype.conj=numeric.Tunop("return new numeric.T(x.x);","return new numeric.T(x.x,numeric.neg(x.y));"),numeric.T.prototype.neg=numeric.Tunop("return new numeric.T(neg(x.x));","return new numeric.T(neg(x.x),neg(x.y));","var neg = numeric.neg;"),numeric.T.prototype.sin=numeric.Tunop("return new numeric.T(numeric.sin(x.x))","return x.exp().sub(x.neg().exp()).div(new numeric.T(0,2));"),numeric.T.prototype.cos=numeric.Tunop("return new numeric.T(numeric.cos(x.x))","return x.exp().add(x.neg().exp()).div(2);"),numeric.T.prototype.abs=numeric.Tunop("return new numeric.T(numeric.abs(x.x));","return new numeric.T(numeric.sqrt(numeric.add(mul(x.x,x.x),mul(x.y,x.y))));","var mul = numeric.mul;"),numeric.T.prototype.log=numeric.Tunop("return new numeric.T(numeric.log(x.x));","var theta = new numeric.T(numeric.atan2(x.y,x.x)), r = x.abs();\nreturn new numeric.T(numeric.log(r.x),theta.x);"),numeric.T.prototype.norm2=numeric.Tunop("return numeric.norm2(x.x);","var f = numeric.norm2Squared;\nreturn Math.sqrt(f(x.x)+f(x.y));"),numeric.T.prototype.inv=function(){var t=this;if(typeof t.y=="undefined")return new numeric.T(numeric.inv(t.x));var n=t.x.length,r,i,s,o=numeric.identity(n),u=numeric.rep([n,n],0),a=numeric.clone(t.x),f=numeric.clone(t.y),l,c,h,p,d,v,m,g,r,i,s,y,b,w,E,S,x,T;for(r=0;ry&&(s=i,y=b);s!==r&&(T=a[r],a[r]=a[s],a[s]=T,T=f[r],f[r]=f[s],f[s]=T,T=o[r],o[r]=o[s],o[s]=T,T=u[r],u[r]=u[s],u[s]=T),l=a[r],c=f[r],d=o[r],v=u[r],w=l[r],E=c[r];for(i=r+1;i0;r--){d=o[r],v=u[r];for(i=r-1;i>=0;i--){m=o[i],g=u[i],w=a[i][r],E=f[i][r];for(s=n-1;s>=0;s--)S=d[s],x=v[s],m[s]-=w*S-E*x,g[s]-=w*x+E*S}}return new numeric.T(o,u)},numeric.T.prototype.get=function(t){var n=this.x,r=this.y,i=0,s,o=t.length;if(r){while(i=0?1:-1,i=r*numeric.norm2(t);n[0]+=i;var s=numeric.norm2(n);if(s===0)throw new Error("eig: internal error");return numeric.div(n,s)},numeric.toUpperHessenberg=function(t){var n=numeric.dim(t);if(n.length!==2||n[0]!==n[1])throw new Error("numeric: toUpperHessenberg() only works on square matrices");var r=n[0],i,s,o,u,a,f=numeric.clone(t),l,c,h,p,d=numeric.identity(r),v;for(s=0;s0){a=numeric.house(u),l=numeric.getBlock(f,[s+1,s],[r-1,r-1]),c=numeric.tensor(a,numeric.dot(a,l));for(i=s+1;i=4*c){var k,L;k=.5*(h+Math.sqrt(h*h-4*c)),L=.5*(h-Math.sqrt(h*h-4*c)),p=numeric.add(numeric.sub(numeric.dot(p,p),numeric.mul(p,k+L)),numeric.diag(numeric.rep([3],k*L)))}else p=numeric.add(numeric.sub(numeric.dot(p,p),numeric.mul(p,h)),numeric.diag(numeric.rep([3],c)));s=[p[0][0],p[1][0],p[2][0]],o=numeric.house(s),g=[e[0],e[1],e[2]],y=numeric.tensor(o,numeric.dot(o,g));for(w=0;w<3;w++){m=e[w],b=y[w];for(S=0;S=0?(w<0?x=-0.5*(w-A(S)):x=-0.5*(w+A(S)),k=(m-x)*(m-x)+g*g,L=y*y+(b-x)*(b-x),k>L?(k=A(k),N=(m-x)/k,C=g/k):(L=A(L),N=y/L,C=(b-x)/L),p=new s([[C,-N],[N,C]]),h.setRows(u,v,p.dot(h.getRows(u,v)))):(x=-0.5*w,T=.5*A(-S),k=(m-x)*(m-x)+g*g,L=y*y+(b-x)*(b-x),k>L?(k=A(k+T*T),N=(m-x)/k,C=g/k,x=0,T/=k):(L=A(L+T*T),N=y/L,C=(b-x)/L,x=T/L,T=0),p=new s([[C,-N],[N,C]],[[x, 2 | T],[T,-x]]),h.setRows(u,v,p.dot(h.getRows(u,v))))}}var O=h.dot(t).dot(h.transjugate()),o=t.length,M=numeric.T.identity(o);for(v=0;v0)for(a=v-1;a>=0;a--){var _=O.get([a,a]),D=O.get([v,v]);if(!numeric.neq(_.x,D.x)&&!numeric.neq(_.y,D.y)){M.setRow(v,M.getRow(a));continue}x=O.getRow(a).getBlock([a],[v-1]),T=M.getRow(v).getBlock([a],[v-1]),M.set([v,a],O.get([a,v]).neg().sub(x.dot(T)).div(_.sub(D)))}for(v=0;v=u.length)u[u.length]=0;i[o]!==0&&u[o]++}}var r=u.length,a=Array(r+1);a[0]=0;for(s=0;s=d){s[f]=h[u];if(u===0)return;++f,--u,p=l[u],d=c[u]}else a=o[r[p]],i[a]===0?(i[a]=1,l[u]=p,++u,h[u]=a,p=n[a],c[u]=d=n[a+1]):++p},numeric.ccsLPSolve=function(t,n,r,i,s,o,u){var a=t[0],f=t[1],l=t[2],c=a.length-1,h=0,p=n[0],d=n[1],v=n[2],m,g,y,b,w,E,S,x,T,N,C,k;g=p[s],y=p[s+1],i.length=0;for(m=g;mb&&(w=m,b=E)}C(h[d])=v){s[l]=o[p[a]];if(a===0)return;++l,--a,d=c[a],v=h[a]}else f=r[d],i[f]===0?(i[f]=1,c[a]=d,++a,p[a]=f,f=o[f],d=n[f],h[a]=v=n[f+1]):++d}},numeric.ccsLPSolve0=function(t,n,r,i,s,o,u,a){var f=t[0],l=t[1],c=t[2],h=f.length-1,p=0,d=n[0],v=n[1],m=n[2],g,y,b,w,E,S,x,T,N,C,k,L;y=d[s],b=d[s+1],i.length=0;for(g=y;gb&&(w=m,b=E)}C(h[k[d]])t[n]&&(t[n]=e.length);var r;for(r in e)e.hasOwnProperty(r)&&dim(e[r],t,n+1);return t},numeric.sclone=function clone(e,t,n){typeof t=="undefined"&&(t=0),typeof n=="undefined"&&(n=numeric.sdim(e).length);var r,i=Array(e.length);if(t===n-1){for(r in e)e.hasOwnProperty(r)&&(i[r]=e[r]);return i}for(r in e)e.hasOwnProperty(r)&&(i[r]=clone(e[r],t+1,n));return i},numeric.sdiag=function(t){var n=t.length,r,i=Array(n),s,o,u;for(r=n-1;r>=1;r-=2)s=r-1,i[r]=[],i[r][r]=t[r],i[s]=[],i[s][s]=t[s];return r===0&&(i[0]=[],i[0][0]=t[r]),i},numeric.sidentity=function(t){return numeric.sdiag(numeric.rep([t],1))},numeric.stranspose=function(t){var n=[],r=t.length,i,s,o;for(i in t){if(!t.hasOwnProperty(i))continue;o=t[i];for(s in o){if(!o.hasOwnProperty(s))continue;typeof n[s]!="object"&&(n[s]=[]),n[s][i]=o[s]}}return n},numeric.sLUP=function(t,n){throw new Error("The function numeric.sLUP had a bug in it and has been removed. Please use the new numeric.ccsLUP function instead.")},numeric.sdotMM=function(t,n){var r=t.length,i=n.length,s=numeric.stranspose(n),o=s.length,u,a,f,l,c,h,p=Array(r),d;for(f=r-1;f>=0;f--){d=[],u=t[f];for(c=o-1;c>=0;c--){h=0,a=s[c];for(l in u){if(!u.hasOwnProperty(l))continue;l in a&&(h+=u[l]*a[l])}h&&(d[c]=h)}p[f]=d}return p},numeric.sdotMV=function(t,n){var r=t.length,i,s,o,u=Array(r),a;for(s=r-1;s>=0;s--){i=t[s],a=0;for(o in i){if(!i.hasOwnProperty(o))continue;n[o]&&(a+=i[o]*n[o])}a&&(u[s]=a)}return u},numeric.sdotVM=function(t,n){var r,i,s,o,u=[],a;for(r in t){if(!t.hasOwnProperty(r))continue;s=n[r],o=t[r];for(i in s){if(!s.hasOwnProperty(i))continue;u[i]||(u[i]=0),u[i]+=o*s[i]}}return u},numeric.sdotVV=function(t,n){var r,i=0;for(r in t)t[r]&&n[r]&&(i+=t[r]*n[r]);return i},numeric.sdot=function(t,n){var r=numeric.sdim(t).length,i=numeric.sdim(n).length,s=r*1e3+i;switch(s){case 0:return t*n;case 1001:return numeric.sdotVV(t,n);case 2001:return numeric.sdotMV(t,n);case 1002:return numeric.sdotVM(t,n);case 2002:return numeric.sdotMM(t,n);default:throw new Error("numeric.sdot not implemented for tensors of order "+r+" and "+i)}},numeric.sscatter=function(t){var n=t[0].length,r,i,s,o=t.length,u=[],a;for(i=n-1;i>=0;--i){if(!t[o-1][i])continue;a=u;for(s=0;s=0;--i)t[i]=[];for(i=r;i>=0;--i)t[i].push(n[i]);t[r+1].push(s)}}else gather(s,t,n)}return n.length>r&&n.pop(),t},numeric.cLU=function(t){var n=t[0],r=t[1],i=t[2],s=n.length,o=0,u,a,f,l,c,h;for(u=0;uo&&(o=n[u]);o++;var p=Array(o),d=Array(o),v=numeric.rep([o],Infinity),m=numeric.rep([o],-Infinity),g,y,b;for(f=0;fm[u]&&(m[u]=a);for(u=0;um[u+1]&&(m[u+1]=m[u]);for(u=o-1;u>=1;u--)v[u]=0;v--){while(l[g]>v)s[v]-=c[g]*s[l[g]],g--;s[v]/=c[g],g--}return s},numeric.cgrid=function(t,n){typeof t=="number"&&(t=[t,t]);var r=numeric.rep(t,-1),i,s,o;if(typeof n!="function")switch(n){case"L":n=function(e,n){return e>=t[0]/2||nf&&(f=i[u]);f++,r=numeric.rep([f],0);for(u=0;u1)o=u((i+s)/2),n[o]<=t?i=o:s=o;return this._at(t,i)}var r=t.length,c,h=Array(r);for(c=r-1;c!==-1;--c)h[c]=this.at(t[c]);return h},numeric.Spline.prototype.diff=function(){var t=this.x,n=this.yl,r=this.yr,i=this.kl,s=this.kr,o=n.length,u,a,f,l=i,c=s,h=Array(o),p=Array(o),d=numeric.add,v=numeric.mul,m=numeric.div,g=numeric.sub;for(u=o-1;u!==-1;--u)a=t[u+1]-t[u],f=g(r[u+1],n[u]),h[u]=m(d(v(f,6),v(i[u],-4*a),v(s[u+1],-2*a)),a*a),p[u+1]=m(d(v(f,-6),v(i[u],2*a),v(s[u+1],4*a)),a*a);return new numeric.Spline(t,l,c,h,p)},numeric.Spline.prototype.roots=function(){function t(e){return e*e}function n(e,t,n,r,i){var s=n*2-(t-e),o=-r*2+(t-e),u=(i+1)*.5,a=u*(1-u);return(1-u)*e+u*t+s*a*(1-u)+o*a*u}var r=[],i=this.x,s=this.yl,o=this.yr,u=this.kl,a=this.kr;typeof s[0]=="number"&&(s=[s],o=[o],u=[u],a=[a]);var f=s.length,l=i.length-1,c,h,p,d,v,m,g,y,b,w,r=Array(f),E,S,x,T,N,C,k,L,A,O,M,_,D,P,H,B,j,F=Math.sqrt;for(c=0;c!==f;++c){g=s[c],y=o[c],b=u[c],w=a[c],E=[];for(h=0;h!==l;h++){h>0&&y[h]*g[h]<0&&E.push(i[h]),A=i[h+1]-i[h],O=i[h],T=g[h],N=y[h+1],S=b[h]/A,x=w[h+1]/A,L=t(S-x+3*(T-N))+12*x*T,C=x+3*T+2*S-3*N,k=3*(x+S+2*(T-N)),L<=0?(_=C/k,_>i[h]&&_i[h]&&_i[h]&&D0){H=B,_=D;continue}var I=0;for(;;){j=(_*B-D*H)/(_-D);if(j<=H||j>=B)break;P=this._at(j,h);if(P*D>0)B=j,D=P,I===-1&&(_*=.5),I=-1;else{if(!(P*_>0))break;H=j,_=P,I===1&&(D*=.5),I=1}}E.push(j),H=M[p+1],_=this._at(H,h)}D===0&&E.push(B)}r[c]=E}return typeof this.yl[0]=="number"?r[0]:r},numeric.spline=function(t,n,r,i){var s=t.length,o=[],u=[],a=[],f,l=numeric.sub,c=numeric.mul,h=numeric.add;for(f=s-2;f>=0;f--)u[f]=t[f+1]-t[f],a[f]=l(n[f+1],n[f]);if(typeof r=="string"||typeof i=="string")r=i="periodic";var p=[[],[],[]];switch(typeof r){case"undefined":o[0]=c(3/(u[0]*u[0]),a[0]),p[0].push(0,0),p[1].push(0,1),p[2].push(2/u[0],1/u[0]);break;case"string":o[0]=h(c(3/(u[s-2]*u[s-2]),a[s-2]),c(3/(u[0]*u[0]),a[0])),p[0].push(0,0,0),p[1].push(s-2,0,1),p[2].push(1/u[s-2],2/u[s-2]+2/u[0],1/u[0]);break;default:o[0]=r,p[0].push(0),p[1].push(0),p[2].push(1)}for(f=1;f20)throw new Error("Numerical gradient fails");u[o]=n[o]+N,a=t(u),u[o]=n[o]-N,f=t(u),u[o]=n[o];if(isNaN(a)||isNaN(f)){N/=16;continue}l[o]=(a-f)/(2*N),y=n[o]-N,b=n[o],w=n[o]+N,S=(a-i)/N,x=(i-f)/N,T=s(m(l[o]),m(i),m(a),m(f),m(y),m(b),m(w),1e-8),p=g(s(m(S-l[o]),m(x-l[o]),m(S-x))/T,N/T);if(!(p>v))break;N/=16}}return l},numeric.uncmin=function(t,n,r,i,s,o,u){var a=numeric.gradient;typeof u=="undefined"&&(u={}),typeof r=="undefined"&&(r=1e-8),typeof i=="undefined"&&(i=function(e){return a(t,e)}),typeof s=="undefined"&&(s=1e3),n=numeric.clone(n);var f=n.length,l=t(n),c,h;if(isNaN(l))throw new Error("uncmin: f(x0) is a NaN!");var p=Math.max,d=numeric.norm2;r=p(r,numeric.epsilon);var v,m,g,y=u.Hinv||numeric.identity(f),b=numeric.dot,w=numeric.inv,E=numeric.sub,S=numeric.add,x=numeric.tensor,T=numeric.div,N=numeric.mul,C=numeric.all,k=numeric.isFinite,L=numeric.neg,A=0,O,M,_,D,P,H,B,j,F,I,q,R,U="";m=i(n);while(A=.1*F*h||isNaN(c)){F*=.5,++A;continue}break}if(F*I1)i=s(.5*(n+r)),a[i]<=t?n=i:r=i;return this._at(t,n)},numeric.dopri=function(t,n,r,i,s,o,u){typeof s=="undefined"&&(s=1e-6),typeof o=="undefined"&&(o=1e3);var a=[t],f=[r],l=[i(t,r)],c,h,p,d,v,m,g=[],y=.2,b=[.075,.225],w=[44/45,-56/15,32/9],E=[19372/6561,-25360/2187,64448/6561,-212/729],S=[9017/3168,-355/33,46732/5247,49/176,-5103/18656],x=[35/384,0,500/1113,125/192,-2187/6784,11/84],T=[.10013431883002395,0,.3918321794184259,-0.02982460176594817,.05893268337240795,-0.04497888809104361,.023904308236133973],N=[.2,.3,.8,8/9,1,1],C=[-71/57600,0,71/16695,-71/1920,17253/339200,-22/525,.025],k=0,L,A,O=(n-t)/10,M=0,_=numeric.add,D=numeric.mul,P,H,B=Math.max,j=Math.min,F=Math.abs,I=numeric.norminf,q=Math.pow,R=numeric.any,U=numeric.lt,z=numeric.and,W=numeric.sub,X,V,$,J=new numeric.Dopri(a,f,l,g,-1,"");typeof u=="function"&&(X=u(t,r));while(tn&&(O=n-t),c=i(t+N[0]*O,_(r,D(y*O,l[k]))),h=i(t+N[1]*O,_(_(r,D(b[0]*O,l[k])),D(b[1]*O,c))),p=i(t+N[2]*O,_(_(_(r,D(w[0]*O,l[k])),D(w[1]*O,c)),D(w[2]*O,h))),d=i(t+N[3]*O,_(_(_(_(r,D(E[0]*O,l[k])),D(E[1]*O,c)),D(E[2]*O,h)),D(E[3]*O,p))),v=i(t+N[4]*O,_(_(_(_(_(r,D(S[0]*O,l[k])),D(S[1]*O,c)),D(S[2]*O,h)),D(S[3]*O,p)),D(S[4]*O,d))),P=_(_(_(_(_(r,D(l[k],O*x[0])),D(h,O*x[2])),D(p,O*x[3])),D(d,O*x[4])),D(v,O*x[5])),m=i(t+O,P),L=_(_(_(_(_(D(l[k],O*C[0]),D(h,O*C[2])),D(p,O*C[3])),D(d,O*C[4])),D(v,O*C[5])),D(m,O*C[6])),typeof L=="number"?H=F(L):H=I(L);if(H>s){O=.2*O*q(s/H,.25);if(t+O===t){J.msg="Step size became too small";break}continue}g[k]=_(_(_(_(_(_(r,D(l[k],O*T[0])),D(h,O*T[2])),D(p,O*T[3])),D(d,O*T[4])),D(v,O*T[5])),D(m,O*T[6])),++k,a[k]=t+O,f[k]=P,l[k]=m;if(typeof u=="function"){var K,Q=t,G=t+.5*O,Y;V=u(G,g[k-1]),$=z(U(X,0),U(0,V)),R($)||(Q=G,G=t+O,X=V,V=u(G,P),$=z(U(X,0),U(0,V)));if(R($)){var Z,et,tt,nt,rt=0,it=1,st=1;for(;;){if(typeof X=="number")Y=(st*V*Q-it*X*G)/(st*V-it*X);else{Y=G;for(A=X.length-1;A!==-1;--A)X[A]<0&&V[A]>0&&(Y=j(Y,(st*V[A]*Q-it*X[A]*G)/(st*V[A]-it*X[A])))}if(Y<=Q||Y>=G)break;K=J._at(Y,k-1),nt=u(Y,K),tt=z(U(X,0),U(0,nt)),R(tt)?(G=Y,V=nt,$=tt,st=1,rt===-1?it*=.5:it=1,rt=-1):(Q=Y,X=nt,it=1,rt===1?st*=.5:st=1,rt=1)}return P=J._at(.5*(t+Y),k-1),J.f[k]=i(Y,K),J.x[k]=Y,J.y[k]=K,J.ymid[k-1]=P,J.events=$,J.iterations=M,J}}t+=O,r=P,X=V,O=j(.8*O*q(s/H,.25),4*O)}return J.iterations=M,J},numeric.LU=function(e,t){t=t||!1;var n=Math.abs,r,i,s,o,u,a,f,l,c,h=e.length,p=h-1,d=new Array(h);t||(e=numeric.clone(e));for(s=0;s=0;--r){l=s[r];for(i=r+1;iK)E=K;W=d(t,l(E,B)),I=h(J,j);for(X=v-1;X!==-1;--X)I[X][X]+=1;$=q(I,p(W,E),!0);var Q=p(R,h(n,$)),G=1;for(X=m-1;X!==-1;--X)Q[X]<0&&(G=D(G,-0.999*Q[X]));g=c(o,l($,G)),R=c(r,h(n,g));if(!P(H(R,0)))return{solution:o,message:"",iterations:U};o=g;if(E=0?y=!1:y=!0;if(y)return{solution:g,message:"Unbounded",iterations:U}}return{solution:o,message:"maximum iteration count exceeded",iterations:U}},numeric._solveLP=function(t,n,r,i,s){var o=t.length,u=r.length,a,f=numeric.sum,l=numeric.log,c=numeric.mul,h=numeric.sub,p=numeric.dot,d=numeric.div,v=numeric.add,m=numeric.rep([o],0).concat([1]),g=numeric.rep([u,1],-1),y=numeric.blockMatrix([[n,g]]),b=r,a=numeric.rep([o],0).concat(Math.max(0,numeric.sup(numeric.neg(r)))+1),w=numeric.__solveLP(m,y,b,i,s,a,!1),E=numeric.clone(w.solution);E.length=o;var S=numeric.inf(h(r,p(n,E)));if(S<0)return{solution:NaN,message:"Infeasible",iterations:w.iterations};var x=numeric.__solveLP(t,n,r,i,s-w.iterations,E,!0);return x.iterations+=w.iterations,x},numeric.solveLP=function(t,n,r,i,s,o,u){typeof u=="undefined"&&(u=1e3),typeof o=="undefined"&&(o=numeric.epsilon);if(typeof i=="undefined")return numeric._solveLP(t,n,r,o,u);var a=i.length,f=i[0].length,l=n.length,c=numeric.echelonize(i),h=numeric.rep([f],0),p=c.P,d=[],v;for(v=p.length-1;v!==-1;--v)h[p[v]]=1;for(v=f-1;v!==-1;--v)h[v]===0&&d.push(v);var m=numeric.getRange,g=numeric.linspace(0,a-1),y=numeric.linspace(0,l-1),b=m(i,g,d),w=m(n,y,p),E=m(n,y,d),S=numeric.dot,x=numeric.sub,T=S(w,c.I),N=x(E,S(T,b)),C=x(r,S(T,s)),k=Array(p.length),L=Array(d.length);for(v=p.length-1;v!==-1;--v)k[v]=t[p[v]];for(v=d.length-1;v!==-1;--v)L[v]=t[d[v]];var A=x(L,S(k,S(c.I,b))),O=numeric._solveLP(A,N,C,o,u),M=O.solution;if(M!==M)return O;var _=S(c.I,x(s,S(b,M))),D=Array(t.length);for(v=p.length-1;v!==-1;--v)D[p[v]]=_[v];for(v=d.length-1;v!==-1;--v)D[d[v]]=M[v];return{solution:D,message:O.message,iterations:O.iterations}},numeric.MPStoLP=function(t){function y(e){throw new Error("MPStoLP: "+e+"\nLine "+s+": "+t[s]+"\nCurrent state: "+r[n]+"\n")}t instanceof String&&t.split("\n");var n=0,r=["Initial state","NAME","ROWS","COLUMNS","RHS","BOUNDS","ENDATA"],i=t.length,s,o,u,a=0,f={},l=[],c=0,h={},p=0,d,v=[],m=[],g=[];for(s=0;s=s)t/=2,u/=2,a>>>=1;return(t+a)/u},c},o=t.pow(n,r),i=t.pow(2,i),s=i*2,f(t.random(),e)}([],numeric.seedrandom,256,6,52),function(e){function t(e){if(typeof e!="object")return e;var n=[],r,i=e.length;for(r=0;rp)g[E]=P;else{g[E]=-Math.abs(P);if(P>0){for(w=1;w<=o;w+=1)f[w][b]=-f[w][b];l[b]=-l[b]}}}for(b=1;b<=v;b+=1)g[L+d[b]]=0;O=0,D=0;for(b=1;b<=h;b+=1)g[L+b]=1;b-=1){P=g[b],E=k+b*(b+3)/2,S=E-b;for(w=b+1;w<=v;w+=1)P-=g[E]*g[C+w],E+=w;P/=g[S],g[C+b]=P;if(d[b]p)g[L+O]=P;else{g[L+O]=-Math.abs(P);if(P>0){for(w=1;w<=o;w+=1)f[w][O]=-f[w][O];l[O]=-l[O]}}return 700}v+=1,d[v]=O,E=k+(v-1)*v/2+1;for(b=1;b<=v-1;b+=1)g[E]=g[b],E+=1;if(v===o)g[E]=g[o];else{for(b=o;b>=v+1;b-=1){if(g[b]===0)break;j=Math.max(Math.abs(g[b-1]),Math.abs(g[b])),F=Math.min(Math.abs(g[b-1]),Math.abs(g[b])),g[b-1]>=0?D=Math.abs(j*Math.sqrt(1+F*F/(j*j))):D=-Math.abs(j*Math.sqrt(1+F*F/(j*j))),j=g[b-1]/D,F=g[b]/D;if(j===1)break;if(j===0){g[b-1]=F*D;for(w=1;w<=o;w+=1)D=e[w][b-1],e[w][b-1]=e[w][b],e[w][b]=D}else{g[b-1]=D,I=F/(1+j);for(w=1;w<=o;w+=1)D=j*e[w][b-1]+F*e[w][b],e[w][b]=I*(e[w][b-1]+D)-e[w][b],e[w][b-1]=D}}g[E]=g[v]}return 0}function J(){E=k+T*(T+1)/2+1,S=E+T;if(g[S]===0)return 798;j=Math.max(Math.abs(g[S-1]),Math.abs(g[S])),F=Math.min(Math.abs(g[S-1]),Math.abs(g[S])),g[S-1]>=0?D=Math.abs(j*Math.sqrt(1+F*F/(j*j))):D=-Math.abs(j*Math.sqrt(1+F*F/(j*j))),j=g[S-1]/D,F=g[S]/D;if(j===1)return 798;if(j===0){for(b=T+1;b<=v;b+=1)D=g[S-1],g[S-1]=g[S],g[S]=D,S+=b;for(b=1;b<=o;b+=1)D=e[b][T],e[b][T]=e[b][T+1],e[b][T+1]=D}else{I=F/(1+j);for(b=T+1;b<=v;b+=1)D=j*g[S-1]+F*g[S],g[S]=I*(g[S-1]+D)-g[S],g[S-1]=D,S+=b;for(b=1;b<=o;b+=1)D=j*e[b][T]+F*e[b][T+1],e[b][T+1]=I*(e[b][T]+D)-e[b][T+1],e[b][T]=D}return 0}function K(){S=E-T;for(b=1;b<=T;b+=1)g[S]=g[E],E+=1,S+=1;return g[A+T]=g[A+T+1],d[T]=d[T+1],T+=1,Tt?e*Math.sqrt(1+t*t/e/e):t==0?e:t*Math.sqrt(1+e*e/t/t)}var n,r=numeric.epsilon,i=1e-64/r,s=50,o=0,u=0,a=0,f=0,l=0,c=numeric.clone(t),h=c.length,p=c[0].length;if(h=0&&(b=-b),w=y*b-T,c[u][u]=y-b;for(a=l;a=0&&(b=-b),w=y*b-T,c[u][u+1]=y-b;for(a=l;aE&&(E=S)}for(u=p-1;u!=-1;u+=-1){if(b!=0){w=b*c[u][u+1];for(a=l;a=s-1)throw"Error: no convergence.";E=v[l],S=v[f-1],b=d[f-1],w=d[f],y=((S-x)*(S+x)+(b-w)*(b+w))/(2*w*S),b=g(y,1),y<0?y=((E-x)*(E+x)+w*(S/(y-b)-w))/E:y=((E-x)*(E+x)+w*(S/(y+b)-w))/E,o=1,T=1;for(u=l+1;u=0;a--)if(v[a] 9 | #include 10 | 11 | class Options { 12 | public: 13 | Options() : threads(DEFAULT_THREADS), width(DEFAULT_WIDTH), height(DEFAULT_HEIGHT), tilesize(32), outfile("out.tga"), infile("-"), scene(0), statistics(true), debug(false) { } 14 | int threads; 15 | int width; 16 | int height; 17 | int tilesize; 18 | std::string outfile; 19 | std::string infile; 20 | int scene; 21 | bool debug; 22 | bool statistics; 23 | 24 | bool validate() const; 25 | 26 | friend std::ostream& operator<<(std::ostream& out, const Options& o); 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /quantjs.js: -------------------------------------------------------------------------------- 1 | var a=1; 2 | 3 | // TODO: Adapt for QuantLib 4 | // Add Option object, with parameters, then send to various pricing functions 5 | // PricingEngine, various pricing methods, then do engine.npv(new OptionParams(...)) 6 | // European, Bermudan and American 7 | 8 | function fromjs() { 9 | return "quantjs!!!!"; 10 | } 11 | 12 | /// Wrapper to make functions global, ie motivated by log, mixup with console.log otherwise 13 | function log(n) { 14 | return quantjs.log(n); 15 | } 16 | 17 | function log10(n) { 18 | return quantjs.log10(n); 19 | } 20 | 21 | function log2(n) { 22 | // TODO: Implement this in C++ 23 | return quantjs.log(n) / quantjs.log(2); 24 | } 25 | 26 | function sin(n) { 27 | return quantjs.sin(n); 28 | } 29 | 30 | function cos(n) { 31 | return quantjs.cos(n); 32 | } 33 | 34 | function tan(n) { 35 | return quantjs.tan(n); 36 | } 37 | 38 | function time(fun) { 39 | // Will meassure execution time 40 | var start = quantjs.timems(); 41 | fun(); 42 | var end = quantjs.timems(); 43 | 44 | return end - start; 45 | } 46 | 47 | function sleep(ms) { 48 | // Will sleep in ms 49 | } 50 | 51 | function exit() { 52 | quantjs.exit(); 53 | } 54 | 55 | 56 | function OptionParams(optionType, underlyingPrice, strikePrice, timeToMaturity, dividendYield, riskFreeRate, volatility) { 57 | this.optionType = optionType; 58 | this.underlyingPrice = underlyingPrice; 59 | this.strikePrice = strikePrice; 60 | this.timeToMaturity = timeToMaturity; 61 | this.dividendYield = dividendYield; 62 | this.riskFreeRate = riskFreeRate; 63 | this.volatility = volatility; 64 | } 65 | 66 | // Different options, all extend base Option 67 | 68 | var Option = function Option(optionKind) { 69 | this.optionKind = optionKind; 70 | } 71 | 72 | Option.prototype = { 73 | getKind: function getKind() { 74 | return this.optionKind; 75 | }, 76 | getParams: function getParams() { 77 | return this.optionParams; 78 | }, 79 | setParams: function setParams(optionParams) { 80 | this.optionParams = optionParams; 81 | } 82 | } 83 | 84 | // 3 supported option types 85 | var AmericanOption = function AmericanOption() { 86 | //this.setParams(new OptionParams(optionType, underlyingPrice, strikePrice, dividendYield, riskFreeRate, volatility)); 87 | } 88 | AmericanOption.prototype = new Option("American"); 89 | 90 | 91 | var EuropeanOption = function EuropeanOption() { 92 | //this.setParams(new Option("European", new OptionParams(optionType, underlyingPrice, strikePrice, dividendYield, riskFreeRate, volatility)); 93 | } 94 | EuropeanOption.prototype = new Option("European"); 95 | 96 | var BermudanOption = function BermudanOption() { 97 | //this.setParams(new OptionParams(optionType, underlyingPrice, strikePrice, dividendYield, riskFreeRate, volatility)); 98 | } 99 | BermudanOption.prototype = new Option("Bermudan"); 100 | 101 | // Class definition / PricingEngine 102 | var PricingEngine = function PricingEngine(method) { 103 | 104 | // Check if method is supported 105 | this.methods = ["Black-Scholes", "Heston semi-analytic", "Binomial Trigeorgis"]; 106 | 107 | if (method in this.methods) { 108 | this.method = method; 109 | } else { 110 | console.log('Method not supported'); 111 | } 112 | } 113 | 114 | // Instance methods 115 | PricingEngine.prototype = { 116 | constructor: PricingEngine, 117 | calculateNPV: function calculateNPV(optionObject) { 118 | if (this.method != null) { 119 | 120 | // Just a hack for now, make more robust, method objects and enums etc. 121 | console.log(this.methods[this.method]); 122 | console.log(optionObject.getKind()); 123 | 124 | return quantjs.eqtest(optionObject.getParams(), this.methods[this.method], optionObject.getKind()); 125 | 126 | } else { 127 | console.log('Method not specified'); 128 | } 129 | }, 130 | listMethods: function listMethods() { 131 | this.methods.forEach( function(m) { 132 | console.log(m); 133 | }); 134 | } 135 | } 136 | 137 | // var pricingEngine = new PricingEngine(1); 138 | // var optionParams = new OptionParams("PUT", 36, 40, 0.00, 0.06, 0.20); 139 | // pricingEngine.calculateNPV(optionParams); 140 | 141 | function testNPV() { 142 | var pricingEngine = new PricingEngine(0); // BS 143 | 144 | var europeanOption = new EuropeanOption(); 145 | europeanOption.setParams(new OptionParams('PUT', 36, 40, 0.5, 0.00, 0.06, 0.20)); 146 | var t = pricingEngine.calculateNPV(europeanOption); // 3.843556981971868 147 | console.log(t); 148 | /* 149 | var americanOption = new AmericanOption(); 150 | americanOption.setParams(new OptionParams('PUT', 36, 40, 0.5, 0.00, 0.06, 0.20)); 151 | pricingEngine.calculateNPV(americanOption); // 4.486461065154719 152 | 153 | var bermudanOption = new BermudanOption(); 154 | bermudanOption.setParams(new OptionParams('PUT', 36, 40, 0.5, 0.00, 0.06, 0.20)); 155 | var t = pricingEngine.calculateNPV(bermudanOption); // 4.360909275428335 156 | console.log(t); 157 | */ 158 | } 159 | 160 | /* 161 | function testNPV1() { 162 | var pricingEngine = new PricingEngine(0); 163 | var optionParams = new OptionParams("PUT", 36, 40, 0.00, 0.06, 0.20); 164 | return pricingEngine.calculateNPV(optionParams); 165 | } 166 | 167 | function testNPV2() { 168 | var pricingEngine = new PricingEngine(2); 169 | var optionParams = new OptionParams("PUT", 36, 40, 0.00, 0.06, 0.20); 170 | return pricingEngine.calculateNPV(optionParams); 171 | } 172 | */ 173 | 174 | function testParams() { 175 | quantjs.Print(new OptionParams('PUT', 36, 40, 0.5, 0.00, 0.06, 0.20)); 176 | 177 | // Rough test of running pricing model, simple BS 178 | // maturity(17, QuantLib::May, 1999); 179 | // QuantLib::Date todaysDate(15, QuantLib::May, 1998); 180 | quantjs.eqtest(new OptionParams('PUT', 36, 40, 0.5, 0.00, 0.06, 0.20)); 181 | 182 | } 183 | 184 | // Initialize 185 | function init() { 186 | console.log('Initializing Quant-JS Library, 0.01 Alpha'); 187 | 188 | console.log(quantjs.version()); 189 | 190 | // load libs 191 | quantjs.load("underscore-min.js"); 192 | 193 | // _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0); 194 | 195 | // Subscribe to market data 196 | /* 197 | raptor.subscribe('EUR/USD', tickHandler, function (data, err) { 198 | console.log('Successfully subscribed to market data'); 199 | 200 | if (err) { 201 | console.log("Order Error", err.message); 202 | } else { 203 | console.log("Order Sent", data.ticket); 204 | } 205 | //}); 206 | });*/ 207 | } 208 | 209 | function tickHandler(data) { 210 | console.log('das'); 211 | 212 | //console.log(data.ask); 213 | 214 | //console.log("Symbol: ", data.symbol, " -- Bid: ", data.bid, " -- Ask: ", data.ask); 215 | 216 | if (1 == 1) { 217 | //OrderSend(Symbol(),OP_BUY,1,Ask,3,Ask-25*Point,Ask+25*Point,"My order #2",16384,0,Green); 218 | } 219 | } 220 | 221 | // Cleanup 222 | function deinit() { 223 | console.log('Cleaning up alog'); 224 | } 225 | 226 | //testParams(); 227 | 228 | function testmatrix() { 229 | var matrix = []; 230 | for(var i=0; i<9; i++) { 231 | matrix[i] = new Array(9); 232 | } 233 | return matrix; 234 | } 235 | 236 | function ident(size) { 237 | return _.range(size).map(function(n) { return _.range(size).map(function(m) { return n==m?1:0; }); }); 238 | } 239 | 240 | function mrand(size) { 241 | return _.range(size).map(function(n) { return _.range(size).map(function(m) { return quantjs.rnd(); }); }); 242 | } 243 | 244 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | rlwrap -p'1;33' -m ./quantjs --debug --infiles quantjs.js 2 | -------------------------------------------------------------------------------- /temp.cc: -------------------------------------------------------------------------------- 1 | 2 | Handle Equity_Option_01(const Arguments& args) 3 | { 4 | double underlyingDouble = 0.0; 5 | double strikeDouble = 0.0; 6 | double timeToMaturityYears = 0.0; 7 | double dividendYieldDouble = 0.0; 8 | double riskFreeRateDouble = 0.0; 9 | double volatilityDouble = 0.0; 10 | 11 | if (args[0]->IsObject()) { 12 | Handle object = Handle::Cast(args[0]); 13 | 14 | //// Get parameters from arguments 15 | Handle optionType = object->Get(String::New("optionType")); 16 | Handle underlyingPrice = object->Get(String::New("underlyingPrice")); 17 | Handle strikePrice = object->Get(String::New("strikePrice")); 18 | Handle timeToMaturity = object->Get(String::New("timeToMaturity")); 19 | Handle dividendYield = object->Get(String::New("dividendYield")); 20 | Handle riskFreeRate = object->Get(String::New("riskFreeRate")); 21 | Handle volatility = object->Get(String::New("volatility")); 22 | 23 | v8::String::AsciiValue optionTypeStr(optionType->ToString()); 24 | 25 | if (underlyingPrice->IsNumber()) { 26 | Handle underlyingPriceNum = Handle::Cast(underlyingPrice); 27 | v8::String::AsciiValue testValue(underlyingPriceNum->ToString()); 28 | underlyingDouble = atof(*testValue); 29 | } 30 | 31 | if (strikePrice->IsNumber()) { 32 | Handle strikePriceNum = Handle::Cast(strikePrice); 33 | v8::String::AsciiValue testValue(strikePriceNum->ToString()); 34 | strikeDouble = atof(*testValue); 35 | } 36 | 37 | if (timeToMaturity->IsNumber()) { 38 | Handle timeToMaturityNum = Handle::Cast(timeToMaturity); 39 | v8::String::AsciiValue testValue(timeToMaturityNum->ToString()); 40 | timeToMaturityYears = atof(*testValue); 41 | } 42 | 43 | if (dividendYield->IsNumber()) { 44 | Handle dividendYieldNum = Handle::Cast(dividendYield); 45 | v8::String::AsciiValue testValue(dividendYieldNum->ToString()); 46 | dividendYieldDouble = atof(*testValue); 47 | } 48 | 49 | if (riskFreeRate->IsNumber()) { 50 | Handle riskFreeRateNum = Handle::Cast(riskFreeRate); 51 | v8::String::AsciiValue testValue(riskFreeRateNum->ToString()); 52 | riskFreeRateDouble = atof(*testValue); 53 | } 54 | 55 | if (volatility->IsNumber()) { 56 | Handle volatilityNum = Handle::Cast(volatility); 57 | v8::String::AsciiValue testValue(volatilityNum->ToString()); 58 | volatilityDouble = atof(*testValue); 59 | } 60 | } 61 | 62 | //// Method for option pricing 63 | v8::String::AsciiValue pricingMethod(args[1]->ToString()); 64 | std::cout << "Method: " << *pricingMethod << std::endl; 65 | 66 | //// Option kind 67 | v8::String::AsciiValue optionKind(args[2]->ToString()); 68 | std::cout << "Kind: " << *optionKind << std::endl; 69 | 70 | // TODO: Implement check for supported pricing functions for each kind 71 | 72 | //// Setup dates 73 | QuantLib::Calendar calendar = QuantLib::TARGET(); 74 | QuantLib::Date todaysDate = QuantLib::Date::todaysDate(); //todaysDate(24, QuantLib::October, 2013); 75 | QuantLib::Date settlementDate = QuantLib::Date::todaysDate(); //(24, QuantLib::October, 2013); 76 | QuantLib::Settings::instance().evaluationDate() = todaysDate; 77 | 78 | //// The options 79 | QuantLib::Option::Type type(QuantLib::Option::Put); 80 | QuantLib::Real underlying = underlyingDouble; 81 | QuantLib::Real strike = strikeDouble; 82 | QuantLib::Spread dividendYield = dividendYieldDouble; 83 | QuantLib::Rate riskFreeRate = riskFreeRateDouble; 84 | QuantLib::Volatility volatility = volatilityDouble; 85 | // 2013-10-18 86 | //QuantLib::Date maturity(18, QuantLib::November, 2013); 87 | QuantLib::Date maturity = QuantLib::Date::todaysDate(); 88 | maturity += 365 * timeToMaturityYears * QuantLib::Days; 89 | QuantLib::DayCounter dayCounter = QuantLib::Actual365Fixed(); 90 | 91 | //// Black-Scholes for European 92 | // TODO: Don't init all if not used 93 | 94 | std::vector exerciseDates; 95 | for (QuantLib::Integer i=1; i<=4; i++) { 96 | exerciseDates.push_back(settlementDate + 3*i*QuantLib::Months); 97 | } 98 | 99 | boost::shared_ptr europeanExercise(new QuantLib::EuropeanExercise(maturity)); 100 | 101 | boost::shared_ptr bermudanExercise(new QuantLib::BermudanExercise(exerciseDates)); 102 | 103 | boost::shared_ptr americanExercise(new QuantLib::AmericanExercise(settlementDate, maturity)); 104 | 105 | boost::shared_ptr payoff(new QuantLib::PlainVanillaPayoff(type, strike)); 106 | 107 | QuantLib::VanillaOption europeanOption(payoff, europeanExercise); 108 | QuantLib::VanillaOption bermudanOption(payoff, bermudanExercise); 109 | QuantLib::VanillaOption americanOption(payoff, americanExercise); 110 | 111 | QuantLib::Handle underlyingH(boost::shared_ptr(new QuantLib::SimpleQuote(underlying))); 112 | QuantLib::Handle flatTermStructure(boost::shared_ptr(new QuantLib::FlatForward(settlementDate, riskFreeRate, dayCounter))); 113 | QuantLib::Handle flatDividendTS(boost::shared_ptr(new QuantLib::FlatForward(settlementDate, dividendYield, dayCounter))); 114 | QuantLib::Handle flatVolTS(boost::shared_ptr(new QuantLib::BlackConstantVol(settlementDate, calendar, volatility, dayCounter))); 115 | 116 | // TODO: Clean up here, and lift to other file/class 117 | 118 | if (strncmp(*pricingMethod, "Black-Scholes", strlen("Black-Scholes") - 1) == 0) { 119 | // Black-Scholes 120 | boost::shared_ptr bsmProcess(new QuantLib::BlackScholesMertonProcess(underlyingH, flatDividendTS,flatTermStructure, flatVolTS)); 121 | europeanOption.setPricingEngine(boost::shared_ptr(new QuantLib::AnalyticEuropeanEngine(bsmProcess))); 122 | return Number::New(europeanOption.NPV()); 123 | 124 | } else if (strncmp(*pricingMethod, "Heston semi-analytic", strlen("Heston semi-analytic") - 1) == 0) { 125 | // Heston semi-analytic 126 | boost::shared_ptr hestonProcess(new QuantLib::HestonProcess(flatTermStructure, flatDividendTS, underlyingH, volatility*volatility, 1.0, volatility*volatility, 0.001, 0.0)); 127 | boost::shared_ptr hestonModel(new QuantLib::HestonModel(hestonProcess)); 128 | europeanOption.setPricingEngine(boost::shared_ptr(new QuantLib::AnalyticHestonEngine(hestonModel))); 129 | return Number::New(europeanOption.NPV()); 130 | 131 | } else if (strncmp(*pricingMethod, "Binomial Trigeorgis", strlen("Binomial Trigeorgis") - 1) == 0) { 132 | // Binomial Trigeorgis 133 | // Works for all three options kinds 134 | 135 | QuantLib::Size timeSteps = 801; 136 | 137 | if (strncmp(*optionKind, "European", strlen("European") - 1) == 0) { 138 | boost::shared_ptr bsmProcess(new QuantLib::BlackScholesMertonProcess(underlyingH, flatDividendTS,flatTermStructure, flatVolTS)); 139 | europeanOption.setPricingEngine(boost::shared_ptr(new QuantLib::BinomialVanillaEngine(bsmProcess, timeSteps))); 140 | return Number::New(europeanOption.NPV()); 141 | } else if (strncmp(*optionKind, "American", strlen("American") - 1) == 0) { 142 | //QuantLib::VanillaOption europeanOption(payoff, europeanExercise); 143 | boost::shared_ptr bsmProcess(new QuantLib::BlackScholesMertonProcess(underlyingH, flatDividendTS,flatTermStructure, flatVolTS)); 144 | americanOption.setPricingEngine(boost::shared_ptr(new QuantLib::BinomialVanillaEngine(bsmProcess, timeSteps))); 145 | return Number::New(americanOption.NPV()); 146 | } else if (strncmp(*optionKind, "Bermudan", strlen("Bermudan") - 1) == 0) { 147 | boost::shared_ptr bsmProcess(new QuantLib::BlackScholesMertonProcess(underlyingH, flatDividendTS,flatTermStructure, flatVolTS)); 148 | bermudanOption.setPricingEngine(boost::shared_ptr(new QuantLib::BinomialVanillaEngine(bsmProcess, timeSteps))); 149 | return Number::New(bermudanOption.NPV()); 150 | } 151 | 152 | return Number::New(-1.0); 153 | } 154 | 155 | return Number::New(-1.0); 156 | } 157 | 158 | 159 | // NEW 160 | 161 | 162 | 163 | #include 164 | #include 165 | 166 | #include 167 | 168 | #include 169 | #include 170 | #include 171 | #include 172 | #include 173 | #include 174 | 175 | typedef boost::mt19937 T_base_prng; 176 | typedef boost::normal_distribution<> T_norm_dist; 177 | typedef boost::variate_generator T_norm_varg; 178 | 179 | 180 | 181 | 182 | 183 | v8::Handle Print(const v8::Arguments& args) { 184 | 185 | if (args[0]->IsObject()) { 186 | Handle object = Handle::Cast(args[0]); 187 | 188 | Handle optionType = object->Get(String::New("optionType")); 189 | Handle underlyingPrice = object->Get(String::New("underlyingPrice")); 190 | Handle strikePrice = object->Get(String::New("strikePrice")); 191 | Handle dividendYield = object->Get(String::New("dividendYield")); 192 | Handle riskFreeRate = object->Get(String::New("riskFreeRate")); 193 | Handle volatility = object->Get(String::New("volatility")); 194 | 195 | v8::String::AsciiValue optionTypeStr(optionType->ToString()); 196 | std::cout << *optionTypeStr << std::endl; 197 | std::cout << ""; 198 | 199 | v8::String::AsciiValue underlyingPriceStr(underlyingPrice->ToString()); 200 | std::cout << *underlyingPriceStr << std::endl; 201 | std::cout << ""; 202 | 203 | v8::String::AsciiValue strikePriceStr(strikePrice->ToString()); 204 | std::cout << *strikePriceStr << std::endl; 205 | std::cout << ""; 206 | 207 | v8::String::AsciiValue dividendYieldStr(dividendYield->ToString()); 208 | std::cout << *dividendYieldStr << std::endl; 209 | std::cout << ""; 210 | 211 | v8::String::AsciiValue riskFreeRateStr(riskFreeRate->ToString()); 212 | std::cout << *riskFreeRateStr << std::endl; 213 | std::cout << ""; 214 | 215 | v8::String::AsciiValue volatilityStr(volatility->ToString()); 216 | std::cout << *volatilityStr << std::endl; 217 | std::cout << ""; 218 | } 219 | 220 | for (int i = 0; i < args.Length(); i++) { 221 | v8::String::AsciiValue str(args[i]->ToString()); 222 | std::cout << *str << std::endl; 223 | std::cout << ""; 224 | } 225 | return v8::Undefined(); 226 | } 227 | 228 | class Console { 229 | public: 230 | v8::Handle Log(v8::Local str) { 231 | v8::String::AsciiValue astr(str); 232 | std::cout << to_iso_extended_string(microsec_clock::local_time()) << " INFO\t- " << *astr << std::endl; 233 | 234 | return v8::Undefined(); 235 | } 236 | }; 237 | 238 | v8::Handle exit(const v8::Arguments& args) 239 | { 240 | // Hack to exit app 241 | exit(0); 242 | } 243 | 244 | boost::random::mt19937 gen; 245 | boost::random::uniform_real_distribution<> dist(1, 3.14159); 246 | 247 | v8::Handle callme(const v8::Arguments& args) 248 | { 249 | Handle global = context->Global(); 250 | 251 | if (args[2]->IsFunction()) { 252 | Handle func = v8::Handle::Cast(args[2]->ToObject()); 253 | Handle argsf[2]; 254 | 255 | //argsf[1] = v8::Number::New(0.02); 256 | 257 | double acc=0; 258 | 259 | Handle aNum = Handle::Cast(args[0]); 260 | Handle bNum = Handle::Cast(args[1]); 261 | 262 | double a = aNum->NumberValue(); 263 | double b = bNum->NumberValue(); 264 | 265 | boost::random::uniform_real_distribution<> dist2(a, b); 266 | 267 | for (int i=0;i<50000;i++) { 268 | 269 | argsf[0] = v8::Number::New(dist2(gen)); 270 | Handle js_result = func->Call(global, 1, argsf); 271 | 272 | //Handle strikePriceNum = Handle::Cast(strikePrice); 273 | //v8::String::AsciiValue testValue(strikePriceNum->ToString()); 274 | //strikeDouble = atof(*testValue); 275 | 276 | acc += js_result->NumberValue(); 277 | 278 | v8::String::Utf8Value value(js_result->ToDetailString()); 279 | //printf("\t%s\n", *value); 280 | } 281 | std::cout << "I: " << (b-a)*acc/50000.0 << std::endl; 282 | } 283 | 284 | return v8::Undefined(); 285 | } 286 | 287 | v8::Handle log10(const v8::Arguments& args) 288 | { 289 | // Returns the common (base-10) logarithm of x 290 | 291 | v8::String::AsciiValue argStr(args[0]->ToString()); 292 | //std::cout << *argStr << std::endl; 293 | double arg = atof(*argStr); 294 | 295 | //v8::String::AsciiValue arg2(args[0]->ToString()); 296 | //std::cout << *arg1 << std::endl; 297 | 298 | return Number::New(log10(arg)); 299 | } 300 | 301 | v8::Handle log(const v8::Arguments& args) 302 | { 303 | // Returns the natural logarithm of x 304 | 305 | v8::String::AsciiValue argStr(args[0]->ToString()); 306 | //std::cout << *argStr << std::endl; 307 | double arg = atof(*argStr); 308 | 309 | //v8::String::AsciiValue arg2(args[0]->ToString()); 310 | //std::cout << *arg1 << std::endl; 311 | 312 | return Number::New(log(arg)); 313 | } 314 | 315 | v8::Handle sin(const v8::Arguments& args) 316 | { 317 | // Returns the natural logarithm of x 318 | 319 | v8::String::AsciiValue argStr(args[0]->ToString()); 320 | //std::cout << *argStr << std::endl; 321 | double arg = atof(*argStr); 322 | 323 | //v8::String::AsciiValue arg2(args[0]->ToString()); 324 | //std::cout << *arg1 << std::endl; 325 | 326 | return Number::New(sin(arg)); 327 | } 328 | 329 | v8::Handle cos(const v8::Arguments& args) 330 | { 331 | // Returns the natural logarithm of x 332 | 333 | v8::String::AsciiValue argStr(args[0]->ToString()); 334 | //std::cout << *argStr << std::endl; 335 | double arg = atof(*argStr); 336 | 337 | //v8::String::AsciiValue arg2(args[0]->ToString()); 338 | //std::cout << *arg1 << std::endl; 339 | 340 | return Number::New(cos(arg)); 341 | } 342 | 343 | v8::Handle tan(const v8::Arguments& args) 344 | { 345 | // Returns the natural logarithm of x 346 | 347 | v8::String::AsciiValue argStr(args[0]->ToString()); 348 | //std::cout << *argStr << std::endl; 349 | double arg = atof(*argStr); 350 | 351 | //v8::String::AsciiValue arg2(args[0]->ToString()); 352 | //std::cout << *arg1 << std::endl; 353 | 354 | return Number::New(tan(arg)); 355 | } 356 | 357 | v8::Handle randfloat(const v8::Arguments& args) 358 | { 359 | return Number::New(dist(gen)); 360 | } 361 | 362 | v8::Handle sleep(const v8::Arguments& args) 363 | { 364 | // Returns the natural logarithm of x 365 | 366 | v8::String::AsciiValue argStr(args[0]->ToString()); 367 | //std::cout << *argStr << std::endl; 368 | int msecs = atoi(*argStr); 369 | 370 | boost::this_thread::sleep(boost::posix_time::milliseconds(msecs)); 371 | 372 | //v8::String::AsciiValue arg2(args[0]->ToString()); 373 | //std::cout << *arg1 << std::endl; 374 | 375 | return v8::Undefined(); 376 | } 377 | 378 | 379 | v8::Handle load(const v8::Arguments& args) 380 | { 381 | // Returns the natural logarithm of x 382 | 383 | v8::String::AsciiValue argStr(args[0]->ToString()); 384 | std::cout << "Supposed to load this: " << *argStr << std::endl; 385 | //int msecs = atoi(*argStr); 386 | 387 | //boost::this_thread::sleep(boost::posix_time::milliseconds(msecs)); 388 | 389 | //v8::String::AsciiValue arg2(args[0]->ToString()); 390 | //std::cout << *arg1 << std::endl; 391 | 392 | return v8::Undefined(); 393 | } 394 | 395 | v8::Handle timems(const v8::Arguments& args) 396 | { 397 | // Returns the natural logarithm of x 398 | 399 | //v8::String::AsciiValue argStr(args[0]->ToString()); 400 | //std::cout << *argStr << std::endl; 401 | //int msecs = atoi(*argStr); 402 | 403 | //boost::this_thread::sleep(boost::posix_time::milliseconds(msecs)); 404 | 405 | //boost::posix_time::ptime t = boost::posix_time::microsec_clock::universal_time(); 406 | 407 | //v8::String::AsciiValue arg2(args[0]->ToString()); 408 | //std::cout << *arg1 << std::endl; 409 | 410 | boost::posix_time::ptime epoch = boost::posix_time::time_from_string("1970-01-01 00:00:00.000"); 411 | boost::posix_time::ptime other = boost::posix_time::microsec_clock::universal_time(); 412 | 413 | long diff = (other-epoch).total_milliseconds(); 414 | 415 | return Number::New(diff); 416 | } 417 | 418 | 419 | 420 | 421 | v8::Handle ConsoleMethod_Log(const Arguments& args) 422 | { 423 | Local self = args.Holder(); 424 | Local wrap = Local::Cast(self->GetInternalField(0)); 425 | void* ptr = wrap->Value(); 426 | static_cast(ptr)->Log(args[0]->ToString()); 427 | 428 | return v8::Undefined(); 429 | } 430 | 431 | class RaptorAPI { 432 | public: 433 | RaptorAPI() : version("Quant-JS Engine, 0.01 Alpha") {}; 434 | 435 | std::string& Version() { 436 | return version; 437 | } 438 | 439 | void Subscribe() { 440 | 441 | } 442 | 443 | private: 444 | std::string version; 445 | }; 446 | 447 | Handle Raptor_Version(const Arguments& args) 448 | { 449 | Local self = args.Holder(); 450 | Local wrap = Local::Cast(self->GetInternalField(0)); 451 | void* ptr = wrap->Value(); 452 | 453 | return v8::String::New(static_cast(ptr)->Version().c_str()); 454 | } 455 | 456 | 457 | Handle Raptor_Subscribe(const Arguments& args) { 458 | 459 | Local self = args.Holder(); 460 | Local wrap = Local::Cast(self->GetInternalField(0)); 461 | void* ptr = wrap->Value(); 462 | 463 | static_cast(ptr)->Subscribe(); 464 | 465 | Handle func = Handle::Cast(args[2]); 466 | Handle argv[0]; 467 | Handle js_result = func->Call(self, 0, argv); 468 | 469 | return v8::Undefined(); 470 | } 471 | 472 | 473 | #define QJS_VERSION "0.0.4" 474 | 475 | // Reads a file into a v8 string. 476 | v8::Handle ReadFile(const char* name) { 477 | 478 | std::ifstream infile (name, std::ios_base::in); 479 | 480 | if (!infile.good()) return v8::Handle(); 481 | 482 | std::stringstream sstream; 483 | while (infile.good() && infile.peek() != -1) { 484 | sstream.put(infile.get()); 485 | } 486 | infile.close(); 487 | 488 | v8::Handle result = v8::String::New(sstream.str().c_str()); 489 | 490 | return result; 491 | } 492 | 493 | 494 | 495 | class ARCore { 496 | public: 497 | ARCore(Options options) : options(options) {} 498 | void run(); 499 | private: 500 | const Options& options; 501 | }; 502 | 503 | v8::Handle Print2(const v8::Arguments& args) { 504 | v8::HandleScope scope; 505 | 506 | for (int i = 0; i < args.Length(); i++) { 507 | v8::Handle str = args[i]->ToString(); 508 | v8::String::AsciiValue ascii(str); 509 | 510 | std::cout << *ascii; 511 | 512 | } 513 | 514 | return v8::Undefined(); 515 | } 516 | 517 | v8::Handle require(const v8::Arguments& args) { 518 | 519 | 520 | v8::String::AsciiValue argStr(args[0]->ToString()); 521 | 522 | Handle global = context->Global(); 523 | 524 | v8::Handle source = ReadFile(*argStr); 525 | Handle