I have set of arrays
[0.21, 0.21, 0.21, 0.21] as a,
[0.31, 0.31, 0.31, 0.31] as b,
[0.48, 0.48, 0.48, 0.48] as c
If you notice, a1+b1+c1 = 1 (where a1 is the first element of array a).
I want to implement a rounding wherein the answer is
[0, 0, 1, 0] for a
[0, 1, 0, 0] for b
[1, 0, 0, 1] for c
Step 1.
Do a round function for a1, b1, c1 -> this will give us a value of a1=0, b1=0 and c1=0 (resulting in a carryforward value of 0.21, 0.31 and 0.48 for next set of values i.e., a2, b2, and c2.
Step 2.
However since after Step 1, the round(a1) + round(b1) + round(c1) < a1+b1+c1, the idea is to roundup the element that got rounded down the maximum (so that we get the rounded sum equal to sum of unrounded values) and then carry forward the excess to decrement from the next value.
For e.g.
after the first allocation, c1 will get rounded up to 1 (getting an excess of 0.52 which we should decrement from c2 0.48-0.52=-0.04). Similarly, since a1 and b1 were 0 and 0 after rounding, we will carryforward 0.21 and 0.31 to a2, b2 giving us a2=0.21+0.21=0.42 and b2=0.31+0.31=0.62 and c2=0.48-0.52=-0.04
Step 3:
Repeat Step 1 for 2nd elements, which in this case will become round(a2) = round(0.42) =0, round(b2) = round(0.62)=1, round(c2)=round(-0.04) = 0.
Carryforwrd the difference, from a2 -> 0.42, from b2 -> -0.38, from c2 = -0.04 to next element
a3 will become 0.21 + 0.42 = 0.63, b3 will become =0.31-0.38 = -0.07, and c3 will become 0.48 - 0.04 = 0.44
After rounding the 3rd element, a3 round will become 1, b3 -> 0, c3 -> 0
... and so on so forth.
Is there any way we can do this using the all-powerful arrays?
It's not a well-suited task for ClickHouse, but you can utilize the fact that an array won't be splitted into two rows and use a custom function to process the array.
The idea is simple. First assemble three arrays into an array of array using groupArrayForEach. So
[0.21, 0.21, 0.21, 0.21] as a,
[0.31, 0.31, 0.31, 0.31] as b,
[0.48, 0.48, 0.48, 0.48] as c
becomes
[[0.21, 0.31, 0.48], [0.21, 0.31, 0.48], [0.21, 0.31, 0.48]]
Then create a arrayReduce like function that does Carry Forward Rounding. Take a look at how arrayReduce is implemented in https://github.com/yandex/ClickHouse/blob/master/dbms/src/Functions/arrayReduce.cpp#L169
In fact you don't need an aggregator, a simple loop should be enough.
It would be better if ClickHouse supports stateful lambdas. I'd expect something like this
select
arrayCum
(
arr, old_carry =>
with
arrayMap(x, y -> x + y, arr, old_carry) as arr,
arrayEnumerate(arr) as idx,
arrayReduce('max', arr) as m
arrayFirstIndex(e -> e = m, arr) as i,
arrayMap(j -> if(i = j, 1, 0), idx) as rounded,
arrayMap(x, y -> x - y, arr, rounded) as carry
--
rounded, carry
, arr, arrayMap(x -> 0, arr)
)
from
( select groupArrayForEach(a) arr from data )
Related
I'm new to Mathematica, and I'm trying to solve a matrix equation in a form as
AX = \lambda BX
Here, Aand B are 4*4 matrices in the following, \lambda is a value, Xis the eigenvector- 4*1 matrix.
A = {{a1 + b1, c, d, f},
{c, a2 + b2 , f , e},
{d , f , a3 + b1 , c},
{ f, e , c, a4 + b2}}
B = {{1, 0, 0 , 0},
{0, 1 , 0 , 0},
{0 , 0 , -1 , 0},
{0, 0 , 0, -1}}
I would like to solve this matrix equation and get the symbolical solution for \lambda using a1,a2,a3,a4,b1,b2,c,d,e,f, etc.
It would be much grateful if anyone can tell me.
Best regards,
mike
See Wolfram: Matrix Computations - specifically the section 'Generalized Eigenvalues'.
For n×n matrices A, B the generalized eigenvalues are the n
roots of its characteristic polynomial, p(𝛇) = det(A - 𝛇 B). For
each generalized eigenvalue, λ ∊ λ(A, B), the vectors, 𝛇, that
satisfy
A χ = λ B χ
are described as generalized eigenvectors.
Example using symbolic values:
matA = {{a11, a12}, {a21, a22}};
matB = {{b11, b12}, {b21, b22}};
Eigenvalues[{matA, matB}]
{(1/(2 (-b12 b21+b11 b22)))(a22 b11-a21 b12-a12 b21+a11 b22-Sqrt[(-a22 b11+a21 b12+a12 b21-a11 b22)^2-4 (-a12 a21+a11 a22) (-b12 b21+b11 b22)]),(1/(2 (-b12 b21+b11 b22)))(a22 b11-a21 b12-a12 b21+a11 b22+Sqrt[(-a22 b11+a21 b12+a12 b21-a11 b22)^2-4 (-a12 a21+a11 a22) (-b12 b21+b11 b22)])}
Eigenvectors[{matA, matB}]
...
I'm trying to find the coefficients of a function by minimizing an equation who I know is zero with Mathematica. My code is:
Clear[f];
Clear[g];
Clear[GetGood];
Clear[int];
Clear[xlist];
Xmax = 10;
n = 10;
dx = Xmax/n;
xlist = Table[i*dx, {i, n}];
A = 3.5;
slope = (A + 2)/3;
f[x_, a_, b_, c_, d_, e_] :=a/(1 + b*x + c*x^2 + d*x^3 + e*x^4)^(slope/4 + 2);
g[x_, a_, b_, c_, d_, e_] :=Derivative[1, 0, 0, 0, 0, 0][f][x, a, b, c, d, e];
int[a_?NumericQ, b_?NumericQ, c_?NumericQ, d_?NumericQ, e_?NumericQ] :=
Module[{ans, i},ans = 0;Do[ans =ans + Quiet[NIntegrate[
y^-slope*(f[Sqrt[xlist[[i]]^2 + y^2 + 2*xlist[[i]]*y*m], a, b,
c, d, e] - f[xlist[[i]], a, b, c, d, e]), {m, -1, 1}, {y,
10^-8, \[Infinity]}, MaxRecursion -> 30]], {i, 1,
Length[xlist]}];
ans
];
GetGood[a_?NumericQ, b_?NumericQ, c_?NumericQ, d_?NumericQ,e_?NumericQ] :=
Module[{ans},ans = Abs[Sum[3*f[x, a, b, c, d, e] + x*g[x, a, b, c, d,e],
{x,xlist}]+2*Pi*int[a, b, c, d, e]];
ans
];
NMinimize[{GetGood[a, b, c, d, e], a > 0, b > 0, c > 0, d > 0,
e > 0}, {a, b, c, d, e}]
The error I get after the last line is:
Part::pspec: Part specification i$3002170 is neither an integer nor a list of integers. >>
NIntegrate::inumr: "The integrand (-(1.84529/(1+<<3>>+0.595769 Part[<<2>>]^4)^2.45833)+1.84529/(1+<<18>> Sqrt[Plus[<<3>>]]+<<1>>+<<1>>+0.595769 Plus[<<3>>]^2)^2.45833)/y^1.83333 has evaluated to non-numerical values for all sampling points in the region with boundaries {{-1,1},{\[Infinity],1.*10^-8}}"
Any ideas why I am getting an error?
Thanks
Change your NMinimize to be
NMinimize[{GetGood[a,b,c,d,e],a>0&&b>0&&c>0&&d>0&&e>0}, {a,b,c,d,e}]
to get your constraints to work correctly. Their help page should really show an example of using more than a single constraint. This old page does show an example.
http://reference.wolfram.com/legacy/v5_2/functions/AdvancedDocumentationNMinimize
If you change your int[] to
int[a_?NumericQ, b_?NumericQ, c_?NumericQ, d_?NumericQ, e_?NumericQ] :=
Module[{ans, i}, ans = 0; Do[
Print["First i=", i];
ans = ans + Quiet[NIntegrate[
Print["Second i=", i];
y^-slope*(f[Sqrt[xlist[[i]]^2 + y^2 + 2*xlist[[i]]*y*m], a,b,c,d,e] -
f[xlist[[i]], a,b,c,d,e]), {m,-1,1}, {y,10^-8, \[Infinity]}, MaxRecursion -> 30]],
{i, 1, Length[xlist]}];
ans];
you will see
First i=1
Second i=1
....
First i=10
Second i=i$28850
where the first debug print never says i=i$nnnn but the second debug print does often show that i has been unassigned a value only inside your NIntegrate, not outside it, and only after i has reached a value of 10, the length of your xlist, and at that point you can't subscript by a symbol and you get the error messages you have seen.
Nothing inside your NIntegrate is changing the value of i.
I think you may have stumbled onto a bug where Mathematica is writing over the value of i.
See if you can simplify the code without driving the bug into hiding. If you can make it simpler and still show the problem you might have more likelihood of success in getting Wolfram to admit you have found a bug.
Hy everyones,
I've a little problem with a mathematica script which I need for fitting data points with a sum of 3 sine functions :
fit = NonlinearModelFit[Data,a1*Sin[b1*x + c1] + a2*Sin[b2*x + c2] + a3*Sin[b3*x + c3], {a1, b1,c1, a2, b2, c2, a3, b3, c3}, x]
I get this error :
NonlinearModelFit::cvmit: Failed to converge to the requested accuracy or precision within 100 iterations
I've tried with different starting values and with MaxIteration set to 10.000...
Maybe it's not the right way to do this kind of fitting. Does anyone have an idea about this?
Thanks!
Perhaps your data is too bad, but it works nicely with a good sample:
data = Table[{x, Sin[ x + .3] + 2 Sin[1.2 x] + 3 Sin[1.5 x + .5]},
{x, .01, 8 Pi, .001}];
fit = NonlinearModelFit[data,
a1*Sin[b1*x + c1] + a2*Sin[b2*x + c2] + a3*Sin[b3*x + c3],
{a1, b1, c1, a2, b2, c2, a3, b3, c3}, x]
Show[ListPlot[data], Plot[fit[x], {x, 0, 8 Pi}, PlotStyle -> Red], Frame -> True]
I have a power function pow that attempts to calculate the value of B to the power of E. So far I handle the cases-
1. exponent is 0
2. exponent is non-zero
pow(B,0,1).
pow(B,E,Result):- E2 is E - 1,
pow(B,E2,Result2),
Result is B*Result2.
How can I add another case where the power function can handle negative exponents?
First, one should consider how to define 00. Formally speaking it is indeterminate. It could be zero or it could be 1. As Wolfram's Mathworld says in its article on powers and in its article on zero:
00 (zero to the zeroth power) itself is undefined. The lack of a well-defined meaning for this quantity follows from the mutually contradictory facts that a0 is always 1, so 00 should equal 1, but 0a is always 0 (for a > 0), so 0a should equal 0. The choice of definition for 00 is usually defined to be indeterminate, although defining 00 = 1 allows some formulas to be expressed simply (Knuth 1992; Knuth 1997, p. 57).
So you should first choose how to define the special case of 00: Is it 0? Is it 1? Is it undefined?
I choose to look at it as being undefined.
That being said, you can look at a positive exponent as indicated repeated multiplication (e.g. 103 is 10*10*10, or 1,000), and you can look at a negative exponent as indicating repeated division (e.g, 10-3 is (((1/10)/10)/10), or 0.001). My inclination, partly because I like the symmetry of this approach and partly to avoid the cuts (since a cut is often a signal that you've not defined the solution properly), would be something like this:
% -----------------------------
% The external/public predicate
% -----------------------------
pow( 0 , 0 , _ ) :- ! , fail .
pow( X , N , R ) :-
pow( X , N , 1 , R )
.
% -----------------------------------
% the tail-recursive worker predicate
% -----------------------------------
pow( _ , 0 , R , R ).
pow( X , N , T , R ) :-
N > 0 ,
T1 is T * X ,
N1 is N-1 ,
pow( X , N1 , T1 , R )
.
pow( _ , 0 , R , R ) :-
N < 0 ,
T1 is T / X ,
N1 is N+1 ,
pow( X , N1 , T1 , R )
.
The other approach, as others have noted, is to define a positive exponent as indicating repeated multiplication, and a negative exponent as indicating the reciprocal of the positive exponent, so 103 is 10*10*10 or 1,000, and 10-3 is 1/(103), or 1/1,000 or 0.001. To use this definition, I'd again avoid the cuts and do something like this:
% -----------------------------
% the external/public predicate
% -----------------------------
pow( 0 , 0 , _ ) :- % 0^0 is indeterminate. Is it 1? Is it 0? Could be either.
! ,
fail
.
pow( X , N , R ) :-
N > 0 ,
pow( X , N , 1 , R )
.
pow( X , N , R ) :-
N < 0 ,
N1 = - N ,
pow( X , N1 , 1 , R1 ) ,
R is 1 / R1
.
% -----------------------------------
% The tail-recursive worker predicate
% -----------------------------------
pow( _ , 0 , R , R ).
pow( X , N , T , R ) :-
N > 0 ,
T1 is T * X ,
N1 is N-1 ,
pow( X , N1 , T1 , R )
.
Don't forget that a^(2b) = (a^b)^2 and x^2 = x*x. It is ok to call a tail-recursive working predicate with accumulator, in a non-tail fashion, from a top-level "UI" predicate. That way you don't have to implement working predicate for negative powers but rather reuse the one for positive power, and alter its result in the top-level predicate (I see this has already been suggested):
pow(B, E, R):- E<0 -> ... ; E=:=0 -> ... ; E>0 -> ... .
To start, your second clause is non tail recursive (you can read about the subject here). It means that eventually, you will run out of call stack memory when running it.
A good thing would be to use an accumulator to make it tail recursive. You can achieve that as follows :
% we add an accumulator to poW/3, making it pow/4.
pow(B, E, Result) :- pow(B, E, 1, Result).
% when we hit 0, our accumulator holds B^E so we unify it with result.
pow(_, 0, Accu, Accu) :- !.
% at each step, we multiply our accumulator by B
pow(B, E, Accu, Result) :-
NewE is E - 1,
NewAccu is Accu * B,
pow(B, NewE, NewAccu, Result).
Then, you can simply handle the negative case by adding this clause on top of the others (it simply tells prolog that a negative power is the inverse of the positive one) :
pow(B, E, Result) :-
E < 0,
PositiveE is - E,
pow(B, PositiveE, 1, R),
!,
Result is 1 / R.
Note that you can do it directly with your code :
pow(B, E, Result) :-
E < 0,
PositiveE is - E,
pow(B, PositiveE, R),
!,
Result is 1 / R.
Plus, we now introduced a very red cut (see here for the meaning of red cut if necessary). So it'd be better to turn into a green cut with this modification :
pow(B, E, Result) :-
E < 0,
PositiveE is - E,
pow(B, PositiveE, 1, R),
!,
Result is 1 / R.
% we add an accumulator to poW/3, making it pow/4.
pow(B, E, Result) :-
E >= 0, %************* HERE *****************
pow(B, E, 1, Result).
% when we hit 0, our accumulator holds B^E so we unify it with result.
pow(_, 0, Accu, Accu) :- !.
% at each step, we multiply our accumulator by B
pow(B, E, Accu, Result) :-
NewE is E - 1,
NewAccu is Accu * B,
pow(B, NewE, NewAccu, Result).
I have, for example, the following polynomials to be equated, and I need to determine the unknowns c1, c2, c3, respectively. How can I do this automatically in mma, especially when there are many terms involved?
x+2*x^3+4*x^5==(c1+c2)*(x+2*c2*x^3)+(4-c1)*c3*x^5
Many thanks.
Edit: ideally, I want to equate the coefficients of left and right for the terms with equal exponents in x. Then solve this system of equations.
If this has to be true for all x, you could use SolveAlways (not tested)
SolveAlways[x+2*x^3+4*x^5==(c1+c2)*(x+2*c2*x^3)+(4-c1)*c3*x^5, x]
Try:
p1 = x + 2*x^3 + 4*x^5;
p2 = (c1 + c2)*(x + 2*c2*x^3) + (4 - c1)*c3*x^5;
Solve[CoefficientList[p2, x] == CoefficientList[p1, x], {c1, c2, c3}]
Out
{{c1 -> 0, c2 -> 1, c3 -> 1}}
This should do what you want even in more complicated situations.
eq = x + 2*x^3 + 4*x^5 == (c1 + c2)*(x + 2*c2*x^3) + (4 - c1)*c3*x^5;
list = CoefficientList[eq /. Equal[k__, l__] -> Plus[k, -l], x];
vars = Variables#list;
Solve[list == Table[0, {i, First#Dimensions#list}], vars]
Out[1] := {{c1 -> 0, c2 -> 1, c3 -> 1}}