Consider a situation where you have data in a list of the form
data = {{x1, x2, x3, ..., xn, y}, {...}, ..., {...}}
For example,
data = {{0, 2, 3, 2}, {0, 0, 1, 4}, {7, 6, 8, 3}}
I'd like to fit the data to a multivariate polynomial of order, say, 2.
So, the 3-variable function values are:
{2, 4, 3}
in respective points
{{0, 2, 3}, {0, 0, 1}, {7, 6, 8}}
I'd say something like
Fit[data, {1, x, y, z, x^2, y^2, z^2, x y , x z, y z}, {x, y, z}]
This is all very nice, but i may not have only 3-variate data, there may be an arbitrary number of variables, and I don't know how to programmatically generate all the linear, quadratic or even higher-order terms, to insert them as the second argument of Fit[].
For 4-variate date do second order, it would be something like:
{1, x1, x2, x3, x4, x1^2, x2^2, x3^2, x4^2, x1 x2, x1 x3, x1 x4, x2 x3, x2 x4, x3 x4}
Is there any way I can generate such a list for n variables, to m-th order?
Like terms (without coefficients) in a m-order power series expansion of an n-variable function.
Does this do what you want?
Union[Times ### Tuples[{1, x, y, z}, 2]]
While the solution of #ruebenko is perfectly correct, I'd like to mention that it will be quite slow for higher powers / larger number of variables, because of the complexity of Tuples and lots of duplicates for higher powers. Here is an algebraic method with a much better performance for those cases (both run-time and memory-wise):
List ## Expand[(1 + x + y + z + t)^2] /. a_Integer*b_ :> b
Here is a comparison for large number of variables:
In[257]:= (res1=Union[Times###Tuples[{1,x,y,z,t},9]])//Short//Timing
Out[257]= {19.345,{1,t,t^2,t^3,t^4,t^5,t^6,t^7,t^8,t^9,x,<<694>>,x^2 z^7,y z^7,
t y z^7,x y z^7,y^2 z^7,z^8,t z^8,x z^8,y z^8,z^9}}
In[259]:= (res2=List##Expand[(1+x+y+z+t)^9]/. a_Integer*b_:>b)//Short//Timing
Out[259]= {0.016,{1,t,t^2,t^3,t^4,t^5,t^6,t^7,t^8,t^9,x,<<694>>,x^2 z^7,y z^7,
t y z^7,x y z^7,y^2 z^7,z^8,t z^8,x z^8,y z^8,z^9}}
In[260]:= res1===res2
Out[260]= True
In this case, we observe a 1000x speedup, but generally the two methods just have different computational complexities. The above code is an application of a general and nice method, called Algebraic Programming. For an interesting discussion of it in the context of Mathematica, see this Mathematica Journal paper by Andrzej Kozlowski.
Using #ruebenko's neat solution,
varsList[y_, n_?IntegerQ, k_?IntegerQ] :=
Union[Times ###
Tuples[Prepend[Table[Subscript[y, i], {i, 1, n}], 1], k]]
you can generate desired list via varsList[x, 4, 2].
Here is another method that I believe is worth knowing:
set = {1, x, y, z};
Union ## Outer[Times, set, set]
Related
I wanted to calculate the probability associated to a given chi-squared value for any given number of degrees of freedom k. I could easily come up with this code:
P[chisquare_, k_] = Manipulate[NIntegrate[PDF[ChiSquareDistribution[k], x], {x, chisquare, Infinity}], {chisquare, 0, 10}, {k, 1, 10}]
but I was wondering: is there any way to do the opposite? I mean having the probability P as an input and getting the associated chi squared value? like if I wanted to compile a chi-squared table such as this https://www.medcalc.org/manual/chi-square-table.php
I tried using Solve but did not accomplish anything, is there an easy way around this?
You can do the integration with CFD and reverse with Quantile, e.g.
NIntegrate[PDF[ChiSquareDistribution[2], a], {a, 0, 3.0}]
0.77687
p = CDF[ChiSquareDistribution[2], 3.0]
0.77687
Quantile[ChiSquareDistribution[2], p]
Re. your link
Quantile[ChiSquareDistribution[2], 1 - #] & /# {0.995, 0.975, 0.20, 0.10, 0.05};
SetPrecision[#, If[# < 1, 3, 4]] & /# %
{0.0100, 0.0506, 3.219, 4.605, 5.991}
I am completely new to Mathematica and I need some help (sorry if it is trivial, but I haven't found the answer). I have this code
K[Q_, n_Integer] := Module[{z, x}, SymmetricReduction[
SeriesCoefficient[
Product[ComposeSeries[Series[Q[z], {z, 0, n}],
Series[x[i] z, {z, 0, n}]], {i, 1, n}], n],
Table[x[i], {i, 1, n}], Table[Subscript[c, i], {i, 1, n}]][[1]]]
Then I call this:
K[ Sqrt[#]/Tanh[Sqrt[#]]&, 8] /. c->p
The output is a polynomial in p1, p2 ... p8 (in this case) with coefficients written as fractions (23412/7538293, for example). What should I do in order to output the numerator and denominator of each function in it's prime factorization (preferably factor out the common divisor of the denominator)?
Thank you!
I'm using FeynCalc to calculate Compton's scattering. I need to use specific values for the components of the photon polarization four-vector. How can I do that?
I am going to give a short answer here, for more details, see my answer on Mathematica StackExchange:
https://mathematica.stackexchange.com/questions/161767/can-i-specify-the-components-of-fourvector-in-feyncalc/204639#204639
So, one can define the two functions
Mink[t1_, t2_] :=
t1[[1]] t2[[1]] - t1[[2]] t2[[2]] - t1[[3]] t2[[3]] -
t1[[4]] t2[[4]];
LevContracted[a_, b_, c_, d_] :=
Sum[-LeviCivitaTensor[
4][[mu, nu, alpha, beta]]] a[[mu]] b[[nu]] c[[alpha]] d[[beta]], {mu, 1, 4}, {nu, 1, 4}, {alpha, 1,
4}, {beta, 1, 4}];
and define vectors as lists, e.g.
p = {x, y, z, w};
in order to calculate fully contracted amplitudes. Here, I am working with the signature (+---). The additional minus sign in the second function arises from the convention that ɛ^{0123}=+1 and our vectors are taken to be contravariant.
Suppose I want to construct a matrix A such that A[[i,i]]=f[x_,y_]+d[i], A[[i,i+1]]=u[i], A[[i+1,i]]=l[i], i=1,N . Say, f[x_,y_]=x^2+y^2.
How can I code this in Mathematica?
Additionally, if I want to integrate the first diagonal element of A, i.e. A[[1,1]] over x and y, both running from 0 to 1, how can I do that?
In[1]:= n = 4;
f[x_, y_] := x^2 + y^2;
A = Normal[SparseArray[{
{i_,i_}/;i>1 -> f[x,y]+ d[i],
{i_,j_}/;j-i==1 -> u[i],
{i_,j_}/;i-j==1 -> l[i-1],
{1, 1} -> Integrate[f[x,y]+d[1], {x,0,1}, {y,0,1}]},
{n, n}]]
Out[3]= {{2/3+d[1], l[1], 0, 0},
{u[1], x^2+y^2+ d[2], l[2], 0},
{0, u[2], x^2+y^2+d[3], l[3]},
{0, 0, u[3], x^2+y^2+d[4]}}
Band is tailored specifically for this:
myTridiagonalMatrix#n_Integer?Positive :=
SparseArray[
{ Band#{1, 1} -> f[x, y] + Array[d, n]
, Band#{1, 2} -> Array[u, n - 1]
, Band#{2, 1} -> Array[l, n - 1]}
, {n, n}]
Check it out (no need to define f, d, u, l):
myTridiagonalMatrix#5 // MatrixForm
Note that MatrixForm should not be part of a definition. For example, it's a bad idea to set A = (something) // MatrixForm. You will get a MatrixForm object instead of a table (= array of arrays) or a sparse array, and its only purpose is to be pretty-printed in FrontEnd. Trying to use MatrixForm in calculations will yield errors and will lead to unnecessary confusion.
Integrating the element at {1, 1}:
myTridiagonalMatrixWithFirstDiagonalElementIntegrated#n_Integer?Positive :=
MapAt[
Integrate[#, {x, 0, 1}, {y, 0, 1}]&
, myTridiagonalMatrix#n
, {1, 1}]
You may check it out without defining f or d, as well:
myTridiagonalMatrixWithFirstDiagonalElementIntegrated#5
The latter operation, however, looks suspicious. For example, it does not leave your matrix (or its corresponding linear system) invariant w.r.t. reasonable transformations. (This operation does not even preserve linearity of matrices.) You probably don't want to do it.
Comment on comment above: there's no need to define A[x_, y_] := … to Integrate[A[[1,1]], {x,0,1}, {y,0,1}]. Note that A[[1,1]] is totally different from A[1, 1]: the former is Part[A, 1, 1] which is a certain element of table A. A[1, 1] is a different expression: if A is some table then A[1, 1] is (that table)[1, 1], which is a valid expression but is normally considered meaningless.
I have two arrays, say A={1, 2, 3} and B={2, 4, 8} (array item count and numbers may vary). How do I find a bijection between the arrays.
In this case, it would be f:A->B; f(x)=2^(x)
I don't think this problem has a general solution. You may try FindSequenceFunction, but it will not always find the solution. For the case at hand, you'd need a bit longer lists:
In[250]:= FindSequenceFunction[Transpose[{{1, 2, 3}, {2, 4, 8}}], n]
Out[250]= FindSequenceFunction[{{1, 2}, {2, 4}, {3, 8}}, n]
but
In[251]:= FindSequenceFunction[Transpose[{{1, 2, 3, 4}, {2, 4, 8, 16}}], n]
Out[251]= 2^n
You can also play with FindFit, if you have some guesses about the bijection:
In[252]:= FindFit[Transpose[{{1, 2, 3}, {2, 4, 8}}], p*q^x, {p, q}, x]
Out[252]= {p -> 1., q -> 2.}
As others have remarked, this problem is ill-defined.
Other possible functions that give the same results are (among probably infinite others): (8 x)/3 - x^2 + x^3/3, x + (37 x^2)/18 - (4 x^3)/3 + (5 x^4)/18, and (259 x^3)/54 - (31 x^4)/9 + (35 x^5)/54.
I found these solutions using:
n = 5; (* try various other values *)
A = {1, 2, 3} ; B = {2, 4, 8}
eqs = Table[
Sum[a[i] x[[1]]^i, {i, n}] == x[[2]], {x, {A, B}\[Transpose]}]
sol = Solve[eqs, Table[a[i], {i, n}], Reals]
Sum[a[i] x^i, {i, n}] /. sol
Sometimes not all of the a[i]'s are fully determined and you may come up with values of your own.
[tip: better not use variables starting with a capital letter in Mathematica so as not to get into conflict with reserved words]
Since you tag Mathematica, I'll use Mathematica functions as a reference.
If you are interested in an arbitrary fit of your data with a smooth function, you can use Interpolation. E.g.
a = {1, 2, 3}; b = {2, 4, 8};
f = Interpolation[Transpose[{a, b}]];
(* Graph the interpolation function *)
Show[Plot[f[x], {x, 1, 3}], Graphics[Point /# Transpose[{a, b}]],
PlotRange -> {{0, 4}, {0, 9}}, Frame -> Automatic, Axes -> None]
Interpolation uses piecewise polynomials. You can do the same in your favorite programming language if you happen know or are willing to learn a bit about numerical methods, especially B-Splines.
If instead you know something about your data, e.g. that it is of the form c d^x, then you can do a minimization to find the unknowns (c and d in this case). If your data is in fact generated from the form c d^x, then the fit will be fairly, otherwise it's the error is minimized in the least-squares sense. So for your data:
FindFit[Transpose[{a, b}], c d^x, {c, d}, {x}]
reports:
{c -> 1., d -> 2.}
Indicating that your function is 2^x, just as you knew all along.