Skip to main content

evaluation - How to return the unevaluated variable names from a list of variables which have been declared


I feel like this should have a simple answer but I haven't found anything that works. The toy example of what I want is as follows:


testx = 1;
testy = 2;
testlist = {testx, testy};


And I'm looking for a function that I could use on testlist (f[testlist]) that will return {testx, testy} in their unevaluated symbols or strings.


I've tried OwnValues, Values, Variables, Information, and various others along with their permutations. My intuition says that some combination of pure functions could do what I want, but I'm still very unsure of how to use most of them.


Edit*


Some context for this problem: I am procedurally defining a function (for example):


func = Sum[ToExpression["a"<>ToString[i]],{i, 1, large_number}]

Separately I generate a list of the variable names which occur in the defintion, like shown above, except in this case it would appear as


varsList = {a1, a2, ... , a}

And I wish to be able to procedurally select the string or undeclared variable symbol from varsList for use in manipulate.



Edit 2*


I'm doing a terrible job asking this question. What I'm attempting to do is use the answer provided here, which allows for manually adjusting parameters within manipulate and then using those manually determined values as starting values for a fit, finally feeding the best-fit values back into the current values for the parameters and allowing for subsequent manual control.


Except in my case, the function must have variable number of parameters. I already procedurally generate my function (as above). But am stuck on how to generate the Sequence of parameters inside manipulate, as well as how to call the symbols for resetting their values to those of the best-fit results. That is the ultimate goal and apparently my previous attempts are not possible.


Final Edit*


I've improved the manipulate functionality shown here to also include procedural generation of a function with variable number of parameters.


To do so required applying Hold to the function and its variables, but this alone was not enough because any attempt to redefine the variables on the LHS of an equation was met with simply trying to define a number as another number. The solution was then to construct the line of code I wanted to run entirely as a string, then Evaluate[ToExpression[[]] it. Code below should run as is, the 4 in testplotfit[] may be changed to any positive integer between 1 and 10 currently, determined by the internal clear command. I truly do wonder why there is no better, or at least more well-known, way to procedurally redefine previously assigned variables.


data = Table[{x, 
8 x^3 - 7 x^2 - 10 x + 1 + RandomReal[{-5, 5}]}, {x, -2, 2, 0.1}];



function[terms_] :=
Sum[ToExpression["a" <> ToString[i]]*x^(i - 1), {i, terms}];
functiontemp[terms_] :=
Sum[ToExpression["b" <> ToString[i]]*x^(i - 1), {i, terms}];

testplotfit[terms_] := DynamicModule[{(*sol, solString*)},
ClearAll[Evaluate[Sequence @@ Table["a" <> ToString[i], {i, 10}]]];
funcString = TextString[function[terms]];
vars =
Thread[Hold@Evaluate[DeleteCases[Variables[function[terms]], x]]];

varsString = ToString[vars[[All, 1]]];
tempvars =
Table[ToExpression["b" <> ToString[i]], {i, Length[vars]}];
solString = ConstantArray["blank", terms];

Manipulate[
If[computeFlag == True,
Evaluate[
sol =
FindFit[data, functiontemp[terms],

Table[{tempvars[[i]], ReleaseHold[vars[[i]]]}, {i,
Length[vars]}], x];
];
Evaluate[
ToExpression[
varsString <> " = " <>(*ToString[solString]*)
ToString[tempvars /. sol]]];
computeFlag = False;
];


Column[
{Dynamic[Button["Compute", computeFlag = True]],
Show[
Plot[#, {x, -2, 2}, PlotStyle -> Black],
ListPlot[data, PlotStyle -> Red],
ImageSize -> 300,
PlotRange -> {{-2.05, 2.05}, All}]}
]

(*;sol*),


{{computeFlag, False}, ControlType -> None},
Evaluate[
Sequence @@
Table[{{i, 1}, -10, 10, Appearance -> "Open"}, {i,
vars[[All, 1]]}]],
LocalizeVariables -> False
] &@function[terms] (*end of Manipulate*)
];


testplotfit[4]

Answer



Why not use 'Hold' ?



testx = 1; testy = 2; testlist = Hold@{testx, testy}
Hold[{testx, testy}]
Thread[%]
{Hold[testx], Hold[testy]}



For the variable names, I would use :




Names["a*"]
{"a1", "a2", "a3", "a4"}



which gives a list of variable names as strings. Those can be turned into variables by



ToExpression



Comments

Popular posts from this blog

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...

equation solving - Invert and fit implicitly defined curve

I need to fit an implicitly defined curve. I thought I could get some data out of Solve , and then using FindFit . Therefore, I would like to find the relation the parametric curve defined by $F(x,y)=0$: Solve[-(1/2) + 1/2 (0.41202 BesselK[0, 0.1 Sqrt[x^2 + y^2]] + (0.101483 x BesselK[1, 0.1 Sqrt[x^2 + y^2]])/Sqrt[x^2 + y^2]) == 0, y] But I can't get an output: Solve was unable to solve the system with inexact coefficients or the system obtained by direct rationalization of inexact numbers present in the system. Since many of the methods used by Solve require exact input, providing Solve with an exact version of the system may help. >> Edit: In particular, I would like to fit the data coming from the curve with the expression of another curve, and not with a function $f(x)$. In particular, since this clearly looks like a cardioid , I would like it to fit to something like it. What other strategies could I try?

dynamic - How can I make a clickable ArrayPlot that returns input?

I would like to create a dynamic ArrayPlot so that the rectangles, when clicked, provide the input. Can I use ArrayPlot for this? Or is there something else I should have to use? Answer ArrayPlot is much more than just a simple array like Grid : it represents a ranged 2D dataset, and its visualization can be finetuned by options like DataReversed and DataRange . These features make it quite complicated to reproduce the same layout and order with Grid . Here I offer AnnotatedArrayPlot which comes in handy when your dataset is more than just a flat 2D array. The dynamic interface allows highlighting individual cells and possibly interacting with them. AnnotatedArrayPlot works the same way as ArrayPlot and accepts the same options plus Enabled , HighlightCoordinates , HighlightStyle and HighlightElementFunction . data = {{Missing["HasSomeMoreData"], GrayLevel[ 1], {RGBColor[0, 1, 1], RGBColor[0, 0, 1], GrayLevel[1]}, RGBColor[0, 1, 0]}, {GrayLevel[0], GrayLevel...