LINUX.ORG.RU

Python: «склейка нескольких» ф-ций в одну


0

1

Есть, например, ф-ция y = (5*f + x)^n, где x и n - переменные. Эта ф-ция в другой Int1 находится под интегралом. Проблема в том, что при одном вызове x,n может быть несколько, тогда под интегралом должно стоять произведение этих ф-ций!!! _не_их_значения_ со своими параметрами. Например, (параметры передаю ввиде списка - первый x, второй - n) передаю в Int1 [ [2,3], [4,5] ], значит надо под интегралом как бы «склеить» путем произведения ф-ции (чтоб не вычислялись их значения) с разными x,n - ((5*f + 2)^3)*((5*f + 4)^5).


Попробуй еще раз. Ладно?

Я не понял " тогда под интегралом должно стоять произведение этих ф-ций!!! _не_их_значения_ "

У тебя ленивые вычисления ии что? Кто тебе мешает записать h = {'a':sin,'b':cos}

А потом написать x = 10; print h['a'](x)*h['b'](x) ?

demmsnt
()
Ответ на: комментарий от demmsnt

У него есть 2*x и 2*x он хочет 4x^2

Тут не ленивые вычисления, тут компьютерная алгебра какая-то.

ТС, хочешь maxima на педоне написать?

Zorn
()

sympy написали же

anonymous
()

«склеить» путем произведения ф-ции (чтоб не вычислялись их значения)

Теперь я не понял. Тебе нужна алгебра, или просто подействовать функцией на результат другой функции. Если последнее, реализуй композицию. В общем случае может не просто, но в частном - раз плюнуть

Zorn
()
Ответ на: комментарий от demmsnt

Ф-ция одна (5*f + x)^n. Количество аргументов, т.е. пар (x,n), может быть много при вызове. Тогда должно быть произведение этих ф-ций с этими аргументами. Все в динамике.

drZlo
() автор топика
Ответ на: комментарий от Zorn

Алгебру с пол пинка не сделать. Хотя можно фронтенд запилить для этой веб как её... железка какая, то вольфрам ВО!

demmsnt
()
Ответ на: комментарий от Zorn

Мне нужно чтоб под интегралом было не произведение значений ф-ций, а символьное, что ли, их произведение. Количество произведений определяется динамически, в зависимости от количества аргументов.

drZlo
() автор топика
Ответ на: комментарий от drZlo

Тоже боюсь, что не донца понял: но может быть вам нужно переменное число параметров: def fun(*args) ... в args будет список - делаете нужный reduce с вызовом ф-ии у перемножением.

anonymous
()
Ответ на: комментарий от drZlo

Хотя если функция у тебя всего-то y=(a*x+b)^n можешь воспользоваться формулой бинома Ньютона, а потом собирать члены с одинаковыми степенями.

Ну а int (x^n,x) = x^(n+1)/(n+1). Далее интеграл подсчитать численно, ну или что там с ним делать. При твоём виде функции фигня задача

Zorn
()
Ответ на: комментарий от drZlo

Тебе значения вообще кода нужны будут?

Может ты тупо напишешь:

F=«$x*$z^$a»

r = «»

for i in abc: r = r+"(«+i+»)*"

а потом сделаешь: r = r.replace(«$r»,«200»)

А потом вычислишь? Я вот телепат не того уровня еще.

Опиши задачу, а не до чего ты дошел....

demmsnt
()
Ответ на: комментарий от Zorn

Ну и перемножение многочленов реализовать, да. Не факт, что это оптимально, но это первое, что пришло в голову

Zorn
()

Негодовать, где формулы в латекс на этом форуме?

Zorn
()
Ответ на: комментарий от Zorn

Да все проще. Я пользую scipy.integrate. В ней под интегралом должно быть, либо (5*f + x)^ndf, либо ((5*f + x)^n)*((5*f + x)^n)df, либо ((5*f + x)^n)*...*((5*f + x)^n)df в зависимости от количества пар (x,n) и все (x,n) - конкретные значения.

drZlo
() автор топика
Ответ на: комментарий от drZlo

Без понятия, что это. Либо делай как я и тогда получишь функцию - интеграл от произведения исходный, либо когда ты заранее знаешь аргумент для этой функции и хочешь число, делай как сказал человек на мотоцикле

Zorn
()
Ответ на: комментарий от demmsnt

Специальную олимпиаду объявляю открытой:

(defmacro powern (n) `#'(lambda (x) (* ,@(loop for i below n collect 'x))))

(funcall (powern 3) 2)

8

Может так питон? ;)

Zorn
()
Ответ на: комментарий от demmsnt

В общем так:

def Int1(list_param):
   size = len(list_param)
   Y = lambda f,x,n: (5*f+x)**n
   .... здесь не знаю что :)
   c=quad(lambda f,x,n : (5*f+x)**n, 0, 0.5, args=(1, 2))[0]

list_param - это список пар x и n. Например, list_param = [ [2,3], [4,5] ] Так вот, используя size надо так замутить, чтоб под quad было size произведений подинтегральных ф-ций. Например для указанного list_param хочу:

c=quad(lambda f,x,n : ((5*f+2)**3)*((5*f+4)**5), 0, 0.5,args=???)[0]
Но, это должно быть в динамике, само так «склеиваться».

drZlo
() автор топика
Ответ на: комментарий от Zorn

плохо парсю. Я еще не того уровня эльф.

Я понял, что ты в макрос запихнул 3. А куда запихнул два не понял. В рукав?

И еще я не совсем понимаю что такое макрос. Если это типа eval от строки, то это не очень хорошо.

demmsnt
()
Ответ на: комментарий от demmsnt

Если это типа eval от строки, то это не очень хорошо.

Понты кидает: вводит элемент синтаксиса, который заменяет аргументы на месте.

anonymous
()
Ответ на: комментарий от drZlo

c=quad(lambda f,x,n : (5*f+x)**n, 0, 0.5, args=(1, 2))[0]

дык используй reduce по list_param (а вообще лямбда - это сахарок: можно бы было бы ведь написать нормальную ф-ию, которая возведет и перемножит).

anonymous
()
Ответ на: комментарий от drZlo

а зачем ты в квад лямбда запихал. У тебя и получается

list_param = [ [2,3], [4,5] ]
l = lambda f: 1
for i in list_param:
    l = lambda f: ((5*f+i[0])**i[1])*l(f)

так? list_param вставили. А f торчит внаружу.... а и что такое f?

demmsnt
()
Ответ на: комментарий от drZlo

Сделай как я написал, это тупо, но будет работать. Смотри:

Определить-функцию перемножить-многочлены (м1 м2):
    let м3 - многочлен
    цикл по n1 от 0 до max-power (м1):
        цикл по n2 от 0 до max-power (м2):
            коэфф (м3, n1+n2) += коэфф (м1, n1)*коэфф(м2,n2)
    return м3

Определить-функцию разложить-в многочлен (a,b,n):
// Раскладывает степень (a*x+b)^n в многочлен по формуле бинома Ньютона

Многочлен определи как список коэффициентов, где индекс - данная степень, например (0 0 3 5) - это 5*x^3+3*x^2

Тупо? Тупо, но чего ты хочешь от меня) К тому же ты не предъявил юзкейс. Когда произведений много, это, естественно, будет тормозить

Zorn
()
Ответ на: комментарий от anonymous

Аааа но я не распарсил где там аргументы и что заменяет.

Вообще это очень хорошие штуки. Очень.

demmsnt
()
Ответ на: комментарий от demmsnt

f - переменная интегрирования $\int\limits_0^{0.5}(5*f+x)^ndf$, кто-то просил )

drZlo
() автор топика
Ответ на: комментарий от Zorn

Может так питон? ;)

>>> def powern(n): return lambda x: x ** n
... 
>>> powern(3)(2)
8

тут макросы - оверкил. Символьные вычисления вообще (дифференцирование / интегрирование, например) - возможно, в SICP про это есть.

quasimoto ★★★★
()
Ответ на: комментарий от demmsnt

Макрос - такое выражение, которое в момент компиляции (не в момент исполнения) разворачивается во некий список с коммандами:

Этот развернется в

(macroexpand-1 '(powern 5))

#'(lambda (x) (* x x x x x))

И соответственно мы вычислим уже (после того как всё развернется)

(funcall #'(lambda (x) (* x x x x x)) 2)

Макросы хороши тем, что позволяют избавиться ото всякого копипаста и прочего. Если бы не было функции expt, возводящей в степень, пришлось бы пастить x n раз) А с макросам этого можно избежать.

// Ща набегут лисперы и скажут, что я нифига не понимаю. Я не понимаю, но я их использую)

Zorn
()
Ответ на: комментарий от Zorn

Аааааа. Ну питон интерпретатор. Хотя возможно при компиляци в байткод.

А мой пример то, что нужно? В итоге ведь получим функцию состоящую из членов из этого лист

demmsnt
()
Ответ на: комментарий от quasimoto

Это просто было ответ-шутка про «набирай что-то пока не надоест»

Символьные вычисления вообще где хочешь можно запилить, было бы желание

Zorn
()
Ответ на: комментарий от Zorn

Я тут ООП пытался к 1С 8 прикрутить.....

Не получается. А жаль.

demmsnt
()
Ответ на: комментарий от demmsnt

Python: «склейка нескольких» ф-ций в одну (комментарий)

Этот пример? Я боюсь - нет, тут ты всё-таки с числами оперируешь, а надо с многочленами, а более общо - просто с некими символами

Ему надо интегрировать функцию, а не её результат

Zorn
()
Ответ на: комментарий от Zorn

Постой паровоз. Оно не вычислится пока ему f не даш.

Это анонимная функция.

demmsnt
()
Ответ на: комментарий от Zorn

Не умеет я так и подумал ибо этапа их вычисления не вижу.

demmsnt
()
Ответ на: комментарий от drZlo

Вообще-то, by design, то что в def лениво), так сойдет?:

def product(f):
    acc = 1
    for (x,n) in list_param:
        acc *= (5*f + x) ** n
    return acc

c = quad(product, 0, 0.5)[0]

(args можно не передавать, list_param в области видимости product)

anonymous
()

А почему просто не использовать в качестве возвращаемого значения строку? А потом уже этой строке, если надо, сделать eval, exec, или как он у вас там... Слишком медленно получится?

A26
()
Ответ на: комментарий от A26

а в строке rm / ?

Всетаки это то чем различается лямбда от темплейта. Там x есть x. А ребенок не сможет стать ' drop database;

demmsnt
()
Ответ на: комментарий от Zorn

Я один, кто пишет пример? Ааа. Давайте устроим олимпиаду

Специальную, надеюсь? Что конкретно пример должен делать?

anonymous
()
Ответ на: комментарий от anonymous

Специальную, конечно

Вернуть функцию от x являющуюся интегралом (неопределенным) произведения членов вида

(a*x+b)^n

Например int((2*x+4)^3*(4*x+2)^4),x)

Ща предоставлю код

Zorn
()
Ответ на: комментарий от Zorn

неопределенным

Произвольную константу положить 0

Zorn
()
Ответ на: комментарий от Zorn

произведения членов вида

То есть написать элемент computer-algebra? А именно раскрыть полиномы.

anonymous
()
Ответ на: Пример от Zorn

Работает так.

Полином - это лист, где индекс - степень, элемент - коэффициент при степени.

Ты берешь твою функцию (2*x+5)^2

Скармливаешь её (newton 2 5 2) и получаешь

(25 20 4), что значит 4*x^2+20*x+25

Далее перемножаешь полиномы с помощью #'mulpoly и интегрируешь с помощью #'intpoly (там небольшая ошибка, исправь сам;)

Из конечного листа легко збацать функцию (используй замыкания)

Zorn
()
Ответ на: комментарий от Zorn

[code=haskell] int poly = zipWith (/) (expand [1] poly) [1..]

expand acc ((a,b,0):rest) = expand acc rest expand acc ((a,b,n):rest) = expand acc' ((a,b,(n-1)):rest) where acc' = zipWith (+) (0 : map (*a) acc) (map (*b) acc ++ [0]) expand acc [] = acc [/code]

int [(2,5,2)] -> [25.0,10.0,1.3333333333333333] (коэф-ы при x, x^2, x^3)

anonymous
()
Ответ на: комментарий от anonymous
 int poly = zipWith (/) (expand [1] poly) [1..]

expand acc ((a,b,0):rest) = expand acc rest expand acc ((a,b,n):rest) = expand acc' ((a,b,(n-1)):rest) where acc' = zipWith (+) (0 : map (*a) acc) (map (*b) acc ++ [0]) expand acc [] = acc 

int [(2,5,2)] -> [25.0,10.0,1.3333333333333333] (коэф-ы при x, x^2, x^3)

anonymous
()
Ответ на: комментарий от Zorn
int poly = zipWith (/) (expand [1] poly) [1..]

expand acc ((a,b,0):rest) = expand acc rest
expand acc ((a,b,n):rest) = expand acc' ((a,b,(n-1)):rest)
    where acc' = zipWith (+) (0 : map (*a) acc) (map (*b) acc ++ [0])
expand acc [] = acc

int [(2,5,2)] -> [25.0,10.0,1.3333333333333333] (коэф-ы при x, x^2, x^3)

// извиняюсь

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.