Author |
Message |
Александр Михалицын
Модератор
Joined: 23 May 2008
Posts: 1299
Карма: 83 поощрить/наказать
|
Posted: Fri May 29, 2009 4:48 pm ()
Post subject:
|
|
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Fri May 29, 2009 4:48 pm (спустя 1 секунду; написано за 3 минуты 3 секунды)
Post subject:
|
|
dimagolov wrote: |
даже с учетом того, что мои личные воспоминания об этом курсе вообще и предмете в частности весьма смутные, никто не отменял вот это: tinyurl.com/lungdd | Представляю себе круглые глаза человека, впервые узнавшего о концепции комплексных чисел и увидевшего формулу для корня порядка N из комплексного числа :).
|
|
Back to top |
|
 |
dimagolov
Участник форума
Joined: 04 Feb 2007
Posts: 1664
Карма: 96 поощрить/наказать
Location: Christ Church, Barbados
|
Posted: Fri May 29, 2009 4:58 pm (спустя 9 минут; написано за 11 секунд)
Post subject:
|
|
Quote: |
А теперь, если ты каждый метод опишешь (как он работает) будет вообще супер. =) | Что там описывать? это просто арифметика комплексных чисел, если Юрий не накосячил (я просто не проверял), то Вы по его коду можете выучить ее. Комплексное число у него представлено массивом - 0-й элемент это действительная часть, 1-й это комплексная. Quote: |
Мне интересно значть что вы тм в ТФКП проходили... =) | Если есть время и желание, то даже 8-й класс не станет проблемой: tinyurl.com/llzu4m
Правда, придется многое чего подучить, я вот не помню когда изучаются тригонометрические ф-ии. На самом деле комплексные числа это просто - вместо числовой прямой это можно представить как плоскость. Правда, уже ф-я комплексной переменной создает некоторые трудности в воображении, так как график такой ф-ии придется рисовать в 4-х мерном пространстве
|
|
Back to top |
|
 |
dimagolov
Участник форума
Joined: 04 Feb 2007
Posts: 1664
Карма: 96 поощрить/наказать
Location: Christ Church, Barbados
|
Posted: Fri May 29, 2009 5:26 pm (спустя 28 минут; написано за 3 минуты 43 секунды)
Post subject:
|
|
кстати, первой программой, которую я самостоятельно написал были именно решалка квадратных уравнений. написана она была на Basic для Искра 226, был в свое время такой персональный компьютер (невероятно компактный, помещался на одном столе даже вместе с приводами 8-дюймовых флопов)... странно, мне казалось, что квадратные уравнения изучались много раньше, чем в 8-м классе, если считать с 6-и лет (хотя тогда ходили в школу с 7-ми) то по идее в 6-м, если даже не в 5-м?
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Fri May 29, 2009 9:13 pm (спустя 3 часа 46 минут; написано за 6 минут 27 секунд)
Post subject:
|
|
Хотя реализация комплексных чисел на js (как мне кажется) не представляет практического интереса, но ради интереса можно попытаться воплотить большинство математических действий для комплексных чисел. Конечно, перегрузка операций в js невозможна, но даже этот недостаток частично можно обойти, например, с помощью функций-методов. Последнее я представляю примерно так: Code (JavaScript): | скопировать код в буфер обмена | // z1 = 1 + i z1 = new Complex(1, 1);
// z2 = 1 - i z2 = new Complex(1, -1);
// z3 = z1 + z2 z3 = a1.add(z2); | Опять же повторюсь, практического значения у данной реализации мало - данное решение интересно лишь с учебной точки зрения. Медленно и отсутствие поддержки перегрузки операторов со стороны языка.
|
|
Back to top |
|
 |
Александр Михалицын
Модератор
Joined: 23 May 2008
Posts: 1299
Карма: 83 поощрить/наказать
|
Posted: Mon Jun 01, 2009 12:02 pm (спустя 2 дня 14 часов 49 минут; написано за 44 секунды)
Post subject:
|
|
Rumata, угу. Как только я разберусь с комплексными числами, обязательно напишу подобные объекты, именно в целях обучения. Спасибо всем, кто подсказал и помог с кодом. [+]ы.
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Mon Jun 01, 2009 12:29 pm (спустя 26 минут; написано за 1 минуту 24 секунды)
Post subject:
|
|
ru.wikipedia.org/wiki/Комплексное_число
en.wikipedia.org/wiki/Complex_number
Информация не самая полная, но для начала должно хватить. Пишите. Хотелось бы увидеть ваше решение. Я уже приготовил каверзных вопросов (-:
|
|
Back to top |
|
 |
Александр Михалицын
Модератор
Joined: 23 May 2008
Posts: 1299
Карма: 83 поощрить/наказать
|
Posted: Mon Jun 01, 2009 5:01 pm (спустя 4 часа 31 минуту; написано за 44 секунды)
Post subject:
|
|
Rumata,Мы на "ты".  Quote: |
Я уже приготовил каверзных вопросов (-: | Отлично... =)
|
|
Back to top |
|
 |
Александр Михалицын
Модератор
Joined: 23 May 2008
Posts: 1299
Карма: 83 поощрить/наказать
|
Posted: Sun Jun 07, 2009 10:39 am (спустя 5 дней 17 часов 38 минут; написано за 18 секунд)
Post subject:
|
|
Code (JavaScript): | скопировать код в буфер обмена | /* function Complex(a, b) { this.a = a; // this.b = b; //
/* this.sum = function(complex) // { return new Complex(this.a + complex.a, this.b + complex.b); }
/* this.diff = function(complex) // { return new Complex(this.a - complex.a, this.b - complex.b); }
/* this.multi = function(complex) // { var a = this.a; var c = complex.a;
var b = this.b; var d = complex.b;
return new Complex(a * c - b * d, b * c + a * d); }
/* this.division = function(complex) // { var a = this.a; var c = complex.a;
var b = this.b; var d = complex.b;
var new_complex_a = (a * c + b * d) / (c * c + d * d); var new_complex_b = (d * c - a * d) / (c * c + d * d);
return new Complex(new_complex_a, new_complex_b); }
/* this.compare = function(complex) // { if (this.a == complex.a && this.b == complex.b) { return true; } else { return false; } }
/* this.modules_compare = function(complex) { var module_this_z = Math.sqrt(this.a * this.a + this.b * this.b); var module_complex_z = Math.sqrt(complex.a * complex.a + complex.b * complex.b);
if (module_this_z > module_complex_z) { return true; // } else if (module_this_z < module_complex_z) { return false; // } else { return null; // } }
this.toString = function() { return this.a + (this.b + 'i'); } } | Жду критики. :)
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sun Jun 07, 2009 11:04 am (спустя 24 минуты; написано за 1 минуту 22 секунды)
Post subject:
|
|
Хм, ну да, и мой вариантик, + решалка квадратных уравнений, переписанная под использование класса комплексных чисел. Code (JavaScript): | скопировать код в буфер обмена | function Complex(x,y) { this.construct(x,y) }
Complex.prototype = { x: 0, y: 0, construct: function(x,y) { this.x = x; this.y = y; }, toString: function() { return this.x+' + i*'+this.y; }, // return |z| abs: function() { return Math.sqrt(this.x*this.x+this.y*this.y); }, mul: function(b) { var a = this; return new Complex(a.x*b.x - a.y*b.y, a.y*b.x + b.y*a.x); }, // complex division: returns (a/b) div: function(b) { // a/b = a*(b*)/|b|^2, where b* = Re b - i*Im b var a = this; var b2 = b.x*b.x + b.y*b.y; // (|b|^2) if(!b2) return false; return a.mul(new Complex(b.x/b2, -b.y/b2)); }, add: function(b) { var a = this; return new Complex( a.x + b.x, a.y + b.y ); }, // a - b sub: function(b) { var a = this; return new Complex( a.x - b.x, a.y - b.y); }, neg: function() { var a = this; return new Complex( -a.x, -a.y ); }, // power (n is real, not complex!): // if n is integer, you will get the n'th power of z // if n = 1/k, where k is integer, you will get an array of k complex k'th roots of z // otherwise you will get 1 complex number // if you want to get, e.g., a power of 2/3, use pow2 pow: function(n) { var a = this; // get the exponential form of an answer var r = Math.sqrt( a.x*a.x + a.y*a.y ); if(r==0) return new Complex(0,0); if(n==0) return new Complex(1,0); var na = Math.abs(n); r = Math.pow(r,na); var phi = Math.atan2(a.y,a.x); if(na >= 1 && Math.round(na) == na || Math.abs( Math.round(1/na) - 1/na ) > 1e-10) // means, that n is integer or n is not (1/k), where k is integer { var ans = new Complex( r*Math.cos(na*phi), r*Math.sin(na*phi) ); // z^|n| if(n < 0) return new Complex(1,0).div(ans); else return ans; }else { // the result will be array of different complex roots var m = Math.round(1/na); // m means the power of the root var answers = []; var ang = 0; for(var i = 0; i < m; i++) // there will be m distinct answers { ang = (phi+i*2*Math.PI)/m; answers[i] = new Complex( r*Math.cos(ang), r*Math.sin(ang) ) ; if(n < 0) answers[i] = new Complex(1,0).div(answers[i]); } return answers; } }, // use this function to get the power (n/m) for z // neither n or m should be equal to 1 or 0 or -1 // returns array of m complex numbers pow2: function(n,m) { if(n!=Math.round(n) || Math.abs(n)<=1 || m!=Math.round(m) || Math.abs(m)<=1) return false; var answers = this.pow(1/m); for(var i = 0; i < m; i++) { answers[i] = answers[i].pow(n); } return answers; }, // complex logarithm of a number // base is optional and must be real // the result is given only for _main_ branch of the logarithm // // the default base is E (2.71) log: function(base) { var a = this; var r = Math.sqrt( a.x*a.x + a.y*a.y ); if(base == 1 || base <= 0) return false; // even though base for complex logarithm, possibly, could be negative, I do not want to consider this case var x = 0; if(base) x = Math.log(r)/Math.log(base); else x = Math.log(r); var phi = Math.atan2(a.y, a.x); return new Complex( x, phi ); }, // complex exponent (in complex power) exp: function() { var z = this; var re = Math.exp(z.x); return new Complex( re*Math.cos(z.y), re*Math.sin(z.y) ); }, // sin: function() { var z = this; var z1 = z.mul(new Complex(0,1)); var z2 = z1.neg(); return ( z1.exp() ).sub( z2.exp() ).div(new Complex(0,2)); }, cos: function() { var z = this; var z1 = z.mul(new Complex(0,1)); var z2 = z1.neg(); return ( z1.exp() ).add( z2.exp() ).div(new Complex(2,0)); }
};
var sq_eq_solver = { // a, b, c -- complex numbers // // another difference -- if a==0,b!=0 the answer is returned in format [ z ] // returns [z1, z2], where z1 and z2 are the roots solve: function(a,b,c) { if(!a.x && !a.y) return b.x&&b.y ? c.div(b).neg() : !c.x&&!c.y; // scale coeffs so, that a=0.5 and x1,x2 = ( -b +- sqrt(D) ); ( 1/2a == 1) var two_a_i = new Complex(0.5,0).div(a); // 1/2a a=new Complex(0.5,0); b=b.mul(two_a_i); // b = b*(1/2a) c=c.mul(two_a_i); // c = c*(1/2a) var D = b.mul(b).sub( c.mul(new Complex(2,0)) ); // var D = b*b - 2*c; var sqD = D.pow(1/2)[0] || new Complex(0,0); var nb = b.neg(); return [nb.add(sqD), nb.sub(sqD)]; } };
function z(x,y) { return new Complex(x,y); }
//alert( z(4,0).pow(1/2)[0] );
//alert( sq_eq_solver.solve(1,0,4) ); alert( sq_eq_solver.solve( z(2,0) , z(-8,-6),z(-4,16) ) ); |
|
|
Back to top |
|
 |
Александр Михалицын
Модератор
Joined: 23 May 2008
Posts: 1299
Карма: 83 поощрить/наказать
|
Posted: Sun Jun 07, 2009 12:20 pm (спустя 1 час 16 минут; написано за 1 минуту 17 секунд)
Post subject:
|
|
Да уж... С такими темпами нам надо открыть доп. форум "Математика". (-: Юрий Насретдинов, классно... Что уж тут сказать...
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sun Jun 07, 2009 6:38 pm (спустя 6 часов 17 минут; написано за 4 минуты 33 секунды)
Post subject:
|
|
Александр Михалицын
Юрий Насретдинов
Есть несколько замечаний. Что-то мне подсказывает, что некоторые места в ваших алгоритмах не оптимальны. Непонятно, почему никто из вас не воспользовался другими формами представления комплексных чисел. А методы - pow, pow2 и log - от чего такие страшные вычисления? Можно же проще. Я ни в коем случае не придираюсь. Не такая уж серьезная задача ставилась. Но все-таки...
|
|
Back to top |
|
 |
Александр Михалицын
Модератор
Joined: 23 May 2008
Posts: 1299
Карма: 83 поощрить/наказать
|
Posted: Sun Jun 07, 2009 6:49 pm (спустя 11 минут; написано за 2 минуты 14 секунд)
Post subject:
|
|
Rumata, Quote: |
Непонятно, почему никто из вас не воспользовался другими формами представления комплексных чисел. | А что может быть оптимальнее объекта? (-: Массив? Тоже объект -- насколько мне кажется, даже более "не оптимальный". (-: Quote: |
А методы - pow, pow2 и log - от чего такие страшные вычисления? Можно же проще. | Давай-ка изложишь тут или мне в ICQ? Интересно будет послушать (зачеркнуто) почитать... Quote: |
Я ни в коем случае не придираюсь. | Да можно и попридираться... (-:
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sun Jun 07, 2009 6:51 pm (спустя 1 минуту 52 секунды; написано за 2 минуты 15 секунд)
Post subject:
|
|
Rumata wrote: |
Непонятно, почему никто из вас не воспользовался другими формами представления комплексных чисел. | Для вычисления степени как раз осуществляется переход к экспоненциальной форме записи :). А проще вряд ли можно сделать, потому что извлечение корня степени n из числа является многозначной функцией, поэтому необходимо такие ситуации обрабатывать правильно и возвращать массив ответов :). Для логарифма количество возвращаемых значений счётно, поэтому возвращается только главное значение логарифма :). К тому же, я не очень понял, чего ты сложного увидел в реализации pow2 и логарифма?
Last edited by Юрий Насретдинов on Sun Jun 07, 2009 7:02 pm; edited 2 times in total
|
|
Back to top |
|
 |
Александр Михалицын
Модератор
Joined: 23 May 2008
Posts: 1299
Карма: 83 поощрить/наказать
|
Posted: Sun Jun 07, 2009 6:56 pm (спустя 5 минут)
Post subject:
|
|
 М |
| Тему скоро надо будет порезать... Как закончим обсуждение -- сделаю. А то тут уже и решение квадратичных уравнений и комплексные числа... Осталось только тригонометрические функции обсудить. (-: |
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sun Jun 07, 2009 7:36 pm (спустя 40 минут; написано за 7 минут 35 секунд)
Post subject:
|
|
Александр Михалицын
Я имел ввиду тригонометрическую форму представленияЮрий Насретдинов
Я видел перевод из алгебраической в тригонометрическую, но почему же так много строк в методе pow? К чему лишние проверки? К вопросу о многозначности результатов вычисления корней. Мне кажется, что pow - функция "общего назначения" для вычисления степени вообще. Не понятен смысл pow и pow2. По моему одна из них повторяет алгоритм другой. А умножение, деление - разве не проще выполнять в тригонометрической форме?
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sun Jun 07, 2009 7:51 pm (спустя 14 минут; написано за 5 минут 52 секунды)
Post subject:
|
|
Юрий Насретдинов wrote: |
К тому же, я не очень понял, чего ты сложного увидел в реализации pow2 и логарифма? | Я понимаю, что там предусмотрено вычисление произвольного логарифма, мне кажется, это можно было бы вынести за пределы. Но я это не оспариваю. Много кода чтобы вычислить логарифм числа. Что может быть проще чемЧто характерно, в классе описан метод вычисления модуля Complex.abs(), но практически не используется.
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sun Jun 07, 2009 10:04 pm (спустя 2 часа 12 минут; написано за 2 минуты 32 секунды)
Post subject:
|
|
Rumata wrote: |
Что характерно, в классе описан метод вычисления модуля Complex.abs(), но практически не используется. | На самом деле, совсем не используется... Rumata wrote: |
Complex.prototype.log = function() { return new Complex(this.abs(), this.arg()); }; | Ну, во-первых, ты забыл самое главное, а именно, логарифм взять от модуля :). К тому же, я думаю, ты мог заметить, что основную часть кода составляет проверка основания логарифма и выполнение соответствующих действий для различных оснований. Ну и последнее, твой код вряд ли будет сильно эффективнее, поскольку вычислений будет на самом деле произведено ровно столько же, просто они запрятаны в методы, некоторых из которых к тому же не существует (к примеру, аргумента :)).
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sun Jun 07, 2009 10:21 pm (спустя 17 минут; написано за 5 минут 23 секунды)
Post subject:
|
|
Конечно я заметил, что ведется большая проверка на корректность входных данных. И твой метод log позволяет вычислить произвольный логарифм для большинства случаев действительных оснований. Для этого и нужны были проверки. Но так ли необходимо такое усложнение? Приводя в качестве примера свое видение метода log я хотел только показать, что некоторые вычисления можно было бы вынести в отдельные методы. Можно даже провести самые тщательные проверки и показать, что мой вариант, возможно, будет слегка проигрывать по скорости. А возможно и нет. Я говорю не об эффективности. Я говорю о красоте кода :)
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sun Jun 07, 2009 10:38 pm (спустя 16 минут; написано за )
Post subject:
|
|
Эм, ну все же проверки на корректность должны быть в коде, от этого никуда не деться. А вот с остальным, в том числе и с использованием .abs() и .arg() я пожалуй соглашусь и постараюсь доделать :).
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sun Jun 07, 2009 11:12 pm (спустя 34 минуты; написано за 5 минут 54 секунды)
Post subject:
|
|
Неточно выразился. Я имел ввиду так ли необходима универсальность, например, того же метода log? Кстатито есть Code (JavaScript): | скопировать код в буфер обмена | Complex.prototype.log = function(base) { ... var r = this.abs(); var x = Math.log(r); var y = this.arg(); if ( base ) { var lg = Math.log(base); x /= lg; y /= lg; } return new Complex(x, y); }; |
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Mon Jun 08, 2009 8:01 am (спустя 8 часов 48 минут; написано за )
Post subject:
|
|
Нда, со сменой основания у логарифма немного лоханулся :). Конечно, надо еще и мнимую часть преобразовывать также... Наверное действительно лучше все же выкинуть поддержку другого основания у логарифма (в принципе, особой необходимости в этом нет).
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Mon Jun 08, 2009 8:22 am (спустя 20 минут; написано за )
Post subject:
|
|
А pow() отличается от pow2() тем, что pow2() рассматривает число, как рациональное, а не вещественное, и соотвественно возвращает n корней вместо одного (в функции pow() считается, что если n или 1/n не являются целыми, то число, подающееся на вход, вещественное, и надо вернуть только 1 результат (как раз то, о чем ты говорил).
|
|
Back to top |
|
 |
Александр Михалицын
Модератор
Joined: 23 May 2008
Posts: 1299
Карма: 83 поощрить/наказать
|
Posted: Mon Jun 08, 2009 10:36 am (спустя 2 часа 14 минут; написано за 2 минуты 25 секунд)
Post subject:
|
|
 М |
| Сейчас дообсуждаем, допилим -- можно будет в "склад". | [off]Я еще строилку графиков писал =) Тоже выложу потом. А то, к сожалению, в разделах JavaScript'a большинство новых тем из серии "Памагите!!!".[/off]
Так с логарифмом, я так понимаю проблема решена? Вариант от Rumata верный?
Last edited by Александр Михалицын on Thu Aug 19, 2010 4:54 pm; edited 1 time in total
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sat Jun 13, 2009 12:58 pm (спустя 5 дней 2 часа 22 минуты; написано за 20 минут 57 секунд)
Post subject:
|
|
Добавлю свое видение задачи. Оно в принципе не отличается от варианта, предложенного Юрием Насретдиновым. Особенностью модуля является вычисление всех частей (вещественной, мнимой, модуля и аргумента) комплексного числа на момент его создания. Это ни прибавляет, ни отнимает скорости вычислений, но оптимизирует некоторые вычисления (например, при вычислениях в алгебраической или полярной формах). Описаны арифметические операции, основные функции над комплексными числами (возведение в степень, логарифм, степенная функция, экспонента, квадратный корень и вычисление всех корней). Арифметические операции расширены для операций над несколькими числами. То есть Code (JavaScript): | скопировать код в буфер обмена | var x = new Complex(1, 1); var y = x.add(new Complex(2, 0)).add(new Complex(3, 0)); // Расширение var y = x.add(new Complex(2, 0), new Complex(3, 0)); | Определены методы вычисления частей комплексного числа - вещественной re(), мнимой im(), модуля abs() и аргумента arg() комплексного числа, а также вычисление сопряженного комплексного числа conj() и его отрицательного значения neg(). Функция строкового преобразования Complex.prototype.toString позволяет отобразить комплексное число как в алгебраической, так и в полярной формах. Добавлены одноименные методы объекту Number для упрощения совместной работы с комплексными и реальными числами. То есть предыдущий пример можно записать еще корочеn-ные корни чисел вычисляются все. Результатом является как массив корней комплексных чисел (по умолчанию), так и массив аргументов комплексных чисел и общий модуль как свойство abs результирующего массива (аргументы корней определены на интервале от -pi до +pi):В общем, никому ненужный модуль. Баловство одно. Code (JavaScript): | скопировать код в буфер обмена | /** * Constructor of the complex in the cartesian coordinates (x, y) * z = x + iy * */ function Complex() {
var self = this;
// Cartesian notation // z = x + iy var x; var y;
// Polar notation // z = r (cos(f) + i sin(f)) // z = r exp(if) var r; var f;
// Initialization x = Number(arguments[0]) || 0; y = Number(arguments[1]) || 0;
if ( arguments.callee.caller == Complex.construct ) { r = Number(arguments[2]); f = Number(arguments[3]); } else { r = Math.sqrt(x * x + y * y); f = Math.atan2(y, x); }
// Normalization within the left-opened interval (-pi +pi] if ( f > Math.PI || f <= -Math.PI ) { var pi2 = 2 * Math.PI;
f += Math.PI; f -= Math.floor(f / pi2) * pi2; f -= Math.PI; }
/** * Comparison of complex * */ self.equals = function(z) { return x == z.re() && y == z.im(); };
/** * True if the complex is real * */ self.isReal = function() { return y == 0; };
/** * Re(z) = x * */ self.re = function() { return x; };
/** * Im(z) = y * */ self.im = function() { return y; };
/** * Module (absolute value) of z * |z| = sqrt(x^2 + y^2) * */ self.abs = function() { return r; };
/** * Argument of z * Arg(z) = arctg(y / x) * */ self.arg = function() { return f; };
/** * Complex conjugate * z = x + iy * z' = x - iy * */ self.conj = function() { return Complex.construct(x, -y, r, -f); };
/** * Complex negative * */ self.neg = function() { return Complex.construct(-x, -y, r, r ? f + Math.PI : 0); };
/** * Add * */ self.add = function() { var x1 = x; var y1 = y; for (var i = 0; i < arguments.length; i++) { var z = arguments[i]; x1 += z.re(); y1 += z.im(); } return new Complex(x1, y1); };
/** * Substract * */ self.sub = function() { var x1 = x; var y1 = y; for (var i = 0; i < arguments.length; i++) { var z = arguments[i]; x1 -= z.re(); y1 -= z.im(); } return new Complex(x1, y1); };
/** * Multiply * */ self.mul = function() { var r1 = r; var f1 = f; for (var i = 0; i < arguments.length; i++) { var z = arguments[i]; r1 *= z.abs(); f1 += z.arg(); } return Complex.fromPolar(r1, f1); };
/** * Divide * */ self.div = function() { var r1 = r; var f1 = f; for (var i = 0; i < arguments.length; i++) { var z = arguments[i]; r1 /= z.abs(); f1 -= z.arg(); } return Complex.fromPolar(r1, f1); };
/** * Degree z^n * */ self.pow = function(n) { n = Number(n) || 0; return Complex.fromPolar(Math.pow(r, n), f * n); };
/** * Returns the list of n-th roots * */ self.roots = function(n, toPolar) { n = Number(n);
if ( n - Math.floor(n) ) { return Number.NaN; }
var nr = Math.pow(r, 1 / n); var nf = [];
var fi = f / n; var d = Math.PI * 2 / n; n = Math.abs(n); var i = n; while ( i-- ) { nf.push(fi); fi += d; };
if ( toPolar ) { nf.abs = nr; return nf; }
var z = []; for (var i = 0; i < n; i++) { z.push(Complex.fromPolar(nr, nf[i])); }
return z; };
/** * Square root of z * */ self.sqrt = function() { return Complex.fromPolar(Math.sqrt(r), f / 2); };
/** * Exponential exp(z) * */ self.exp = function() { return Complex.fromPolar(Math.exp(x), y); };
/** * Natural logarithm ln(z) * */ self.log = function() { return new Complex(Math.log(r), f); };
/** * Creates a new complex from itself * */ self.z = function() { return Complex.construct(this.re(), this.im(), this.abs(), this.arg()); };
var eps = function(x) { return Math.abs(x) <= Complex.ZERO_THRESHOLD ? 0 : x; };
/** * String presentation of the complex number * If toPolar is true then this method returns the (r, f) pair * Otherwise the (x, y) pair * */ self.toString = function(toPolar) { if ( toPolar ) { return [eps(r), eps(f)].join(' '); }
if ( ! eps(y) ) { return '' + eps(x); }
return [eps(x), y].join('i'); };
};
/** * Zero displaying threshold * ZERO_THRESHOLD = 1e-15 */ Complex.ZERO_THRESHOLD = 1e-15;
/** * Internally used method * */ Complex.construct = function(x, y, r, f) { return new Complex(x, y, r, f); };
/** * Creates a complex from polar coordinates (r, f) * z = r (cos(f) + isin(f)) * z = r exp(if) * */ Complex.fromPolar = function() { var r = Number(arguments[0]) || 0; var f = Number(arguments[1]) || 0;
var x = r * Math.cos(f); var y = r * Math.sin(f);
return Complex.construct(x, y, r, f); };
/** * Creates a complex from a real * */ Complex.re = function() { if ( arguments[0] && arguments[0].constructor != Number ) { throw new TypeError(); }
var n = Number(arguments[0]) || 0; return n.z(); };
/** * Creates imaginary number * */ Complex.im = function() { if ( arguments[0] && arguments[0].constructor != Number ) { throw new TypeError(); }
var y = Number(arguments[0]) || 1; var f = Math.PI / 2; return Complex.construct(0, y, Math.abs(y), y < 0 ? -f : f); };
/** * Clones new complex without calculation of internal variables * */ Complex.z = function(x, y) { return new Complex(x, y); };
/** * Methods for compatibility of Number with Complex * */ Number.prototype.equals = function(z) { return this == z.re() && z.im() == 0; };
Number.prototype.isReal = function() { return true; };
Number.prototype.re = function() { return this; };
Number.prototype.im = function() { return 0; };
Number.prototype.abs = function() { return Math.abs(this); };
Number.prototype.arg = function() { return this >= 0 ? 0 : Math.PI; };
Number.prototype.conj = function() { return this.z(); };
Number.prototype.neg = function() { return (-this).z(); };
Number.prototype.add = function(z) { return this.z().add.apply(this, arguments); };
Number.prototype.sub = function(z) { return this.z().sub.apply(this, arguments); };
Number.prototype.mul = function(z) { return this.z().mul.apply(this, arguments); };
Number.prototype.div = function(z) { return this.z().pow.apply(this, arguments); };
Number.prototype.pow = function(n) { return this.z().pow(n); };
Number.prototype.roots = function(n, toPolar) { return this.z().roots(n, toPolar); };
Number.prototype.sqrt = function() { return this.z().sqrt(); };
Number.prototype.exp = function() { return Math.exp(this).z(); };
Number.prototype.log = function() { return this.z().log(); };
Number.prototype.z = function() { return Complex.construct(this.re(), this.im(), this.abs(), this.arg()); }; |
Last edited by Rumata on Sun Jun 21, 2009 1:57 pm; edited 6 times in total
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sat Jun 13, 2009 2:42 pm (спустя 1 час 43 минуты; написано за 3 минуты 31 секунду)
Post subject:
|
|
Rumata wrote: |
self.neg = function() { return Complex.construct(-x, -y, r, -f); }; | Кажется, тут всё-таки ошибка. К примеру: есть число 1. У него аргумент = 0. После того, как взяли его с обратным знаком (-1), согласно этой формуле аргумент всё равно остаётся 0. А должен быть аргумент PI (ну или -PI). Поэтому, правильная формула должна выглядеть примерно так: Code (JavaScript): | скопировать код в буфер обмена | self.neg = function() { return Complex.construct(-x, -y, r, f>0 ? Math.PI-f : Math.PI-f - 2*Math.PI); }; |
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sat Jun 13, 2009 3:56 pm (спустя 1 час 14 минут; написано за 2 минуты 43 секунды)
Post subject:
|
|
И то верно. Юрий Насретдинов, спасибо за подсказку. Издержки копи-паста. Вот верный вариант:Учитывает действительные числа и "комплексные нули", так что аргументы чисел лежат в интервале (-pi, +pi], а ноль он по всем параметрам ноль.
Last edited by Rumata on Sat Jun 13, 2009 4:31 pm; edited 1 time in total
|
|
Back to top |
|
 |
Александр Михалицын
Модератор
Joined: 23 May 2008
Posts: 1299
Карма: 83 поощрить/наказать
|
Posted: Sat Jun 13, 2009 4:22 pm (спустя 25 минут; написано за 1 минуту 14 секунд)
Post subject:
|
|
Rumata, [+] За хорошую реализацию. М |
| Я думаю самое время переместить эти классы в "склад". Не так ли? Что решим? Оба ваших класса туда выставить? |
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sat Jun 13, 2009 4:22 pm (спустя 30 секунд; написано за 2 минуты 36 секунд)
Post subject:
|
|
Сильно измененная версия, по-максимуму избавленная от непонятных и сложных операций (кроме метода .toString(), который сделан «умным»). Также изменено название класса с Complex на Z для краткости, а также новый способ передачи аргументов функциям: если указывается 2 аргумента, а не 1, то они трактуются как компоненты комплексного числа. Пример: Code (JavaScript): | скопировать код в буфер обмена | var a = new Z(1,2); alert( a.mul(0,1) ); // выведет -2+i
// эквивалентно следующему:
alert( a.mul( new Z(0,1) ) ); // выведет то же самое | Код: Code (JavaScript): | скопировать код в буфер обмена | function Z(x,y,r,f) { this.construct(x,y,r,f); }
Z.prototype = { /* should be read-only properties */ x: 0, y: 0, r: 0, // abs f: 0, // arg construct: function(x,y,r,f) { if(r && r < 0) throw new Error('Absolute value of a complex number cannot be less than zero'); if(r) { x = r*Math.cos(f); y = r*Math.sin(f); } this.x = x; this.y = y; this.r = r || Math.sqrt(x*x+y*y); this.f = Math.atan2(y,x); // guarantees that you get normalized form of arg }, toString: function(polar) { var sign = function(x) { return x<0 ? '-' : '+'; } var sigm = function(x) { return x<0 ? '-' : ''; } // returns "-" or nothing var a = function(x) { return Math.abs(x); } var is0 = this._is0; var is1 = function(x) { return is0(a(x) - 1); } // is |x| == 1 ? var r = this.r, f = this.f, x = this.x, y = this.y; if(is0(r)) return '0'; var ans = ''; if(polar) { var rm = is1(r) ? '': r; var exp = is0(f) ? '' : 'exp('+(is1(f) ? sigm(f)+'i' : sigm(f)+'i*'+a(f))+')'; ans = rm + (!is1(r)&&exp?'*':'') + exp; if(!ans.length) ans+='1'; // either sign (-) or nothing means 1 }else { ans = (is0(x)?'':x)+(is0(y) ? '' : sign(y)+'i'+(is1(y)?'':'*'+a(y))); } return ans; }, mul: function(b) { b = this._pa(b,arguments); var a = this; return new Z(a.x*b.x - a.y*b.y, a.y*b.x + b.y*a.x); }, // complex division: returns (a/b) div: function(b) { b = this._pa(b,arguments); // a/b = a*(b*) / |b|^2, where b* = Re b - i*Im b if(!b.r) throw new Error('Complex division by zero'); return this.mul( b.x/b.r/b.r, -b.y/b.r/b.r ) }, add: function(b) { b = this._pa(b,arguments); return new Z( this.x + b.x, this.y + b.y ); }, // z - b sub: function(b) { b = this._pa(b,arguments); return new Z( this.x - b.x, this.y - b.y); }, neg: function() { return new Z( -this.x, -this.y ); }, conj: function() { return new Z( this.x, -this.y ); }, // is*() return BOOL isEqual: function(b) { b = this._pa(b,arguments); return this._is0(b.x - this.x) && this._is0(b.y - this.y); }, isReal: function() { return this._is0(this.y); }, isIm: function() { return this._is0(this.x); }, // power: z^b (b is complex!) pow: function(b) { b = this._pa(b,arguments); // z^a = exp(a * log(z) ) return b.mul( this.log() ).exp(); }, // complex logarithm of a number // the result is given only for _main_ branch of the logarithm // if you want other branches, add or subtract 2*PI*i as many times as you want log: function() { return new Z( Math.log(this.r), this.f ); }, // alias for log ln: function() { return this.log(); }, // exp(z), z is complex exp: function() { return new Z(0, 0, Math.exp(this.x), this.y ); }, // sin(z) sin: function() { var z = this; var z1 = z.mul(0,1); var z2 = z1.neg(); return ( z1.exp() ).sub( z2.exp() ).div(0,2); }, // cos(z) cos: function() { var z = this; var z1 = z.mul(0,1); var z2 = z1.neg(); return ( z1.exp() ).add( z2.exp() ).div(2,0); }, // check, if the method of Z with name mname // is differentiable at point z // // _diff_delta and _diff_eps are the value of delta in formula f'(x) = (f(x+delta)-f(x))/delta // and the value of epsilon when f'(x-0) is compared to f'(x+0) and other // derivatives comparison _diff_delta: Math.pow(2, -25), _diff_eps: Math.pow(2, -15), is_diff: function(mname, alert_reason) { try { var der = this.deriv(mname); }catch(e) { if(alert_reason) alert(e); return false; } return true; }, deriv: function(mname) { var z = this; var x0 = z.x, y0 = z.y; // the idea is that a complex function is differentiable if // the Cauchy-Riemann conditions are satisfied // f(z) = u(x,y) + i*v(x,y) // // define real functions of 1 argument try { var ux = this._deriv( function(x){ return (new Z(x,y0))[mname]().x; }, x0, 'ux', mname); // u'(x,y0)|x=x0 var uy = this._deriv( function(y){ return (new Z(x0,y))[mname]().x; }, y0, 'uy', mname); // u'(x0,y)|y=y0 var vx = this._deriv( function(x){ return (new Z(x,y0))[mname]().y; }, x0, 'vx', mname); // v'(x,y0)|x=x0 var vy = this._deriv( function(y){ return (new Z(x0,y))[mname]().y; }, y0, 'vy', mname); // v'(x0,y)|y=y0 }catch(e) { // there is only 1 case when the exception is thrown: when a real function is non-diff throw e; } var damp = Math.max(Math.abs(ux), Math.abs(uy), Math.abs(vx), Math.abs(vy)); // damping factor to take scale of variables into account if(damp < 1) damp = 1; if( !this._diff_is0( (ux-vy)/damp ) || !this._diff_is0( (uy+vx)/damp ) ) throw new Error('Cauchy-Riemann conditions for '+mname+' are not met (ux-vy='+(ux-vy)+', uy+vx='+(uy+vx)+')'); return new Z(ux, vx); }, // count the derivative of a real function func // at real point x _deriv: function(func, x, fname, mname) { var delta = this._diff_delta; // the function of x must not oscillate faster than 1/delta if(Math.abs(x) > 1) delta *= Math.abs(x); // coefficient for delta and epsilon to take scale into account var left_der = (func(x) - func(x - delta)) / delta; var right_der = (func(x + delta) - func(x)) / delta; var damp = Math.max(Math.abs(left_der), Math.abs(right_der)); // damping factor to take scale of variables into account if(damp < 1) damp = 1; if( ! this._diff_is0( (left_der - right_der) / damp) ) throw new Error('The function '+fname+' of '+mname+' is non-differentiable (left_der - right_der = '+(left_der - right_der)+', left_der = '+(left_der)+', right_der = '+(right_der)+')'); // the function is not differentiable in that point return (left_der + right_der)/2; }, _pa: function(b,args) // _parseArguments -- returns new b if needed { if(args.length==2) b = new Z(args[0], args[1]); if(b.length && b.length == 2) b = new Z(b[0],b[1]); if(!b instanceof Z) b = new Z(b,0); return b; }, _is0: function(x) { return Math.abs(x) < 1e-15; }, _diff_is0: function(x) { return Math.abs(x) < this._diff_eps; }
};
Z.ONE = new Z(1,0); Z.I = new Z(0,1);
var sq_eq_solver = { // a, b, c -- complex numbers // // another difference -- if a==0,b!=0 the answer is returned in format [ z ] // returns [z1, z2], where z1 and z2 are the roots solve: function(a,b,c) { if(!a.r) return b.r ? c.div(b).neg() : !c.r; // scale coeffs so, that a=0.5 and x1,x2 = ( -b +- sqrt(D) ); ( 1/2a == 1) var two_a_i = new Z(0.5,0).div(a); // 1/2a a=new Z(0.5,0); b=b.mul(two_a_i); // b = b*(1/2a) c=c.mul(two_a_i); // c = c*(1/2a) var D = b.mul(b).sub( c.mul(2,0) ); // var D = b*b - 2*c; var sqD = D.pow(1/2,0); var nb = b.neg(); return [nb.add(sqD), nb.sub(sqD)]; } };
alert( sq_eq_solver.solve( new Z(2,0) , new Z(-8,-6), new Z(-4,16) ) ); // var a = new Z(1,2); alert( a.mul(0,1) ); // alert('check, if are differentiable:\n\n' + 'sin: '+(new Z(100,100)).is_diff('sin', 1) + '\n' + 'cos: '+(new Z(100,100)).is_diff('cos', 1) + '\n' + 'exp: '+(new Z(100,100)).is_diff('exp', 1) + '\n' + 'conj: '+(new Z(5e10,5e10)).is_diff('conj', 1) + '\n' + 'neg: '+(new Z(5000,5000)).is_diff('neg', 1) + '\n' + 'log: '+(new Z(5000,5000)).is_diff('log', 1) + '\n' + ''); |
Last edited by Юрий Насретдинов on Tue Jun 16, 2009 3:31 pm; edited 11 times in total
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sat Jun 13, 2009 4:32 pm (спустя 10 минут; написано за 3 минуты 1 секунду)
Post subject:
|
|
Rumata wrote: |
self.neg = function() { return Complex.construct(-x, -y, r, x || y ? -f || Math.PI : 0); }; | И всё равно «не то»... Сравните: Code (JavaScript): | скопировать код в буфер обмена | var a = new Z(1,1.5); var b = new Complex(1,1.5); alert(a.neg().toString(true) + ' vs. ' + b.neg().toString(true));
// выведет 1.8027756377319946*exp(-i*2.158798930342464) vs. 1.8027756377319946 -0.982793723247329 | Лучше в таком случае просто Math.atan2() используйте напрямую:Простая же задача, вот смотрите: -1 = exp(i*PI) = exp(-i*PI) -1*r*exp(i*f) = exp(-i*PI)*r*exp(i*f) = r*exp(i*(f-PI)); Откуда у Вас берется просто «-f»??
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sat Jun 13, 2009 4:44 pm (спустя 11 минут; написано за 9 секунд)
Post subject:
|
|
Юрий Насретдинов wrote: |
Также изменено название класса с Complex на Z для краткости, а также новый способ передачи аргументов функциям: если указывается 2 аргумента, а не 1, то они трактуются как компоненты комплексного числа. | Очень понравилась идея с аргументами. А также можно массив двух элементов трактовать как комплексное число, и т.д (-:. Немного спорно переименование, но, в-целом, тоже нравится. Мне больше нравится "сливать" всякие вычисления в eval, например:
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sat Jun 13, 2009 4:52 pm (спустя 8 минут; написано за 8 секунд)
Post subject:
|
|
Юрий Насретдинов wrote: |
И всё равно «не то | А-а-а! Шайтан!
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sat Jun 13, 2009 4:53 pm (спустя 46 секунд; написано за 5 секунд)
Post subject:
|
|
Rumata wrote: |
eval.equ2 = fucntion(a, b, c) ... var x = eval.equ2(1, 1, -1); | Да, идея прикольная :). Rumata wrote: |
А также можно массив двух элементов трактовать как комплексное число, и т.д (-:. | И т.д., к сожалению, лень, но вот про массив из двух элементов добавил :).
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sat Jun 13, 2009 5:11 pm (спустя 18 минут; написано за 55 секунд)
Post subject:
|
|
Rumata wrote: |
self.neg = function() { return Complex.construct(-x, -y, r, r ? f + Math.PI : 0); }; | Хехе :). А если f > 0, то у Вас получится, что новый аргумент выходит за границы (-pi, pi], что как бы не очень здорово (а при извлечении корня так вообще губительно).
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sat Jun 13, 2009 5:24 pm (спустя 12 минут; написано за 30 секунд)
Post subject:
|
|
Юрий Насретдинов wrote: |
И всё равно «не то»... | Я всячески не хотел делать вычисления компонентов (корни, квадраты, арктангенсы), поэтому у меня вылезло -f, когда надо было f+PI или f-PI. Или опять ошибка? Юрий Насретдинов wrote: |
если f > 0, то у Вас получится, что новый аргумен | Не выходит. Учтено изначально в Complex.construct.
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sat Jun 13, 2009 5:36 pm (спустя 12 минут; написано за 1 минуту 9 секунд)
Post subject:
|
|
Rumata wrote: |
Я всячески не хотел делать вычисления компонентов (корни, квадраты, арктангенсы), поэтому у меня вылезло -f, когда надо было f+PI или f-PI. Или опять ошибка? | Да, вроде бы теперь нормально, с учетом проверки в конструкторе. В моем классе таких проблем чисто в принципе не возникло, потому что у меня в конструкторе значения r и f в основном синтезируются на основе x и y, а не считаются вручную :).
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sat Jun 13, 2009 5:54 pm (спустя 18 минут; написано за 8 минут 54 секунды)
Post subject:
|
|
Да. Когда я начал реализовывать свой класс, у меня возникла мысль, что неплохо бы вычислять сразу все части числа, тогда код усложняется ненамного, а преимущества видны сразу - инициализация объекта комплексного числа готовыми полями для исключения некоторых вычислений (например, при умножении используются модули и аргументы перемножаемых чисел). Насколько это оправдано, сказать сложно. Оба представления (x, y) и (r, f) - равнозначны и при выборе только одного представления неизбежна операция перевода из одного в другое. Ну а эта путаница - conj() и neg() была создана бездумным копированием и исправлением первого из второй.
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Sat Jun 13, 2009 6:12 pm (спустя 18 минут; написано за 4 минуты)
Post subject:
|
|
Rumata
«Но и это ещё не всё» © Нормализация аргумента сделана тоже некорректно :) (я это заметил, когда добавил нормализацию аргумента в свой конструктор)! Смотрите: Code (JavaScript): | скопировать код в буфер обмена | var a = new Z(0,0,1,2.5*Math.PI); alert(a.toString(true));
var b = Complex.fromPolar(1,2.5*Math.PI); alert( b.toString(true) ); | Аргумент (правильный) должен быть PI/2. А в Вашей реализации это -PI/2, что соответствует смене знака у числа :). Я, поэтому, некоторую хитрость добавил: Code (JavaScript): | скопировать код в буфер обмена | // normalize argument if(Math.abs(f) >= Math.PI) { f+=Math.PI; f-=Math.floor(f/2/Math.PI)*2*Math.PI; f-=Math.PI; } | Т.е. для нормализации сначала переводится к интервалу [0; 2*PI], потом аргумент нормализуется в таком интервале, а потом интервал возвращается обратно к [-PI, PI]. Границы эта вещь не учитывает, но ИМХО они не настолько важны, особенно в вычислительной технике.
|
|
Back to top |
|
 |
Юрий Насретдинов
Модератор

Joined: 13 Mar 2003
Posts: 8642
Карма: 198 поощрить/наказать
Location: 007 495
|
Posted: Tue Jun 16, 2009 3:08 pm (спустя 2 дня 20 часов 55 минут; написано за 6 минут 8 секунд)
Post subject:
|
|
Добавил в класс также проверку на дифференцируемость функции комплексного переменного, а также на подсчет производной от этой функции в случае её дифференцируемости. Пример: Code (JavaScript): | скопировать код в буфер обмена | Z.prototype.tan = function() { return this.sin().div( this.cos() ); }
var tp = new Z(3,5); // test point
alert( tp.deriv('tan') + ' vs. ' + Z.ONE.div( tp.cos().pow(2,0) ) ); // ( tan(z) )' = 1 / (cos(z))^2
alert('Is complex conjugation differentiable: '+tp.is_diff('conj')); | Если Вы попытаетесь посчитать производную от функции, которая не дифференцируема в этой точке, выпадет исключение наподобие (Error: Cauchy-Riemann conditions for conj are not met (ux-vy=2, uy+vx=0) или The function ux of some_func is non-differentiable (left_der - right_der = ..., left_der = ..., right_der = ...) ). Готов выслушать ваши мнения по этому поводу :).
|
|
Back to top |
|
 |
Rumata
Профессионал

Joined: 17 Aug 2003
Posts: 1850
Карма: 185 поощрить/наказать
|
Posted: Sun Jun 21, 2009 2:05 pm (спустя 4 дня 22 часа 56 минут; написано за 25 секунд)
Post subject:
|
|
Юрий Насретдинов wrote: |
Но и это ещё не всё |
|
|
Back to top |
|
 |
|