Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Mathematica function writing

  1. Feb 24, 2013 #1
    Hello all,

    It's quite a mouthful but I need help writing a function that will behave as follows:
    1.if called with an argument which is an integer, it will return the absolute value of the input
    2. if called with a real argument, it will return the number rounded to the nearest integer if the argument is positive, zero if the argument is negative.
    3. if called with a complex argument, it will round the real part and the imaginary part to the nearest integer and return the modulus of the result.

    I starting with something like this.
    rr = {a_integer -> Abs[a], a_real -> If[a_real < 0, 0, Integer[a]],
    a_complex ->

    Then I found the 'which' function
    ff[a_] = Which[integer[a], Abs[a], a_Real,
    If[a_real < 0, 0, Integer[a]],
    a_Complex, {Real[a] & Im[a] -> Mod[integer[a]] }]

    However I don't think I'm inputting things correctly.

    Any tips would be appreciated

    Thanks
     
  2. jcsd
  3. Feb 24, 2013 #2
    I'm guessing this is homework, so I'll just provide hints.
    It this REALLY isn't homework then convince me and I'll hand it to you.

    There is no integer[] function.
    Your a_Real and a_Complex are not doing what you may think they are.
    Your Mod[] is not doing what you may think it is.

    Hints:
    Using := instead of = will help you
    IntegerQ[] will help you.
    Im[]==0 will help you.
    Combining two tests using And[] or && will help you.
    Start just implementing part of the requirements, carefully test to see that is working and then add more.
     
  4. Feb 25, 2013 #3

    Hepth

    User Avatar
    Gold Member

    Also, one thing you may be missing is "element", read the help on it.
     
  5. Feb 25, 2013 #4
  6. Feb 27, 2013 #5
    Hello everyone

    Thanks for replying.

    Taking Bills comments on board ( althoughh not sure why Im==0 will be handy?) and using the If function I came up with the following. although still likely gaping errors.

    rr[a_] := [{If[IntegerQ[a_], Abs[a], a] && Re[a_] ->
    If[a > 0, Round[a], 0] && Complex[a_] ->
    Det[Round[Real[a]] && Round[Im[a]]]

    Using the piecewise function;

    rr[a_] := Piecewise[{{Abs[a], IntegerQ[a]}, {Round[a],
    Re[a] /; a >= 0}, {0,
    Re[a] /; a < 0}, {Abs[Round[Re[a] && Im[a]]], Complex[a]}}]

    which doesn't work but seems good.

    The element function could be handy for stating what argument a is eg complex, real or integer. But isn't that done already in specifying conditions using the above mathematica functions.

    Thanks for you're help,

    P.s it is homework
     
  7. Feb 27, 2013 #6
    You are making a little progress.
    Some more tips:

    If you have a_ on the left of your := then you almost always don't want a_ on the right, you almost always want just a on the right.

    Your If[] seems a little mixed up. Perhaps think of it this way
    If[trueORfalseExpression,valueIfItWasTrue, valueIfItWasFalse]
    or just
    If[trueORfalseExpression,valueIfItWasTrue]
    and it returns nothing or null if it was not true.

    In Mathematica almost EVERYTHING is a function, even If[] is a function, similar to the way that Sin[x] is a function. Some of the functions don't return anything useful, but almost everything is still a function. If you keep that in mind then some things may begin to make a little more sense as you learn more about this truly strange language.

    Your -> is usually used for pattern matching substitution, which you don't seem to be doing.

    Perhaps your original Which[] might make this easier for you.
    Which[trueOrfalseExpression,valueIfItWasTrue,
    nexttrueOrfalseExpression,valueIfThatWasTrue,
    evennexttrueOrfalseExpression,valueIfThatWasTrue
    etc.
    ]

    Can you then think of a specific true or false test to do first?
    And the result to return if that is true?
    And then the next specific true or false test to do if the first test was false?
    And the result to return if that second test was true?
    etc.

    You are trying to eliminate one category of inputs and provide a result for those on each line.

    Does that help.

    Awfully nice of you to admit it was homework. I realize too many people today just want someone to do their homework for them.
     
    Last edited: Feb 27, 2013
  8. Feb 28, 2013 #7
    Hello, Thanks for that lengthy reply, It's most helpful.

    I've now got something like this

    ff[a_] := Which[IntegerQ[a], Abs[a], Element[a, Reals],
    If[a < 0, 0, Integer[a]], Element[a, Complexs],
    Abs[Round[Re[a] && Im[a]]]]

    still a bit dodgy I think.

    Thanks
     
  9. Feb 28, 2013 #8
    You are showing you can correctly understand a good hint and figure out how to use it. That is excellent.

    More tips.

    See if Mathematica provides the "Integer" function you are using or not and if not then use a bit of thinking and perhaps a bit of guessing to make your next step.

    Look up Mathematica's definition of the Round function and what kind of arguments it accepts. Then think about what kind of argument you are giving it. Is what you are doing with that correct or not? Likewise for the Abs function.

    Then explore using various inputs to your ff function to test each kind of possible input that it is supposed to accept. Verify which kinds of inputs are giving correct results. Make sure to test "boundaries" carefully. For example, if it is supposed to do one thing with a positive input and a different thing with a negative input then make sure that it does the right thing when given something on the boundary between those two, zero.

    Keep up the good work and I think you will perhaps do well with this.
     
  10. Mar 1, 2013 #9
    ff[a_] :=
    Which[IntegerQ[a], Abs[a], Element[a, Reals],
    If[a < 0, 0, IntegerPart[a]],
    Element[a, Complexs], {Abs[Round[Re[a]]]} && Abs[Round[Im[a]]]]

    It now works for getting the real number rounded to the nearest integer if positive.It doesn't make it 0 if -ve though.

    As far as I can see Abs is the only function to use and the inputs for that and Round are ok.

    Thanks
     
  11. Mar 2, 2013 #10
    Complexs is misspelled. Mathematica is FANATIC about exactly correct spelling and capitalization and will give you nothing, error messages you probably won't know what to do with or incorrect answers with the tiniest error in this.

    In[1]:= ff[a_]:=Which[
    IntegerQ[a],Abs[a],
    Element[a,Reals],If[a<0,0,IntegerPart[a]],
    Element[a,Complexes],{Abs[Round[Re[a]]]}&&Abs[Round[Im[a]]]];

    {{-5,ff[-5]},{-1,ff[-1]},{0,ff[0]},{1,ff[1]},{5,ff[5]},
    {-5.6,ff[-5.6]},{-5.5,ff[-5.5]},{-5.4,ff[-5.4]},
    {5.4,ff[5.4]},{5.5,ff[5.5]},{5.6,ff[5.6]},
    {-5.6-5.6I,ff[-5.6-5.6I]}}

    Out[2]= {{-5, 5}, {-1, 1}, {0, 0}, {1, 1}, {5, 5},
    {-5.6, 0}, {-5.5, 0}, {-5.4, 0},
    {5.4, 5}, {5.5, 5}, {5.6, 5},
    {-5.6 - 5.6*I, {6} && 6}}

    It doesn't look to me like the third line of output satisfies the specification you originally gave and you should be able to figure out what to do to fix that.
    It doesn't look to me like the fourth line of output satisfies the specification and perhaps studying the definition of modulus for complex numbers will enable you to figure out what to do to fix that.

    Then you should try lots more test cases to verify all the special cases and boundary conditions you can think of.

    You are making considerable progress.
     
  12. Mar 4, 2013 #11
    Thanks for all you're help,

    Think I got it now
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook