Related
I am trying to evaluate the following integral:
where the issue lies with variables like F since it is defined as
F[x_, y_] := f[x, y]/(2*Cto[Norm[x]]*Cto[Norm[y]]) and Cto[x_] := C_t[[Round[x]]]
where C_t is a 1d array and x and y are two vector and I need to access the element of C_t corresponding to the integer of the magnitude of x for example. However, this gives me the following errors when evaluating the integral:
Ci = Flatten[Import["Downloads/ctjulien.txt", "table"]]
Cp = Flatten[Import["Downloads/clphiphi.txt", "table"]]
Subscript[C, t] = Flatten[Import["Downloads/ctobs.txt", "table"]]
Lp[a_] := 1052*{Cos[a], Sin[a]}
vL[L_] := {L, 0}
l[l1_, \[CapitalPhi]1_] :=
l1*{Cos[\[CapitalPhi]1], Sin[\[CapitalPhi]1]}
Cii[x_] := Ci[[Round[x]]]
f[x_, y_] := Cii[Norm[x]]*Dot[x + y, x] + Cii[Norm[y]]*Dot[x + y, y]
Cto[x_] := Subscript[C, t][[Round[x]]]
F[x_, y_] := f[x, y]/(2*Cto[Norm[x]]*Cto[Norm[y]])
Cpp[x_] := Cp[[Round[x]]]
NIntegrate[l1*F[l[l1,\[CapitalPhi]],{L,0}-l[l1,\[CapitalPhi]]]*F[Lp[\[CapitalPhi]p],{L,0}-Lp[\[CapitalPhi]p]]*(Dot[Lp[\[CapitalPhi]p],Lp[\[CapitalPhi]p]-l[l1,\[CapitalPhi]]]*If[Norm[Lp[\[CapitalPhi]p]-l[l1,\[CapitalPhi]]]<=2900,Cpp[Norm[Lp[\[CapitalPhi]p]-l[l1,\[CapitalPhi]]]],0]*f[-{L,0}+l[l1,\[CapitalPhi]],{L,0}-Lp[\[CapitalPhi]p]]+Dot[Lp[\[CapitalPhi]p],Lp[\[CapitalPhi]p]-l[{L,0}-l[l1,\[CapitalPhi]],\[CapitalPhi]]]*If[Norm[Lp[\[CapitalPhi]p]-l[{L,0}-l[l1,\[CapitalPhi]],\[CapitalPhi]]]<=2900,Cpp[Norm[Lp[\[CapitalPhi]p]-l[{L,0}-l[l1,\[CapitalPhi]],\[CapitalPhi]]]],0]*f[-l[l1,\[CapitalPhi]],{L,0}-Lp[\[CapitalPhi]p]]),{\[CapitalPhi],-Pi,Pi},{\[CapitalPhi]p,-Pi,Pi},{l1,2,3000}]
This isn't anywhere near an answer yet, but it is a start. Watch out for Subscript and greek characters and use those appropriately when you test this.
If you insert in front of your code
Ci =Table[RandomInteger[{1,10}],{3000}];
Cp =Table[RandomInteger[{1,10}],{3000}];
Ct =Table[RandomInteger[{1,10}],{3000}];
then you can try to test your code without having your data files present.
If you then test your code you get a stream of "The expression Round[Abs[2+L]] cannot be used as a part" but if you instead insert in front of your code L=2 or some other integer assignment then that error goes away
If you use NIntegrate[yourlongexpression...] then you get a stream of "Round[Sqrt[Abs[l1 Cos[phi]]^2+Abs[l1 Sin[phi]]^2 cannot be used as a part" If you instead use fun[phi_?NumericQ, phip_?NumericQ, l1_?NumericQ]:=yourlongexpression;
NIntegrate[fun[phi,phip,l1]...] then that error goes away.
If you use Table[fun[phi,phip,l1],{phi,-Pi,Pi,Pi/2},{phip,-Pi,Pi,Pi/2},{l1,2,10}] instead of your integral and you look carefully at the output then you should see the word List appearing a number of times. That means you have somelist[[0]] somewhere in your code and Mathematica subscripts all start with 1, not with 0 and that has to be tracked down and fixed.
That is probably the first three or four levels of errors that need to found and fixed.
Until now, I change req manually. The code works, including saving the result into a file.
But now I want to run the code for all possible values of req.
Without saving it into a file, the code works but obviously it overwrite the result.
That is why I put that line of code that saving the result by giving it a different name depending of the values of req. But this gives me error.
error:
error: sprintf: wrong type argument 'cell'
error: called from
testforloop at line 26 column 1
my code:
clear all;
clc;
for req = {"del_1", "del_2", "del_3"}
request = req;
if (strcmp(request, "del_1"))
tarr = 11;
# and a bunch of other variables
elseif (strcmp(request, "del_2"))
tarr = 22;
# and a bunch of other variables
elseif (strcmp(request, "del_3"))
tarr = 33;
# and a bunch of other variables
else
# do nothing
endif
#long calculation producing many variable including aa, bb, cc.
aa = 2 * tarr;
bb = 3 * tarr;
cc = 4 * tarr;
#collecting variables of interest: aa, bb, cc and save it to a file.
result_matrix = [aa bb cc];
dlmwrite (sprintf('file_result_%s.csv', request), result_matrix);
endfor
if I use ["del_1" "del_2" "del_3"], the error is
error: 'tarr' undefined near line 20 column 10
error: called from
testforloop at line 20 column 4
Inside the loop
for req = {"del_1", "del_2", "del_3"}
req gets as value each of the cells of the cell array, not the contents of the cells (weird design decision, IMO, but this is the way it works). Thus, req={"del_1"} in the first iteration. The string itself can then be obtained with req{1}. So all you need to change is:
request = req{1};
However, I would implement this differently, as so:
function myfunction(request, tarr)
% long calculation producing many variable including aa, bb, cc.
aa = 2 * tarr;
bb = 3 * tarr;
cc = 4 * tarr;
% collecting variables of interest: aa, bb, cc and save it to a file.
result_matrix = [aa bb cc];
dlmwrite (sprintf('file_result_%s.csv', request), result_matrix);
end
myfunction("del_1", 11)
myfunction("del_2", 22)
myfunction("del_3", 33)
I think this obtains a clearer view of what you're actually doing, the code is less complicated.
Note that in Octave, ["del_1" "del_2" "del_3"] evaluates to "del_1del_2del_3". That is, you concatenate the strings. In MATLAB this is not the case, but Octave doesn't know the string type, and uses " in the same way as ' to create char arrays.
I am having an issue where a field is stored in our database as '##ABC' with no space between the number and letters. The number can be anything from 1-100 and the letters can be any combination, so no consistency of beginning letter or numeric length.
I am trying to find a way to insert a space between the number and letters.
For example, '1DRM' would transform to '1 DRM'
'35PLT' would transform to '35 PLT'
Does anyone know of a way to accomplish this?
You can use regular expressions like the one below (assuming your pattern is digits-characters)
= System.Text.RegularExpressions.Regex.Replace( Fields!txt.Value, "(\d)(\D)", "$1 $2")
Unfortunately, there's no built in function to do this.
Fortunately, Visual Studio lets you create functions to help with things like this.
You can add Visual BASIC custom code by going to the Report Properties and going to the Custom Code tab.
You would just need to write some code to go through some text input character by character. If it finds a number and a letter in the next character, add a space.
Here's what I wrote in a few minutes that seems to work:
Function SpaceNumberLetter(ByVal Text1 AS String) AS String
DIM F AS INTEGER
IF LEN(Text1) < 2 THEN GOTO EndFunction
F = 1
CheckCharacter:
IF ASC(MID(Text1, F, 1)) >= 48 AND ASC(MID(Text1, F, 1)) <=57 AND ASC(MID(Text1, F + 1, 1)) >= 65 AND ASC(MID(Text1, F + 1, 1)) <=90 THEN Text1 = LEFT(Text1, F) + " " + MID(Text1, F+1, LEN(Text1))
F = F + 1
IF F < LEN(Text1) THEN GOTO CheckCharacter
EndFunction:
SpaceNumberLetter = Text1
End Function
Then you call the function from your text box expression:
=CODE.SpaceNumberLetter("56EF78GH12AB34CD")
Result:
I used text to test but you'd use your field.
How can I define a cluster in Haskell using list comprehension?
I want to define a function for the cluster :
( a b c ) = [ a <- [1 .. 10],b<-[2 .. 10], c = (a, b)]
In your comment you gave the example [(1,2,1),(1,3,1),(1,4,1),(1,5,1),(1,6,1),(1,7,1)].
In that example, only the middle number changes, the other two are always 1. You can do this particular one with
ones = [(1,a,1)| a<-[1..7]]
However, you might want to vary the other ones. Let's have a look at how that works, but I'll use letters instead to make it clearer:
> [(1,a,b)| a<-[1..3],b<-['a'..'c']]
[(1,1,'a'),(1,1,'b'),(1,1,'c'),(1,2,'a'),(1,2,'b'),(1,2,'c'),(1,3,'a'),(1,3,'b'),(1,3,'c')]
You can see that the letters are varying more frequently than the numbers - the b<-[1..3] is like an outer loop, with c<-['a'..'c'] being the inner loop.
You could copy the c into the first of the three elements of the tuple:
> [(b,a,b)| a<-[1..3],b<-['a'..'b']]
[('a',1,'a'),('b',1,'b'),('a',2,'a'),('b',2,'b'),('a',3,'a'),('b',3,'b')]
Or give each its own varying input
> [(a,b,c)| a<-[1..2],b<-['a'..'b'],c<-[True,False]]
[(1,'a',True),(1,'a',False),(1,'b',True),(1,'b',False),(2,'a',True),(2,'a',False),(2,'b',True),(2,'b',False)]
The usage message for Set reminds us that multiple assignments can easily be made across two lists, without having to rip anything apart. For example:
Remove[x1, x2, y1, y2, z1, z2];
{x1, x2} = {a, b}
Performs the assignment and returns:
{a, b}
Thread, commonly used to generate lists of rules, can also be called explicitly to achieve the same outcome:
Thread[{y1, y2} = {a, b}]
Thread[{z1, z2} -> {a, b}]
Gives:
{a, b}
{z1 -> a, z2 -> b}
However, employing this approach to generate localized constants generates an error. Consider this trivial example function:
Remove[f];
f[x_] :=
With[{{x1, x2} = {a, b}},
x + x1 + x2
]
f[z]
Here the error message:
With::lvset: "Local variable specification {{x1,x2}={a,b}} contains
{x1,x2}={a,b}, which is an assignment to {x1,x2}; only assignments
to symbols are allowed."
The error message documentation (ref/message/With/lvw), says in the 'More Information' section that, "This message is generated when the first element in With is not a list of assignments to symbols." Given this explanation, I understand the mechanics of why my assignment failed. Nonetheless, I'm puzzled and wondering if this is necessary restriction by WRI, or a minor design oversight that should be reported.
So here's my question:
Can anyone shed some light on this behavior and/or offer a workaround? I experimented with trying to force Evaluation, without luck, and I'm not sure what else to try.
What you request is tricky. This is a job for macros, as already exposed by the others. I will explore a different possibility - to use the same symbols but put some wrappers around the code you want to write. The advantage of this technique is that the code is transformed "lexically" and at "compile-time", rather than at run-time (as in the other answers). This is generally both faster and easier to debug.
So, here is a function which would transform the With with your proposed syntax:
Clear[expandWith];
expandWith[heldCode_Hold] :=
Module[{with},
heldCode /. With -> with //. {
HoldPattern[with[{{} = {}, rest___}, body_]] :>
with[{rest}, body],
HoldPattern[
with[{
Set[{var_Symbol, otherVars___Symbol}, {val_, otherVals___}], rest___},
body_]] :>
with[{{otherVars} = {otherVals}, var = val, rest}, body]
} /. with -> With]
Note that this operates on held code. This has the advantage that we don't have to worry about possible evaluation o the code neither at the start nor when expandWith is finished. Here is how it works:
In[46]:= expandWith#Hold[With[{{x1,x2,x3}={a,b,c}},x+x1+x2+x3]]
Out[46]= Hold[With[{x3=c,x2=b,x1=a},x+x1+x2+x3]]
This is, however, not very convenient to use. Here is a convenience function to simplify this:
ew = Function[code, ReleaseHold#expandWith#Hold#code, HoldAll]
We can use it now as:
In[47]:= ew#With[{{x1,x2}={a,b}},x+x1+x2]
Out[47]= a+b+x
So, to make the expansion happen in the code, simply wrap ew around it. Here is your case for the function's definition:
Remove[f];
ew[f[x_] := With[{{x1, x2} = {a, b}}, x + x1 + x2]]
We now check and see that what we get is an expanded definition:
?f
Global`f
f[x_]:=With[{x2=b,x1=a},x+x1+x2]
The advantage of this approach is that you can wrap ew around an arbitrarily large chunk of your code. What happens is that first, expanded code is generated from it, as if you would write it yourself, and then that code gets executed. For the case of function's definitions, like f above, we cansay that the code generation happens at "compile-time", so you avoid any run-time overhead when usin the function later, which may be substantial if the function is called often.
Another advantage of this approach is its composability: you can come up with many syntax extensions, and for each of them write a function similar to ew. Then, provided that these custom code-transforming functions don't conlict with each other, you can simply compose (nest) them, to get a cumulative effect. In a sense, in this way you create a custom code generator which generates valid Mathematica code from some Mathematica expressions representing programs in your custom languuage, that you may create within Mathematica using these means.
EDIT
In writing expandWith, I used iterative rule application to avoid dealing with evaluation control, which can be a mess. However, for those interested, here is a version which does some explicit work with unevaluated pieces of code.
Clear[expandWithAlt];
expandWithAlt[heldCode_Hold] :=
Module[{myHold},
SetAttributes[myHold, HoldAll];
heldCode //. HoldPattern[With[{Set[{vars__}, {vals__}]}, body_]] :>
With[{eval =
(Thread[Unevaluated[Hold[vars] = Hold[vals]], Hold] /.
Hold[decl___] :> myHold[With[{decl}, body]])},
eval /; True] //. myHold[x_] :> x]
I find it considerably more complicated than the first one though.
The tricky issue is to keep the first argument of Set unevaluated.
Here is my suggestion (open to improvements of course):
SetAttributes[myWith, HoldAll];
myWith[{s : Set[a_List, b_List]}, body_] :=
ReleaseHold#
Hold[With][
Table[Hold[Set][Extract[Hold[s], {1, 1, i}, Hold],
Extract[Hold[s], {1, 2, i}]], {i, Length#b}], Hold#body]
x1 = 12;
Remove[f];
f[x_] := myWith[{{x1, x2} = {a, b}}, x + x1 + x2]
f[z]
results in
a+b+z
Inspired by halirutan below I think his solution, made slightly more safely, is equivalent to the above:
SetAttributes[myWith, HoldAll];
myWith[{Set[a : {__Symbol}, b_List]} /; Length[a] == Length[b],
body_] :=
ReleaseHold#
Hold[With][
Replace[Thread[Hold[a, b]], Hold[x_, y_] :> Hold[Set[x, y]], 1],
Hold#body]
The tutorial "LocalConstants" says
The way With[{x=Subscript[x, 0],...},body] works is to take body, and replace every
occurrence of x, etc. in it by Subscript[x, 0], etc. You can think of With as a
generalization of the /. operator, suitable for application to Mathematica code instead of
other expressions.
Referring to this explanation it seems obvious that something like
x + x1 + x2 /. {x1, x2} -> {a, b}
will not work as it might be expected in the With notation.
Let's assume you really want to hack around this. With[] has the attribute HoldAll, therefore everything you give as first parameter is not evaluated. To make such a vector-assignment work you would have to create
With[{x1=a, x2=b}, ...]
from the vector-notation. Unfortunately,
Thread[{a, b} = {1, 2}]
does not work because the argument to Thread is not held and the assignment is evaluated before Thread can do anything.
Lets fix this
SetAttributes[myThread, HoldFirst];
myThread[Set[a_, b_]] := mySet ### Transpose[{a, b}]
gives
In[31]:= myThread[{a, b, c} = {1, 2, 3}]
Out[31]= {mySet[a, 1], mySet[b, 2], mySet[c, 3]}
What looks promising at first, just moved the problem a bit away. To use this in With[] you have to replace at some point the mySet with the real Set. Exactly then, With[] does not see the list {a=1, b=2, c=3} but, since it has to be evaluated, the result of all assignments
In[32]:= With[
Evaluate[myThread[{a, b, c} = {1, 2, 3}] /. mySet :> Set], a + b + c]
During evaluation of In[32]:= With::lvw: Local
variable specification {1,2,3} contains 1, which is not an assignment to a symbol. >>
Out[32]= With[{1, 2, 3}, a + b + c]
There seems to be not easy way around this and there is a second question here: If there is a way around this restriction, is it as fast as With would be or do we lose the speed advantage compared to Module? And if speed is not so important, why not using Module or Block in the first place?
You could use Transpose to shorten Rolfs solution by 100 characters:
SetAttributes[myWith, HoldAll];
myWith[{Set[a_List, b_List]}, body_] :=
ReleaseHold[Hold[With][Hold[Set[#1, #2]] & ### Transpose[{a, b}],
Hold#body
]]
#Heike, yep the above breaks if either variable has already a value. What about this:
SetAttributes[myWith, HoldAll];
myWith[{Set[a_List, b_List]}, body_] :=
ReleaseHold#
Hold[With][Thread[Hold[a, b]] /. Hold[p__] :> Hold[Set[p]],
Hold#body]